OSDN Git Service

Fix up ncurses interface so that it handles resizes correctly.
authorTheodore Ts'o <tytso@mit.edu>
Mon, 13 May 2002 11:53:11 +0000 (07:53 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 13 May 2002 11:53:11 +0000 (07:53 -0400)
Removed the readline library (still available using if HAVE_READLINE is defined)
since it really doesn't play well with ncurses.  The only real feature it added
was command completion, and it didn't really handle it completely correctly anyway.
(If readline printed a completion list, it completely screwed up the screen.)

We now use the wgetch ncurses interface to get input; this allows the PGDN and PGUP
keys to work correctly, and also helped fix up the resizing logic.

ext2ed/ChangeLog
ext2ed/Makefile.in
ext2ed/README
ext2ed/general_com.c
ext2ed/init.c
ext2ed/main.c
ext2ed/win.c

index 85ac560..d5657a7 100644 (file)
@@ -1,3 +1,36 @@
+2002-05-12    <tytso@mit.edu>
+
+       * README: Add warning about shortcomings in ext2ed.  Please don't
+               include this in distributions --- it's too buggy for that.
+
+       * init.c (signal_SIGWINCH_handler): Reinstall signal handler after
+               it is activated.
+
+       * main.c: Make use of readline library optional (currently
+               disabled).  Allow the filesystem/device which is to be
+               examined/edited to be specified on the command line, with
+               the -w option indicating that the filesystem should be
+               opened read/write.  Use the ncurses functions to read from
+               the keyboard, and use the pgdn and pgup keys to activate
+               the relavant commands.  Also poll the keyboard with a
+               timeout of .1 second, so that window-size changes can be
+               dealt with automatically.
+
+       * Makefile.in: Remove ncurses library from link line.
+
+       * win.c: Rewrite redraw function so that it changes the all of the
+               ncurses's windows, instead of destroying all of the
+               windows and recreating them all.  (This assumes requires
+               some ncurses-specific functions, and isn't quite as
+               portable, but that's OK.)  Create two new windows and
+               force the lines above and below the showpad area to be
+               empty.
+
+       * general_com.c: Remove e-mail address for Gadi Oxman, since it
+               doesn't work anymore, and I've made enough changes that
+               Gadi shouldn't get any complaints or bug reports for this
+               version.
+       
 2002-05-11    <tytso@mit.edu>
 
        * win.c, main.c, general_com.c: Use e2fsprogs's version
@@ -11,6 +44,8 @@
                __u32 and __u16 instead of unsigned long and unsigned
                short.  Add data structures for direcctory indexing code.
 
+       * Makefile.in: Added make depend logic.
+
 2002-05-11    <tytso@mit.edu>
 
        * ext2ed.h: Remove VAR_DIR, and replace it with ETC_DIR.
index d6e82c1..a581ee3 100644 (file)
@@ -16,8 +16,8 @@ MANPAGES=     ext2ed.8
 
 DOC_DIR                =       $datadir/doc/ext2ed
 
-XTRA_CFLAGS    =       $(FLAGS) -DETC_DIR=\"$(root_sysconfdir)\" -I/usr/include/readline
-LIBS           =       -lreadline -lncurses
+XTRA_CFLAGS    =       $(FLAGS) -DETC_DIR=\"$(root_sysconfdir)\" 
+LIBS           =       -lncurses
 
 SRCS=  $(srcdir)/main.c $(srcdir)/init.c $(srcdir)/general_com.c       \
        $(srcdir)/inode_com.c $(srcdir)/dir_com.c $(srcdir)/super_com.c \
index 2c64526..7cad671 100644 (file)
@@ -1,3 +1,43 @@
+ext2ed - The extended-2 filesystem editor, version e2fsprogs
+
+
+This version of ext2ed has been modified and updated by Theodore Ts'o
+for inclusion with the e2fsprogs package.
+
+It is currently not built by default -- the top-level e2fsprogs
+Makefile doesn't recurse into this directory.  This is because ext2ed
+has a number of VERY SERIOUS shortcomings:
+
+1)  It doesn't work on filesystems bigger that 2GB
+
+2)  It assumes that all's the world an Intel, and assumes that
+       everything is in Intel (little-endian) byte order.
+
+Fixing both of these problems are non-trivial, and so I at this point
+DO NOT RECOMMEND that distributions try to include this program, even
+as modified and updated in e2fsprogs.  This especially goes for
+Debian, where the Debian maintainer for e2fsprogs has a history of
+making authorized changes to e2fsprogs to include programs that aren't
+supported, and then starts bugging me with bug reports.  YES I KNOW.
+THIS PROGRAM HAS HORRIBLE SHORTCOMINGS.  IT IS INCLUDED HERE ONLY
+BECAUSE IT'S A CONVENIENT WAY FOR (FOR E2FSPROGS DEVELOPERS ON INTEL
+MACHINES) TO GENERATE TEST CASES BY SELECTIVELY CORRUPTING
+FILESYSTEMS.  I WILL NOT SUPPORT THIS PROGRAM FOR USE BY GENERAL
+USERS SO PLEASE DO NOT INCLUDE IT IN A DISTRIBUTION.  
+
+I have currently disabled the use of GNU Readline in this program,
+because readline and ncurses really don't play well together at all.
+Readline assumes that it can write arbitrary text to the screen
+(especially when it tries to print out a completion list), which just
+doesn't work with ncurses.  Fixing this so they would work together
+would require wholesale changes to readline.   
+
+                               Theodore Ts'o
+                               tytso@MIT.EDU
+                               May 12, 2001
+
+----------------------------------------------------------------------------
+
 ext2ed - The extended-2 filesystem editor, version 0.2
 ------------------------------------------------------
 
