diff options
Diffstat (limited to 'ext2ed/general_com.c')
-rw-r--r-- | ext2ed/general_com.c | 907 |
1 files changed, 907 insertions, 0 deletions
diff --git a/ext2ed/general_com.c b/ext2ed/general_com.c new file mode 100644 index 0000000..aa274e3 --- /dev/null +++ b/ext2ed/general_com.c @@ -0,0 +1,907 @@ +/* + +/usr/src/ext2ed/general_com.c + +A part of the extended file system 2 disk editor. + +--------------------- +General user commands +--------------------- + +First written on: April 9 1995 + +Copyright (C) 1995 Gadi Oxman + +*/ + +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "ext2ed.h" +#include "../version.h" + +void help (char *command_line) + +{ + int i,max_line=0; + char argument [80],*ptr; + + werase (show_pad);wmove (show_pad,0,0); + + ptr=parse_word (command_line,argument); + + if (*ptr!=0) { + ptr=parse_word (ptr,argument); + if (*argument!=0) { + detailed_help (argument); + return; + } + } + + if (current_type!=NULL) { + + wprintw (show_pad,"Type %s specific commands:\n",current_type->name);max_line++; + + if (current_type->type_commands.last_command==-1) { + wprintw (show_pad,"\nnone\n");max_line+=2; + } + else + for (i=0;i<=current_type->type_commands.last_command;i++) { + if (i%5==0) { + wprintw (show_pad,"\n");max_line++; + } + wprintw (show_pad,"%-13s",current_type->type_commands.names [i]); + if (i%5!=4) + wprintw (show_pad,"; "); + } + + wprintw (show_pad,"\n\n");max_line+=2; + } + + if (ext2_commands.last_command != -1) { + wprintw (show_pad,"ext2 filesystem general commands: \n");max_line++; + for (i=0;i<=ext2_commands.last_command;i++) { + if (i%5==0) { + wprintw (show_pad,"\n");max_line++; + } + wprintw (show_pad,"%-13s",ext2_commands.names [i]); + if (i%5!=4) + wprintw (show_pad,"; "); + + } + wprintw (show_pad,"\n\n");max_line+=2; + } + + wprintw (show_pad,"General commands: \n"); + + for (i=0;i<=general_commands.last_command;i++) { + if (i%5==0) { + wprintw (show_pad,"\n");max_line++; + } + wprintw (show_pad,"%-13s",general_commands.names [i]); + if (i%5!=4) + wprintw (show_pad,"; "); + } + + wprintw (show_pad,"\n\n");max_line+=2; + + wprintw (show_pad,"EXT2ED ver %s (%s)\n",E2FSPROGS_VERSION, E2FSPROGS_DATE); + wprintw (show_pad,"Copyright (C) 1995 Gadi Oxman\n"); + wprintw (show_pad,"Reviewed 2001 Christian Bac\n"); + wprintw (show_pad,"Modified and enhanced by Theodore Ts'o, 2002\n"); + wprintw (show_pad,"EXT2ED is hereby placed under the terms of the GNU General Public License.\n\n"); + wprintw (show_pad,"EXT2ED was programmed as a student project in the software laboratory\n"); + wprintw (show_pad,"of the faculty of electrical engineering in the\n"); + wprintw (show_pad,"Technion - Israel Institute of Technology\n"); + wprintw (show_pad,"with the guide of Avner Lottem and Dr. Ilana David.\n"); + + max_line+=10; + + show_pad_info.line=0;show_pad_info.max_line=max_line; + + werase (show_win);wmove (show_win,0,0); + wprintw (show_win,"EXT2ED help"); + + refresh_show_win (); + refresh_show_pad (); +} + +void detailed_help (char *text) + +{ + int i; + + if (current_type != NULL) + for (i=0;i<=current_type->type_commands.last_command;i++) { + if (strcmp (current_type->type_commands.names [i],text)==0) { + wprintw (show_pad,"%s - %s\n",text,current_type->type_commands.descriptions [i]); + refresh_show_pad ();return; + } + } + + for (i=0;i<=ext2_commands.last_command;i++) { + if (strcmp (ext2_commands.names [i],text)==0) { + wprintw (show_pad,"%s - %s\n",text,ext2_commands.descriptions [i]); + refresh_show_pad ();return; + } + } + + for (i=0;i<=general_commands.last_command;i++) { + if (strcmp (general_commands.names [i],text)==0) { + wprintw (show_pad,"%s - %s\n",text,general_commands.descriptions [i]); + refresh_show_pad ();return; + } + } + + if (strcmp ("quit",text)==0) { + wprintw (show_pad,"quit - Exists EXT2ED"); + refresh_show_pad ();return; + } + + wprintw (show_pad,"Error - Command %s not available now\n",text); + refresh_show_pad ();return; +} + + + +void set_device (char *command_line) + +{ + char *ptr,new_device [80]; + + ptr=parse_word (command_line,new_device); + if (*ptr==0) { + wprintw (command_win,"Error - Device name not specified\n"); + refresh_command_win ();return; + } + parse_word (ptr,new_device); + check_mounted (new_device); + if (mounted && !AllowMountedRead) { + wprintw (command_win,"Error - Filesystem is mounted, aborting\n"); + wprintw (command_win,"You may wish to use the AllowMountedRead on configuration option\n"); + refresh_command_win ();return; + } + + if (mounted && AllowMountedRead) { + wprintw (command_win,"Warning - Filesystem is mounted. Displayed data may be unreliable.\n"); + refresh_command_win (); + } + + if (device_handle!=NULL) + fclose (device_handle); + + if ( (device_handle=fopen (new_device,"rb"))==NULL) { + wprintw (command_win,"Error - Can not open device %s\n",new_device);refresh_command_win (); + return; + } + else { + strcpy (device_name,new_device); + write_access=0; /* Write access disabled */ + current_type=NULL; /* There is no type now */ + remember_lifo.entries_count=0; /* Empty Object memory */ + free_user_commands (&ext2_commands); /* Free filesystem specific objects */ + free_struct_descriptors (); + if (!set_file_system_info ()) { /* Error while getting info --> abort */ + free_user_commands (&ext2_commands); + free_struct_descriptors (); + fclose (device_handle); + device_handle=NULL; /* Notice that our device is still not set up */ + device_offset=-1; + return; + } + if (*AlternateDescriptors) /* Check if user defined objects exist */ + set_struct_descriptors (AlternateDescriptors); + dispatch ("setoffset 0"); + dispatch ("help"); /* Show help screen */ + wprintw (command_win,"Device changed to %s",device_name);refresh_command_win (); + } +} + +void set_offset (char *command_line) + +{ + long mult=1; + long new_offset; + char *ptr,new_offset_buffer [80]; + + if (device_handle==NULL) { + wprintw (command_win,"Error - No device opened\n");refresh_command_win (); + return; + } + + ptr=parse_word (command_line,new_offset_buffer); + + if (*ptr==0) { + wprintw (command_win,"Error - No argument specified\n");refresh_command_win (); + return; + } + + ptr=parse_word (ptr,new_offset_buffer); + + if (strcmp (new_offset_buffer,"block")==0) { + mult=file_system_info.block_size; + ptr=parse_word (ptr,new_offset_buffer); + } + + if (strcmp (new_offset_buffer,"type")==0) { + if (current_type==NULL) { + wprintw (command_win,"Error - No type set\n");refresh_command_win (); + return; + } + + mult=current_type->length; + ptr=parse_word (ptr,new_offset_buffer); + } + + if (*new_offset_buffer==0) { + wprintw (command_win,"Error - No offset specified\n");refresh_command_win (); + return; + } + + if (new_offset_buffer [0]=='+') { + if (device_offset==-1) { + wprintw (command_win,"Error - Select a fixed offset first\n");refresh_command_win (); + return; + } + new_offset=device_offset+atol (new_offset_buffer+1)*mult; + } + + else if (new_offset_buffer [0]=='-') { + if (device_offset==-1) { + wprintw (command_win,"Error - Select a fixed offset first\n");refresh_command_win (); + return; + } + new_offset=device_offset-atol (new_offset_buffer+1)*mult; + if (new_offset<0) new_offset=0; + } + + else + new_offset=atol (new_offset_buffer)*mult; + + if ( (fseek (device_handle,new_offset,SEEK_SET))==-1) { + wprintw (command_win,"Error - Failed to seek to offset %ld in device %s\n",new_offset,device_name); + refresh_command_win (); + return; + }; + device_offset=new_offset; + wprintw (command_win,"Device offset changed to %ld\n",device_offset);refresh_command_win (); + load_type_data (); + type_data.offset_in_block=0; +} + +void set_int(short len, void *ptr, char *name, char *value) +{ + char *char_ptr; + short *short_ptr; + long *long_ptr; + long v; + char *tmp; + + v = strtol(value, &tmp, 0); + if (*tmp) { + wprintw( command_win, "Bad value - %s\n", value); + return; + } + switch (len) { + case 1: + char_ptr = (char *) ptr; + *char_ptr = v; + break; + case 2: + short_ptr = (short *) ptr; + *short_ptr = v; + break; + case 4: + long_ptr = (long *) ptr; + *long_ptr = v; + break; + default: + wprintw (command_win, + "set_int: unsupported length: %d\n", len); + return; + } + wprintw (command_win, "Variable %s set to %s\n", + name, value); +} + +void set_uint(short len, void *ptr, char *name, char *value) +{ + unsigned char *char_ptr; + unsigned short *short_ptr; + unsigned long *long_ptr; + unsigned long v; + char *tmp; + + v = strtoul(value, &tmp, 0); + if (*tmp) { + wprintw( command_win, "Bad value - %s\n", value); + return; + } + switch (len) { + case 1: + char_ptr = (unsigned char *) ptr; + *char_ptr = v; + break; + case 2: + short_ptr = (unsigned short *) ptr; + *short_ptr = v; + break; + case 4: + long_ptr = (unsigned long *) ptr; + *long_ptr = v; + break; + default: + wprintw (command_win, + "set_uint: unsupported length: %d\n", len); + return; + } + wprintw (command_win, "Variable %s set to %s\n", + name, value); +} + +void set_char(short len, void *ptr, char *name, char *value) +{ + if (strlen(value)+1 > len) { + wprintw( command_win, "Value %s too big for field\n", + name, len); + return; + } + memset(ptr, 0, len); + strcpy((char *) ptr, value); + wprintw (command_win, "Variable %s set to %s\n", + name, value); +} + + +void set (char *command_line) + +{ + unsigned short *int_ptr; + unsigned char *char_ptr; + unsigned long *long_ptr,offset=0; + int i,len, found=0; + char *ptr,buffer [80],variable [80],value [80]; + + if (device_handle==NULL) { + wprintw (command_win,"Error - No device opened\n");refresh_command_win (); + return; + } + + if (current_type==NULL) { + hex_set (command_line); + return; + } + + ptr=parse_word (command_line,buffer); + if (ptr==NULL || *ptr==0) { + wprintw (command_win,"Error - Missing arguments\n");refresh_command_win (); + return; + } + parse_word (ptr,buffer); + ptr=strchr (buffer,'='); + if (ptr==NULL) { + wprintw (command_win,"Error - Bad syntax\n");refresh_command_win ();return; + } + strncpy (variable,buffer,ptr-buffer);variable [ptr-buffer]=0; + strcpy (value,++ptr); + + if (current_type==NULL) { + wprintw (command_win,"Sorry, not yet supported\n");refresh_command_win ();return; + } + + for (i=0;i<current_type->fields_num && !found;i++) { + if (strcmp (current_type->field_names [i],variable)==0) { + found=1; + ptr=type_data.u.buffer+offset; + len = current_type->field_lengths [i]; + switch (current_type->field_types [i]) { + case FIELD_TYPE_INT: + set_int(len, ptr, variable, value); + break; + case FIELD_TYPE_UINT: + set_uint(len, ptr, variable, value); + break; + case FIELD_TYPE_CHAR: + set_char(len, ptr, variable, value); + break; + default: + wprintw (command_win, + "set: unhandled type %d\n", + current_type->field_types [i]); + break; + } + refresh_command_win (); + } + offset+=current_type->field_lengths [i]; + } + if (found) + dispatch ("show"); + else { + wprintw (command_win,"Error - Variable %s not found\n",variable); + refresh_command_win (); + } +} + +void hex_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); + type_data.u.buffer [type_data.offset_in_block]=tmp; + type_data.offset_in_block++; + ptr=parse_word (ptr,buffer); + if (type_data.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 (); + } + type_data.offset_in_block--; + } + } while (*buffer) ; + } + + else { + ch_ptr=buffer; + while (*ch_ptr) { + tmp=(unsigned char) *ch_ptr++; + type_data.u.buffer [type_data.offset_in_block]=tmp; + type_data.offset_in_block++; + if (type_data.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 (); + } + type_data.offset_in_block--; + } + } + } + + strcpy (buffer,"show");dispatch (buffer); +} + + + +void set_type (char *command_line) + +{ + struct struct_descriptor *descriptor_ptr; + char *ptr,buffer [80],tmp_buffer [80]; + short found=0; + + if (!load_type_data ()) + return; + + ptr=parse_word (command_line,buffer); + parse_word (ptr,buffer); + + if (strcmp (buffer,"none")==0 || strcmp (buffer,"hex")==0) { + wprintw (command_win,"Data will be shown as hex dump\n");refresh_command_win (); + current_type=NULL; + sprintf (tmp_buffer,"show");dispatch (tmp_buffer); + return; + } + + descriptor_ptr=first_type; + while (descriptor_ptr!=NULL && !found) { + if (strcmp (descriptor_ptr->name,buffer)==0) + found=1; + else + descriptor_ptr=descriptor_ptr->next; + } + if (found) { + wprintw (command_win,"Structure type set to %s\n",buffer);refresh_command_win (); + current_type=descriptor_ptr; + sprintf (tmp_buffer,"show");dispatch (tmp_buffer); + } + else { + wprintw (command_win,"Error - %s is not a valid type\n",buffer);refresh_command_win (); + } +} + +void show_int(short len, void *ptr) +{ + long temp; + char *format; + + switch (len) { + case 1: + temp = *((char *) ptr); + format = "%3d (0x%02x)\n"; + break; + case 2: + temp = *((short *) ptr); + format = "%d (0x%x)\n"; + break; + case 4: + temp = *((long *) ptr); + format = "%d\n"; + break; + default: + wprintw (show_pad, "unimplemented\n"); + return; + } + wprintw(show_pad, format, temp, temp); +} + +void show_uint(short len, void *ptr) +{ + unsigned long temp; + char *format; + + switch (len) { + case 1: + temp = *((unsigned char *) ptr); + temp = temp & 0xFF; + format = "%3u (0x%02x)\n"; + break; + case 2: + temp = *((unsigned short *) ptr); + temp = temp & 0xFFFF; + format = "%u (0x%x)\n"; + break; + case 4: + temp = (unsigned long) *((unsigned long *) ptr); + format = "%u\n"; + break; + default: + wprintw (show_pad, "unimplemented\n"); + return; + } + wprintw(show_pad, format, temp, temp); +} + +void show_char(short len, void *ptr) +{ + unsigned char *cp = (unsigned char *) ptr; + unsigned char ch; + int i,j; + + wprintw(show_pad, "\""); + + for (i=0; i < len; i++) { + ch = *cp++; + if (ch == 0) { + for (j=i+1; j < len; j++) + if (cp[j-i]) + break; + if (j == len) + break; + } + if (ch > 128) { + wprintw(show_pad, "M-"); + ch -= 128; + } + if ((ch < 32) || (ch == 0x7f)) { + wprintw(show_pad, "^"); + ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */ + } + wprintw(show_pad, "%c", ch); + } + + wprintw(show_pad, "\"\n"); +} + + + +void show (char *command_line) + +{ + unsigned int i,l,len,temp_int; + unsigned long offset=0,temp_long; + unsigned char temp_char,*ch_ptr; + void *ptr; + + if (device_handle==NULL) + return; + + show_pad_info.line=0; + + if (current_type==NULL) { + wmove (show_pad,0,0); + ch_ptr=type_data.u.buffer; + for (l=0;l<file_system_info.block_size/16;l++) { + wprintw (show_pad,"%08ld : ",offset); + for (i=0;i<16;i++) { + if (type_data.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 (type_data.offset_in_block==offset+i) + wattrset (show_pad,A_NORMAL); + } + wprintw (show_pad," "); + for (i=0;i<16;i++) { + if (type_data.offset_in_block==offset+i) + wattrset (show_pad,A_REVERSE); + + wprintw (show_pad,"%02x",ch_ptr [i]); + + if (type_data.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+=16; + ch_ptr+=16; + } + show_pad_info.max_line=l-1;show_pad_info.max_col=COLS-1; + refresh_show_pad ();show_info (); + } + else { + wmove (show_pad,0,0);l=0; + for (i=0;i<current_type->fields_num;i++) { + wprintw (show_pad,"%-20s = ",current_type->field_names [i]); + ptr=type_data.u.buffer+offset; + len = current_type->field_lengths[i]; + switch (current_type->field_types[i]) { + case FIELD_TYPE_INT: + show_int(len, ptr); + break; + case FIELD_TYPE_UINT: + show_uint(len, ptr); + break; + case FIELD_TYPE_CHAR: + show_char(len, ptr); + break; + default: + wprintw (show_pad, "unimplemented\n"); + break; + } + offset+=len; + l++; + } + current_type->length=offset; + show_pad_info.max_line=l-1; + refresh_show_pad ();show_info (); + } +} + +void next (char *command_line) + +{ + long offset=1; + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + + if (*ptr!=0) { + ptr=parse_word (ptr,buffer); + offset*=atol (buffer); + } + + if (current_type!=NULL) { + sprintf (buffer,"setoffset type +%ld",offset); + dispatch (buffer); + return; + } + + if (type_data.offset_in_block+offset < file_system_info.block_size) { + type_data.offset_in_block+=offset; + sprintf (buffer,"show");dispatch (buffer); + } + + else { + wprintw (command_win,"Error - Offset out of block\n");refresh_command_win (); + } +} + +void prev (char *command_line) + +{ + long offset=1; + char *ptr,buffer [80]; + + ptr=parse_word (command_line,buffer); + + if (*ptr!=0) { + ptr=parse_word (ptr,buffer); + offset*=atol (buffer); + } + + if (current_type!=NULL) { + sprintf (buffer,"setoffset type -%ld",offset); + dispatch (buffer); + return; + } + + if (type_data.offset_in_block-offset >= 0) { + type_data.offset_in_block-=offset; + sprintf (buffer,"show");dispatch (buffer); + } + + else { + wprintw (command_win,"Error - Offset out of block\n");refresh_command_win (); + } +} + +void pgdn (char *commnad_line) + +{ + show_pad_info.line+=show_pad_info.display_lines; + refresh_show_pad ();refresh_show_win (); +} + +void pgup (char *command_line) + +{ + show_pad_info.line-=show_pad_info.display_lines; + refresh_show_pad ();refresh_show_win (); +} + +void redraw (char *command_line) + +{ + redraw_all (); + dispatch ("show"); +} + +void remember (char *command_line) + +{ + long entry_num; + char *ptr,buffer [80]; + + if (device_handle==NULL) { + wprintw (command_win,"Error - No device opened\n");refresh_command_win (); + return; + } + + 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); + + entry_num=remember_lifo.entries_count++; + if (entry_num>REMEMBER_COUNT-1) { + entry_num=0; + remember_lifo.entries_count--; + } + + remember_lifo.offset [entry_num]=device_offset; + remember_lifo.type [entry_num]=current_type; + strcpy (remember_lifo.name [entry_num],buffer); + + if (current_type!=NULL) + wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",current_type->name,device_offset,buffer); + else + wprintw (command_win,"Offset %ld remembered as %s\n",device_offset,buffer); + + refresh_command_win (); +} + +void recall (char *command_line) + +{ + char *ptr,buffer [80]; + long entry_num; + + if (device_handle==NULL) { + wprintw (command_win,"Error - No device opened\n");refresh_command_win (); + return; + } + + 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); + + + for (entry_num=remember_lifo.entries_count-1;entry_num>=0;entry_num--) { + if (strcmp (remember_lifo.name [entry_num],buffer)==0) + break; + } + + if (entry_num==-1) { + wprintw (command_win,"Error - Can not recall %s\n",buffer);refresh_command_win (); + return; + } + + sprintf (buffer,"setoffset %ld",remember_lifo.offset [entry_num]);dispatch (buffer); + if (remember_lifo.type [entry_num] != NULL) { + sprintf (buffer,"settype %s",remember_lifo.type [entry_num]->name);dispatch (buffer); + } + + else { + sprintf (buffer,"settype none");dispatch (buffer); + } + + wprintw (command_win,"Object %s in Offset %ld recalled\n",current_type->name,device_offset); + refresh_command_win (); +} + +void enable_write (char *command_line) + +{ + FILE *fp; + + if (device_handle==NULL) { + wprintw (command_win,"Error - No device opened\n");refresh_command_win (); + return; + } + + if (!AllowChanges) { + wprintw (command_win,"Sorry, write access is not allowed\n"); + return; + } + + if (mounted) { + wprintw (command_win,"Error - Filesystem is mounted\n"); + return; + } + + if ( (fp=fopen (device_name,"r+b"))==NULL) { + wprintw (command_win,"Error - Can not open device %s for reading and writing\n",device_name);refresh_command_win (); + return; + } + fclose (device_handle); + device_handle=fp;write_access=1; + wprintw (command_win,"Write access enabled - Be careful\n");refresh_command_win (); +} + +void disable_write (char *command_line) + +{ + FILE *fp; + + if (device_handle==NULL) { + wprintw (command_win,"Error - No device opened\n");refresh_command_win (); + return; + } + + if ( (fp=fopen (device_name,"rb"))==NULL) { + wprintw (command_win,"Error - Can not open device %s\n",device_name);refresh_command_win (); + return; + } + + fclose (device_handle); + device_handle=fp;write_access=0; + wprintw (command_win,"Write access disabled\n");refresh_command_win (); +} + +void write_data (char *command_line) + +{ + write_type_data (); +} |