1 /*
2
3 /usr/src/ext2ed/inode_com.c
4
5 A part of the extended file system 2 disk editor.
6
7 Commands relevant to ext2_inode type.
8
9 First written on: April 9 1995
10
11 Copyright (C) 1995 Gadi Oxman
12
13 */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <time.h>
19
20 #include "ext2ed.h"
21
type_ext2_inode___prev(char * command_line)22 void type_ext2_inode___prev (char *command_line)
23
24 {
25
26 char *ptr,buffer [80];
27
28 long group_num,group_offset,entry_num,block_num,first_entry,last_entry;
29 long inode_num,mult=1;
30 struct ext2_group_desc desc;
31
32 ptr=parse_word (command_line,buffer);
33
34 if (*ptr!=0) {
35 ptr=parse_word (ptr,buffer);
36 mult=atol (buffer);
37 }
38
39 block_num=device_offset/file_system_info.block_size;
40
41 group_num=inode_offset_to_group_num (device_offset);
42 group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
43
44 low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
45
46 entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
47
48 first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
49 inode_num=0;
50
51 if (entry_num-mult+1>0) {
52 device_offset-=sizeof (struct ext2_inode)*mult;
53 entry_num-=mult;
54
55 sprintf (buffer,"setoffset %ld",device_offset);dispatch (buffer);
56 strcpy (buffer,"show");dispatch (buffer);
57 }
58
59 else {
60 wprintw (command_win,"Error - Entry out of limits\n");refresh_command_win ();
61 }
62
63 if (entry_num==0) {
64 wprintw (command_win,"Reached first inode in current group descriptor\n");
65 refresh_command_win ();
66 }
67 }
68
type_ext2_inode___next(char * command_line)69 void type_ext2_inode___next (char *command_line)
70
71 {
72
73 char *ptr,buffer [80];
74
75 long group_num,group_offset,entry_num,block_num,first_entry,last_entry;
76 long inode_num,mult=1;
77 struct ext2_group_desc desc;
78
79 ptr=parse_word (command_line,buffer);
80
81 if (*ptr!=0) {
82 ptr=parse_word (ptr,buffer);
83 mult=atol (buffer);
84 }
85
86
87 block_num=device_offset/file_system_info.block_size;
88
89 group_num=inode_offset_to_group_num (device_offset);
90 group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
91
92 low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
93
94 entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
95
96 first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
97 inode_num=0;
98
99 if (entry_num+mult-1<last_entry) {
100 device_offset+=sizeof (struct ext2_inode)*mult;
101 entry_num+=mult;
102
103 sprintf (buffer,"setoffset %ld",device_offset);dispatch (buffer);
104 strcpy (buffer,"show");dispatch (buffer);
105 }
106
107 else {
108 wprintw (command_win,"Error - Entry out of limits\n");refresh_command_win ();
109 }
110
111 if (entry_num==last_entry) {
112 wprintw (command_win,"Reached last inode in current group descriptor\n");
113 refresh_command_win ();
114 }
115 }
116
117
type_ext2_inode___show(char * command_line)118 void type_ext2_inode___show (char *command_line)
119
120 {
121 struct ext2_inode *inode_ptr;
122
123 unsigned short temp;
124 int i;
125
126 long group_num,group_offset,entry_num,block_num,first_entry,last_entry,inode_num;
127 struct ext2_group_desc desc;
128
129 block_num=device_offset/file_system_info.block_size;
130
131 group_num=inode_offset_to_group_num (device_offset);
132 group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
133
134 low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
135
136 entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
137 first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
138 inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1;
139 inode_num+=entry_num;
140
141 inode_ptr=&type_data.u.t_ext2_inode;
142
143 show (command_line);
144
145 wmove (show_pad,0,40);wprintw (show_pad,"octal = %06o ",inode_ptr->i_mode);
146 for (i=6;i>=0;i-=3) {
147 temp=inode_ptr->i_mode & 0x1ff;
148 temp=temp >> i;
149 if (temp & 4)
150 wprintw (show_pad,"r");
151 else
152 wprintw (show_pad,"-");
153
154 if (temp & 2)
155 wprintw (show_pad,"w");
156 else
157 wprintw (show_pad,"-");
158
159 if (temp & 1)
160 wprintw (show_pad,"x");
161 else
162 wprintw (show_pad,"-");
163 }
164 wmove (show_pad,3,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_atime));
165 wmove (show_pad,4,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_ctime));
166 wmove (show_pad,5,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_mtime));
167 wmove (show_pad,6,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_dtime));
168
169 wmove (show_pad,10,40);
170 temp=inode_ptr->i_flags;
171
172 if (temp & EXT2_SECRM_FL)
173 wprintw (show_pad,"s");
174 else
175 wprintw (show_pad,"-");
176
177
178 if (temp & EXT2_UNRM_FL)
179 wprintw (show_pad,"u");
180 else
181 wprintw (show_pad,"-");
182
183 if (temp & EXT2_COMPR_FL)
184 wprintw (show_pad,"c");
185 else
186 wprintw (show_pad,"-");
187
188 if (temp & EXT2_SYNC_FL)
189 wprintw (show_pad,"S");
190 else
191 wprintw (show_pad,"-");
192
193 if (temp & EXT2_IMMUTABLE_FL)
194 wprintw (show_pad,"i");
195 else
196 wprintw (show_pad,"-");
197
198 if (temp & EXT2_APPEND_FL)
199 wprintw (show_pad,"a");
200 else
201 wprintw (show_pad,"-");
202
203 if (temp & EXT2_NODUMP_FL)
204 wprintw (show_pad,"d");
205 else
206 wprintw (show_pad,"-");
207
208 refresh_show_pad ();
209
210 wmove (show_win,1,0);
211
212 wprintw (show_win,"Inode %ld of %ld. Entry %ld of %ld in group descriptor %ld.\n"
213 ,inode_num,file_system_info.super_block.s_inodes_count,entry_num,last_entry,group_num);
214
215 wprintw (show_win,"Inode type: ");
216
217 if (inode_num < EXT2_GOOD_OLD_FIRST_INO) {
218 switch (inode_num) {
219 case EXT2_BAD_INO:
220 wprintw (show_win,"Bad blocks inode - ");
221 break;
222 case EXT2_ROOT_INO:
223 wprintw (show_win,"Root inode - ");
224 break;
225 case EXT4_USR_QUOTA_INO:
226 wprintw (show_win,"User quota inode - ");
227 break;
228 case EXT4_GRP_QUOTA_INO:
229 wprintw (show_win,"Group quota inode - ");
230 break;
231 case EXT2_BOOT_LOADER_INO:
232 wprintw (show_win,"Boot loader inode - ");
233 break;
234 case EXT2_UNDEL_DIR_INO:
235 wprintw (show_win,"Undelete directory inode - ");
236 break;
237 default:
238 wprintw (show_win,"Reserved inode - ");
239 break;
240 }
241 }
242 if (type_data.u.t_ext2_inode.i_mode==0)
243 wprintw (show_win,"Free. ");
244
245 if (S_ISREG (type_data.u.t_ext2_inode.i_mode))
246 wprintw (show_win,"File. ");
247
248 if (S_ISDIR (type_data.u.t_ext2_inode.i_mode))
249 wprintw (show_win,"Directory. ");
250
251 if (S_ISLNK (type_data.u.t_ext2_inode.i_mode)) {
252 wprintw (show_win,"Symbolic link. ");
253 wmove (show_pad,12,40);
254
255 if (inode_ptr->i_size <= 60)
256 wprintw (show_pad,"-> %s",(char *) &type_data.u.t_ext2_inode.i_block [0]);
257 else
258 wprintw (show_pad,"Slow symbolic link\n");
259 refresh_show_pad ();
260 }
261
262 if (S_ISCHR (type_data.u.t_ext2_inode.i_mode))
263 wprintw (show_win,"Character device.");
264
265 if (S_ISBLK (type_data.u.t_ext2_inode.i_mode))
266 wprintw (show_win,"Block device. ");
267
268 wprintw (show_win,"\n");refresh_show_win ();
269
270 if (entry_num==last_entry) {
271 wprintw (command_win,"Reached last inode in current group descriptor\n");
272 refresh_command_win ();
273 }
274
275 if (entry_num==first_entry) {
276 wprintw (command_win,"Reached first inode in current group descriptor\n");
277 refresh_command_win ();
278 }
279
280 }
281
type_ext2_inode___entry(char * command_line)282 void type_ext2_inode___entry (char *command_line)
283
284 {
285 char *ptr,buffer [80];
286
287 long group_num,group_offset,entry_num,block_num,wanted_entry;
288 struct ext2_group_desc desc;
289
290 ptr=parse_word (command_line,buffer);
291 if (*ptr==0) return;
292 ptr=parse_word (ptr,buffer);
293 wanted_entry=atol (buffer);
294
295 block_num=device_offset/file_system_info.block_size;
296
297 group_num=inode_offset_to_group_num (device_offset);
298 group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
299
300 low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
301
302 entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
303
304 if (wanted_entry > entry_num) {
305 sprintf (buffer,"next %ld",wanted_entry-entry_num);
306 dispatch (buffer);
307 }
308
309 else if (wanted_entry < entry_num) {
310 sprintf (buffer,"prev %ld",entry_num-wanted_entry);
311 dispatch (buffer);
312 }
313 }
314
type_ext2_inode___group(char * command_line)315 void type_ext2_inode___group (char *command_line)
316
317 {
318 char buffer [80];
319
320 long group_num,group_offset;
321
322 group_num=inode_offset_to_group_num (device_offset);
323 group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
324
325 sprintf (buffer,"setoffset %ld",group_offset);dispatch (buffer);
326 sprintf (buffer,"settype ext2_group_desc");dispatch (buffer);
327 }
328
type_ext2_inode___file(char * command_line)329 void type_ext2_inode___file (char *command_line)
330
331 {
332 char buffer [80];
333
334 if (!S_ISREG (type_data.u.t_ext2_inode.i_mode)) {
335 wprintw (command_win,"Error - Inode type is not file\n");refresh_command_win ();
336 return;
337 }
338
339 if (!init_file_info ()) {
340 wprintw (command_win,"Error - Unable to show file\n");refresh_command_win ();
341 return;
342 }
343
344 sprintf (buffer,"settype file");dispatch (buffer);
345 }
346
type_ext2_inode___dir(char * command_line)347 void type_ext2_inode___dir (char *command_line)
348
349 {
350 char buffer [80];
351
352 if (!S_ISDIR (type_data.u.t_ext2_inode.i_mode)) {
353 wprintw (command_win,"Error - Inode type is not directory\n");refresh_command_win ();
354 return;
355 }
356
357 /* It is very important to init first_file_info first, as search_dir_entries relies on it */
358
359 if (!init_dir_info (&first_file_info)) {
360 wprintw (command_win,"Error - Unable to show directory\n");refresh_command_win ();
361 return;
362 }
363
364 file_info=first_file_info;
365
366 sprintf (buffer,"settype dir");dispatch (buffer);
367 }
368
inode_offset_to_group_num(long inode_offset)369 long inode_offset_to_group_num (long inode_offset)
370
371 {
372 int found=0;
373 struct ext2_group_desc desc;
374
375 long block_num,group_offset,group_num;
376
377 block_num=inode_offset/file_system_info.block_size;
378
379 group_offset=file_system_info.first_group_desc_offset;
380 group_num=(group_offset-file_system_info.first_group_desc_offset)/sizeof (struct ext2_group_desc);
381
382 while (!found && group_num>=0 && group_num<file_system_info.groups_count) {
383 low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
384 if (block_num>=desc.bg_inode_table && block_num<desc.bg_inode_table+file_system_info.blocks_per_group)
385 found=1;
386 else
387 group_offset+=sizeof (struct ext2_group_desc);
388 group_num=(group_offset-file_system_info.first_group_desc_offset)/sizeof (struct ext2_group_desc);
389 }
390
391 if (!found)
392 return (-1);
393
394 return (group_num);
395 }
396
397
398
inode_offset_to_inode_num(long inode_offset)399 long int inode_offset_to_inode_num (long inode_offset)
400
401 {
402 long group_num,group_offset,entry_num,block_num,first_entry,last_entry,inode_num;
403 struct ext2_group_desc desc;
404
405 block_num=inode_offset/file_system_info.block_size;
406
407 group_num=inode_offset_to_group_num (inode_offset);
408 group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
409
410 low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
411
412 entry_num=(inode_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
413 first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
414 inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1;
415 inode_num+=entry_num;
416
417 return (inode_num);
418 }
419
inode_num_to_inode_offset(long inode_num)420 long int inode_num_to_inode_offset (long inode_num)
421
422 {
423 long group_num,group_offset,inode_offset,inode_entry;
424 struct ext2_group_desc desc;
425
426 inode_num--;
427
428 group_num=inode_num/file_system_info.super_block.s_inodes_per_group;
429 inode_entry=inode_num%file_system_info.super_block.s_inodes_per_group;
430 group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
431 low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
432
433 inode_offset=desc.bg_inode_table*file_system_info.block_size+inode_entry*sizeof (struct ext2_inode);
434
435 return (inode_offset);
436 }
437