5
A part of the extended file system 2 disk editor.
7
--------------------------------
8
Various initialization routines.
9
--------------------------------
11
First written on: April 9 1995
13
Copyright (C) 1995 Gadi Oxman
26
#include <sys/types.h>
32
char lines_s [80],cols_s [80];
34
void signal_handler (void);
36
void prepare_to_close (void)
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 ();
50
printf ("Initializing ...\n");
52
if (!process_configuration_file ()) {
53
fprintf (stderr,"Error - Unable to complete configuration. Quitting.\n");
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 */
62
current_type=NULL; /* No filesystem specific types yet */
64
remember_lifo.entries_count=0; /* Object memory is empty */
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 */
71
strcpy (last_command_line,"help"); /* Show the help screen to the user */
73
return (1); /* Success */
76
void add_general_commands (void)
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);
97
void add_ext2_general_commands (void)
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);
105
int set_struct_descriptors (char *file_name)
109
char current_line [500],current_word [50],*ch;
110
char variable_name [50],variable_type [20];
111
struct struct_descriptor *current_descriptor;
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);
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);
126
while (strchr (current_line,'{')==NULL) {
127
fgets (current_line,500,fp);
128
if (feof (fp)) break;
130
if (feof (fp)) break;
132
fgets (current_line,500,fp);
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;
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);
146
variable_name [strlen (variable_name)-1]=0;
147
add_new_variable (current_descriptor,variable_type,variable_name);
148
fgets (current_line,500,fp);
157
void free_struct_descriptors (void)
160
struct struct_descriptor *ptr,*next;
165
free_user_commands (&ptr->type_commands);
169
first_type=last_type=current_type=NULL;
172
void free_user_commands (struct struct_commands *ptr)
177
for (i=0;i<=ptr->last_command;i++) {
178
free (ptr->names [i]);
179
free (ptr->descriptions [i]);
182
ptr->last_command=-1;
185
struct struct_descriptor *add_new_descriptor (char *name)
188
struct struct_descriptor *ptr;
190
ptr = malloc (sizeof (struct struct_descriptor));
192
printf ("Error - Can not allocate memory - Quitting\n");
195
memset(ptr, 0, sizeof(struct struct_descriptor));
196
ptr->prev = ptr->next = NULL;
197
strcpy (ptr->name,name);
200
if (first_type==NULL) {
201
first_type = last_type = ptr;
203
ptr->prev = last_type; last_type->next = ptr; last_type=ptr;
205
ptr->type_commands.last_command=-1;
206
fill_type_commands (ptr);
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 },
229
void add_new_variable (struct struct_descriptor *ptr,char *v_type,char *v_name)
233
char field_type=FIELD_TYPE_INT;
234
struct type_table *p;
236
strcpy (ptr->field_names [ptr->fields_num],v_name);
237
ptr->field_positions [ptr->fields_num]=ptr->length;
239
for (p = type_table; p->name; p++) {
240
if (strcmp(v_type, p->name) == 0) {
242
field_type = p->field_type;
247
if (strncmp(v_type, "char[", 5) == 0) {
248
len = atoi(v_type+5);
249
field_type = FIELD_TYPE_CHAR;
251
printf("Unknown type %s for field %s\n", v_type, v_name);
256
ptr->field_lengths [ptr->fields_num] = len;
257
ptr->field_types [ptr->fields_num] = field_type;
263
void fill_type_commands (struct struct_descriptor *ptr)
267
Set specific type user commands.
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);
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);
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);
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);
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);
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);
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);
349
void add_user_command (struct struct_commands *ptr,char *name,char *description,PF callback)
354
num=ptr->last_command;
355
if (num+1==MAX_COMMANDS_NUM) {
356
printf ("Internal Error - Can't add command %s\n",name);
360
ptr->last_command=++num;
362
ptr->names [num]=(char *) malloc (strlen (name)+1);
363
strcpy (ptr->names [num],name);
365
if (*description!=0) {
366
ptr->descriptions [num]=(char *) malloc (strlen (description)+1);
367
strcpy (ptr->descriptions [num],description);
370
ptr->callback [num]=callback;
373
int set_file_system_info (void)
377
struct ext2_super_block *sb;
379
file_system_info.super_block_offset=1024;
380
file_system_info.file_system_size=DefaultTotalBlocks*DefaultBlockSize;
382
low_read ((char *) &file_system_info.super_block,sizeof (struct ext2_super_block),file_system_info.super_block_offset);
384
sb=&file_system_info.super_block;
386
if (sb->s_magic == EXT2_SUPER_MAGIC)
390
wprintw (command_win,"Detected extended 2 file system on device %s\n",device_name);
392
wprintw (command_win,"Warning - Extended 2 filesystem not detected on device %s\n",device_name);
394
if (!ext2_detected && !ForceExt2)
395
wprintw (command_win,"You may wish to use the configuration option ForceExt2 on\n");
397
if (ForceExt2 && !ext2_detected)
398
wprintw (command_win,"Forcing extended 2 filesystem\n");
400
if (ForceDefault || !ext2_detected)
401
wprintw (command_win,"Forcing default parameters\n");
403
refresh_command_win ();
405
if (ext2_detected || ForceExt2) {
406
add_ext2_general_commands ();
407
if (!set_struct_descriptors (Ext2Descriptors))
411
if (!ForceDefault && ext2_detected) {
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;
417
file_system_info.first_group_desc_offset=file_system_info.block_size;
418
file_system_info.groups_count=( sb->s_blocks_count-sb->s_first_data_block+sb->s_blocks_per_group-1) /
419
sb->s_blocks_per_group;
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=(sb->s_blocks_count-1)*file_system_info.block_size;
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;
433
if (file_system_info.file_system_size > 2147483647) {
434
wprintw (command_win,"Sorry, filesystems bigger than 2 GB are currently not supported\n");
440
void init_readline (void)
444
rl_completion_entry_function=(Function *) complete_command;
448
void init_signals (void)
451
signal (SIGWINCH, signal_SIGWINCH_handler); /* Catch SIGWINCH */
452
signal (SIGTERM, signal_SIGTERM_handler);
453
signal (SIGSEGV, signal_SIGSEGV_handler);
457
void signal_SIGWINCH_handler (int sig_num)
460
redraw_request=1; /* We will handle it in main.c */
462
/* Reset signal handler */
463
signal (SIGWINCH, signal_SIGWINCH_handler);
467
void signal_SIGTERM_handler (int sig_num)
471
printf ("Terminated due to signal %d\n",sig_num);
475
void signal_SIGSEGV_handler (int sig_num)
479
printf ("Killed by signal %d !\n",sig_num);
483
int process_configuration_file (void)
487
char option [80],value [80];
490
strcpy (buffer, ETC_DIR);
491
strcat (buffer,"/ext2ed.conf");
493
if ((fp=fopen (buffer,"rt"))==NULL) {
494
fprintf (stderr,"Error - Unable to open configuration file %s\n",buffer);
498
while (get_next_option (fp,option,value)) {
499
if (strcasecmp (option,"Ext2Descriptors")==0) {
500
strcpy (Ext2Descriptors,value);
503
else if (strcasecmp (option,"AlternateDescriptors")==0) {
504
strcpy (AlternateDescriptors,value);
507
else if (strcasecmp (option,"LogFile")==0) {
508
strcpy (LogFile,value);
511
else if (strcasecmp (option,"LogChanges")==0) {
512
if (strcasecmp (value,"on")==0)
514
else if (strcasecmp (value,"off")==0)
517
fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
518
fclose (fp);return (0);
522
else if (strcasecmp (option,"AllowChanges")==0) {
523
if (strcasecmp (value,"on")==0)
525
else if (strcasecmp (value,"off")==0)
528
fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
529
fclose (fp);return (0);
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;
539
fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
540
fclose (fp);return (0);
544
else if (strcasecmp (option,"ForceExt2")==0) {
545
if (strcasecmp (value,"on")==0)
547
else if (strcasecmp (value,"off")==0)
550
fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
551
fclose (fp);return (0);
555
else if (strcasecmp (option,"DefaultBlockSize")==0) {
556
DefaultBlockSize = atoi (value);
559
else if (strcasecmp (option,"DefaultTotalBlocks")==0) {
560
DefaultTotalBlocks = strtoul (value,NULL,10);
563
else if (strcasecmp (option,"DefaultBlocksInGroup")==0) {
564
DefaultBlocksInGroup = strtoul (value,NULL,10);
567
else if (strcasecmp (option,"ForceDefault")==0) {
568
if (strcasecmp (value,"on")==0)
570
else if (strcasecmp (value,"off")==0)
573
fprintf (stderr,"Error - Illegal value: %s %s\n",option,value);
574
fclose (fp);return (0);
579
fprintf (stderr,"Error - Unknown option: %s\n",option);
580
fclose (fp);return (0);
584
printf ("Configuration completed\n");
589
int get_next_option (FILE *fp,char *option,char *value)
595
if (feof (fp)) return (0);
597
if (feof (fp)) return (0);
598
fgets (buffer,500,fp);
599
} while (buffer [0]=='#' || buffer [0]=='\n');
601
ptr=parse_word (buffer,option);
602
ptr=parse_word (ptr,value);
606
void check_mounted (char *name)
611
char current_line [500],current_word [200];
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;
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;