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