Whamcloud - gitweb
debian: add support for DEB_BUILD_OPTIONS=parallel=N
[tools/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 "config.h"
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <time.h>
20
21 #include "ext2ed.h"
22
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
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
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
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
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
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
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
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
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
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 }