]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - ext2ed/inode_com.c
libext2fs: fix potential divide by zero bug caused by a lxcfs bug
[thirdparty/e2fsprogs.git] / ext2ed / inode_com.c
CommitLineData
583a1ce5
TT
1/*
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
d1154eb4 15#include "config.h"
583a1ce5
TT
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <time.h>
20
21#include "ext2ed.h"
22
23void 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;
efc6f628 55
583a1ce5
TT
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 }
efc6f628 63
583a1ce5
TT
64 if (entry_num==0) {
65 wprintw (command_win,"Reached first inode in current group descriptor\n");
66 refresh_command_win ();
67 }
68}
69
70void 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);
efc6f628 81
583a1ce5
TT
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;
efc6f628 103
583a1ce5
TT
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 }
efc6f628 111
583a1ce5
TT
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
119void type_ext2_inode___show (char *command_line)
120
121{
122 struct ext2_inode *inode_ptr;
efc6f628 123
583a1ce5
TT
124 unsigned short temp;
125 int i;
efc6f628 126
583a1ce5
TT
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,"-");
efc6f628 154
583a1ce5
TT
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;
efc6f628 172
583a1ce5
TT
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,"-");
efc6f628 208
583a1ce5
TT
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);
efc6f628 215
583a1ce5
TT
216 wprintw (show_win,"Inode type: ");
217
0f31c737 218 if (inode_num < EXT2_GOOD_OLD_FIRST_INO) {
583a1ce5
TT
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;
0edcc270
AK
226 case EXT4_USR_QUOTA_INO:
227 wprintw (show_win,"User quota inode - ");
583a1ce5 228 break;
0edcc270
AK
229 case EXT4_GRP_QUOTA_INO:
230 wprintw (show_win,"Group quota inode - ");
583a1ce5
TT
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. ");
efc6f628 245
583a1ce5
TT
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
efc6f628 259 wprintw (show_pad,"Slow symbolic link\n");
583a1ce5
TT
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 ();
efc6f628 270
583a1ce5
TT
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
283void 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 }
efc6f628 309
583a1ce5
TT
310 else if (wanted_entry < entry_num) {
311 sprintf (buffer,"prev %ld",entry_num-wanted_entry);
312 dispatch (buffer);
313 }
314}
315
316void type_ext2_inode___group (char *command_line)
317
318{
319 char buffer [80];
efc6f628 320
583a1ce5 321 long group_num,group_offset;
efc6f628 322
583a1ce5
TT
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);
efc6f628 325
583a1ce5
TT
326 sprintf (buffer,"setoffset %ld",group_offset);dispatch (buffer);
327 sprintf (buffer,"settype ext2_group_desc");dispatch (buffer);
328}
329
330void type_ext2_inode___file (char *command_line)
331
332{
333 char buffer [80];
efc6f628 334
583a1ce5
TT
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 ();
efc6f628 337 return;
583a1ce5 338 }
efc6f628 339
583a1ce5
TT
340 if (!init_file_info ()) {
341 wprintw (command_win,"Error - Unable to show file\n");refresh_command_win ();
efc6f628 342 return;
583a1ce5 343 }
efc6f628 344
583a1ce5
TT
345 sprintf (buffer,"settype file");dispatch (buffer);
346}
347
348void type_ext2_inode___dir (char *command_line)
349
350{
351 char buffer [80];
efc6f628 352
583a1ce5
TT
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 ();
efc6f628 355 return;
583a1ce5
TT
356 }
357
efc6f628 358/* It is very important to init first_file_info first, as search_dir_entries relies on it */
583a1ce5
TT
359
360 if (!init_dir_info (&first_file_info)) {
361 wprintw (command_win,"Error - Unable to show directory\n");refresh_command_win ();
efc6f628 362 return;
583a1ce5 363 }
efc6f628 364
583a1ce5 365 file_info=first_file_info;
efc6f628 366
583a1ce5
TT
367 sprintf (buffer,"settype dir");dispatch (buffer);
368}
369
370long inode_offset_to_group_num (long inode_offset)
371
372{
373 int found=0;
374 struct ext2_group_desc desc;
efc6f628 375
583a1ce5 376 long block_num,group_offset,group_num;
efc6f628 377
583a1ce5
TT
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 }
efc6f628 391
583a1ce5
TT
392 if (!found)
393 return (-1);
394
395 return (group_num);
396}
397
efc6f628 398
583a1ce5
TT
399
400long 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;
efc6f628 417
583a1ce5
TT
418 return (inode_num);
419}
420
421long 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--;
efc6f628 428
583a1ce5
TT
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}