/* /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 (); }