cleanup spec
[platform/upstream/e2fsprogs.git] / ext2ed / general_com.c
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 }