Home | History | Annotate | Download | only in ext2ed
      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 
     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 
     50 void type_file___inode (char *command_line)
     51 
     52 {
     53 	dispatch ("settype ext2_inode");
     54 }
     55 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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