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