blob: 8d4b9f33be9f3c5658ddad6e7bbb0f742a6ca334 [file] [log] [blame]
Theodore Ts'o583a1ce2002-05-11 13:00:22 -04001/*
2
3/usr/src/ext2ed/inode_com.c
4
5A part of the extended file system 2 disk editor.
6
7Commands relevant to ext2_inode type.
8
9First written on: April 9 1995
10
11Copyright (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
22void 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;
Theodore Ts'oefc6f622008-08-27 23:07:54 -040054
Theodore Ts'o583a1ce2002-05-11 13:00:22 -040055 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 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -040062
Theodore Ts'o583a1ce2002-05-11 13:00:22 -040063 if (entry_num==0) {
64 wprintw (command_win,"Reached first inode in current group descriptor\n");
65 refresh_command_win ();
66 }
67}
68
69void 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);
Theodore Ts'oefc6f622008-08-27 23:07:54 -040080
Theodore Ts'o583a1ce2002-05-11 13:00:22 -040081 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;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400102
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400103 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 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400110
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400111 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
118void type_ext2_inode___show (char *command_line)
119
120{
121 struct ext2_inode *inode_ptr;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400122
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400123 unsigned short temp;
124 int i;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400125
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400126 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,"-");
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400153
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400154 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;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400171
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400172 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,"-");
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400207
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400208 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);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400214
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400215 wprintw (show_win,"Inode type: ");
216
Theodore Ts'o0f31c732002-05-11 13:03:25 -0400217 if (inode_num < EXT2_GOOD_OLD_FIRST_INO) {
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400218 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;
JP Abgralle0ed7402014-03-19 19:08:39 -0700225 case EXT4_USR_QUOTA_INO:
226 wprintw (show_win,"User quota inode - ");
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400227 break;
JP Abgralle0ed7402014-03-19 19:08:39 -0700228 case EXT4_GRP_QUOTA_INO:
229 wprintw (show_win,"Group quota inode - ");
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400230 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. ");
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400244
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400245 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
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400258 wprintw (show_pad,"Slow symbolic link\n");
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400259 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 ();
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400269
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400270 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
282void 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 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400308
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400309 else if (wanted_entry < entry_num) {
310 sprintf (buffer,"prev %ld",entry_num-wanted_entry);
311 dispatch (buffer);
312 }
313}
314
315void type_ext2_inode___group (char *command_line)
316
317{
318 char buffer [80];
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400319
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400320 long group_num,group_offset;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400321
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400322 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);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400324
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400325 sprintf (buffer,"setoffset %ld",group_offset);dispatch (buffer);
326 sprintf (buffer,"settype ext2_group_desc");dispatch (buffer);
327}
328
329void type_ext2_inode___file (char *command_line)
330
331{
332 char buffer [80];
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400333
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400334 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 ();
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400336 return;
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400337 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400338
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400339 if (!init_file_info ()) {
340 wprintw (command_win,"Error - Unable to show file\n");refresh_command_win ();
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400341 return;
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400342 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400343
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400344 sprintf (buffer,"settype file");dispatch (buffer);
345}
346
347void type_ext2_inode___dir (char *command_line)
348
349{
350 char buffer [80];
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400351
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400352 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 ();
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400354 return;
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400355 }
356
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400357/* It is very important to init first_file_info first, as search_dir_entries relies on it */
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400358
359 if (!init_dir_info (&first_file_info)) {
360 wprintw (command_win,"Error - Unable to show directory\n");refresh_command_win ();
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400361 return;
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400362 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400363
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400364 file_info=first_file_info;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400365
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400366 sprintf (buffer,"settype dir");dispatch (buffer);
367}
368
369long inode_offset_to_group_num (long inode_offset)
370
371{
372 int found=0;
373 struct ext2_group_desc desc;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400374
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400375 long block_num,group_offset,group_num;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400376
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400377 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 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400390
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400391 if (!found)
392 return (-1);
393
394 return (group_num);
395}
396
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400397
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400398
399long 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;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400416
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400417 return (inode_num);
418}
419
420long 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--;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400427
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400428 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}