Merge change 9990
[android/platform/external/e2fsprogs.git] / ext2ed / inode_com.c
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
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
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
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 EXT2_ACL_IDX_INO:
226                                 wprintw (show_win,"ACL index inode - ");
227                                 break;
228                         case EXT2_ACL_DATA_INO:
229                                 wprintw (show_win,"ACL data 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
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
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
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
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
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
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
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 }