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 
type_ext2_inode___prev(char * command_line)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 
type_ext2_inode___next(char * command_line)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 
type_ext2_inode___show(char * command_line)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 EXT4_USR_QUOTA_INO:
226 				wprintw (show_win,"User quota inode - ");
227 				break;
228 			case EXT4_GRP_QUOTA_INO:
229 				wprintw (show_win,"Group quota 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 
type_ext2_inode___entry(char * command_line)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 
type_ext2_inode___group(char * command_line)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 
type_ext2_inode___file(char * command_line)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 
type_ext2_inode___dir(char * command_line)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 
inode_offset_to_group_num(long inode_offset)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 
inode_offset_to_inode_num(long inode_offset)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 
inode_num_to_inode_offset(long inode_num)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 }
437