diff options
Diffstat (limited to 'ext2ed/file_com.c')
-rw-r--r-- | ext2ed/file_com.c | 565 |
1 files changed, 565 insertions, 0 deletions
diff --git a/ext2ed/file_com.c b/ext2ed/file_com.c new file mode 100644 index 0000000..d667959 --- /dev/null +++ b/ext2ed/file_com.c @@ -0,0 +1,565 @@ +/* + +/usr/src/ext2ed/file_com.c + +A part of the extended file system 2 disk editor. + +---------------------------- +Commands which handle a file +---------------------------- + +First written on: April 18 1995 + +Copyright (C) 1995 Gadi Oxman + +*/ + +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "ext2ed.h" + +int init_file_info (void) + +{ + struct ext2_inode *ptr; + + ptr=&type_data.u.t_ext2_inode; + + file_info.inode_ptr=ptr; + file_info.inode_offset=device_offset; + + file_info.global_block_num=ptr->i_block [0]; + file_info.global_block_offset=ptr->i_block [0]*file_system_info.block_size; + file_info.block_num=0; + file_info.blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size; + file_info.file_offset=0; + file_info.file_length=ptr->i_size; + file_info.level=0; + file_info.offset_in_block=0; + + file_info.display=HEX; + + low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); + + return (1); +} + + +void type_file___inode (char *command_line) + +{ + dispatch ("settype ext2_inode"); +} + +void type_file___show (char *command_line) + +{ + if (file_info.display==HEX) + file_show_hex (); + if (file_info.display==TEXT) + file_show_text (); +} + +void type_file___nextblock (char *command_line) + +{ + long block_offset=1; + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + + if (*ptr!=0) { + ptr=parse_word (ptr,buffer); + block_offset*=atol (buffer); + } + + if (file_info.block_num+block_offset >= file_info.blocks_count) { + wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win); + return; + } + + file_info.block_num+=block_offset; + file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info); + file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size; + file_info.file_offset=file_info.block_num*file_system_info.block_size; + + low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); + + strcpy (buffer,"show");dispatch (buffer); +} + +void type_file___next (char *command_line) + +{ + int offset=1; + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + + if (*ptr!=0) { + ptr=parse_word (ptr,buffer); + offset*=atol (buffer); + } + + if (file_info.offset_in_block+offset < file_system_info.block_size) { + file_info.offset_in_block+=offset; + sprintf (buffer,"show");dispatch (buffer); + } + + else { + wprintw (command_win,"Error - Offset out of block\n");refresh_command_win (); + } +} + +void type_file___offset (char *command_line) + +{ + unsigned long offset; + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + + if (*ptr!=0) { + ptr=parse_word (ptr,buffer); + offset=atol (buffer); + } + else { + wprintw (command_win,"Error - Argument not specified\n");refresh_command_win (); + return; + } + + if (offset < file_system_info.block_size) { + file_info.offset_in_block=offset; + sprintf (buffer,"show");dispatch (buffer); + } + + else { + wprintw (command_win,"Error - Offset out of block\n");refresh_command_win (); + } +} + +void type_file___prev (char *command_line) + +{ + int offset=1; + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + + if (*ptr!=0) { + ptr=parse_word (ptr,buffer); + offset*=atol (buffer); + } + + if (file_info.offset_in_block-offset >= 0) { + file_info.offset_in_block-=offset; + sprintf (buffer,"show");dispatch (buffer); + } + + else { + wprintw (command_win,"Error - Offset out of block\n");refresh_command_win (); + } +} + +void type_file___prevblock (char *command_line) + +{ + long block_offset=1; + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + + if (*ptr!=0) { + ptr=parse_word (ptr,buffer); + block_offset*=atol (buffer); + } + + if (file_info.block_num-block_offset < 0) { + wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win); + return; + } + + file_info.block_num-=block_offset; + file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info); + file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size; + file_info.file_offset=file_info.block_num*file_system_info.block_size; + + low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); + + strcpy (buffer,"show");dispatch (buffer); +} + +void type_file___block (char *command_line) + +{ + long block_offset=1; + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + + if (*ptr==0) { + wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win); + return; + } + + ptr=parse_word (ptr,buffer); + block_offset=atol (buffer); + + if (block_offset < 0 || block_offset >= file_info.blocks_count) { + wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win); + return; + } + + file_info.block_num=block_offset; + file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info); + file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size; + file_info.file_offset=file_info.block_num*file_system_info.block_size; + + low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); + + strcpy (buffer,"show");dispatch (buffer); +} + +void type_file___display (char *command_line) + +{ + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + if (*ptr==0) + strcpy (buffer,"hex"); + else + ptr=parse_word (ptr,buffer); + + if (strcasecmp (buffer,"hex")==0) { + wprintw (command_win,"Display set to hex\n");wrefresh (command_win); + file_info.display=HEX; + sprintf (buffer,"show");dispatch (buffer); + } + + else if (strcasecmp (buffer,"text")==0) { + wprintw (command_win,"Display set to text\n");wrefresh (command_win); + file_info.display=TEXT; + sprintf (buffer,"show");dispatch (buffer); + } + + else { + wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win); + } +} + +void file_show_hex (void) + +{ + long offset=0,l,i; + unsigned char *ch_ptr; + + /* device_offset and type_data points to the inode */ + + show_pad_info.line=0; + + wmove (show_pad,0,0); + ch_ptr=file_info.buffer; + for (l=0;l<file_system_info.block_size/16;l++) { + if (file_info.file_offset+offset>file_info.file_length-1) break; + wprintw (show_pad,"%08ld : ",offset); + for (i=0;i<16;i++) { + + if (file_info.file_offset+offset+i>file_info.file_length-1) { + wprintw (show_pad," "); + } + + else { + if (file_info.offset_in_block==offset+i) + wattrset (show_pad,A_REVERSE); + + if (ch_ptr [i]>=' ' && ch_ptr [i]<='z') + wprintw (show_pad,"%c",ch_ptr [i]); + else + wprintw (show_pad,"."); + + if (file_info.offset_in_block==offset+i) + wattrset (show_pad,A_NORMAL); + } + } + + wprintw (show_pad," "); + for (i=0;i<16;i++) { + if (file_info.file_offset+offset+i>file_info.file_length-1) break; + if (file_info.offset_in_block==offset+i) + wattrset (show_pad,A_REVERSE); + + wprintw (show_pad,"%02x",ch_ptr [i]); + + if (file_info.offset_in_block==offset+i) { + wattrset (show_pad,A_NORMAL); + show_pad_info.line=l-l % show_pad_info.display_lines; + } + + wprintw (show_pad," "); + + } + + wprintw (show_pad,"\n"); + offset+=i; + ch_ptr+=i; + } + + show_pad_info.max_line=l-1; + + refresh_show_pad (); + + show_status (); +} + +void file_show_text (void) + +{ + long offset=0,last_offset,l=0,cols=0; + unsigned char *ch_ptr; + + /* device_offset and type_data points to the inode */ + + show_pad_info.line=0; + wmove (show_pad,0,0); + ch_ptr=file_info.buffer; + + last_offset=file_system_info.block_size-1; + + if (file_info.file_offset+last_offset > file_info.file_length-1) + last_offset=file_info.file_length-1-file_info.file_offset; + + while ( (offset <= last_offset) && l<SHOW_PAD_LINES) { + + if (cols==SHOW_PAD_COLS-1) { + wprintw (show_pad,"\n"); + l++;cols=0; + } + + + if (file_info.offset_in_block==offset) + wattrset (show_pad,A_REVERSE); + + if (*ch_ptr >= ' ' && *ch_ptr <= 'z') + wprintw (show_pad,"%c",*ch_ptr); + + + else { + if (*ch_ptr == 0xa) { + wprintw (show_pad,"\n"); + l++;cols=0; + } + + else if (*ch_ptr == 0x9) + wprintw (show_pad," "); + + else + wprintw (show_pad,"."); + } + + if (file_info.offset_in_block==offset) { + wattrset (show_pad,A_NORMAL); + show_pad_info.line=l-l % show_pad_info.display_lines; + } + + + offset++;cols++;ch_ptr++; + } + + wprintw (show_pad,"\n"); + show_pad_info.max_line=l; + + refresh_show_pad (); + + show_status (); +} + +void show_status (void) + +{ + long inode_num; + + werase (show_win);wmove (show_win,0,0); + wprintw (show_win,"File contents. Block %ld. ",file_info.global_block_num); + wprintw (show_win,"File block %ld of %ld. ",file_info.block_num,file_info.blocks_count-1); + wprintw (show_win,"File Offset %ld of %ld.",file_info.file_offset,file_info.file_length-1); + + wmove (show_win,1,0); + inode_num=inode_offset_to_inode_num (file_info.inode_offset); + wprintw (show_win,"File inode %ld. Indirection level %ld.",inode_num,file_info.level); + + refresh_show_win (); +} + +void type_file___remember (char *command_line) + +{ + int found=0; + long entry_num; + char *ptr,buffer [80]; + struct struct_descriptor *descriptor_ptr; + + ptr=parse_word (command_line,buffer); + + if (*ptr==0) { + wprintw (command_win,"Error - Argument not specified\n");wrefresh (command_win); + return; + } + + ptr=parse_word (ptr,buffer); + + entry_num=remember_lifo.entries_count++; + if (entry_num>REMEMBER_COUNT-1) { + entry_num=0; + remember_lifo.entries_count--; + } + + descriptor_ptr=first_type; + while (descriptor_ptr!=NULL && !found) { + if (strcmp (descriptor_ptr->name,"ext2_inode")==0) + found=1; + else + descriptor_ptr=descriptor_ptr->next; + } + + + remember_lifo.offset [entry_num]=device_offset; + remember_lifo.type [entry_num]=descriptor_ptr; + strcpy (remember_lifo.name [entry_num],buffer); + + wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",descriptor_ptr->name,device_offset,buffer); + wrefresh (command_win); +} + +void type_file___set (char *command_line) + +{ + unsigned char tmp; + char *ptr,buffer [80],*ch_ptr; + int mode=HEX; + + ptr=parse_word (command_line,buffer); + if (*ptr==0) { + wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();return; + } + + ptr=parse_word (ptr,buffer); + + if (strcasecmp (buffer,"text")==0) { + mode=TEXT; + strcpy (buffer,ptr); + } + + else if (strcasecmp (buffer,"hex")==0) { + mode=HEX; + ptr=parse_word (ptr,buffer); + } + + if (*buffer==0) { + wprintw (command_win,"Error - Data not specified\n");refresh_command_win ();return; + } + + if (mode==HEX) { + do { + tmp=(unsigned char) strtol (buffer,NULL,16); + file_info.buffer [file_info.offset_in_block]=tmp; + file_info.offset_in_block++; + ptr=parse_word (ptr,buffer); + if (file_info.offset_in_block==file_system_info.block_size) { + if (*ptr) { + wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n"); + refresh_command_win (); + } + file_info.offset_in_block--; + } + } while (*buffer) ; + } + + else { + ch_ptr=buffer; + while (*ch_ptr) { + tmp=(unsigned char) *ch_ptr++; + file_info.buffer [file_info.offset_in_block]=tmp; + file_info.offset_in_block++; + if (file_info.offset_in_block==file_system_info.block_size) { + if (*ch_ptr) { + wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n"); + refresh_command_win (); + } + file_info.offset_in_block--; + } + } + } + + strcpy (buffer,"show");dispatch (buffer); +} + +void type_file___writedata (char *command_line) + +{ + low_write (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); + return; +} + +long file_block_to_global_block (long file_block,struct struct_file_info *file_info_ptr) + +{ + long last_direct,last_indirect,last_dindirect; + + last_direct=EXT2_NDIR_BLOCKS-1; + last_indirect=last_direct+file_system_info.block_size/4; + last_dindirect=last_indirect+(file_system_info.block_size/4)*(file_system_info.block_size/4); + + if (file_block <= last_direct) { + file_info_ptr->level=0; + return (file_info_ptr->inode_ptr->i_block [file_block]); + } + + if (file_block <= last_indirect) { + file_info_ptr->level=1; + file_block=file_block-last_direct-1; + return (return_indirect (file_info_ptr->inode_ptr->i_block [EXT2_IND_BLOCK],file_block)); + } + + if (file_block <= last_dindirect) { + file_info_ptr->level=2; + file_block=file_block-last_indirect-1; + return (return_dindirect (file_info_ptr->inode_ptr->i_block [EXT2_DIND_BLOCK],file_block)); + } + + file_info_ptr->level=3; + file_block=file_block-last_dindirect-1; + return (return_tindirect (file_info_ptr->inode_ptr->i_block [EXT2_TIND_BLOCK],file_block)); +} + +long return_indirect (long table_block,long block_num) + +{ + long block_table [EXT2_MAX_BLOCK_SIZE/4]; + + low_read ((char *) block_table,file_system_info.block_size,table_block*file_system_info.block_size); + return (block_table [block_num]); +} + +long return_dindirect (long table_block,long block_num) + +{ + long f_indirect; + + f_indirect=block_num/(file_system_info.block_size/4); + f_indirect=return_indirect (table_block,f_indirect); + return (return_indirect (f_indirect,block_num%(file_system_info.block_size/4))); +} + +long return_tindirect (long table_block,long block_num) + +{ + long s_indirect; + + s_indirect=block_num/((file_system_info.block_size/4)*(file_system_info.block_size/4)); + s_indirect=return_indirect (table_block,s_indirect); + return (return_dindirect (s_indirect,block_num%((file_system_info.block_size/4)*(file_system_info.block_size/4)))); +} |