index efcd3e2..679f177 100644 (file)
@@ -89,20 +89,14 @@ void help (char *command_line)
        wprintw (show_pad,"EXT2ED ver %s (%s)\n",E2FSPROGS_VERSION, E2FSPROGS_DATE);
        wprintw (show_pad,"Copyright (C) 1995 Gadi Oxman\n");
        wprintw (show_pad,"Reviewed 2001 Christian Bac\n");
+       wprintw (show_pad,"Modified and enchanced by Theodore Ts'o, 2002\n");
        wprintw (show_pad,"EXT2ED is hereby placed under the terms of the GNU General Public License.\n\n");
        wprintw (show_pad,"EXT2ED was programmed as a student project in the software laboratory\n");
        wprintw (show_pad,"of the faculty of electrical engineering in the\n");
        wprintw (show_pad,"Technion - Israel Institute of Technology\n");
        wprintw (show_pad,"with the guide of Avner Lottem and Dr. Ilana David.\n");
 
-       max_line+=6;
-       
-       wprintw (show_pad,"\n\n");max_line+=2;
-       
-       wprintw (show_pad,"Please feel free to mail me at (currently) %s\n",email_address);
-       wprintw (show_pad,"with any commet, suggestion, and of-course, bug report concerning EXT2ED.\n");
-       
-       max_line+=2;
+       max_line+=10;
        
        show_pad_info.line=0;show_pad_info.max_line=max_line;
 
index 6ee1d37..de504b4 100644 (file)
@@ -17,7 +17,9 @@ Copyright (C) 1995 Gadi Oxman
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef HAVE_READLINE
 #include <readline.h>
+#endif
 #include <signal.h>
 #include <unistd.h>
 
@@ -438,7 +440,9 @@ int set_file_system_info (void)
 void init_readline (void)
 
 {
+#ifdef HAVE_READLINE
        rl_completion_entry_function=(Function *) complete_command;
+#endif
 }
 
 void init_signals (void)
@@ -453,7 +457,11 @@ void init_signals (void)
 void signal_SIGWINCH_handler (int sig_num)
 
 {
-       redraw_request=1;                                               /* We will handle it in main.c */
+       redraw_request=1;       /* We will handle it in main.c */
+       
+       /* Reset signal handler */      
+       signal (SIGWINCH, signal_SIGWINCH_handler);     
+       
 }
 
 void signal_SIGTERM_handler (int sig_num)
index 5ea116b..e239454 100644 (file)
@@ -21,13 +21,23 @@ First written on: March 30 1995
 Copyright (C) 1995 Gadi Oxman
 
 */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <signal.h>
 
+#ifdef HAVE_READLINE
 #include <readline.h>
 #include <history.h>
+#endif
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+extern int optind;
+extern char *optarg;
+#endif
 
 #include "ext2ed.h"
 
@@ -77,106 +87,275 @@ struct struct_inode_bitmap_info inode_bitmap_info;                /* Used by inodebitmap_com.c
 
 int redraw_request=0;                                          /* Is set by a signal handler to handle terminal */
                                                                /* screen size change. */
