Merge change 9990
[android/platform/external/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 <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 }