Whamcloud - gitweb
ef59b27ad9838e0a383cd6cbb5d4da1c9a688e38
[tools/e2fsprogs.git] / ext2ed / init.c
1 /*
2
3 /usr/src/ext2ed/init.c
4
5 A part of the extended file system 2 disk editor.
6
7 --------------------------------
8 Various initialization routines.
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 #include <readline.h>
21 #include <signal.h>
22 #include <unistd.h>
23 #include <sys/ioctl.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27
28 #include "ext2ed.h"
29
30 char lines_s [80],cols_s [80];
31
32 void signal_handler (void);
33
34 void prepare_to_close (void)
35
36 {
37         close_windows ();
38         if (device_handle!=NULL)
39                 fclose (device_handle);
40         free_user_commands (&general_commands);
41         free_user_commands (&ext2_commands);
42         free_struct_descriptors ();
43 }
44
45 int init (void)
46
47 {
48         printf ("Initializing ...\n");
49         
50         if (!process_configuration_file ()) {
51                 fprintf (stderr,"Error - Unable to complete configuration. Quitting.\n");
52                 return (0);             
53         };
54         
55         general_commands.last_command=-1;       /* No commands whatsoever meanwhile */
56         ext2_commands.last_command=-1;
57         add_general_commands ();                /* Add the general commands, aviable always */
58         device_handle=NULL;                     /* Notice that our device is still not set up */
59         device_offset=-1;
60         current_type=NULL;                      /* No filesystem specific types yet */
61
62         remember_lifo.entries_count=0;          /* Object memory is empty */
63         
64         init_windows ();                        /* Initialize the NCURSES interface */
65         init_readline ();                       /* Initialize the READLINE interface */
66         init_signals ();                        /* Initialize the signal handlers */
67         write_access=0;                         /* Write access disabled */
68         
69         strcpy (last_command_line,"help");      /* Show the help screen to the user */
70         dispatch ("help");
71         return (1);                             /* Success */
72 }
73
74 void add_general_commands (void)
75
76 {
77         add_user_command (&general_commands,"help","EXT2ED help system",help);
78         add_user_command (&general_commands,"set","Changes a variable in the current object",set);
79         add_user_command (&general_commands,"setdevice","Selects the filesystem block device (e.g. /dev/hda1)",set_device);
80         add_user_command (&general_commands,"setoffset","Moves asynchronicly in the filesystem",set_offset);
81         add_user_command (&general_commands,"settype","Tells EXT2ED how to interpert the current object",set_type);
82         add_user_command (&general_commands,"show","Displays the current object",show);
83         add_user_command (&general_commands,"pgup","Scrolls data one page up",pgup);
84         add_user_command (&general_commands,"pgdn","Scrolls data one page down",pgdn);
85         add_user_command (&general_commands,"redraw","Redisplay the screen",redraw);
86         add_user_command (&general_commands,"remember","Saves the current position and data information",remember);
87         add_user_command (&general_commands,"recall","Gets back to the saved object position",recall);
88         add_user_command (&general_commands,"enablewrite","Enters Read/Write mode - Allows changing the filesystem",enable_write);
89         add_user_command (&general_commands,"disablewrite","Enters read only mode",disable_write);
90         add_user_command (&general_commands,"writedata","Write data back to disk",write_data);
91         add_user_command (&general_commands,"next","Moves to the next byte in hex mode",next);
92         add_user_command (&general_commands,"prev","Moves to the previous byte in hex mode",prev);
93 }
94
95 void add_ext2_general_commands (void)
96
97 {
98         add_user_command (&ext2_commands,"super","Moves to the superblock of the filesystem",type_ext2___super);
99         add_user_command (&ext2_commands,"group","Moves to the first group descriptor",type_ext2___group);
100         add_user_command (&ext2_commands,"cd","Moves to the directory specified",type_ext2___cd);
101 }
102
103 int set_struct_descriptors (char *file_name)
104
105 {
106         FILE *fp;
107         char current_line [500],current_word [50],*ch;
108         char variable_name [50],variable_type [20];
109         struct struct_descriptor *current_descriptor;
110         
111         if ( (fp=fopen (file_name,"rt"))==NULL) {
112                 wprintw (command_win,"Error - Failed to open descriptors file %s\n",file_name);
113                 refresh_command_win (); return (0);
114         };
115         
116         while (!feof (fp)) {
117                 fgets (current_line,500,fp);
118                 if (feof (fp)) break;   
119                 ch=parse_word (current_line,current_word);
120                 if (strcmp (current_word,"struct")==0) {
121                         ch=parse_word (ch,current_word);
122                         current_descriptor=add_new_descriptor (current_word);
123                         
124                         while (strchr (current_line,'{')==NULL) {
125                                 fgets (current_line,500,fp);
126                                 if (feof (fp)) break;
127                         };
128                         if (feof (fp)) break;
129                         
130                         fgets (current_line,500,fp);
131
132                         while (strchr (current_line,'}')==NULL) {
133                                 while (strchr (current_line,';')==NULL) {
134                                         fgets (current_line,500,fp);
135                                         if (strchr (current_line,'}')!=NULL) break;
136                                 };
137                                 if (strchr (current_line,'}') !=NULL) break;
138                                 ch=parse_word (current_line,variable_type);
139                                 ch=parse_word (ch,variable_name);
140                                 while (variable_name [strlen (variable_name)-1]!=';') {
141                                         strcpy (variable_type,variable_name);
142                                         ch=parse_word (ch,variable_name);
143                                 };
144                                 variable_name [strlen (variable_name)-1]=0;
145                                 add_new_variable (current_descriptor,variable_type,variable_name);
146                                 fgets (current_line,500,fp);
147                         };
148                 }; 
149         };
150         
151         fclose (fp);
152         return (1);
153 }
154
155 void free_struct_descriptors (void)
156
157 {
158         struct struct_descriptor *ptr,*next;
159         
160         ptr=first_type;
161         while (ptr!=NULL) {
162                 next=ptr->next;
163                 free_user_commands (&ptr->type_commands);
164                 free (ptr);
165                 ptr=next;
166         }
167         first_type=last_type=current_type=NULL;
168 }
169
170 void free_user_commands (struct struct_commands *ptr)
171
172 {
173         int i;
174         
175         for (i=0;i<=ptr->last_command;i++) {
176                 free (ptr->names [i]);
177                 free (ptr->descriptions [i]);
178         }
179         
180         ptr->last_command=-1;
181 }
182
183 struct struct_descriptor *add_new_descriptor (char *name)
184
185 {
186         struct struct_descriptor *ptr;
187         
188         if (first_type==NULL) {
189                 first_type=last_type=ptr=(struct struct_descriptor *) malloc (sizeof (struct struct_descriptor));
190                 if (ptr==NULL) {
191                         printf ("Error - Can not allocate memory - Quitting\n");
192                         exit (1);
193                 }
194                 ptr->prev=ptr->next=NULL;
195                 strcpy (ptr->name,name);
196                 ptr->length=0;
197                 ptr->fields_num=0;
198                 ptr->type_commands.last_command=-1;
199                 fill_type_commands (ptr);
200         }
201         else {
202                 ptr=(struct struct_descriptor *) malloc (sizeof (struct struct_descriptor));
203                 if (ptr==NULL) {
204                         printf ("Error - Can not allocate memory - Quitting\n");
205                         exit (1);
206                 }
207                 ptr->prev=last_type;last_type->next=ptr;last_type=ptr;
208                 strcpy (ptr->name,name);
209                 ptr->length=0;
210                 ptr->fields_num=0;
211                 ptr->type_commands.last_command=-1;
212                 fill_type_commands (ptr);
213         }
214         return (ptr);
215 }
216
217 void add_new_variable (struct struct_descriptor *ptr,char *v_type,char *v_name)
218
219 {
220         short len=1;
221         
222         strcpy (ptr->field_names [ptr->fields_num],v_name);
223         ptr->field_positions [ptr->fields_num]=ptr->length;
224         
225         if (strcasecmp (v_type,"long")==0)  len=4;
226         if (strcasecmp (v_type,"__u32")==0) len=4;
227         if (strcasecmp (v_type,"__s32")==0) len=4;
228
229         if (strcasecmp (v_type,"__u16")==0) len=2;
230         if (strcasecmp (v_type,"__s16")==0) len=2;
231         if (strcasecmp (v_type,"short")==0) len=2;
232         if (strcasecmp (v_type,"int")==0)   len=2;
233
234         if (strcasecmp (v_type,"__u8")==0)  len=1;
235         if (strcasecmp (v_type,"__s8")==0)  len=1;
236         if (strcasecmp (v_type,"char")==0)  len=1;
237         
238         ptr->field_lengths [ptr->fields_num]=len;
239
240         ptr->length+=len;
241         ptr->fields_num++; 
242 }
243
244 void fill_type_commands (struct struct_descriptor *ptr)
245
246 /*
247
248 Set specific type user commands.
249
250 */
251
252 {
253
254         if (strcmp ((ptr->name),"file")==0) {
255                 add_user_command (&ptr->type_commands,"show","Shows file data",type_file___show);
256                 add_user_command (&ptr->type_commands,"inode","Returns to the inode of the current file",type_file___inode);
257                 add_user_command (&ptr->type_commands,"display","Specifies data format - text or hex",type_file___display);
258                 add_user_command (&ptr->type_commands,"next","Pass to next byte",type_file___next);
259                 add_user_command (&ptr->type_commands,"prev","Pass to the previous byte",type_file___prev);
260                 add_user_command (&ptr->type_commands,"offset","Pass to a specified byte in the current block",type_file___offset);
261                 add_user_command (&ptr->type_commands,"nextblock","Pass to next file block",type_file___nextblock);
262                 add_user_command (&ptr->type_commands,"prevblock","Pass to the previous file block",type_file___prevblock);
263                 add_user_command (&ptr->type_commands,"block","Specify which file block to edit",type_file___block);
264                 add_user_command (&ptr->type_commands,"remember","Saves the file\'s inode position for later reference",type_file___remember);
265                 add_user_command (&ptr->type_commands,"set","Sets the current byte",type_file___set);
266                 add_user_command (&ptr->type_commands,"writedata","Writes the current block to the disk",type_file___writedata);
267         }
268
269         if (strcmp ((ptr->name),"ext2_inode")==0) {
270                 add_user_command (&ptr->type_commands,"show","Shows inode data",type_ext2_inode___show);
271                 add_user_command (&ptr->type_commands,"next","Move to next inode in current block group",type_ext2_inode___next);
272                 add_user_command (&ptr->type_commands,"prev","Move to next inode in current block group",type_ext2_inode___prev);
273                 add_user_command (&ptr->type_commands,"group","Move to the group descriptors of the current inode table",type_ext2_inode___group);
274                 add_user_command (&ptr->type_commands,"entry","Move to a specified entry in the current inode table",type_ext2_inode___entry);
275                 add_user_command (&ptr->type_commands,"file","Display file data of the current inode",type_ext2_inode___file);
276                 add_user_command (&ptr->type_commands,"dir","Display directory data of the current inode",type_ext2_inode___dir);
277         }
278         
279         if (strcmp ((ptr->name),"dir")==0) {
280                 add_user_command (&ptr->type_commands,"show","Shows current directory data",type_dir___show);
281                 add_user_command (&ptr->type_commands,"inode","Returns to the inode of the current directory",type_dir___inode);
282                 add_user_command (&ptr->type_commands,"next","Pass to the next directory entry",type_dir___next);
283                 add_user_command (&ptr->type_commands,"prev","Pass to the previous directory entry",type_dir___prev);
284                 add_user_command (&ptr->type_commands,"followinode","Follows the inode specified in this directory entry",type_dir___followinode);
285                 add_user_command (&ptr->type_commands,"remember","Remember the inode of the current directory entry",type_dir___remember);
286                 add_user_command (&ptr->type_commands,"cd","Changes directory relative to the current directory",type_dir___cd);
287                 add_user_command (&ptr->type_commands,"entry","Moves to a specified entry in the current directory",type_dir___entry);
288                 add_user_command (&ptr->type_commands,"writedata","Writes the current entry to the disk",type_dir___writedata);
289                 add_user_command (&ptr->type_commands,"set","Changes a variable in the current directory entry",type_dir___set);
290         }
291         
292         if (strcmp ((ptr->name),"ext2_super_block")==0) {
293                 add_user_command (&ptr->type_commands,"show","Displays the super block data",type_ext2_super_block___show);
294                 add_user_command (&ptr->type_commands,"gocopy","Move to another backup copy of the superblock",type_ext2_super_block___gocopy);
295                 add_user_command (&ptr->type_commands,"setactivecopy","Copies the current superblock to the main superblock",type_ext2_super_block___setactivecopy);
296         }
297
298         if (strcmp ((ptr->name),"ext2_group_desc")==0) {
299                 add_user_command (&ptr->type_commands,"next","Pass to the next block group decriptor",type_ext2_group_desc___next);
300                 add_user_command (&ptr->type_commands,"prev","Pass to the previous group descriptor",type_ext2_group_desc___prev);
301                 add_user_command (&ptr->type_commands,"entry","Pass to a specific group descriptor",type_ext2_group_desc___entry);
302                 add_user_command (&ptr->type_commands,"show","Shows the current group descriptor",type_ext2_group_desc___show);
303                 add_user_command (&ptr->type_commands,"inode","Pass to the inode table of the current group block",type_ext2_group_desc___inode);
304                 add_user_command (&ptr->type_commands,"gocopy","Move to another backup copy of the group descriptor",type_ext2_group_desc___gocopy);
305                 add_user_command (&ptr->type_commands,"blockbitmap","Show the block allocation bitmap of the current group block",type_ext2_group_desc___blockbitmap);
306                 add_user_command (&ptr->type_commands,"inodebitmap","Show the inode allocation bitmap of the current group block",type_ext2_group_desc___inodebitmap);
307                 add_user_command (&ptr->type_commands,"setactivecopy","Copies the current group descriptor to the main table",type_ext2_super_block___setactivecopy);
308         }
309
310         if (strcmp ((ptr->name),"block_bitmap")==0) {
311                 add_user_command (&ptr->type_commands,"show","Displays the block allocation bitmap",type_ext2_block_bitmap___show);
312                 add_user_command (&ptr->type_commands,"entry","Moves to a specific bit",type_ext2_block_bitmap___entry);
313                 add_user_command (&ptr->type_commands,"next","Moves to the next bit",type_ext2_block_bitmap___next);
314                 add_user_command (&ptr->type_commands,"prev","Moves to the previous bit",type_ext2_block_bitmap___prev);
315                 add_user_command (&ptr->type_commands,"allocate","Allocates the current block",type_ext2_block_bitmap___allocate);
316                 add_user_command (&ptr->type_commands,"deallocate","Deallocates the current block",type_ext2_block_bitmap___deallocate);
317         }
318
319         if (strcmp ((ptr->name),"inode_bitmap")==0) {
320                 add_user_command (&ptr->type_commands,"show","Displays the inode allocation bitmap",type_ext2_inode_bitmap___show);
321                 add_user_command (&ptr->type_commands,"entry","Moves to a specific bit",type_ext2_inode_bitmap___entry);
322                 add_user_command (&ptr->type_commands,"next","Moves to the next bit",type_ext2_inode_bitmap___next);
323                 add_user_command (&ptr->type_commands,"prev","Moves to the previous bit",type_ext2_inode_bitmap___prev);
324                 add_user_command (&ptr->type_commands,"allocate","Allocates the current inode",type_ext2_inode_bitmap___allocate);
325                 add_user_command (&ptr->type_commands,"deallocate","Deallocates the current inode",type_ext2_inode_bitmap___deallocate);
326         }
327         
328 }
329
330 void add_user_command (struct struct_commands *ptr,char *name,char *description,PF callback)
331
332 {
333         int num;
334         
335         num=ptr->last_command;
336         if (num+1==MAX_COMMANDS_NUM) {
337                 printf ("Internal Error - Can't add command %s\n",name);
338                 return;
339         }
340         
341         ptr->last_command=++num;
342
343         ptr->names [num]=(char *) malloc (strlen (name)+1);
344         strcpy (ptr->names [num],name);
345         
346         if (*description!=0) {
347                 ptr->descriptions [num]=(char *) malloc (strlen (description)+1);
348                 strcpy (ptr->descriptions [num],description);
349         }
350         
351         ptr->callback [num]=callback;
352 }
353
354 int set_file_system_info (void)
355
356 {
357         int ext2_detected=0;
358         struct ext2_super_block *sb;
359         
360         file_system_info.super_block_offset=1024;
361         file_system_info.file_system_size=DefaultTotalBlocks*DefaultBlockSize;
362
363         low_read ((char *) &file_system_info.super_block,sizeof (struct ext2_super_block),file_system_info.super_block_offset);
364
365         sb=&file_system_info.super_block;
366
367         if (sb->s_magic == EXT2_SUPER_MAGIC) 
368                 ext2_detected=1;
369
370         if (ext2_detected)
371                 wprintw (command_win,"Detected extended 2 file system on device %s\n",device_name);
372         else
373                 wprintw (command_win,"Warning - Extended 2 filesystem not detected on device %s\n",device_name);
374
375         if (!ext2_detected && !ForceExt2)
376                 wprintw (command_win,"You may wish to use the configuration option ForceExt2 on\n");
377
378         if (ForceExt2 && !ext2_detected)
379                 wprintw (command_win,"Forcing extended 2 filesystem\n");
380         
381         if (ForceDefault || !ext2_detected)
382                 wprintw (command_win,"Forcing default parameters\n");
383
384         refresh_command_win ();
385
386         if (ext2_detected || ForceExt2) {
387                 add_ext2_general_commands ();
388                 if (!set_struct_descriptors (Ext2Descriptors))
389                         return (0);
390         }
391         
392         if (!ForceDefault && ext2_detected) {
393         
394                 file_system_info.block_size=EXT2_MIN_BLOCK_SIZE << sb->s_log_block_size;
395                 if (file_system_info.block_size == EXT2_MIN_BLOCK_SIZE)
396                         file_system_info.first_group_desc_offset=2*EXT2_MIN_BLOCK_SIZE;
397                 else
398                         file_system_info.first_group_desc_offset=file_system_info.block_size;
399                 file_system_info.groups_count=( sb->s_blocks_count-sb->s_first_data_block+sb->s_blocks_per_group-1) /
400                                                 sb->s_blocks_per_group;
401         
402                 file_system_info.inodes_per_block=file_system_info.block_size/sizeof (struct ext2_inode);
403                 file_system_info.blocks_per_group=sb->s_inodes_per_group/file_system_info.inodes_per_block;
404                 file_system_info.no_blocks_in_group=sb->s_blocks_per_group;
405                 file_system_info.file_system_size=(sb->s_blocks_count-1)*file_system_info.block_size;
406         }
407
408         else {
409                 file_system_info.file_system_size=DefaultTotalBlocks*DefaultBlockSize;
410                 file_system_info.block_size=DefaultBlockSize;           
411                 file_system_info.no_blocks_in_group=DefaultBlocksInGroup;
412         }
413         
414         if (file_system_info.file_system_size > 2147483647) {
415                 wprintw (command_win,"Sorry, filesystems bigger than 2 GB are currently not supported\n");
416                 return (0);
417         }
418         return (1);
419 }
420
421 void init_readline (void)
422
423 {
424         rl_completion_entry_function=(Function *) complete_command;
425 }
426
427 void init_signals (void)
428
429 {
430         signal (SIGWINCH,(SignalHandler) signal_SIGWINCH_handler);      /* Catch SIGWINCH */
431         signal (SIGTERM,(SignalHandler) signal_SIGTERM_handler);
432         signal (SIGSEGV,(SignalHandler) signal_SIGSEGV_handler);
433         
434 }
435
436 void signal_SIGWINCH_handler (int sig_num)
437
438 {
439         redraw_request=1;                                               /* We will handle it in main.c */
440 }
441
442 void signal_SIGTERM_handler (int sig_num)
443
444 {
445         prepare_to_close ();
446         printf ("Terminated due to signal %d\n",sig_num);
447         exit (1);
448 }
449
450 void signal_SIGSEGV_handler (int sig_num)
451
452 {
453         prepare_to_close ();
454         printf ("Killed by signal %d !\n",sig_num);
455         exit (1);
456 }
457
458 int process_configuration_file (void)
459
460 {
461         char buffer [300];
462         char option [80],value [80];
463         FILE *fp;
464
465         strcpy (buffer,VAR_DIR);
466         strcat (buffer,"/ext2ed.conf");
467                 
468         if ((fp=fopen (buffer,"rt"))==NULL) {
469                 fprintf (stderr,"Error - Unable to open configuration file %s\n",buffer);
470                 return (0);
471         }
472         
473         while (get_next_option (fp,option,value)) {
474                 if (strcasecmp (option,"Ext2Descriptors")==0) {
475                         strcpy (Ext2Descriptors,value);
476                 }
477
478                 else if (strcasecmp (option,"AlternateDescriptors")==0) {
479                         strcpy (AlternateDescriptors,value);
480                 }
481
482                 else if (strcasecmp (option,"LogFile")==0) {
483                         strcpy (LogFile,value);
484                 }
485
486                 else if (strcasecmp (option,"LogChanges")==0) {
487                         if (strcasecmp (value,"on")==0)
488                                 LogChanges = 1;
489                         else if (strcasecmp (value,"off")==0)
490                                 LogChanges = 0;
491                         else {
492                                 fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
493                                 fclose (fp);return (0);
494                         }
495                 }
496
497                 else if (strcasecmp (option,"AllowChanges")==0) {
498                         if (strcasecmp (value,"on")==0)
499                                 AllowChanges = 1;
500                         else if (strcasecmp (value,"off")==0)
501                                 AllowChanges = 0;
502                         else {
503                                 fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
504                                 fclose (fp);return (0);
505                         }
506                 }
507
508                 else if (strcasecmp (option,"AllowMountedRead")==0) {
509                         if (strcasecmp (value,"on")==0)
510                                 AllowMountedRead = 1;
511                         else if (strcasecmp (value,"off")==0)
512                                 AllowMountedRead = 0;
513                         else {
514                                 fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
515                                 fclose (fp);return (0);
516                         }
517                 }
518
519                 else if (strcasecmp (option,"ForceExt2")==0) {
520                         if (strcasecmp (value,"on")==0)
521                                 ForceExt2 = 1;
522                         else if (strcasecmp (value,"off")==0)
523                                 ForceExt2 = 0;
524                         else {
525                                 fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
526                                 fclose (fp);return (0);
527                         }
528                 }
529
530                 else if (strcasecmp (option,"DefaultBlockSize")==0) {
531                         DefaultBlockSize = atoi (value);
532                 }
533
534                 else if (strcasecmp (option,"DefaultTotalBlocks")==0) {
535                         DefaultTotalBlocks = strtoul (value,NULL,10);
536                 }
537
538                 else if (strcasecmp (option,"DefaultBlocksInGroup")==0) {
539                         DefaultBlocksInGroup = strtoul (value,NULL,10);
540                 }
541
542                 else if (strcasecmp (option,"ForceDefault")==0) {
543                         if (strcasecmp (value,"on")==0)
544                                 ForceDefault = 1;
545                         else if (strcasecmp (value,"off")==0)
546                                 ForceDefault = 0;
547                         else {
548                                 fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
549                                 fclose (fp);return (0);
550                         }
551                 }
552                 
553                 else {
554                         fprintf (stderr,"Error - Unknown option: %s\n",option);
555                         fclose (fp);return (0);
556                 }
557         }
558
559         printf ("Configuration completed\n");
560         fclose (fp);
561         return (1);
562 }
563
564 int get_next_option (FILE *fp,char *option,char *value)
565
566 {
567         char *ptr;
568         char buffer [600];
569         
570         if (feof (fp)) return (0);
571         do{
572                 if (feof (fp)) return (0);
573                 fgets (buffer,500,fp);
574         } while (buffer [0]=='#' || buffer [0]=='\n');
575         
576         ptr=parse_word (buffer,option);
577         ptr=parse_word (ptr,value);
578         return (1);
579 }
580
581 void check_mounted (char *name)
582
583 {
584         FILE *fp;
585         char *ptr;
586         char current_line [500],current_word [200];
587
588         mounted=0;
589         
590         if ( (fp=fopen ("/etc/mtab","rt"))==NULL) {
591                 wprintw (command_win,"Error - Failed to open /etc/mtab. Assuming filesystem is mounted.\n");
592                 refresh_command_win ();mounted=1;return;
593         };
594         
595         while (!feof (fp)) {
596                 fgets (current_line,500,fp);
597                 if (feof (fp)) break;   
598                 ptr=parse_word (current_line,current_word);
599                 if (strcasecmp (current_word,name)==0) {
600                         mounted=1;fclose (fp);return;
601                 }
602         };
603
604         fclose (fp);
605         
606         return; 
607 }