-char email_address [80]="tgud@tochnapc2.technion.ac.il";
-
-int main (void)
 
-/* We just call the parser to get commands from the user. We quit when parser returns. */
 
+/*
+ * We just call the parser to get commands from the user. We quit when
+ * parser returns.
+ */
+int main (int argc, char **argv)
 {
-       if (!init ()) return (0);                               /* Perform some initial initialization */
-                                                               /* Quit if failed */
-
-       parser ();                                              /* Get and parse user commands */
+       int     write_priv = 0;
+       int     c;
+       char    *buf;
        
-       prepare_to_close ();                                    /* Do some cleanup */
-       printf ("Quitting ...\n");
-       return (1);                                             /* And quit */
+       if (!init ())
+               return (1);
+       while ((c = getopt (argc, argv, "w")) != EOF) {
+               switch (c) {
+               case 'w':
+                       write_priv++;
+                       break;
+               }
+       }
+       if (optind < argc) {
+               buf = malloc(strlen(argv[optind]) + 32);
+               if (!buf) {
+                       fprintf(stderr, "Couldn't allocate filename buffer\n");
+                       exit(1);
+               }
+               strcpy(buf, "set_device ");
+               strcat(buf, argv[optind]);
+               set_device(buf);
+               free(buf);
+               if (write_priv) {
+                       wprintw (command_win,"\n");                     
+                       enable_write("enable_write");
+               }
+       }
+       parser ();                      /* Get and parse user commands */
+       prepare_to_close();             /* Do some cleanup */
+       printf("Quitting ...\n");
+       return(0);
 }
 
 
-void parser (void)
-
 /*
+ * Read a character from the command window
+ */
+int command_read_key()
+{
+       int     key = 0;
 
-This function asks the user for a command and calls the dispatcher function, dispatch, to analyze it.
-We use the readline library function readline to read the command, hence all the usual readline keys
-are available.
-The new command is saved both in the readline's history and in our tiny one-command cache, so that
-only the enter key is needed to retype it.
+       while (!key) {
+               if (redraw_request) {
+                       redraw_all();
+                       redraw_request=0;
+               }
+               key = wgetch(command_win);
+               switch (key) {
+               case 0x1A:
+                       key = 0;
+                       kill(getpid(), SIGTSTP);
+                       break;
+                       
+               case KEY_NPAGE:
+                       pgdn("");
+                       refresh_command_win ();
+                       break;
+
+               case KEY_PPAGE:
+                       pgup("");
+                       refresh_command_win ();
+                       break;
+               case ERR:
+                       key = 0;
+                       break;
+                       
+               case KEY_BACKSPACE:
+                       key = '\b';
+               }
+               if ((key < 32 && key != '\b' && key != '\n') ||
+                   (key > 127))
+                       key = 0;
+       }
+       return key;
+}
 
-*/
+#ifdef HAVE_READLINE
+int rl_getc_replacement(FILE *f)
+{
+       int     key = command_read_key();
+
+       if (key == '\b') {
+               if (rl_point > 0)
+                       wprintw(command_win, "\b \b");
+       } else
+               wprintw(command_win, "%c", key);
+       return key;
+}
 
