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