Home | History | Annotate | Download | only in ext2ed
      1 /*
      2 
      3 /usr/src/ext2ed/general_com.c
      4 
      5 A part of the extended file system 2 disk editor.
      6 
      7 ---------------------
      8 General user commands
      9 ---------------------
     10 
     11 First written on: April 9 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 #include "../version.h"
     24 
     25 void help (char *command_line)
     26 
     27 {
     28 	int i,max_line=0;
     29 	char argument [80],*ptr;
     30 
     31 	werase (show_pad);wmove (show_pad,0,0);
     32 
     33 	ptr=parse_word (command_line,argument);
     34 
     35 	if (*ptr!=0) {
     36 		 ptr=parse_word (ptr,argument);
     37 		 if (*argument!=0) {
     38 			 detailed_help (argument);
     39 			 return;
     40 		}
     41 	}
     42 
     43 	if (current_type!=NULL) {
     44 
     45 		wprintw (show_pad,"Type %s specific commands:\n",current_type->name);max_line++;
     46 
     47 		if (current_type->type_commands.last_command==-1) {
     48 			wprintw (show_pad,"\nnone\n");max_line+=2;
     49 		}
     50 		else
     51 			for (i=0;i<=current_type->type_commands.last_command;i++) {
     52 				if (i%5==0) {
     53 					wprintw (show_pad,"\n");max_line++;
     54 				}
     55 				wprintw (show_pad,"%-13s",current_type->type_commands.names [i]);
     56 				if (i%5!=4)
     57 					wprintw (show_pad,";  ");
     58 			}
     59 
     60 		wprintw (show_pad,"\n\n");max_line+=2;
     61 	}
     62 
     63 	if (ext2_commands.last_command != -1) {
     64 		wprintw (show_pad,"ext2 filesystem general commands: \n");max_line++;
     65 		for (i=0;i<=ext2_commands.last_command;i++) {
     66 			if (i%5==0) {
     67 				wprintw (show_pad,"\n");max_line++;
     68 			}
     69 			wprintw (show_pad,"%-13s",ext2_commands.names [i]);
     70 			if (i%5!=4)
     71 				wprintw (show_pad,";  ");
     72 
     73 		}
     74 		wprintw (show_pad,"\n\n");max_line+=2;
     75 	}
     76 
     77 	wprintw (show_pad,"General commands: \n");
     78 
     79 	for (i=0;i<=general_commands.last_command;i++) {
     80 		if (i%5==0) {
     81 			wprintw (show_pad,"\n");max_line++;
     82 		}
     83 		wprintw (show_pad,"%-13s",general_commands.names [i]);
     84 		if (i%5!=4)
     85 			wprintw (show_pad,";  ");
     86 	}
     87 
     88 	wprintw (show_pad,"\n\n");max_line+=2;
     89 
     90 	wprintw (show_pad,"EXT2ED ver %s (%s)\n",E2FSPROGS_VERSION, E2FSPROGS_DATE);
     91 	wprintw (show_pad,"Copyright (C) 1995 Gadi Oxman\n");
     92 	wprintw (show_pad,"Reviewed 2001 Christian Bac\n");
     93 	wprintw (show_pad,"Modified and enchanced by Theodore Ts'o, 2002\n");
     94 	wprintw (show_pad,"EXT2ED is hereby placed under the terms of the GNU General Public License.\n\n");
     95 	wprintw (show_pad,"EXT2ED was programmed as a student project in the software laboratory\n");
     96 	wprintw (show_pad,"of the faculty of electrical engineering in the\n");
     97 	wprintw (show_pad,"Technion - Israel Institute of Technology\n");
     98 	wprintw (show_pad,"with the guide of Avner Lottem and Dr. Ilana David.\n");
     99 
    100 	max_line+=10;
    101 
    102 	show_pad_info.line=0;show_pad_info.max_line=max_line;
    103 
    104 	werase (show_win);wmove (show_win,0,0);
    105 	wprintw (show_win,"EXT2ED help");
    106 
    107 	refresh_show_win ();
    108 	refresh_show_pad ();
    109 }
    110 
    111 void detailed_help (char *text)
    112 
    113 {
    114 	int i;
    115 
    116 	if (current_type != NULL)
    117 		for (i=0;i<=current_type->type_commands.last_command;i++) {
    118 			if (strcmp (current_type->type_commands.names [i],text)==0) {
    119 				wprintw (show_pad,"%s - %s\n",text,current_type->type_commands.descriptions [i]);
    120 				refresh_show_pad ();return;
    121 			}
    122 		}
    123 
    124 	for (i=0;i<=ext2_commands.last_command;i++) {
    125 		if (strcmp (ext2_commands.names [i],text)==0) {
    126 				wprintw (show_pad,"%s - %s\n",text,ext2_commands.descriptions [i]);
    127 				refresh_show_pad ();return;
    128 		}
    129 	}
    130 
    131 	for (i=0;i<=general_commands.last_command;i++) {
    132 		if (strcmp (general_commands.names [i],text)==0) {
    133 				wprintw (show_pad,"%s - %s\n",text,general_commands.descriptions [i]);
    134 				refresh_show_pad ();return;
    135 		}
    136 	}
    137 
    138 	if (strcmp ("quit",text)==0) {
    139 		wprintw (show_pad,"quit - Exists EXT2ED");
    140 		refresh_show_pad ();return;
    141 	}
    142 
    143 	wprintw (show_pad,"Error - Command %s not aviable now\n",text);
    144 	refresh_show_pad ();return;
    145 }
    146 
    147 
    148 
    149 void set_device (char *command_line)
    150 
    151 {
    152 	char *ptr,new_device [80];
    153 
    154 	ptr=parse_word (command_line,new_device);
    155 	if (*ptr==0) {
    156 		wprintw (command_win,"Error - Device name not specified\n");
    157 		refresh_command_win ();return;
    158 	}
    159 	parse_word (ptr,new_device);
    160 	check_mounted (new_device);
    161 	if (mounted && !AllowMountedRead) {
    162 		wprintw (command_win,"Error - Filesystem is mounted, aborting\n");
    163 		wprintw (command_win,"You may wish to use the AllowMountedRead on configuration option\n");
    164 		refresh_command_win ();return;
    165 	}
    166 
    167 	if (mounted && AllowMountedRead) {
    168 		wprintw (command_win,"Warning - Filesystem is mounted. Displayed data may be unreliable.\n");
    169 		refresh_command_win ();
    170 	}
    171 
    172 	if (device_handle!=NULL)
    173 		fclose (device_handle);
    174 
    175 	if ( (device_handle=fopen (new_device,"rb"))==NULL) {
    176 		wprintw (command_win,"Error - Can not open device %s\n",new_device);refresh_command_win ();
    177 		return;
    178 	}
    179 	else {
    180 		strcpy (device_name,new_device);
    181 		write_access=0;				/* Write access disabled */
    182 		current_type=NULL;			/* There is no type now */
    183 		remember_lifo.entries_count=0;		/* Empty Object memory */
    184 		free_user_commands (&ext2_commands);	/* Free filesystem specific objects */
    185 		free_struct_descriptors ();
    186 		if (!set_file_system_info ()) {		/* Error while getting info --> abort */
    187 			free_user_commands (&ext2_commands);
    188 			free_struct_descriptors ();
    189 			fclose (device_handle);
    190 			device_handle=NULL;		/* Notice that our device is still not set up */
    191 			device_offset=-1;
    192 			return;
    193 		}
    194 		if (*AlternateDescriptors)		/* Check if user defined objects exist */
    195 			set_struct_descriptors (AlternateDescriptors);
    196 		dispatch ("setoffset 0");
    197 		dispatch ("help");			/* Show help screen */
    198 		wprintw (command_win,"Device changed to %s",device_name);refresh_command_win ();
    199 	}
    200 }
    201 
    202 void set_offset (char *command_line)
    203 
    204 {
    205 	long mult=1;
    206 	long new_offset;
    207 	char *ptr,new_offset_buffer [80];
    208 
    209 	if (device_handle==NULL) {
    210 		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
    211 		return;
    212 	}
    213 
    214 	ptr=parse_word (command_line,new_offset_buffer);
    215 
    216 	if (*ptr==0) {
    217 		wprintw (command_win,"Error - No argument specified\n");refresh_command_win ();
    218 		return;
    219 	}
    220 
    221 	ptr=parse_word (ptr,new_offset_buffer);
    222 
    223 	if (strcmp (new_offset_buffer,"block")==0) {
    224 		mult=file_system_info.block_size;
    225 		ptr=parse_word (ptr,new_offset_buffer);
    226 	}
    227 
    228 	if (strcmp (new_offset_buffer,"type")==0) {
    229 		if (current_type==NULL) {
    230 			wprintw (command_win,"Error - No type set\n");refresh_command_win ();
    231 			return;
    232 		}
    233 
    234 		mult=current_type->length;
    235 		ptr=parse_word (ptr,new_offset_buffer);
    236 	}
    237 
    238 	if (*new_offset_buffer==0) {
    239 		wprintw (command_win,"Error - No offset specified\n");refresh_command_win ();
    240 		return;
    241 	}
    242 
    243 	if (new_offset_buffer [0]=='+') {
    244 		if (device_offset==-1) {
    245 			wprintw (command_win,"Error - Select a fixed offset first\n");refresh_command_win ();
    246 			return;
    247 		}
    248 		new_offset=device_offset+atol (new_offset_buffer+1)*mult;
    249 	}
    250 
    251 	else if (new_offset_buffer [0]=='-') {
    252 		if (device_offset==-1) {
    253 			wprintw (command_win,"Error - Select a fixed offset first\n");refresh_command_win ();
    254 			return;
    255 		}
    256 		new_offset=device_offset-atol (new_offset_buffer+1)*mult;
    257 		if (new_offset<0) new_offset=0;
    258 	}
    259 
    260 	else
    261 		new_offset=atol (new_offset_buffer)*mult;
    262 
    263 	if ( (fseek (device_handle,new_offset,SEEK_SET))==-1) {
    264 		wprintw (command_win,"Error - Failed to seek to offset %ld in device %s\n",new_offset,device_name);
    265 		refresh_command_win ();
    266 		return;
    267 	};
    268 	device_offset=new_offset;
    269 	wprintw (command_win,"Device offset changed to %ld\n",device_offset);refresh_command_win ();
    270 	load_type_data ();
    271 	type_data.offset_in_block=0;
    272 }
    273 
    274 void set_int(short len, void *ptr, char *name, char *value)
    275 {
    276 	char	*char_ptr;
    277 	short	*short_ptr;
    278 	long	*long_ptr;
    279 	long	v;
    280 	char	*tmp;
    281 
    282 	v = strtol(value, &tmp, 0);
    283 	if (*tmp) {
    284 		wprintw( command_win, "Bad value - %s\n", value);
    285 		return;
    286 	}
    287 	switch (len) {
    288 	case 1:
    289 		char_ptr = (char *) ptr;
    290 		*char_ptr = v;
    291 		break;
    292 	case 2:
    293 		short_ptr = (short *) ptr;
    294 		*short_ptr = v;
    295 		break;
    296 	case 4:
    297 		long_ptr = (long *) ptr;
    298 		*long_ptr = v;
    299 		break;
    300 	default:
    301 		wprintw (command_win,
    302 			 "set_int: unsupported length: %d\n", len);
    303 		return;
    304 	}
    305 	wprintw (command_win, "Variable %s set to %s\n",
    306 		 name, value);
    307 }
    308 
    309 void set_uint(short len, void *ptr, char *name, char *value)
    310 {
    311 	unsigned char	*char_ptr;
    312 	unsigned short	*short_ptr;
    313 	unsigned long	*long_ptr;
    314 	unsigned long	v;
    315 	char		*tmp;
    316 
    317 	v = strtoul(value, &tmp, 0);
    318 	if (*tmp) {
    319 		wprintw( command_win, "Bad value - %s\n", value);
    320 		return;
    321 	}
    322 	switch (len) {
    323 	case 1:
    324 		char_ptr = (unsigned char *) ptr;
    325 		*char_ptr = v;
    326 		break;
    327 	case 2:
    328 		short_ptr = (unsigned short *) ptr;
    329 		*short_ptr = v;
    330 		break;
    331 	case 4:
    332 		long_ptr = (unsigned long *) ptr;
    333 		*long_ptr = v;
    334 		break;
    335 	default:
    336 		wprintw (command_win,
    337 			 "set_uint: unsupported length: %d\n", len);
    338 		return;
    339 	}
    340 	wprintw (command_win, "Variable %s set to %s\n",
    341 		 name, value);
    342 }
    343 
    344 void set_char(short len, void *ptr, char *name, char *value)
    345 {
    346 	if (strlen(value)+1 > len) {
    347 		wprintw( command_win, "Value %s too big for field\n",
    348 			name, len);
    349 		return;
    350 	}
    351 	memset(ptr, 0, len);
    352 	strcpy((char *) ptr, value);
    353 	wprintw (command_win, "Variable %s set to %s\n",
    354 		 name, value);
    355 }
    356 
    357 
    358 void set (char *command_line)
    359 
    360 {
    361 	unsigned short *int_ptr;
    362 	unsigned char *char_ptr;
    363 	unsigned long *long_ptr,offset=0;
    364 	int i,len, found=0;
    365 	char *ptr,buffer [80],variable [80],value [80];
    366 
    367 	if (device_handle==NULL) {
    368 		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
    369 		return;
    370 	}
    371 
    372 	if (current_type==NULL) {
    373 		hex_set (command_line);
    374 		return;
    375 	}
    376 
    377 	ptr=parse_word (command_line,buffer);
    378 	if (ptr==NULL || *ptr==0) {
    379 		wprintw (command_win,"Error - Missing arguments\n");refresh_command_win ();
    380 		return;
    381 	}
    382 	parse_word (ptr,buffer);
    383 	ptr=strchr (buffer,'=');
    384 	if (ptr==NULL) {
    385 		wprintw (command_win,"Error - Bad syntax\n");refresh_command_win ();return;
    386 	}
    387 	strncpy (variable,buffer,ptr-buffer);variable [ptr-buffer]=0;
    388 	strcpy (value,++ptr);
    389 
    390 	if (current_type==NULL) {
    391 		wprintw (command_win,"Sorry, not yet supported\n");refresh_command_win ();return;
    392 	}
    393 
    394 	for (i=0;i<current_type->fields_num && !found;i++) {
    395 		if (strcmp (current_type->field_names [i],variable)==0) {
    396 			found=1;
    397 			ptr=type_data.u.buffer+offset;
    398 			len = current_type->field_lengths [i];
    399 			switch (current_type->field_types [i]) {
    400 			case FIELD_TYPE_INT:
    401 				set_int(len, ptr, variable, value);
    402 				break;
    403 			case FIELD_TYPE_UINT:
    404 				set_uint(len, ptr, variable, value);
    405 				break;
    406 			case FIELD_TYPE_CHAR:
    407 				set_char(len, ptr, variable, value);
    408 				break;
    409 			default:
    410 				wprintw (command_win,
    411 					 "set: unhandled type %d\n",
    412 					 current_type->field_types [i]);
    413 				break;
    414 			}
    415 			refresh_command_win ();
    416 		}
    417 		offset+=current_type->field_lengths [i];
    418 	}
    419 	if (found)
    420 		dispatch ("show");
    421 	else {
    422 		wprintw (command_win,"Error - Variable %s not found\n",variable);
    423 		refresh_command_win ();
    424 	}
    425 }
    426 
    427 void hex_set (char *command_line)
    428 
    429 {
    430 	unsigned char tmp;
    431 	char *ptr,buffer [80],*ch_ptr;
    432 	int mode=HEX;
    433 
    434 	ptr=parse_word (command_line,buffer);
    435 	if (*ptr==0) {
    436 		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();return;
    437 	}
    438 
    439 	ptr=parse_word (ptr,buffer);
    440 
    441 	if (strcasecmp (buffer,"text")==0) {
    442 		mode=TEXT;
    443 		strcpy (buffer,ptr);
    444 	}
    445 
    446 	else if (strcasecmp (buffer,"hex")==0) {
    447 		mode=HEX;
    448 		ptr=parse_word (ptr,buffer);
    449 	}
    450 
    451 	if (*buffer==0) {
    452 		wprintw (command_win,"Error - Data not specified\n");refresh_command_win ();return;
    453 	}
    454 
    455 	if (mode==HEX) {
    456 		do {
    457 			tmp=(unsigned char) strtol (buffer,NULL,16);
    458 			type_data.u.buffer [type_data.offset_in_block]=tmp;
    459 			type_data.offset_in_block++;
    460 			ptr=parse_word (ptr,buffer);
    461 			if (type_data.offset_in_block==file_system_info.block_size) {
    462 				if (*ptr) {
    463 					wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
    464 					refresh_command_win ();
    465 				}
    466 				type_data.offset_in_block--;
    467 			}
    468 		} while (*buffer) ;
    469 	}
    470 
    471 	else {
    472 		ch_ptr=buffer;
    473 		while (*ch_ptr) {
    474 			tmp=(unsigned char) *ch_ptr++;
    475 			type_data.u.buffer [type_data.offset_in_block]=tmp;
    476 			type_data.offset_in_block++;
    477 			if (type_data.offset_in_block==file_system_info.block_size) {
    478 				if (*ch_ptr) {
    479 					wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
    480 					refresh_command_win ();
    481 				}
    482 				type_data.offset_in_block--;
    483 			}
    484 		}
    485 	}
    486 
    487 	strcpy (buffer,"show");dispatch (buffer);
    488 }
    489 
    490 
    491 
    492 void set_type (char *command_line)
    493 
    494 {
    495 	struct struct_descriptor *descriptor_ptr;
    496 	char *ptr,buffer [80],tmp_buffer [80];
    497 	short found=0;
    498 
    499 	if (!load_type_data ())
    500 		return;
    501 
    502 	ptr=parse_word (command_line,buffer);
    503 	parse_word (ptr,buffer);
    504 
    505 	if (strcmp (buffer,"none")==0 || strcmp (buffer,"hex")==0) {
    506 		wprintw (command_win,"Data will be shown as hex dump\n");refresh_command_win ();
    507 		current_type=NULL;
    508 		sprintf (tmp_buffer,"show");dispatch (tmp_buffer);
    509 		return;
    510 	}
    511 
    512 	descriptor_ptr=first_type;
    513 	while (descriptor_ptr!=NULL && !found) {
    514 		if (strcmp (descriptor_ptr->name,buffer)==0)
    515 			found=1;
    516 		else
    517 			descriptor_ptr=descriptor_ptr->next;
    518 	}
    519 	if (found) {
    520 		wprintw (command_win,"Structure type set to %s\n",buffer);refresh_command_win ();
    521 		current_type=descriptor_ptr;
    522 		sprintf (tmp_buffer,"show");dispatch (tmp_buffer);
    523 	}
    524 	else {
    525 		wprintw (command_win,"Error - %s is not a valid type\n",buffer);refresh_command_win ();
    526 	}
    527 }
    528 
    529 void show_int(short len, void *ptr)
    530 {
    531 	long	temp;
    532 	char	*format;
    533 
    534 	switch (len) {
    535 	case 1:
    536 		temp = *((char *) ptr);
    537 		format = "%3d (0x%02x)\n";
    538 		break;
    539 	case 2:
    540 		temp = *((short *) ptr);
    541 		format = "%d (0x%x)\n";
    542 		break;
    543 	case 4:
    544 		temp = *((long *) ptr);
    545 		format = "%d\n";
    546 		break;
    547 	default:
    548 		wprintw (show_pad, "unimplemented\n");
    549 		return;
    550 	}
    551 	wprintw(show_pad, format, temp, temp);
    552 }
    553 
    554 void show_uint(short len, void *ptr)
    555 {
    556 	unsigned long	temp;
    557 	char		*format;
    558 
    559 	switch (len) {
    560 	case 1:
    561 		temp = *((unsigned char *) ptr);
    562 		temp = temp & 0xFF;
    563 		format = "%3u (0x%02x)\n";
    564 		break;
    565 	case 2:
    566 		temp = *((unsigned short *) ptr);
    567 		temp = temp & 0xFFFF;
    568 		format = "%u (0x%x)\n";
    569 		break;
    570 	case 4:
    571 		temp = (unsigned long) *((unsigned long *) ptr);
    572 		format = "%u\n";
    573 		break;
    574 	default:
    575 		wprintw (show_pad, "unimplemented\n");
    576 		return;
    577 	}
    578 	wprintw(show_pad, format, temp, temp);
    579 }
    580 
    581 void show_char(short len, void *ptr)
    582 {
    583 	unsigned char	*cp = (unsigned char *) ptr;
    584 	unsigned char	ch;
    585 	int		i,j;
    586 
    587 	wprintw(show_pad, "\"");
    588 
    589 	for (i=0; i < len; i++) {
    590 		ch = *cp++;
    591 		if (ch == 0) {
    592 			for (j=i+1; j < len; j++)
    593 				if (cp[j-i])
    594 					break;
    595 			if (j == len)
    596 				break;
    597 		}
    598 		if (ch > 128) {
    599 			wprintw(show_pad, "M-");
    600 			ch -= 128;
    601 		}
    602 		if ((ch < 32) || (ch == 0x7f)) {
    603 			wprintw(show_pad, "^");
    604 			ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
    605 		}
    606 		wprintw(show_pad, "%c", ch);
    607 	}
    608 
    609 	wprintw(show_pad, "\"\n");
    610 }
    611 
    612 
    613 
    614 void show (char *command_line)
    615 
    616 {
    617 	unsigned int i,l,len,temp_int;
    618 	unsigned long offset=0,temp_long;
    619 	unsigned char temp_char,*ch_ptr;
    620 	void *ptr;
    621 
    622 	if (device_handle==NULL)
    623 		return;
    624 
    625 	show_pad_info.line=0;
    626 
    627 	if (current_type==NULL) {
    628 		wmove (show_pad,0,0);
    629 		ch_ptr=type_data.u.buffer;
    630 		for (l=0;l<file_system_info.block_size/16;l++) {
    631 			wprintw (show_pad,"%08ld :  ",offset);
    632 			for (i=0;i<16;i++) {
    633 				if (type_data.offset_in_block==offset+i)
    634 					wattrset (show_pad,A_REVERSE);
    635 
    636 				if (ch_ptr [i]>=' ' && ch_ptr [i]<='z')
    637 					wprintw (show_pad,"%c",ch_ptr [i]);
    638 				else
    639 					wprintw (show_pad,".");
    640 				if (type_data.offset_in_block==offset+i)
    641 					wattrset (show_pad,A_NORMAL);
    642 			}
    643 			wprintw (show_pad,"   ");
    644 			for (i=0;i<16;i++) {
    645 				if (type_data.offset_in_block==offset+i)
    646 					wattrset (show_pad,A_REVERSE);
    647 
    648 				wprintw (show_pad,"%02x",ch_ptr [i]);
    649 
    650 				if (type_data.offset_in_block==offset+i) {
    651 					wattrset (show_pad,A_NORMAL);
    652 					show_pad_info.line=l-l % show_pad_info.display_lines;
    653 				}
    654 
    655 				wprintw (show_pad," ");
    656 			}
    657 			wprintw (show_pad,"\n");
    658 			offset+=16;
    659 			ch_ptr+=16;
    660 		}
    661 		show_pad_info.max_line=l-1;show_pad_info.max_col=COLS-1;
    662 		refresh_show_pad ();show_info ();
    663 	}
    664 	else {
    665 		wmove (show_pad,0,0);l=0;
    666 		for (i=0;i<current_type->fields_num;i++) {
    667 			wprintw (show_pad,"%-20s = ",current_type->field_names [i]);
    668 			ptr=type_data.u.buffer+offset;
    669 			len = current_type->field_lengths[i];
    670 			switch (current_type->field_types[i]) {
    671 			case FIELD_TYPE_INT:
    672 				show_int(len, ptr);
    673 				break;
    674 			case FIELD_TYPE_UINT:
    675 				show_uint(len, ptr);
    676 				break;
    677 			case FIELD_TYPE_CHAR:
    678 				show_char(len, ptr);
    679 				break;
    680 			default:
    681 				wprintw (show_pad, "unimplemented\n");
    682 				break;
    683 			}
    684 			offset+=len;
    685 			l++;
    686 		}
    687 		current_type->length=offset;
    688 		show_pad_info.max_line=l-1;
    689 		refresh_show_pad ();show_info ();
    690 	}
    691 }
    692 
    693 void next (char *command_line)
    694 
    695 {
    696 	long offset=1;
    697 	char *ptr,buffer [80];
    698 
    699 	ptr=parse_word (command_line,buffer);
    700 
    701 	if (*ptr!=0) {
    702 		ptr=parse_word (ptr,buffer);
    703 		offset*=atol (buffer);
    704 	}
    705 
    706 	if (current_type!=NULL) {
    707 		sprintf (buffer,"setoffset type +%ld",offset);
    708 		dispatch (buffer);
    709 		return;
    710 	}
    711 
    712 	if (type_data.offset_in_block+offset < file_system_info.block_size) {
    713 		type_data.offset_in_block+=offset;
    714 		sprintf (buffer,"show");dispatch (buffer);
    715 	}
    716 
    717 	else {
    718 		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
    719 	}
    720 }
    721 
    722 void prev (char *command_line)
    723 
    724 {
    725 	long offset=1;
    726 	char *ptr,buffer [80];
    727 
    728 	ptr=parse_word (command_line,buffer);
    729 
    730 	if (*ptr!=0) {
    731 		ptr=parse_word (ptr,buffer);
    732 		offset*=atol (buffer);
    733 	}
    734 
    735 	if (current_type!=NULL) {
    736 		sprintf (buffer,"setoffset type -%ld",offset);
    737 		dispatch (buffer);
    738 		return;
    739 	}
    740 
    741 	if (type_data.offset_in_block-offset >= 0) {
    742 		type_data.offset_in_block-=offset;
    743 		sprintf (buffer,"show");dispatch (buffer);
    744 	}
    745 
    746 	else {
    747 		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
    748 	}
    749 }
    750 
    751 void pgdn (char *commnad_line)
    752 
    753 {
    754 	show_pad_info.line+=show_pad_info.display_lines;
    755 	refresh_show_pad ();refresh_show_win ();
    756 }
    757 
    758 void pgup (char *command_line)
    759 
    760 {
    761 	show_pad_info.line-=show_pad_info.display_lines;
    762 	refresh_show_pad ();refresh_show_win ();
    763 }
    764 
    765 void redraw (char *command_line)
    766 
    767 {
    768 	redraw_all ();
    769 	dispatch ("show");
    770 }
    771 
    772 void remember (char *command_line)
    773 
    774 {
    775 	long entry_num;
    776 	char *ptr,buffer [80];
    777 
    778 	if (device_handle==NULL) {
    779 		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
    780 		return;
    781 	}
    782 
    783 	ptr=parse_word (command_line,buffer);
    784 
    785 	if (*ptr==0) {
    786 		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();
    787 		return;
    788 	}
    789 
    790 	ptr=parse_word (ptr,buffer);
    791 
    792 	entry_num=remember_lifo.entries_count++;
    793 	if (entry_num>REMEMBER_COUNT-1) {
    794 		entry_num=0;
    795 		remember_lifo.entries_count--;
    796 	}
    797 
    798 	remember_lifo.offset [entry_num]=device_offset;
    799 	remember_lifo.type [entry_num]=current_type;
    800 	strcpy (remember_lifo.name [entry_num],buffer);
    801 
    802 	if (current_type!=NULL)
    803 		wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",current_type->name,device_offset,buffer);
    804 	else
    805 		wprintw (command_win,"Offset %ld remembered as %s\n",device_offset,buffer);
    806 
    807 	refresh_command_win ();
    808 }
    809 
    810 void recall (char *command_line)
    811 
    812 {
    813 	char *ptr,buffer [80];
    814 	long entry_num;
    815 
    816 	if (device_handle==NULL) {
    817 		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
    818 		return;
    819 	}
    820 
    821 	ptr=parse_word (command_line,buffer);
    822 
    823 	if (*ptr==0) {
    824 		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();
    825 		return;
    826 	}
    827 
    828 	ptr=parse_word (ptr,buffer);
    829 
    830 
    831 	for (entry_num=remember_lifo.entries_count-1;entry_num>=0;entry_num--) {
    832 		if (strcmp (remember_lifo.name [entry_num],buffer)==0)
    833 			break;
    834 	}
    835 
    836 	if (entry_num==-1) {
    837 		wprintw (command_win,"Error - Can not recall %s\n",buffer);refresh_command_win ();
    838 		return;
    839 	}
    840 
    841 	sprintf (buffer,"setoffset %ld",remember_lifo.offset [entry_num]);dispatch (buffer);
    842 	if (remember_lifo.type [entry_num] != NULL) {
    843 		sprintf (buffer,"settype %s",remember_lifo.type [entry_num]->name);dispatch (buffer);
    844 	}
    845 
    846 	else {
    847 		sprintf (buffer,"settype none");dispatch (buffer);
    848 	}
    849 
    850 	wprintw (command_win,"Object %s in Offset %ld recalled\n",current_type->name,device_offset);
    851 	refresh_command_win ();
    852 }
    853 
    854 void enable_write (char *command_line)
    855 
    856 {
    857 	FILE *fp;
    858 
    859 	if (device_handle==NULL) {
    860 		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
    861 		return;
    862 	}
    863 
    864 	if (!AllowChanges) {
    865 		wprintw (command_win,"Sorry, write access is not allowed\n");
    866     		return;
    867     	}
    868 
    869     	if (mounted) {
    870     		wprintw (command_win,"Error - Filesystem is mounted\n");
    871 		return;
    872     	}
    873 
    874 	if ( (fp=fopen (device_name,"r+b"))==NULL) {
    875 		wprintw (command_win,"Error - Can not open device %s for reading and writing\n",device_name);refresh_command_win ();
    876 		return;
    877 	}
    878 	fclose (device_handle);
    879 	device_handle=fp;write_access=1;
    880 	wprintw (command_win,"Write access enabled - Be careful\n");refresh_command_win ();
    881 }
    882 
    883 void disable_write (char *command_line)
    884 
    885 {
    886 	FILE *fp;
    887 
    888 	if (device_handle==NULL) {
    889 		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
    890 		return;
    891 	}
    892 
    893 	if ( (fp=fopen (device_name,"rb"))==NULL) {
    894 		wprintw (command_win,"Error - Can not open device %s\n",device_name);refresh_command_win ();
    895 		return;
    896 	}
    897 
    898 	fclose (device_handle);
    899 	device_handle=fp;write_access=0;
    900 	wprintw (command_win,"Write access disabled\n");refresh_command_win ();
    901 }
    902 
    903 void write_data (char *command_line)
    904 
    905 {
    906 	write_type_data ();
    907 }
    908