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