+/*
+ * This function asks the user for a command and calls the dispatcher
+ * function, dispatch, to analyze it.  We use the readline library
+ * function readline to read the command, hence all the usual readline
+ * keys are available.  The new command is saved both in the
+ * readline's history and in our tiny one-command cache, so that only
+ * the enter key is needed to retype it.
+ */
+void parser (void)
 {
        char *ptr,command_line [80];
        int quit=0;
 
+#if 0
+       noecho();
+       cbreak();
+       keypad(command_win, 1);
+       wtimeout(command_win, 100);
+       
+       rl_getc_function = rl_getc_replacement;
+#endif
+       
        while (!quit) {
-               
-               if (redraw_request) {                           /* Terminal screen size has changed */
-                       dispatch ("redraw");dispatch ("show");redraw_request=0;
+               /* Terminal screen size has changed */
+               if (redraw_request) {
+                       redraw_all();
+                       redraw_request=0;
                }
 
-               wmove (command_win,0,0);wclrtoeol (command_win);refresh_command_win ();
-
-               mvcur (-1,-1,LINES-COMMAND_WIN_LINES,0);        /* At last ! I spent ** days ** on this one */
-
-                                                               /* The ncurses library optimizes cursor movement by */
-                                                               /* keeping track of the cursor position. However, by */
-                                                               /* using the readline library I'm breaking its */
-                                                               /* assumptions. The double -1 arguments tell ncurses */
-                                                               /* to disable cursor movement optimization this time. */
-               //echo ();
-               ptr=readline ("ext2ed > ");                     /* Read the user's command line. */
-               //noecho ();
+               wmove (command_win,0,0);
+               wclrtoeol (command_win);
+               wprintw (command_win,"ext2ed > ");
+               refresh_command_win ();
 
-               strcpy (command_line,ptr);                      /* Readline allocated the buffer - Copy the string */
-               free (ptr);                                     /* and free the allocated buffer */
+               /*
+                * The ncurses library optimizes cursor movement by
+                * keeping track of the cursor position. However, by
+                * using the readline library I'm breaking its
+                * assumptions. The double -1 arguments tell ncurses
+                * to disable cursor movement optimization this
+                * time.
+                */
+               mvcur (-1,-1,LINES-COMMAND_WIN_LINES,0);
+               
+               /* echo (); */
+               ptr=readline ("ext2ed > ");
+               /* noecho (); */
+
+               /*
+                * Readline allocated the buffer - Copy the string
+                * and free the allocated buffer
+                * XXX WHY???
+                */
+               strcpy (command_line,ptr);
+               free (ptr);                                     
 
                if (*command_line != 0)
-                       add_history (command_line);             /* Add the non-empty command to the command histroy */
+                       add_history (command_line);
 
-               if (*command_line==0)                           /* If only enter was pressed, recall the last command */
+               /* If only enter was pressed, recall the last command */
+               if (*command_line==0)                           
                        strcpy (command_line,last_command_line);
                
-                                                               /* Emulate readline's actions for ncurses */
-
-               mvcur (-1,-1,LINES-COMMAND_WIN_LINES,0);        /* Again, needed for correct integration of the */
-                                                               /* ncurses and readline libraries */
-
+               /* Emulate readline's actions for ncurses */
+               mvcur (-1,-1,LINES-COMMAND_WIN_LINES,0);
                werase (command_win);
-               wprintw (command_win,"ext2ed > ");wprintw (command_win,command_line);
-               wprintw (command_win,"\n");refresh_command_win ();
+               wprintw (command_win,"ext2ed > ");
+               wprintw (command_win,command_line);
+               wprintw (command_win,"\n");
+               refresh_command_win ();
 
-               strcpy (last_command_line,command_line);        /* Save this command in our tiny cache */
+               /* Save this command in our tiny cache */
+               strcpy (last_command_line,command_line);
 
-               quit=dispatch (command_line);                   /* And call dispatch to do the actual job */
+               /* And call dispatch to do the actual job */
+               quit=dispatch (command_line);
        }               
 }
+#else
+void read_line(char * foo) {
+       char * chptr = foo;
+       int ch;
+       int done = 0;
+
+       while (!done && (ch = command_read_key())) {
+               switch (ch) {
+               case '\n':
+                       done = 1;
+                       break;
+
+               case '\b':
+                       if (chptr > foo) {
+                               wprintw(command_win, "\b \b");
+                               chptr--;
+                       }
+                       break;
+
+               default:
+                       if (ch > 256)
+                               break;
+                       if (ch == '\n') break;
+                       *chptr++ = ch;
+                       wprintw(command_win, "%c", ch);
+                       break;
+               }
+       }
+       *chptr = '\0';
+}
 
+void parser (void)
+{
+       char command_line [80];
+       int quit=0;
 
-int dispatch (char *command_line)
+       noecho();
+       cbreak();
+       wtimeout(command_win, 100);
+       keypad(command_win, 1);
 
-/*
+       while (!quit) {
+               /* Terminal screen size has changed */
+               if (redraw_request) {
+                       redraw_all();
+                       redraw_request=0;
+               }
 
-This is a very important function. Its task is to recieve a command name and link it to a C function.
-There are three type of commands:
+               wmove (command_win,0,0);wclrtoeol (command_win);
 
-1.     General commands - Always available and accessed through general_commands.
-2.     Ext2 specific commands - Available when editing an ext2 filesystem, accessed through ext2_commands.
-3.     Type specific commands - Those are changing according to the current type. The global
-       variable current_type points to the current object definition (of type struct_descriptor).
-       In it, the struct_commands entry contains the type specific commands links.
-       
-Overriding is an important feature - Much like in C++ : The same command name can dispatch to different
-functions. The overriding priority is 3,2,1; That is - A type specific command will always override a
-general command. This is used through the program to allow fine tuned operation.
+               wmove(command_win, 0, 0);
+               wprintw(command_win, "ext2ed > ");
+               read_line(command_line);
 
-When an handling function is found, it is called along with the command line that was passed to us. The handling
-function is then free to interpert the arguments in its own style.
+               /* If only enter was pressed, recall the last command */
+               if (*command_line==0)
+                       strcpy (command_line,last_command_line);
+
+               mvcur (-1,-1,LINES-COMMAND_WIN_LINES + 1,0);    
+
+               strcpy (last_command_line,command_line);        /* Save this command in our tiny cache */
+               
+               /* And call dispatch to do the actual job */
+               quit=dispatch (command_line);
+       }               
+}
+#endif
 
