• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
div_ceil(unsigned int a,unsigned int b)373 static unsigned int div_ceil(unsigned int a, unsigned int b)
374 {
375 	if (!a)
376 		return 0;
377 	return ((a - 1) / b) + 1;
378 }
379 
set_file_system_info(void)380 int set_file_system_info (void)
381 
382 {
383 	int ext2_detected=0;
384 	struct ext2_super_block *sb;
385 
386 	file_system_info.super_block_offset=1024;
387 	file_system_info.file_system_size=DefaultTotalBlocks*DefaultBlockSize;
388 
389 	low_read ((char *) &file_system_info.super_block,sizeof (struct ext2_super_block),file_system_info.super_block_offset);
390 
391 	sb=&file_system_info.super_block;
392 
393 	if (sb->s_magic == EXT2_SUPER_MAGIC)
394 		ext2_detected=1;
395 
396 	if (ext2_detected)
397 		wprintw (command_win,"Detected extended 2 file system on device %s\n",device_name);
398 	else
399 		wprintw (command_win,"Warning - Extended 2 filesystem not detected on device %s\n",device_name);
400 
401 	if (!ext2_detected && !ForceExt2)
402 		wprintw (command_win,"You may wish to use the configuration option ForceExt2 on\n");
403 
404 	if (ForceExt2 && !ext2_detected)
405 		wprintw (command_win,"Forcing extended 2 filesystem\n");
406 
407 	if (ForceDefault || !ext2_detected)
408 		wprintw (command_win,"Forcing default parameters\n");
409 
410 	refresh_command_win ();
411 
412 	if (ext2_detected || ForceExt2) {
413 		add_ext2_general_commands ();
414 		if (!set_struct_descriptors (Ext2Descriptors))
415 			return (0);
416 	}
417 
418 	if (!ForceDefault && ext2_detected) {
419 
420 		file_system_info.block_size=EXT2_MIN_BLOCK_SIZE << sb->s_log_block_size;
421 		if (file_system_info.block_size == EXT2_MIN_BLOCK_SIZE)
422 			file_system_info.first_group_desc_offset=2*EXT2_MIN_BLOCK_SIZE;
423 		else
424 			file_system_info.first_group_desc_offset=file_system_info.block_size;
425 		file_system_info.groups_count = div_ceil(sb->s_blocks_count,
426 						 sb->s_blocks_per_group);
427 
428 		file_system_info.inodes_per_block=file_system_info.block_size/sizeof (struct ext2_inode);
429 		file_system_info.blocks_per_group=sb->s_inodes_per_group/file_system_info.inodes_per_block;
430 		file_system_info.no_blocks_in_group=sb->s_blocks_per_group;
431 		file_system_info.file_system_size=(sb->s_blocks_count-1)*file_system_info.block_size;
432 	}
433 
434 	else {
435 		file_system_info.file_system_size=DefaultTotalBlocks*DefaultBlockSize;
436 		file_system_info.block_size=DefaultBlockSize;
437 		file_system_info.no_blocks_in_group=DefaultBlocksInGroup;
438 	}
439 
440 	if (file_system_info.file_system_size > 2147483647) {
441 		wprintw (command_win,"Sorry, filesystems bigger than 2 GB are currently not supported\n");
442 		return (0);
443 	}
444 	return (1);
445 }
446 
init_readline(void)447 void init_readline (void)
448 
449 {
450 #ifdef HAVE_READLINE
451 	rl_completion_entry_function=(Function *) complete_command;
452 #endif
453 }
454 
init_signals(void)455 void init_signals (void)
456 
457 {
458 	signal (SIGWINCH, signal_SIGWINCH_handler);	/* Catch SIGWINCH */
459 	signal (SIGTERM, signal_SIGTERM_handler);
460 	signal (SIGSEGV, signal_SIGSEGV_handler);
461 
462 }
463 
signal_SIGWINCH_handler(int sig_num)464 void signal_SIGWINCH_handler (int sig_num)
465 
466 {
467 	redraw_request=1;	/* We will handle it in main.c */
468 
469 	/* Reset signal handler */
470 	signal (SIGWINCH, signal_SIGWINCH_handler);
471 
472 }
473 
signal_SIGTERM_handler(int sig_num)474 void signal_SIGTERM_handler (int sig_num)
475 
476 {
477 	prepare_to_close ();
478 	printf ("Terminated due to signal %d\n",sig_num);
479 	exit (1);
480 }
481 
signal_SIGSEGV_handler(int sig_num)482 void signal_SIGSEGV_handler (int sig_num)
483 
484 {
485 	prepare_to_close ();
486 	printf ("Killed by signal %d!\n",sig_num);
487 	exit (1);
488 }
489 
process_configuration_file(void)490 int process_configuration_file (void)
491 
492 {
493 	char buffer [300];
494 	char option [80],value [80];
495 	FILE *fp;
496 
497 	strcpy (buffer, ETC_DIR);
498 	strcat (buffer,"/ext2ed.conf");
499 
500 	if ((fp=fopen (buffer,"rt"))==NULL) {
501 		fprintf (stderr,"Error - Unable to open configuration file %s\n",buffer);
502 		return (0);
503 	}
504 
505 	while (get_next_option (fp,option,value)) {
506 		if (strcasecmp (option,"Ext2Descriptors")==0) {
507 			strcpy (Ext2Descriptors,value);
508 		}
509 
510 		else if (strcasecmp (option,"AlternateDescriptors")==0) {
511 			strcpy (AlternateDescriptors,value);
512 		}
513 
514 		else if (strcasecmp (option,"LogFile")==0) {
515 			strcpy (LogFile,value);
516 		}
517 
518 		else if (strcasecmp (option,"LogChanges")==0) {
519 			if (strcasecmp (value,"on")==0)
520 				LogChanges = 1;
521 			else if (strcasecmp (value,"off")==0)
522 				LogChanges = 0;
523 			else {
524 				fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
525 				fclose (fp);return (0);
526 			}
527 		}
528 
529 		else if (strcasecmp (option,"AllowChanges")==0) {
530 			if (strcasecmp (value,"on")==0)
531 				AllowChanges = 1;
532 			else if (strcasecmp (value,"off")==0)
533 				AllowChanges = 0;
534 			else {
535 				fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
536 				fclose (fp);return (0);
537 			}
538 		}
539 
540 		else if (strcasecmp (option,"AllowMountedRead")==0) {
541 			if (strcasecmp (value,"on")==0)
542 				AllowMountedRead = 1;
543 			else if (strcasecmp (value,"off")==0)
544 				AllowMountedRead = 0;
545 			else {
546 				fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
547 				fclose (fp);return (0);
548 			}
549 		}
550 
551 		else if (strcasecmp (option,"ForceExt2")==0) {
552 			if (strcasecmp (value,"on")==0)
553 				ForceExt2 = 1;
554 			else if (strcasecmp (value,"off")==0)
555 				ForceExt2 = 0;
556 			else {
557 				fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
558 				fclose (fp);return (0);
559 			}
560 		}
561 
562 		else if (strcasecmp (option,"DefaultBlockSize")==0) {
563 			DefaultBlockSize = atoi (value);
564 		}
565 
566 		else if (strcasecmp (option,"DefaultTotalBlocks")==0) {
567 			DefaultTotalBlocks = strtoul (value,NULL,10);
568 		}
569 
570 		else if (strcasecmp (option,"DefaultBlocksInGroup")==0) {
571 			DefaultBlocksInGroup = strtoul (value,NULL,10);
572 		}
573 
574 		else if (strcasecmp (option,"ForceDefault")==0) {
575 			if (strcasecmp (value,"on")==0)
576 				ForceDefault = 1;
577 			else if (strcasecmp (value,"off")==0)
578 				ForceDefault = 0;
579 			else {
580 				fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
581 				fclose (fp);return (0);
582 			}
583 		}
584 
585 		else {
586 			fprintf (stderr,"Error - Unknown option: %s\n",option);
587 			fclose (fp);return (0);
588 		}
589 	}
590 
591 	printf ("Configuration completed\n");
592 	fclose (fp);
593 	return (1);
594 }
595 
get_next_option(FILE * fp,char * option,char * value)596 int get_next_option (FILE *fp,char *option,char *value)
597 
598 {
599 	char *ptr;
600 	char buffer [600];
601 
602 	if (feof (fp)) return (0);
603 	do{
604 		if (feof (fp)) return (0);
605 		fgets (buffer,500,fp);
606 	} while (buffer [0]=='#' || buffer [0]=='\n');
607 
608 	ptr=parse_word (buffer,option);
609 	ptr=parse_word (ptr,value);
610 	return (1);
611 }
612 
check_mounted(char * name)613 void check_mounted (char *name)
614 
615 {
616 	FILE *fp;
617 	char *ptr;
618 	char current_line [500],current_word [200];
619 
620 	mounted=0;
621 
622 	if ( (fp=fopen ("/etc/mtab","rt"))==NULL) {
623 		wprintw (command_win,"Error - Failed to open /etc/mtab. Assuming filesystem is mounted.\n");
624 		refresh_command_win ();mounted=1;return;
625 	};
626 
627 	while (!feof (fp)) {
628 		fgets (current_line,500,fp);
629 		if (feof (fp)) break;
630 		ptr=parse_word (current_line,current_word);
631 		if (strcasecmp (current_word,name)==0) {
632 			mounted=1;fclose (fp);return;
633 		}
634 	};
635 
636 	fclose (fp);
637 
638 	return;
639 }
640