1 /*
2 
3 /usr/src/ext2ed/file_com.c
4 
5 A part of the extended file system 2 disk editor.
6 
7 ----------------------------
8 Commands which handle a file
9 ----------------------------
10 
11 First written on: April 18 1995
12 
13 Copyright (C) 1995 Gadi Oxman
14 
15 */
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 
21 #include "ext2ed.h"
22 
init_file_info(void)23 int init_file_info (void)
24 
25 {
26 	struct ext2_inode *ptr;
27 
28 	ptr=&type_data.u.t_ext2_inode;
29 
30 	file_info.inode_ptr=ptr;
31 	file_info.inode_offset=device_offset;
32 
33 	file_info.global_block_num=ptr->i_block [0];
34 	file_info.global_block_offset=ptr->i_block [0]*file_system_info.block_size;
35 	file_info.block_num=0;
36 	file_info.blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size;
37 	file_info.file_offset=0;
38 	file_info.file_length=ptr->i_size;
39 	file_info.level=0;
40 	file_info.offset_in_block=0;
41 
42 	file_info.display=HEX;
43 
44 	low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
45 
46 	return (1);
47 }
48 
49 
type_file___inode(char * command_line)50 void type_file___inode (char *command_line)
51 
52 {
53 	dispatch ("settype ext2_inode");
54 }
55 
type_file___show(char * command_line)56 void type_file___show (char *command_line)
57 
58 {
59 	if (file_info.display==HEX)
60 		file_show_hex ();
61 	if (file_info.display==TEXT)
62 		file_show_text ();
63 }
64 
type_file___nextblock(char * command_line)65 void type_file___nextblock (char *command_line)
66 
67 {
68 	long block_offset=1;
69 	char *ptr,buffer [80];
70 
71 	ptr=parse_word (command_line,buffer);
72 
73 	if (*ptr!=0) {
74 		ptr=parse_word (ptr,buffer);
75 		block_offset*=atol (buffer);
76 	}
77 
78 	if (file_info.block_num+block_offset >= file_info.blocks_count) {
79 		wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
80 		return;
81 	}
82 
83 	file_info.block_num+=block_offset;
84 	file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
85 	file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
86 	file_info.file_offset=file_info.block_num*file_system_info.block_size;
87 
88 	low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
89 
90 	strcpy (buffer,"show");dispatch (buffer);
91 }
92 
type_file___next(char * command_line)93 void type_file___next (char *command_line)
94 
95 {
96 	int offset=1;
97 	char *ptr,buffer [80];
98 
99 	ptr=parse_word (command_line,buffer);
100 
101 	if (*ptr!=0) {
102 		ptr=parse_word (ptr,buffer);
103 		offset*=atol (buffer);
104 	}
105 
106 	if (file_info.offset_in_block+offset < file_system_info.block_size) {
107 		file_info.offset_in_block+=offset;
108 		sprintf (buffer,"show");dispatch (buffer);
109 	}
110 
111 	else {
112 		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
113 	}
114 }
115 
type_file___offset(char * command_line)116 void type_file___offset (char *command_line)
117 
118 {
119 	unsigned long offset;
120 	char *ptr,buffer [80];
121 
122 	ptr=parse_word (command_line,buffer);
123 
124 	if (*ptr!=0) {
125 		ptr=parse_word (ptr,buffer);
126 		offset=atol (buffer);
127 	}
128 	else {
129 		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();
130 		return;
131 	}
132 
133 	if (offset < file_system_info.block_size) {
134 		file_info.offset_in_block=offset;
135 		sprintf (buffer,"show");dispatch (buffer);
136 	}
137 
138 	else {
139 		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
140 	}
141 }
142 
type_file___prev(char * command_line)143 void type_file___prev (char *command_line)
144 
145 {
146 	int offset=1;
147 	char *ptr,buffer [80];
148 
149 	ptr=parse_word (command_line,buffer);
150 
151 	if (*ptr!=0) {
152 		ptr=parse_word (ptr,buffer);
153 		offset*=atol (buffer);
154 	}
155 
156 	if (file_info.offset_in_block-offset >= 0) {
157 		file_info.offset_in_block-=offset;
158 		sprintf (buffer,"show");dispatch (buffer);
159 	}
160 
161 	else {
162 		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
163 	}
164 }
165 
type_file___prevblock(char * command_line)166 void type_file___prevblock (char *command_line)
167 
168 {
169 	long block_offset=1;
170 	char *ptr,buffer [80];
171 
172 	ptr=parse_word (command_line,buffer);
173 
174 	if (*ptr!=0) {
175 		ptr=parse_word (ptr,buffer);
176 		block_offset*=atol (buffer);
177 	}
178 
179 	if (file_info.block_num-block_offset < 0) {
180 		wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
181 		return;
182 	}
183 
184 	file_info.block_num-=block_offset;
185 	file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
186 	file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
187 	file_info.file_offset=file_info.block_num*file_system_info.block_size;
188 
189 	low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
190 
191 	strcpy (buffer,"show");dispatch (buffer);
192 }
193 
type_file___block(char * command_line)194 void type_file___block (char *command_line)
195 
196 {
197 	long block_offset=1;
198 	char *ptr,buffer [80];
199 
200 	ptr=parse_word (command_line,buffer);
201 
202 	if (*ptr==0) {
203 		wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win);
204 		return;
205 	}
206 
207 	ptr=parse_word (ptr,buffer);
208 	block_offset=atol (buffer);
209 
210 	if (block_offset < 0 || block_offset >= file_info.blocks_count) {
211 		wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
212 		return;
213 	}
214 
215 	file_info.block_num=block_offset;
216 	file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
217 	file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
218 	file_info.file_offset=file_info.block_num*file_system_info.block_size;
219 
220 	low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
221 
222 	strcpy (buffer,"show");dispatch (buffer);
223 }
224 
type_file___display(char * command_line)225 void type_file___display (char *command_line)
226 
227 {
228 	char *ptr,buffer [80];
229 
230 	ptr=parse_word (command_line,buffer);
231 	if (*ptr==0)
232 		strcpy (buffer,"hex");
233 	else
234 		ptr=parse_word (ptr,buffer);
235 
236 	if (strcasecmp (buffer,"hex")==0) {
237 		wprintw (command_win,"Display set to hex\n");wrefresh (command_win);
238 		file_info.display=HEX;
239 		sprintf (buffer,"show");dispatch (buffer);
240 	}
241 
242 	else if (strcasecmp (buffer,"text")==0) {
243 		wprintw (command_win,"Display set to text\n");wrefresh (command_win);
244 		file_info.display=TEXT;
245 		sprintf (buffer,"show");dispatch (buffer);
246 	}
247 
248 	else {
249 		wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win);
250 	}
251 }
252 
file_show_hex(void)253 void file_show_hex (void)
254 
255 {
256 	long offset=0,l,i;
257 	unsigned char *ch_ptr;
258 
259 	/* device_offset and type_data points to the inode */
260 
261 	show_pad_info.line=0;
262 
263 	wmove (show_pad,0,0);
264 	ch_ptr=file_info.buffer;
265 	for (l=0;l<file_system_info.block_size/16;l++) {
266 		if (file_info.file_offset+offset>file_info.file_length-1) break;
267 		wprintw (show_pad,"%08ld :  ",offset);
268 		for (i=0;i<16;i++) {
269 
270 			if (file_info.file_offset+offset+i>file_info.file_length-1) {
271 				wprintw (show_pad," ");
272 			}
273 
274 			else {
275 				if (file_info.offset_in_block==offset+i)
276 					wattrset (show_pad,A_REVERSE);
277 
278 				if (ch_ptr [i]>=' ' && ch_ptr [i]<='z')
279 					wprintw (show_pad,"%c",ch_ptr [i]);
280 				else
281 					wprintw (show_pad,".");
282 
283 				if (file_info.offset_in_block==offset+i)
284 					wattrset (show_pad,A_NORMAL);
285 			}
286 		}
287 
288 		wprintw (show_pad,"   ");
289 		for (i=0;i<16;i++) {
290 			if (file_info.file_offset+offset+i>file_info.file_length-1) break;
291 			if (file_info.offset_in_block==offset+i)
292 				wattrset (show_pad,A_REVERSE);
293 
294 			wprintw (show_pad,"%02x",ch_ptr [i]);
295 
296 			if (file_info.offset_in_block==offset+i) {
297 				wattrset (show_pad,A_NORMAL);
298 				show_pad_info.line=l-l % show_pad_info.display_lines;
299 			}
300 
301 			wprintw (show_pad," ");
302 
303 		}
304 
305 		wprintw (show_pad,"\n");
306 		offset+=i;
307 		ch_ptr+=i;
308 	}
309 
310 	show_pad_info.max_line=l-1;
311 
312 	refresh_show_pad ();
313 
314 	show_status ();
315 }
316 
file_show_text(void)317 void file_show_text (void)
318 
319 {
320 	long offset=0,last_offset,l=0,cols=0;
321 	unsigned char *ch_ptr;
322 
323 	/* device_offset and type_data points to the inode */
324 
325 	show_pad_info.line=0;
326 	wmove (show_pad,0,0);
327 	ch_ptr=file_info.buffer;
328 
329 	last_offset=file_system_info.block_size-1;
330 
331 	if (file_info.file_offset+last_offset > file_info.file_length-1)
332 		last_offset=file_info.file_length-1-file_info.file_offset;
333 
334 	while ( (offset <= last_offset) && l<SHOW_PAD_LINES) {
335 
336 		if (cols==SHOW_PAD_COLS-1) {
337 			wprintw (show_pad,"\n");
338 			l++;cols=0;
339 		}
340 
341 
342 		if (file_info.offset_in_block==offset)
343 			wattrset (show_pad,A_REVERSE);
344 
345 		if (*ch_ptr >= ' ' && *ch_ptr <= 'z')
346 			wprintw (show_pad,"%c",*ch_ptr);
347 
348 
349 		else {
350 			if (*ch_ptr == 0xa) {
351 				wprintw (show_pad,"\n");
352 				l++;cols=0;
353 			}
354 
355 			else if (*ch_ptr == 0x9)
356 				wprintw (show_pad,"    ");
357 
358 			else
359 				wprintw (show_pad,".");
360 		}
361 
362 		if (file_info.offset_in_block==offset) {
363 			wattrset (show_pad,A_NORMAL);
364 			show_pad_info.line=l-l % show_pad_info.display_lines;
365 		}
366 
367 
368 		offset++;cols++;ch_ptr++;
369 	}
370 
371 	wprintw (show_pad,"\n");
372 	show_pad_info.max_line=l;
373 
374 	refresh_show_pad ();
375 
376 	show_status ();
377 }
378 
show_status(void)379 void show_status (void)
380 
381 {
382 	long inode_num;
383 
384 	werase (show_win);wmove (show_win,0,0);
385 	wprintw (show_win,"File contents. Block %ld. ",file_info.global_block_num);
386 	wprintw (show_win,"File block %ld of %ld. ",file_info.block_num,file_info.blocks_count-1);
387 	wprintw (show_win,"File Offset %ld of %ld.",file_info.file_offset,file_info.file_length-1);
388 
389 	wmove (show_win,1,0);
390 	inode_num=inode_offset_to_inode_num (file_info.inode_offset);
391 	wprintw (show_win,"File inode %ld. Indirection level %ld.",inode_num,file_info.level);
392 
393 	refresh_show_win ();
394 }
395 
type_file___remember(char * command_line)396 void type_file___remember (char *command_line)
397 
398 {
399 	int found=0;
400 	long entry_num;
401 	char *ptr,buffer [80];
402 	struct struct_descriptor *descriptor_ptr;
403 
404 	ptr=parse_word (command_line,buffer);
405 
406 	if (*ptr==0) {
407 		wprintw (command_win,"Error - Argument not specified\n");wrefresh (command_win);
408 		return;
409 	}
410 
411 	ptr=parse_word (ptr,buffer);
412 
413 	entry_num=remember_lifo.entries_count++;
414 	if (entry_num>REMEMBER_COUNT-1) {
415 		entry_num=0;
416 		remember_lifo.entries_count--;
417 	}
418 
419 	descriptor_ptr=first_type;
420 	while (descriptor_ptr!=NULL && !found) {
421 		if (strcmp (descriptor_ptr->name,"ext2_inode")==0)
422 			found=1;
423 		else
424 			descriptor_ptr=descriptor_ptr->next;
425 	}
426 
427 
428 	remember_lifo.offset [entry_num]=device_offset;
429 	remember_lifo.type [entry_num]=descriptor_ptr;
430 	strcpy (remember_lifo.name [entry_num],buffer);
431 
432 	wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",descriptor_ptr->name,device_offset,buffer);
433 	wrefresh (command_win);
434 }
435 
type_file___set(char * command_line)436 void type_file___set (char *command_line)
437 
438 {
439 	unsigned char tmp;
440 	char *ptr,buffer [80],*ch_ptr;
441 	int mode=HEX;
442 
443 	ptr=parse_word (command_line,buffer);
444 	if (*ptr==0) {
445 		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();return;
446 	}
447 
448 	ptr=parse_word (ptr,buffer);
449 
450 	if (strcasecmp (buffer,"text")==0) {
451 		mode=TEXT;
452 		strcpy (buffer,ptr);
453 	}
454 
455 	else if (strcasecmp (buffer,"hex")==0) {
456 		mode=HEX;
457 		ptr=parse_word (ptr,buffer);
458 	}
459 
460 	if (*buffer==0) {
461 		wprintw (command_win,"Error - Data not specified\n");refresh_command_win ();return;
462 	}
463 
464 	if (mode==HEX) {
465 		do {
466 			tmp=(unsigned char) strtol (buffer,NULL,16);
467 			file_info.buffer [file_info.offset_in_block]=tmp;
468 			file_info.offset_in_block++;
469 			ptr=parse_word (ptr,buffer);
470 			if (file_info.offset_in_block==file_system_info.block_size) {
471 				if (*ptr) {
472 					wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
473 					refresh_command_win ();
474 				}
475 				file_info.offset_in_block--;
476 			}
477 		} while (*buffer) ;
478 	}
479 
480 	else {
481 		ch_ptr=buffer;
482 		while (*ch_ptr) {
483 			tmp=(unsigned char) *ch_ptr++;
484 			file_info.buffer [file_info.offset_in_block]=tmp;
485 			file_info.offset_in_block++;
486 			if (file_info.offset_in_block==file_system_info.block_size) {
487 				if (*ch_ptr) {
488 					wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
489 					refresh_command_win ();
490 				}
491 				file_info.offset_in_block--;
492 			}
493 		}
494 	}
495 
496 	strcpy (buffer,"show");dispatch (buffer);
497 }
498 
type_file___writedata(char * command_line)499 void type_file___writedata (char *command_line)
500 
501 {
502 	low_write (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
503 	return;
504 }
505 
file_block_to_global_block(long file_block,struct struct_file_info * file_info_ptr)506 long file_block_to_global_block (long file_block,struct struct_file_info *file_info_ptr)
507 
508 {
509 	long last_direct,last_indirect,last_dindirect;
510 
511 	last_direct=EXT2_NDIR_BLOCKS-1;
512 	last_indirect=last_direct+file_system_info.block_size/4;
513 	last_dindirect=last_indirect+(file_system_info.block_size/4)*(file_system_info.block_size/4);
514 
515 	if (file_block <= last_direct) {
516 		file_info_ptr->level=0;
517 		return (file_info_ptr->inode_ptr->i_block [file_block]);
518 	}
519 
520 	if (file_block <= last_indirect) {
521 		file_info_ptr->level=1;
522 		file_block=file_block-last_direct-1;
523 		return (return_indirect (file_info_ptr->inode_ptr->i_block [EXT2_IND_BLOCK],file_block));
524 	}
525 
526 	if (file_block <= last_dindirect) {
527 		file_info_ptr->level=2;
528 		file_block=file_block-last_indirect-1;
529 		return (return_dindirect (file_info_ptr->inode_ptr->i_block [EXT2_DIND_BLOCK],file_block));
530 	}
531 
532 	file_info_ptr->level=3;
533 	file_block=file_block-last_dindirect-1;
534 	return (return_tindirect (file_info_ptr->inode_ptr->i_block [EXT2_TIND_BLOCK],file_block));
535 }
536 
return_indirect(long table_block,long block_num)537 long return_indirect (long table_block,long block_num)
538 
539 {
540 	long block_table [EXT2_MAX_BLOCK_SIZE/4];
541 
542 	low_read ((char *) block_table,file_system_info.block_size,table_block*file_system_info.block_size);
543 	return (block_table [block_num]);
544 }
545 
return_dindirect(long table_block,long block_num)546 long return_dindirect (long table_block,long block_num)
547 
548 {
549 	long f_indirect;
550 
551 	f_indirect=block_num/(file_system_info.block_size/4);
552 	f_indirect=return_indirect (table_block,f_indirect);
553 	return (return_indirect (f_indirect,block_num%(file_system_info.block_size/4)));
554 }
555 
return_tindirect(long table_block,long block_num)556 long return_tindirect (long table_block,long block_num)
557 
558 {
559 	long s_indirect;
560 
561 	s_indirect=block_num/((file_system_info.block_size/4)*(file_system_info.block_size/4));
562 	s_indirect=return_indirect (table_block,s_indirect);
563 	return (return_dindirect (s_indirect,block_num%((file_system_info.block_size/4)*(file_system_info.block_size/4))));
564 }
565