-*/
 
+/*
+ * This is a very important function. Its task is to recieve a command
+ * name and link it to a C function.  There are three types of commands:
+ * 
+ * 1.  General commands - Always available and accessed through
+ * general_commands. 
+ * 2.  Ext2 specific commands - Available when editing an ext2
+ * filesystem, accessed through ext2_commands. 
+ * 3.  Type specific commands - Those are changing according to the
+ * current type. The global variable current_type points to the
+ * current object definition (of type struct_descriptor). In it, the
+ * struct_commands entry contains the type specific commands links. 
+ *     
+ * Overriding is an important feature - Much like in C++ : The same
+ * command name can dispatch to different functions. The overriding
+ * priority is 3,2,1; That is - A type specific command will always
+ * override a general command. This is used through the program to
+ * allow fine tuned operation. 
+ * 
+ * When an handling function is found, it is called along with the
+ * command line that was passed to us. The handling function is then
+ * free to interpert the arguments in its own style. 
+ */
+int dispatch (char *command_line)
 {
        int i,found=0;
        
@@ -186,10 +365,13 @@ function is then free to interpert the arguments in its own style.
                        
        if (strcasecmp (command,"quit")==0) return (1); 
 
-       /* 1. Search for type specific commands FIRST - Allows overriding of a general command */
+       /* 1. Search for type specific commands FIRST - Allows
+       overriding of a general command */
 
        if (current_type != NULL)
-               for (i=0;i<=current_type->type_commands.last_command && !found;i++) {
+               for (i=0;
+                    i<=current_type->type_commands.last_command && !found;
+                    i++) {
                        if (strcasecmp (command,current_type->type_commands.names [i])==0) {
                                (*current_type->type_commands.callback [i]) (command_line);
                                found=1;
@@ -227,16 +409,14 @@ function is then free to interpert the arguments in its own style.
        return (0);
 }
 
-char *parse_word (char *source,char *dest)
 
 /*
-
-This function copies the next word in source to the variable dest, ignoring whitespaces.
-It returns a pointer to the next word in source.
-It is used to split the command line into command and arguments.
-
-*/
-
+ * 
+ * This function copies the next word in source to the variable dest,
+ * ignoring whitespaces.  It returns a pointer to the next word in
+ * source.  It is used to split the command line into command and arguments.
+ */
+char *parse_word (char *source,char *dest)
 {
        char ch,*source_ptr,*target_ptr;
        
@@ -265,22 +445,22 @@ It is used to split the command line into command and arguments.
        return (--source_ptr);
 }
 
-char *complete_command (char *text,int state)
-
 /*
-
-text is the partial command entered by the user; We assume that it is a part of a command - I didn't write code
-for smarter completion.
-
-The state variable is an index which tells us how many possible completions we already returned to readline.
-
-We return only one possible completion or (char *) NULL if there are no more completions. This
-function will be called by readline over and over until we tell it to stop.
-
-While scanning for possible completions, we use the same priority definition which was used in dispatch.
-
-*/
-
+ * text is the partial command entered by the user; We assume that it
+ * is a part of a command - I didn't write code for smarter completion.
+ * 
+ * The state variable is an index which tells us how many possible
+ * completions we already returned to readline. 
+ * 
+ * We return only one possible completion or (char *) NULL if there
+ * are no more completions. This function will be called by readline
+ * over and over until we tell it to stop. 
+ * 
+ * While scanning for possible completions, we use the same priority
+ * definition which was used in dispatch. 
+ */
+#if HAVE_READLINE
+char *complete_command (char *text,int state)
 {
        int state_index=-1;
        int i,len;
@@ -332,15 +512,13 @@ While scanning for possible completions, we use the same priority definition whi
        
        return ((char *) NULL);
 }
+#endif
 
-char *dupstr (char *src)
 
 /* 
-
-Nothing special - Just allocates enough space and copy the string.
-
-*/
-
+ * Nothing special - Just allocates enough space and copy the string.
+ */
+char *dupstr (char *src)
 {
        char *ptr;
        
@@ -350,18 +528,13 @@ Nothing special - Just allocates enough space and copy the string.
 }
 
 #ifdef DEBUG
-
-void internal_error (char *description,char *source_name,char *function_name)
-
 /*
-
-This function reports an internal error. It is almost not used. One place in which I do check for internal
-errors is disk.c.
-
-We just report the error, and try to continue ...
-
-*/
-
+ * This function reports an internal error. It is almost not used. One
+ * place in which I do check for internal errors is disk.c.
+ * 
+ * We just report the error, and try to continue ...
+ */
+void internal_error (char *description,char *source_name,char *function_name)
 {
        wprintw (command_win,"Internal error - Found by source: %s.c , function: %s\n",source_name,function_name);
        wprintw (command_win,"\t%s\n",description);     
index 55fa23c..758bc6a 100644 (file)
@@ -22,23 +22,44 @@ Copyright (C) 1995 Gadi Oxman
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
+#include <sys/ioctl.h>
 
 #include "ext2ed.h"
 #include "../version.h"
 
 struct struct_pad_info show_pad_info;
-WINDOW *title_win,*show_win,*command_win,*show_pad;
+WINDOW *title_win,*show_win,*command_win,*mt_win1,*mt_win2,*show_pad;
 
 /* to remember configuration after initscr 
  * and modify it
  */
-struct termios termioInit, termioCurrent; 
+struct termios termioInit, termioCurrent;
 
-void init_windows (void)
+void draw_title_win (void)
+{
+       char title_string [128];
 
+       werase(title_win);
+       box (title_win,0,0);
+       sprintf (title_string,"EXT2ED - Extended-2 File System editor ver %s (%s)", E2FSPROGS_VERSION, E2FSPROGS_DATE);
+       wmove (title_win,TITLE_WIN_LINES/2,(COLS-strlen (title_string))/2);
+       wprintw (title_win,title_string);
+       wrefresh(title_win);
+}
+
+void setup_show_win(void)
+{
+       wbkgdset (show_win,A_REVERSE);werase (show_win);
+       show_pad_info.line=0;
+       show_pad_info.col=0;
+       show_pad_info.display_lines=LINES-TITLE_WIN_LINES-SHOW_WIN_LINES-COMMAND_WIN_LINES-2;
+       show_pad_info.display_cols=COLS;
+       show_pad_info.max_line=show_pad_info.display_lines-1;show_pad_info.max_col=show_pad_info.display_cols-1;
+       show_pad_info.disable_output=0;
+}      
+
+void init_windows (void)
 {
-       char title_string [80];
-       
        initscr ();
        tcgetattr(0,&termioInit); /* save initial config */
        termioCurrent = termioInit;
@@ -54,41 +75,34 @@ void init_windows (void)
        title_win=newwin (TITLE_WIN_LINES,COLS,0,0);
        show_win=newwin (SHOW_WIN_LINES,COLS,TITLE_WIN_LINES,0);
        show_pad=newpad (SHOW_PAD_LINES,SHOW_PAD_COLS);
+       mt_win1=newwin (1,COLS,TITLE_WIN_LINES+SHOW_WIN_LINES,0);
+       mt_win2=newwin (1,COLS,LINES-COMMAND_WIN_LINES-1,0);
        command_win=newwin (COMMAND_WIN_LINES,COLS,LINES-COMMAND_WIN_LINES,0);
 
        if (title_win==NULL || show_win==NULL || show_pad==NULL || command_win==NULL) {
                printf ("Error - Not enough memory - Can not initialize windows\n");exit (1);
        }
 
-       box (title_win,0,0);
-       sprintf (title_string,"EXT2ED - Extended-2 File System editor ver %s (%s)", E2FSPROGS_VERSION, E2FSPROGS_DATE);
-       wmove (title_win,TITLE_WIN_LINES/2,(COLS-strlen (title_string))/2);
-       wprintw (title_win,title_string);
+       draw_title_win();
+
+       setup_show_win();
 
-#ifdef OLD_NCURSES
-       wattrset (show_win,A_NORMAL);werase (show_win);
-#else
-       wbkgdset (show_win,A_REVERSE);werase (show_win);
-#endif
-       show_pad_info.line=0;show_pad_info.col=0;
-       show_pad_info.display_lines=LINES-TITLE_WIN_LINES-SHOW_WIN_LINES-COMMAND_WIN_LINES-2;
-       show_pad_info.display_cols=COLS;
-       show_pad_info.max_line=show_pad_info.display_lines-1;show_pad_info.max_col=show_pad_info.display_cols-1;
-       show_pad_info.disable_output=0;
-       
        scrollok (command_win,TRUE);
 
-       refresh_title_win ();refresh_show_win ();refresh_show_pad ();refresh_command_win ();
+       refresh_title_win ();
+       refresh_show_win ();
+       refresh_show_pad();
+       refresh_command_win ();
+       wrefresh(mt_win1);
+       wrefresh(mt_win2);
 }
 
 void refresh_title_win (void)
-
 {
        wrefresh (title_win);
 }
 
 void refresh_show_win (void)
-
 {
        int current_page,total_pages;
        
@@ -135,13 +149,11 @@ void refresh_show_pad (void)
 }
 
 void refresh_command_win (void)
-
 {
        wrefresh (command_win);
 }
 
 void close_windows (void)
-
 {
 //     echo ();
        tcsetattr(0,TCSANOW,&termioInit);
@@ -155,7 +167,6 @@ void close_windows (void)
 }
 
 void show_info (void)
-
 {
        int block_num,block_offset;
        
@@ -174,12 +185,47 @@ void show_info (void)
 
 
 void redraw_all (void)
-
 {
-       close_windows ();
-       init_windows ();
-       
-       wmove (command_win,0,0);
-       mvcur (-1,-1,LINES-COMMAND_WIN_LINES,0);
-       
+       int min_lines = TITLE_WIN_LINES+SHOW_WIN_LINES+COMMAND_WIN_LINES+3;
+       struct winsize ws;
+       int     save_col, save_lines;
+
+       /* get the size of the terminal connected to stdout */
+       ioctl(1, TIOCGWINSZ, &ws);
+       /*
+        * Do it again because GDB doesn't stop before the first ioctl
+        * call, we want an up-to-date size when we're
+        * single-stepping.
+        */
+       if (ioctl(1, TIOCGWINSZ, &ws) == 0) {
+               if (ws.ws_row < min_lines)
+                       ws.ws_row = min_lines;
+               if ((ws.ws_row != LINES) || (ws.ws_col != COLS)) {
+                       wmove (show_win,2,COLS-18);
+                       wclrtoeol(show_win);
+                       wrefresh(show_win);
+                       resizeterm(ws.ws_row, ws.ws_col);
+                       wresize(title_win, TITLE_WIN_LINES,COLS);
+                       wresize(show_win, SHOW_WIN_LINES,COLS);
+                       wresize(command_win, COMMAND_WIN_LINES,COLS);
+                       wresize(mt_win1, 1,COLS);
+                       wresize(mt_win2, 1,COLS);
+                       mvwin(mt_win2, LINES-COMMAND_WIN_LINES-1,0);
+                       mvwin(command_win, LINES-COMMAND_WIN_LINES,0);
+                       draw_title_win();
+                       show_pad_info.display_lines=LINES-TITLE_WIN_LINES-SHOW_WIN_LINES-COMMAND_WIN_LINES-2;
+                       show_pad_info.display_cols=COLS;
+               }
+       }
+       clearok(title_win, 1);
+       clearok(show_win, 1);
+       clearok(command_win, 1);
+       clearok(mt_win1, 1);
+       clearok(mt_win2, 1);
+       wrefresh(mt_win1);
+       wrefresh(mt_win2);
+       refresh_show_pad();
+       refresh_show_win();
+       refresh_title_win ();
+       refresh_command_win ();
 }