diff --git a/utils/fgadmin/src/fgadmin.cxx b/utils/fgadmin/src/fgadmin.cxx
index e9e55524b..db4368b69 100644
--- a/utils/fgadmin/src/fgadmin.cxx
+++ b/utils/fgadmin/src/fgadmin.cxx
@@ -1,6 +1,14 @@
 // generated by Fast Light User Interface Designer (fluid) version 1.0104
 
 #include "fgadmin.h"
+#include <FL/fl_ask.H>
+
+inline void FGAdminUI::cb_main_window_i(Fl_Double_Window*, void*) {
+  fl_alert("Use the Quit button to exit fgadmin");
+}
+void FGAdminUI::cb_main_window(Fl_Double_Window* o, void* v) {
+  ((FGAdminUI*)(o->user_data()))->cb_main_window_i(o,v);
+}
 
 inline void FGAdminUI::cb_quit_b_i(Fl_Button*, void*) {
   quit();
@@ -46,7 +54,7 @@ FGAdminUI::FGAdminUI() {
   Fl_Double_Window* w;
   { Fl_Double_Window* o = main_window = new Fl_Double_Window(465, 435, "FlightGear Admin Wizard");
     w = o;
-    o->user_data((void*)(this));
+    o->callback((Fl_Callback*)cb_main_window, (void*)(this));
     { Fl_Button* o = quit_b = new Fl_Button(360, 405, 85, 25, "Quit");
       o->callback((Fl_Callback*)cb_quit_b);
     }
@@ -58,8 +66,12 @@ FGAdminUI::FGAdminUI() {
       o->callback((Fl_Callback*)cb_dest_b);
     }
     dest_text = new Fl_Input(235, 35, 225, 25);
-    install_box = new Fl_Check_Browser(5, 65, 225, 270, "Select Files to Install");
-    remove_box = new Fl_Check_Browser(235, 65, 225, 270, "Select Files to Remove");
+    { Fl_Group* o = new Fl_Group(5, 65, 455, 270);
+      install_box = new Fl_Check_Browser(5, 65, 225, 270, "Select Files to Install");
+      remove_box = new Fl_Check_Browser(235, 65, 225, 270, "Select Files to Remove");
+      o->end();
+      Fl_Group::current()->resizable(o);
+    }
     { Fl_Button* o = install_b = new Fl_Button(20, 360, 195, 35, "Install Selected Files");
       o->labelfont(1);
       o->callback((Fl_Callback*)cb_install_b);
@@ -68,7 +80,7 @@ FGAdminUI::FGAdminUI() {
       o->labelfont(1);
       o->callback((Fl_Callback*)cb_remove_b);
     }
-    { Fl_Progress* o = progress = new Fl_Progress(20, 405, 195, 25);
+    { Fl_Progress* o = progress = new Fl_Progress(5, 405, 345, 25);
       o->color(FL_BACKGROUND_COLOR);
       o->selection_color((Fl_Color)175);
     }
diff --git a/utils/fgadmin/src/fgadmin.fl b/utils/fgadmin/src/fgadmin.fl
index afb2b62fc..d752a46c7 100644
--- a/utils/fgadmin/src/fgadmin.fl
+++ b/utils/fgadmin/src/fgadmin.fl
@@ -8,6 +8,8 @@ decl {\#include <string>} {public
 decl {\#include <FL/Fl_Preferences.H>} {public
 } 
 
+decl {\#include <FL/fl_ask.H>} {} 
+
 decl {using std::string;} {public
 } 
 
@@ -19,8 +21,9 @@ class FGAdminUI {open
   Function {FGAdminUI()} {open
   } {
     Fl_Window main_window {
-      label {FlightGear Admin Wizard} open
-      xywh {294 195 465 435} type Double visible
+      label {FlightGear Admin Wizard}
+      callback {fl_alert("Use the Quit button to exit fgadmin");} open
+      xywh {500 247 465 435} type Double resizable visible
     } {
       Fl_Button quit_b {
         label Quit
@@ -45,13 +48,17 @@ refresh_lists();}
       Fl_Input dest_text {
         xywh {235 35 225 25}
       }
-      Fl_Check_Browser install_box {
-        label {Select Files to Install}
-        xywh {5 65 225 270}
-      }
-      Fl_Check_Browser remove_box {
-        label {Select Files to Remove}
-        xywh {235 65 225 270}
+      Fl_Group {} {open
+        xywh {5 65 455 270} resizable
+      } {
+        Fl_Check_Browser install_box {
+          label {Select Files to Install}
+          xywh {5 65 225 270}
+        }
+        Fl_Check_Browser remove_box {
+          label {Select Files to Remove}
+          xywh {235 65 225 270}
+        }
       }
       Fl_Button install_b {
         label {Install Selected Files}
@@ -63,8 +70,8 @@ refresh_lists();}
         callback {remove_selected();}
         xywh {250 360 195 35} labelfont 1
       }
-      Fl_Progress progress {selected
-        xywh {20 405 195 25} color 49 selection_color 175
+      Fl_Progress progress {
+        xywh {5 405 345 25} color 49 selection_color 175
       }
     }
   }
@@ -74,7 +81,9 @@ refresh_lists();}
   }
   decl {void show();} {public
   }
-  decl {static void step( void * );} {public
+  decl {static void step( void * );} {selected public
+  }
+  decl {static void step( void *, int );} {public
   }
   decl {void refresh_lists();} {}
   decl {void quit();} {}
@@ -87,4 +96,5 @@ refresh_lists();}
   decl {Fl_Preferences *prefs;} {}
   decl {string source;} {}
   decl {string dest;} {}
+  decl {string progress_label;} {}
 } 
diff --git a/utils/fgadmin/src/fgadmin.h b/utils/fgadmin/src/fgadmin.h
index 42926f263..cff861278 100644
--- a/utils/fgadmin/src/fgadmin.h
+++ b/utils/fgadmin/src/fgadmin.h
@@ -9,6 +9,7 @@ using std::string;
 #include <FL/Fl_Double_Window.H>
 #include <FL/Fl_Button.H>
 #include <FL/Fl_Input.H>
+#include <FL/Fl_Group.H>
 #include <FL/Fl_Check_Browser.H>
 #include <FL/Fl_Progress.H>
 
@@ -16,6 +17,10 @@ class FGAdminUI {
 public:
   FGAdminUI();
   Fl_Double_Window *main_window;
+private:
+  inline void cb_main_window_i(Fl_Double_Window*, void*);
+  static void cb_main_window(Fl_Double_Window*, void*);
+public:
   Fl_Button *quit_b;
 private:
   inline void cb_quit_b_i(Fl_Button*, void*);
@@ -50,6 +55,7 @@ public:
   void init();
   void show();
   static void step( void * );
+  static void step( void *, int );
 private:
   void refresh_lists();
   void quit();
@@ -62,5 +68,6 @@ private:
   Fl_Preferences *prefs;
   string source;
   string dest;
+  string progress_label;
 };
 #endif
diff --git a/utils/fgadmin/src/fgadmin_funcs.cxx b/utils/fgadmin/src/fgadmin_funcs.cxx
index 261c16cad..ba52467d2 100644
--- a/utils/fgadmin/src/fgadmin_funcs.cxx
+++ b/utils/fgadmin/src/fgadmin_funcs.cxx
@@ -24,6 +24,7 @@
 #include <iostream>
 #include <string>
 #include <vector>
+#include <sys/stat.h>
 
 #ifdef _MSC_VER
 #  include <direct.h>
@@ -42,6 +43,9 @@ using std::endl;
 using std::vector;
 using std::string;
 
+extern string def_install_source;
+extern string def_scenery_dest;
+
 static const float min_progress = 0.0;
 static const float max_progress = 5000.0;
 
@@ -57,11 +61,11 @@ void FGAdminUI::init() {
                                 "flightgear.org",
                                 "fgadmin" );
     char buf[FL_PATH_MAX];
-    prefs->get( "install-source", buf, "", FL_PATH_MAX );
+    prefs->get( "install-source", buf, def_install_source.c_str(), FL_PATH_MAX );
     source_text->value( buf );
     source = buf;
 
-    prefs->get( "scenery-dest", buf, "", FL_PATH_MAX );
+    prefs->get( "scenery-dest", buf, def_scenery_dest.c_str(), FL_PATH_MAX );
     dest_text->value( buf );
     dest = buf;
 
@@ -69,6 +73,8 @@ void FGAdminUI::init() {
 
     progress->minimum( min_progress );
     progress->maximum( max_progress );
+
+    main_window->size_range( 465, 435 );
 }
 
 // show our UI
@@ -249,6 +255,7 @@ void FGAdminUI::install_selected() {
 
     install_b->deactivate();
     remove_b->deactivate();
+    quit_b->deactivate();
 
     // traverse install box and install each item
     for ( int i = 0; i <= install_box->nitems(); ++i ) {
@@ -256,14 +263,23 @@ void FGAdminUI::install_selected() {
             f = install_box->text( i );
             SGPath file( source );
             file.append( f );
-            cout << "installing " << file.str() << endl;
+            struct stat info;
+            stat( file.str().c_str(), &info );
+            float old_max = progress->maximum();
+            progress->maximum( info.st_size );
+            progress_label = "Installing ";
+            progress_label += f;
+            progress->label( progress_label.c_str() );
             progress->value( min_progress );
             main_window->cursor( FL_CURSOR_WAIT );
             tarextract( (char *)file.c_str(), (char *)dest.c_str(), true, &FGAdminUI::step, this );
             progress->value( min_progress );
             main_window->cursor( FL_CURSOR_DEFAULT );
+            progress->label( "" );
+            progress->maximum( old_max );
         }
     }
+    quit_b->activate();
     install_b->activate();
     remove_b->activate();
 
@@ -271,7 +287,28 @@ void FGAdminUI::install_selected() {
 }
 
 
-static void remove_dir( const char *dir_name, void (*step)(void*), void *data ) {
+static unsigned long count_dir( const char *dir_name ) {
+    ulDir *dir = ulOpenDir( dir_name ) ;
+    ulDirEnt *ent;
+    unsigned long cnt = 0L;
+    while ( ent = ulReadDir( dir ) ) {
+        if ( strcmp( ent->d_name, "." ) == 0 ) {
+            // ignore "."
+        } else if ( strcmp( ent->d_name, ".." ) == 0 ) {
+            // ignore ".."
+        } else if ( ent->d_isdir ) {
+            SGPath child( dir_name );
+            child.append( ent->d_name );
+            cnt += count_dir( child.c_str() );
+        } else {
+            cnt += 1;
+        }
+    }
+    ulCloseDir( dir );
+    return cnt;
+}
+
+static void remove_dir( const char *dir_name, void (*step)(void*,int), void *data ) {
     ulDir *dir = ulOpenDir( dir_name ) ;
     ulDirEnt *ent;
     while ( ent = ulReadDir( dir ) ) {
@@ -287,7 +324,7 @@ static void remove_dir( const char *dir_name, void (*step)(void*), void *data )
             SGPath child( dir_name );
             child.append( ent->d_name );
             unlink( child.c_str() );
-            if (step) step( data );
+            if (step) step( data, 1 );
         }
     }
     ulCloseDir( dir );
@@ -301,20 +338,28 @@ void FGAdminUI::remove_selected() {
 
     install_b->deactivate();
     remove_b->deactivate();
+    quit_b->deactivate();
     // traverse remove box and recursively remove each item
     for ( int i = 0; i <= remove_box->nitems(); ++i ) {
         if ( remove_box->checked( i ) ) {
             f = remove_box->text( i );
             SGPath dir( dest );
             dir.append( f );
+            float old_max = progress->maximum();
+            progress_label = "Removing ";
+            progress_label += f;
+            progress->label( progress_label.c_str() );
             progress->value( min_progress );
             main_window->cursor( FL_CURSOR_WAIT );
-            cout << "removing " << dir.str() << endl;
+            progress->maximum( count_dir( dir.c_str() ) );
             remove_dir( dir.c_str(), &FGAdminUI::step, this );
             progress->value( min_progress );
             main_window->cursor( FL_CURSOR_DEFAULT );
+            progress->label( "" );
+            progress->maximum( old_max );
         }
     }
+    quit_b->activate();
     install_b->activate();
     remove_b->activate();
 
@@ -322,7 +367,6 @@ void FGAdminUI::remove_selected() {
    
 }
 
-
 void FGAdminUI::step(void *data)
 {
    Fl_Progress *p = ((FGAdminUI*)data)->progress;
@@ -338,3 +382,13 @@ void FGAdminUI::step(void *data)
 
    Fl::check();
 }
+
+void FGAdminUI::step(void *data, int n)
+{
+   Fl_Progress *p = ((FGAdminUI*)data)->progress;
+
+   float tmp = p->value() + n;
+   p->value( tmp );
+
+   Fl::check();
+}
diff --git a/utils/fgadmin/src/main.cxx b/utils/fgadmin/src/main.cxx
index ae0821522..45ac1e14f 100644
--- a/utils/fgadmin/src/main.cxx
+++ b/utils/fgadmin/src/main.cxx
@@ -27,41 +27,39 @@
 
 #include <string>
 #include <FL/Fl.H>
+#include <FL/filename.H>
 
 #include "fgadmin.h"
 
-std::string def_fg_exe = "";
-std::string def_fg_root = "";
-std::string def_fg_scenery = "";
+using std::string;
+
+string def_install_source;
+string def_scenery_dest;
+bool silent = false;
 
 /**
- * --fg-exe=<PATH>
- * --fg-root=<DIR>
- * --fg-scenery=<DIR>
+ * --silent
+ * --install-source=<DIR>
+ * --scenery-dest=<DIR>
  */
 static int
 parse_args( int, char** argv, int& i )
 {
-    if (strncmp( argv[i], "--fg-exe=", 9 ) == 0)
+    if (strcmp( argv[i], "--silent" ) == 0)
     {
-	def_fg_exe.assign( &argv[i][9] );
+	silent = true;
 	++i;
 	return 1;
     }
-
-    if (strncmp( argv[i], "--fg-root=", 10 ) == 0)
+    else if (strncmp( argv[i], "--install-source=", 17 ) == 0)
     {
-	def_fg_root.assign( &argv[i][10] );
-	def_fg_scenery = def_fg_root;
-	def_fg_scenery += "/Scenery";
-
+	def_install_source.assign( &argv[i][17] );
 	++i;
 	return 1;
     }
-
-    if (strncmp( argv[i], "--fg-scenery=", 13 ) == 0)
+    else if (strncmp( argv[i], "--scenery-dest=", 15 ) == 0)
     {
-	def_fg_scenery.assign( &argv[i][13] );
+	def_scenery_dest.assign( &argv[i][15] );
 	++i;
 	return 1;
     }
@@ -75,7 +73,21 @@ main( int argc, char* argv[] )
     int i = 0;
     if (Fl::args( argc, argv, i, parse_args ) < argc)
     {
-	Fl::fatal("Options are:\n --fg-exe=<PATH>\n --fg-root=<DIR>\n --fg-scenery=<DIR>\n%s", Fl::help );
+	Fl::fatal("Options are:\n --silent\n --install-source=<DIR>\n --scenery-dest=<DIR>\n%s", Fl::help );
+    }
+
+    if ( silent )
+    {
+        Fl_Preferences prefs( Fl_Preferences::USER, "flightgear.org", "fgadmin" );
+	char abs_name[ FL_PATH_MAX ];
+
+	fl_filename_absolute( abs_name, def_install_source.c_str() );
+	prefs.set( "install-source", abs_name );
+
+	fl_filename_absolute( abs_name, def_scenery_dest.c_str() );
+        prefs.set( "scenery-dest", abs_name );
+
+	return 0;
     }
 
     FGAdminUI ui;
diff --git a/utils/fgadmin/src/untarka.c b/utils/fgadmin/src/untarka.c
index f7f35bd89..8ca6b452a 100644
--- a/utils/fgadmin/src/untarka.c
+++ b/utils/fgadmin/src/untarka.c
@@ -101,6 +101,8 @@
 
 static void error OF((const char *msg));
 
+static unsigned long total_read;
+
 /* #define TAR_GZ 1 */
 
 typedef struct Readable {
@@ -117,10 +119,11 @@ typedef struct Readable {
 enum { FMT_U=1, FMT_Z=2, FMT_GZ=3, FMT_BZ2=4 };
 
 /* #define xFILE FILE* */
-static int xU_Open4Read(struct Readable* self, char const* filename) { return NULL==(self->f=fopen(filename,"rb")); }
+static int xU_Open4Read(struct Readable* self, char const* filename) { total_read=0; return NULL==(self->f=fopen(filename,"rb")); }
 static int xU_Close(struct Readable* self) { return fclose((FILE*)self->f); }
 static unsigned xU_Read(struct Readable* self, void* buf, unsigned len) {
   unsigned got=fread(buf,1,len,(FILE*)self->f);
+  total_read+=got;
   return got>0 ? got : ferror((FILE*)self->f) ? 0U-1 : 0;
 }
 static char const* xU_Error(struct Readable* self, int *errnum_ret) { return (*errnum_ret=ferror((FILE*)self->f))?"I/O error":"OK"; }
@@ -154,9 +157,9 @@ static char const* xZ_Error(struct Readable* self, int *errnum_ret) {
 #if HAVE_ZLIB
 #include "zlib.h"
 /* #define xFILE gzFile */
-static int xGZ_Open4Read(struct Readable* self, char const* filename) { return NULL==(self->f=gzopen(filename,"rb")); }
+static int xGZ_Open4Read(struct Readable* self, char const* filename) { total_read=0; return NULL==(self->f=gzopen(filename,"rb")); }
 static int xGZ_Close(struct Readable* self) { return gzclose((gzFile)self->f); }
-static unsigned xGZ_Read(struct Readable* self, void* buf, unsigned len) { return gzread((gzFile)self->f,buf,len); }
+static unsigned xGZ_Read(struct Readable* self, void* buf, unsigned len) { unsigned l=gzread((gzFile)self->f,buf,len); total_read=((z_streamp)self->f)->total_in; return l; }
 static char const* xGZ_Error(struct Readable* self, int *errnum_ret) { return gzerror((gzFile)self->f, errnum_ret); }
 #endif
 
@@ -1166,7 +1169,7 @@ static int matchname (int arg,int argc,char **argv,char *fname)
 
 /* Tar file list or extract */
 
-static int tar (Readable* rin,int action,int arg,int argc,char **argv, char const* TGZfile, int verbose, void (*step)(void *), void *data) {
+static int tar (Readable* rin,int action,int arg,int argc,char **argv, char const* TGZfile, int verbose, void (*step)(void *,int), void *data) {
   union  tar_buffer buffer;
   int    is_tar_ok=0;
   int    len;
@@ -1176,6 +1179,7 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons
   FILE   *outfile = NULL;
   char   fname[BLOCKSIZE];
   time_t tartime;
+  unsigned long last_read;
 
 #if 0
   while (0<(len=rin->xRead(rin, &buffer, BLOCKSIZE))) {
@@ -1184,6 +1188,7 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons
   exit(0);
 #endif
 
+  last_read = 0;
   if (action == TGZ_LIST)
     printf("     day      time     size                       file\n"
 	   " ---------- -------- --------- -------------------------------------\n");
@@ -1191,6 +1196,7 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons
       len = rin->xRead(rin, &buffer, BLOCKSIZE);
       if (len+1 == 0)
 	error (rin->xError(rin, &err));
+      if (step) { step(data,total_read - last_read); last_read = total_read; }
       if (!is_tar_ok && !(is_tar_ok=is_tar(buffer.buffer, len))) {
         fprintf(stderr, "%s: compressed file not tared: %s\n", prog, TGZfile);
         if (action == TGZ_EXTRACT) {
@@ -1341,7 +1347,6 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons
 		  outfile = NULL;
 		  utime(fname,&settime);
 #endif
-                  if (step) step(data);
 		}
 	    }
 	}