]> git.mxchange.org Git - flightgear.git/commitdiff
Initial revision.
authorcurt <curt>
Sun, 15 Feb 2004 04:00:48 +0000 (04:00 +0000)
committercurt <curt>
Sun, 15 Feb 2004 04:00:48 +0000 (04:00 +0000)
12 files changed:
utils/fgadmin/Makefile.am [new file with mode: 0644]
utils/fgadmin/autogen.sh [new file with mode: 0755]
utils/fgadmin/configure.ac [new file with mode: 0644]
utils/fgadmin/src/Makefile.am [new file with mode: 0644]
utils/fgadmin/src/config.h [new file with mode: 0644]
utils/fgadmin/src/fgadmin.cxx [new file with mode: 0644]
utils/fgadmin/src/fgadmin.fl [new file with mode: 0644]
utils/fgadmin/src/fgadmin.h [new file with mode: 0644]
utils/fgadmin/src/fgadmin_funcs.cxx [new file with mode: 0644]
utils/fgadmin/src/main.cxx [new file with mode: 0644]
utils/fgadmin/src/tar_utils.cxx [new file with mode: 0644]
utils/fgadmin/src/tar_utils.hxx [new file with mode: 0644]

diff --git a/utils/fgadmin/Makefile.am b/utils/fgadmin/Makefile.am
new file mode 100644 (file)
index 0000000..af437a6
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = src
diff --git a/utils/fgadmin/autogen.sh b/utils/fgadmin/autogen.sh
new file mode 100755 (executable)
index 0000000..f57cd8f
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+OSTYPE=`uname -s`
+MACHINE=`uname -m`
+AUTO_MAKE_VERSION=`automake --version | head -1 | awk '{print $4}' | sed -e 's/\.\([0-9]*\).*/\1/'`
+if test $AUTO_MAKE_VERSION -lt 15; then
+    echo ""
+    echo "You need to upgrade to automake version 1.5 or greater."
+    echo "Most distributions have packages available to install or you can"
+    echo "find the source for the most recent version at"
+    echo "ftp://ftp.gnu.org/gnu/automake"
+    exit 1
+fi
+
+echo "Host info: $OSTYPE $MACHINE"
+echo -n " automake: `automake --version | head -1 | awk '{print $4}'`"
+echo " ($AUTO_MAKE_VERSION)"
+echo ""
+
+echo "Running aclocal"
+aclocal
+
+echo "Running autoheader"
+autoheader
+if [ ! -e src/config.h.in ]; then
+    echo "ERROR: autoheader didn't create src/configh.in!"
+    exit 1
+fi    
+
+echo "Running automake --add-missing"
+automake --add-missing
+
+echo "Running autoconf"
+autoconf
+
+if [ ! -e configure ]; then
+    echo "ERROR: configure was not created!"
+    exit 1
+fi
+
+echo ""
+echo "======================================"
+
+if [ -f config.cache ]; then
+    echo "config.cache exists.  Removing the config.cache file will force"
+    echo "the ./configure script to rerun all it's tests rather than using"
+    echo "the previously cached values."
+    echo ""
+fi
+
+echo "Now you are ready to run './configure'"
+echo "======================================"
diff --git a/utils/fgadmin/configure.ac b/utils/fgadmin/configure.ac
new file mode 100644 (file)
index 0000000..9aeb6df
--- /dev/null
@@ -0,0 +1,200 @@
+dnl Process this file with autoget.sh to produce a working configure
+dnl script.
+dnl
+dnl $Id$
+
+AC_INIT
+AC_CONFIG_SRCDIR([src/fgadmin.fl])
+
+dnl Require at least automake 2.52
+AC_PREREQ(2.52)
+
+dnl Initialize the automake stuff
+AM_INIT_AUTOMAKE(fgadmin, 1.0)
+
+dnl Checks for programs.
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+AC_PROG_LN_S
+
+dnl set the $host variable based on local machine/os
+AC_CANONICAL_HOST
+
+case "${host}" in
+*-*-irix*)
+    if test "$CXX" = "CC"; then
+        AR="CC -ar"
+        ARFLAGS="-o"
+        CXXFLAGS="$CXXFLAGS -I$with_simgear/include/simgear/compatibility"
+    else
+        AR="ar"
+        ARFLAGS="cru"
+    fi
+    ;;
+*)
+    AR="ar"
+    ARFLAGS="cru"
+    ;;
+esac
+AC_SUBST(AR)
+AC_SUBST(ARFLAGS)
+
+# Check for MS Windows environment
+AC_CHECK_HEADER(windows.h)
+
+dnl Checks for libraries.
+
+AC_CHECK_LIB(fltk,main,LIBS="$LIBS `fltk-config --use-images --ldflags`"
+             LDFLAGS="$LDFLAGS `fltk-config --use-images --ldflags`"
+            CPPFLAGS="$CPPFLAGS `fltk-config --cxxflags`",
+  AC_MSG_ERROR(fltk library required get it at http://www.fltk.org))
+
+# The following are C++ items that need to be tested for with the c++
+# compiler
+
+AC_LANG_PUSH(C++)
+
+# Check for "plib" without which we cannot go on
+AC_CHECK_HEADER(plib/ul.h)
+if test "x$ac_cv_header_plib_ul_h" != "xyes"; then
+    echo
+    echo "You *must* have the plib library installed on your system to build"
+    echo "the FGFS simulator!"
+    echo
+    echo "Please see README.plib for more details."
+    echo
+    echo "configure aborted."
+    exit
+fi
+
+AC_MSG_CHECKING([for plib 1.6.0 or newer])
+AC_TRY_RUN([
+#include <plib/ul.h>
+
+#define MIN_PLIB_VERSION 160
+
+int main() {
+    int major, minor, micro;
+
+    if ( PLIB_VERSION < MIN_PLIB_VERSION ) {
+        return -1;
+    }
+
+    return 0;
+}
+
+],
+  AC_MSG_RESULT(yes),
+  [AC_MSG_RESULT(wrong version);
+   AC_MSG_ERROR([Install plib 1.6.0 or later first...])],
+  AC_MSG_RESULT(yes)
+)
+
+dnl Check for the presence of SimGear
+AC_CHECK_HEADER(simgear/version.h)
+if test "x$ac_cv_header_simgear_version_h" != "xyes"; then
+    echo
+    echo "You *must* have the SimGear support library installed on your system"
+    echo "to build the FGFS simulator!"
+    echo
+    echo "Please see README.SimGear for more details."
+    echo
+    echo "configure aborted."
+    exit
+fi
+
+AC_MSG_CHECKING([for simgear 0.3.4 or newer])
+AC_TRY_RUN([
+#include <stdio.h>
+
+#include <simgear/version.h>
+
+#define STRINGIFY(X) XSTRINGIFY(X)
+#define XSTRINGIFY(X) #X
+
+#define MIN_MAJOR 0
+#define MIN_MINOR 3
+#define MIN_MICRO 4
+
+int main() {
+    int major, minor, micro;
+
+    printf("%d.%d.%d or greater... ", MIN_MAJOR, MIN_MINOR, MIN_MICRO);
+
+    sscanf( STRINGIFY(SIMGEAR_VERSION), "%d.%d.%d", &major, &minor, &micro );
+
+    if ( major < MIN_MAJOR ) {
+        return -1;
+    } else if ( major == MIN_MAJOR && minor < MIN_MINOR ) {
+        return -1;
+    } else if ( major == MIN_MAJOR && minor == MIN_MINOR && micro < MIN_MICRO ){
+        return -1;
+    }
+
+    return 0;
+}
+
+],
+  AC_MSG_RESULT(yes),
+  [AC_MSG_RESULT(wrong version);
+   AC_MSG_ERROR([Install latest simgear first...])],
+  AC_MSG_RESULT(yes)
+)
+
+AC_LANG_POP
+
+dnl Check for system installed zlib
+AC_CHECK_HEADER(zlib.h)
+if test "x$ac_cv_header_zlib_h" != "xyes"; then
+    echo
+    echo "zlib library not found."
+    echo
+    echo "If your OS does not provide an installable package for zlib"
+    echo "you will have to compile and install it first yourself.  A copy"
+    echo "of zlib-1.1.4.tar.gz is included with SimGear.  You will"
+    echo "have to untar this source code, and follow it's included instructions"
+    echo "to compile and install on your system."
+    echo
+    echo "configure aborted."
+    echo
+    exit
+fi
+
+dnl Check for system installed zlib
+AC_CHECK_HEADER(libtar.h)
+if test "x$ac_cv_header_libtar_h" != "xyes"; then
+    echo
+    echo "libtar library not found."
+    echo
+    echo "If your OS does not provide an installable package for libtar"
+    echo "you will have to compile and install it first yourself."
+    echo
+    echo "configure aborted."
+    echo
+    exit
+fi
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS( errno.h fcntl.h sys/types.h sys/stat.h )
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+AC_CHECK_FUNCS( [ rmdir unlink ] )
+
+AM_CONFIG_HEADER(src/config.h)
+
+AC_CONFIG_FILES([ \
+       Makefile \
+       src/Makefile \
+])
+
+AC_OUTPUT
diff --git a/utils/fgadmin/src/Makefile.am b/utils/fgadmin/src/Makefile.am
new file mode 100644 (file)
index 0000000..8db1c72
--- /dev/null
@@ -0,0 +1,12 @@
+EXTRA_DIST = fgadmin.fl
+
+bin_PROGRAMS = fgadmin
+
+fgadmin_SOURCES = \
+       fgadmin.cxx fgadmin.h \
+       fgadmin_funcs.cxx \
+       main.cxx \
+       tar_utils.cxx tar_utils.hxx
+
+fgadmin_LDADD = -lsgmisc -lplibul -ltar -lz
+
diff --git a/utils/fgadmin/src/config.h b/utils/fgadmin/src/config.h
new file mode 100644 (file)
index 0000000..1e74f6e
--- /dev/null
@@ -0,0 +1,77 @@
+/* src/config.h.  Generated by configure.  */
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `rmdir' function. */
+#define HAVE_RMDIR 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `unlink' function. */
+#define HAVE_UNLINK 1
+
+/* Name of package */
+#define PACKAGE "fgadmin"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Version number of package */
+#define VERSION "1.0"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/utils/fgadmin/src/fgadmin.cxx b/utils/fgadmin/src/fgadmin.cxx
new file mode 100644 (file)
index 0000000..2578284
--- /dev/null
@@ -0,0 +1,73 @@
+// generated by Fast Light User Interface Designer (fluid) version 1.0104
+
+#include "fgadmin.h"
+
+inline void FGAdminUI::cb_quit_b_i(Fl_Button*, void*) {
+  quit();
+}
+void FGAdminUI::cb_quit_b(Fl_Button* o, void* v) {
+  ((FGAdminUI*)(o->parent()->user_data()))->cb_quit_b_i(o,v);
+}
+
+inline void FGAdminUI::cb_source_b_i(Fl_Button*, void*) {
+  select_install_source();
+refresh_lists();
+}
+void FGAdminUI::cb_source_b(Fl_Button* o, void* v) {
+  ((FGAdminUI*)(o->parent()->user_data()))->cb_source_b_i(o,v);
+}
+
+inline void FGAdminUI::cb_dest_b_i(Fl_Button*, void*) {
+  select_install_dest();
+refresh_lists();
+}
+void FGAdminUI::cb_dest_b(Fl_Button* o, void* v) {
+  ((FGAdminUI*)(o->parent()->user_data()))->cb_dest_b_i(o,v);
+}
+
+inline void FGAdminUI::cb_install_b_i(Fl_Button*, void*) {
+  install_selected();
+}
+void FGAdminUI::cb_install_b(Fl_Button* o, void* v) {
+  ((FGAdminUI*)(o->parent()->user_data()))->cb_install_b_i(o,v);
+}
+
+inline void FGAdminUI::cb_remove_b_i(Fl_Button*, void*) {
+  remove_selected();
+}
+void FGAdminUI::cb_remove_b(Fl_Button* o, void* v) {
+  ((FGAdminUI*)(o->parent()->user_data()))->cb_remove_b_i(o,v);
+}
+#include <iostream>
+using std::cout;
+using std::endl;
+
+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));
+    { Fl_Button* o = quit_b = new Fl_Button(190, 405, 85, 25, "Quit");
+      o->callback((Fl_Callback*)cb_quit_b);
+    }
+    { Fl_Button* o = source_b = new Fl_Button(5, 5, 225, 25, "Select Scenery Source ...");
+      o->callback((Fl_Callback*)cb_source_b);
+    }
+    source_text = new Fl_Input(5, 35, 225, 25);
+    { Fl_Button* o = dest_b = new Fl_Button(235, 5, 225, 25, "Select Install Destination ...");
+      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_Button* o = install_b = new Fl_Button(20, 360, 195, 35, "Install Selected Files");
+      o->labelfont(1);
+      o->callback((Fl_Callback*)cb_install_b);
+    }
+    { Fl_Button* o = remove_b = new Fl_Button(250, 360, 195, 35, "Remove Selected Files");
+      o->labelfont(1);
+      o->callback((Fl_Callback*)cb_remove_b);
+    }
+    o->end();
+  }
+}
diff --git a/utils/fgadmin/src/fgadmin.fl b/utils/fgadmin/src/fgadmin.fl
new file mode 100644 (file)
index 0000000..84a13f8
--- /dev/null
@@ -0,0 +1,85 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0104 
+header_name {.h} 
+code_name {.cxx}
+decl {\#include <string>} {public
+} 
+
+decl {\#include <FL/Fl_Preferences.H>} {public
+} 
+
+decl {using std::string;} {public
+} 
+
+class FGAdminUI {open selected
+} {
+  decl {\#include <iostream>} {}
+  decl {using std::cout;} {}
+  decl {using std::endl;} {}
+  Function {FGAdminUI()} {open
+  } {
+    Fl_Window main_window {
+      label {FlightGear Admin Wizard} open
+      xywh {186 521 465 435} type Double visible
+    } {
+      Fl_Button quit_b {
+        label Quit
+        callback {quit();}
+        xywh {190 405 85 25}
+      }
+      Fl_Button source_b {
+        label {Select Scenery Source ...}
+        callback {select_install_source();
+refresh_lists();}
+        xywh {5 5 225 25}
+      }
+      Fl_Input source_text {
+        xywh {5 35 225 25}
+      }
+      Fl_Button dest_b {
+        label {Select Install Destination ...}
+        callback {select_install_dest();
+refresh_lists();}
+        xywh {235 5 225 25}
+      }
+      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_Button install_b {
+        label {Install Selected Files}
+        callback {install_selected();}
+        xywh {20 360 195 35} labelfont 1
+      }
+      Fl_Button remove_b {
+        label {Remove Selected Files}
+        callback {remove_selected();}
+        xywh {250 360 195 35} labelfont 1
+      }
+    }
+  }
+  decl {~FGAdminUI();} {public
+  }
+  decl {void init();} {public
+  }
+  decl {void show();} {public
+  }
+  decl {void refresh_lists();} {}
+  decl {void quit();} {}
+  decl {void select_install_source();} {}
+  decl {void select_install_dest();} {}
+  decl {void update_install_box();} {}
+  decl {void update_remove_box();} {}
+  decl {void install_selected();} {}
+  decl {void remove_selected();} {}
+  decl {Fl_Preferences *prefs;} {}
+  decl {string source;} {}
+  decl {string dest;} {}
+} 
diff --git a/utils/fgadmin/src/fgadmin.h b/utils/fgadmin/src/fgadmin.h
new file mode 100644 (file)
index 0000000..821e2be
--- /dev/null
@@ -0,0 +1,63 @@
+// generated by Fast Light User Interface Designer (fluid) version 1.0104
+
+#ifndef fgadmin_h
+#define fgadmin_h
+#include <FL/Fl.H>
+#include <string>
+#include <FL/Fl_Preferences.H>
+using std::string;
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Check_Browser.H>
+
+class FGAdminUI {
+public:
+  FGAdminUI();
+  Fl_Double_Window *main_window;
+  Fl_Button *quit_b;
+private:
+  inline void cb_quit_b_i(Fl_Button*, void*);
+  static void cb_quit_b(Fl_Button*, void*);
+public:
+  Fl_Button *source_b;
+private:
+  inline void cb_source_b_i(Fl_Button*, void*);
+  static void cb_source_b(Fl_Button*, void*);
+public:
+  Fl_Input *source_text;
+  Fl_Button *dest_b;
+private:
+  inline void cb_dest_b_i(Fl_Button*, void*);
+  static void cb_dest_b(Fl_Button*, void*);
+public:
+  Fl_Input *dest_text;
+  Fl_Check_Browser *install_box;
+  Fl_Check_Browser *remove_box;
+  Fl_Button *install_b;
+private:
+  inline void cb_install_b_i(Fl_Button*, void*);
+  static void cb_install_b(Fl_Button*, void*);
+public:
+  Fl_Button *remove_b;
+private:
+  inline void cb_remove_b_i(Fl_Button*, void*);
+  static void cb_remove_b(Fl_Button*, void*);
+public:
+  ~FGAdminUI();
+  void init();
+  void show();
+private:
+  void refresh_lists();
+  void quit();
+  void select_install_source();
+  void select_install_dest();
+  void update_install_box();
+  void update_remove_box();
+  void install_selected();
+  void remove_selected();
+  Fl_Preferences *prefs;
+  string source;
+  string dest;
+};
+#endif
diff --git a/utils/fgadmin/src/fgadmin_funcs.cxx b/utils/fgadmin/src/fgadmin_funcs.cxx
new file mode 100644 (file)
index 0000000..91a4492
--- /dev/null
@@ -0,0 +1,278 @@
+// fgadmin_funcs.cxx -- FG Admin UI functions.
+//
+// Written by Curtis Olson, started February 2004.
+//
+// Copyright (c) 2004  Curtis L. Olson - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <FL/Fl_File_Chooser.H>
+#include <plib/ul.h>
+
+#include <simgear/misc/sg_path.hxx>
+
+#include "fgadmin.h"
+#include "tar_utils.hxx"
+
+using std::cout;
+using std::endl;
+using std::vector;
+using std::string;
+
+
+// destructor
+FGAdminUI::~FGAdminUI() {
+    delete prefs;
+}
+
+
+// initialize additional class elements
+void FGAdminUI::init() {
+    prefs = new Fl_Preferences( Fl_Preferences::USER,
+                                "flightgear.org",
+                                "fgadmin" );
+    char buf[FL_PATH_MAX];
+    prefs->get( "install-source", buf, "", FL_PATH_MAX );
+    source_text->value( buf );
+    source = buf;
+
+    prefs->get( "scenery-dest", buf, "", FL_PATH_MAX );
+    dest_text->value( buf );
+    dest = buf;
+
+    refresh_lists();
+}
+
+// show our UI
+void FGAdminUI::show() {
+    main_window->show();
+}
+
+
+// refresh the check box lists
+void FGAdminUI::refresh_lists() {
+    update_install_box();
+    update_remove_box();
+}
+
+
+// scan the source directory and update the install_box contents
+// quit
+void FGAdminUI::quit() {
+    main_window->hide();
+}
+
+
+// select the install source
+void FGAdminUI::select_install_source() {
+    char* p = fl_dir_chooser( "Select Scenery Source Directory",
+                              source.c_str(),
+                              0 );
+    if ( p != 0 ) {
+       source = p;
+        source_text->value( p );
+        prefs->set( "install-source", p );
+        prefs->flush();
+    }
+}
+
+
+// select the install source
+void FGAdminUI::select_install_dest() {
+    char* p = fl_dir_chooser( "Select Scenery Install Directory",
+                              dest.c_str(),
+                              0 );
+    if ( p != 0 ) {
+       dest = p;
+        dest_text->value( p );
+        prefs->set( "scenery-dest", p );
+        prefs->flush();
+    }
+}
+
+
+// Like strcmp, but for strings
+static int stringCompare(const void *string1, const void *string2)
+{
+    const string *s1 = (const string *)string1;
+    const string *s2 = (const string *)string2;
+
+    // Compare name first, and then index.
+    return strcmp(s1->c_str(), s2->c_str());
+}
+
+
+void FGAdminUI::update_install_box() {
+    int i;
+    vector<string> file_list;
+    file_list.clear();
+
+    install_box->clear();
+
+    if ( source.length() ) {
+        ulDir *dir = ulOpenDir( source.c_str() ) ;
+        ulDirEnt *ent;
+        while ( ent = ulReadDir( dir ) ) {
+            // find base name of archive file
+            char base[FL_PATH_MAX];
+            strncpy( base, ent->d_name, FL_PATH_MAX );
+            const char *p = fl_filename_ext( base );
+            int offset;
+            if ( strcmp( p, ".gz" ) == 0 ) {
+                offset = p - base;
+                base[offset] = '\0';
+                p = fl_filename_ext( base );
+                if ( strcmp( p, ".tar" ) == 0 ) {
+                    offset = p - base;
+                    base[offset] = '\0';
+                }
+            } else if ( strcmp( p, ".zip" ) == 0 ) {
+                offset = p - base;
+                base[offset] = '\0';
+            }
+
+            // add to list if not installed
+            SGPath install( dest );
+            install.append( base );
+            if ( ! fl_filename_isdir( install.c_str() ) ) {
+                // cout << install.str() << " install candidate." << endl;
+                file_list.push_back( ent->d_name );
+            } else {
+                // cout << install.str() << " exists." << endl;
+            }
+        }
+        ulCloseDir( dir );
+
+        // convert to a qsort()'able array
+        string *sort_list = new string[file_list.size()];
+        for ( i = 0; i < file_list.size(); ++i ) {
+            sort_list[i] = fl_filename_name( file_list[i].c_str() );
+        }
+
+        // Sort the file list into display order
+        qsort(sort_list, file_list.size(), sizeof(string), stringCompare);
+
+        for ( int i = 0; i < file_list.size(); ++i ) {
+            install_box->add( sort_list[i].c_str() );
+        }
+
+        delete [] sort_list;
+    }
+}
+
+
+// scan the source directory and update the install_box contents
+void FGAdminUI::update_remove_box() {
+    int i;
+    vector<string> dir_list;
+    dir_list.clear();
+
+    remove_box->clear();
+
+    if ( dest.length() ) {
+        ulDir *dir = ulOpenDir( dest.c_str() ) ;
+        ulDirEnt *ent;
+        while ( ent = ulReadDir( dir ) ) {
+            if ( strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..") ) {
+                dir_list.push_back( ent->d_name );
+            }
+        }
+        ulCloseDir( dir );
+
+        // convert to a qsort()'able array
+        string *sort_list = new string[dir_list.size()];
+        for ( i = 0; i < dir_list.size(); ++i ) {
+            sort_list[i] = fl_filename_name( dir_list[i].c_str() );
+        }
+
+        // Sort the file list into display order
+        qsort(sort_list, dir_list.size(), sizeof(string), stringCompare);
+
+        for ( int i = 0; i < dir_list.size(); ++i ) {
+            remove_box->add( sort_list[i].c_str() );
+        }
+
+        delete [] sort_list;
+    }
+}
+
+
+// install selected files
+void FGAdminUI::install_selected() {
+    char *f;
+
+    // traverse install box and install each item
+    for ( int i = 0; i < install_box->nitems(); ++i ) {
+        if ( install_box->checked( i ) ) {
+            f = install_box->text( i );
+            SGPath file( source );
+            file.append( f );
+            cout << "installing " << file.str() << endl;
+            tarextract( (char *)file.c_str(), (char *)dest.c_str(), true );
+        }
+    }
+
+    refresh_lists();
+}
+
+
+static void remove_dir( const char *dir_name ) {
+    ulDir *dir = ulOpenDir( dir_name ) ;
+    ulDirEnt *ent;
+    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 );
+            remove_dir( child.c_str() );
+        } else {
+            SGPath child( dir_name );
+            child.append( ent->d_name );
+            unlink( child.c_str() );
+        }
+    }
+    ulCloseDir( dir );
+    rmdir( dir_name );
+}
+
+
+// remove selected files
+void FGAdminUI::remove_selected() {
+    char *f;
+
+    // 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 );
+            cout << "removing " << dir.str() << endl;
+            remove_dir( dir.c_str() );
+        }
+    }
+
+    refresh_lists();
+   
+}
diff --git a/utils/fgadmin/src/main.cxx b/utils/fgadmin/src/main.cxx
new file mode 100644 (file)
index 0000000..ae08215
--- /dev/null
@@ -0,0 +1,86 @@
+// main.cxx -- FlightGear Scenery/Aircraft Admin Tool
+//
+// Written by Curtis Olson, started February 2004.
+//
+// Copyright (c) 2004  Curtis L. Olson - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string>
+#include <FL/Fl.H>
+
+#include "fgadmin.h"
+
+std::string def_fg_exe = "";
+std::string def_fg_root = "";
+std::string def_fg_scenery = "";
+
+/**
+ * --fg-exe=<PATH>
+ * --fg-root=<DIR>
+ * --fg-scenery=<DIR>
+ */
+static int
+parse_args( int, char** argv, int& i )
+{
+    if (strncmp( argv[i], "--fg-exe=", 9 ) == 0)
+    {
+       def_fg_exe.assign( &argv[i][9] );
+       ++i;
+       return 1;
+    }
+
+    if (strncmp( argv[i], "--fg-root=", 10 ) == 0)
+    {
+       def_fg_root.assign( &argv[i][10] );
+       def_fg_scenery = def_fg_root;
+       def_fg_scenery += "/Scenery";
+
+       ++i;
+       return 1;
+    }
+
+    if (strncmp( argv[i], "--fg-scenery=", 13 ) == 0)
+    {
+       def_fg_scenery.assign( &argv[i][13] );
+       ++i;
+       return 1;
+    }
+
+    return 0;
+}
+
+int
+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 );
+    }
+
+    FGAdminUI ui;
+    ui.init();
+    ui.show();
+
+    return Fl::run();
+}
diff --git a/utils/fgadmin/src/tar_utils.cxx b/utils/fgadmin/src/tar_utils.cxx
new file mode 100644 (file)
index 0000000..fbe1cb2
--- /dev/null
@@ -0,0 +1,136 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <tar.h>
+
+#include <libtar.h>
+#include <zlib.h>
+
+#include "tar_utils.hxx"
+
+
+int gzopen_frontend( char *pathname, int oflags, int mode ) {
+    char *gzoflags;
+    gzFile gzf;
+    int fd;
+
+    switch (oflags & O_ACCMODE)
+        {
+        case O_WRONLY:
+            gzoflags = "wb";
+            break;
+        case O_RDONLY:
+            gzoflags = "rb";
+            break;
+        default:
+        case O_RDWR:
+            errno = EINVAL;
+            return -1;
+        }
+
+    fd = open(pathname, oflags, mode);
+    if (fd == -1)
+        return -1;
+
+    if ((oflags & O_CREAT) && fchmod(fd, mode))
+        return -1;
+
+    gzf = gzdopen(fd, gzoflags);
+    if (!gzf) {
+        errno = ENOMEM;
+        return -1;
+    }
+
+    return (int)gzf;
+}
+
+
+tartype_t gztype = {
+    (openfunc_t) gzopen_frontend,
+    (closefunc_t) gzclose,
+    (readfunc_t) gzread,
+    (writefunc_t) gzwrite
+};
+
+
+// list the contents of the specified tar file
+bool tarlist( char *tarfile, char *destdir, bool verbose ) {
+    TAR *t;
+    int i;
+
+    int tarflags = TAR_GNU;
+    if ( verbose ) {
+        tarflags |= TAR_VERBOSE;
+    }
+
+    if ( tar_open( &t, tarfile, &gztype, O_RDONLY, 0, tarflags ) == -1) {
+        fprintf(stderr, "tar_open(): %s\n", strerror(errno));
+        return -1;
+    }
+
+    while ((i = th_read(t)) == 0) {
+        th_print_long_ls(t);
+#ifdef DEBUG
+        th_print(t);
+#endif
+        if (TH_ISREG(t) && tar_skip_regfile(t) != 0) {
+            fprintf(stderr, "tar_skip_regfile(): %s\n",
+                    strerror(errno));
+            return -1;
+        }
+    }
+
+#ifdef DEBUG
+    printf( "th_read() returned %d\n", i);
+    printf( "EOF mark encountered after %ld bytes\n",
+            gzseek((gzFile) t->fd, 0, SEEK_CUR)
+            );
+#endif
+
+    if (tar_close(t) != 0) {
+        fprintf(stderr, "tar_close(): %s\n", strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+
+// extract the specified tar file into the specified destination
+// directory
+int tarextract( char *tarfile, char *destdir, bool verbose ) {
+    TAR *t;
+
+#ifdef DEBUG
+    puts("opening tarfile...");
+#endif
+
+    int tarflags = TAR_GNU;
+    if ( verbose ) {
+        tarflags |= TAR_VERBOSE;
+    }
+
+    if ( tar_open(&t, tarfile, &gztype, O_RDONLY, 0, tarflags) == -1 ) {
+        fprintf(stderr, "tar_open(): %s\n", strerror(errno));
+        return -1;
+    }
+
+#ifdef DEBUG
+    puts("extracting tarfile...");
+#endif
+    if (tar_extract_all(t, destdir) != 0) {
+        fprintf(stderr, "tar_extract_all(): %s\n", strerror(errno));
+        return -1;
+    }
+
+#ifdef DEBUG
+    puts("closing tarfile...");
+#endif
+    if (tar_close(t) != 0) {
+        fprintf(stderr, "tar_close(): %s\n", strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/utils/fgadmin/src/tar_utils.hxx b/utils/fgadmin/src/tar_utils.hxx
new file mode 100644 (file)
index 0000000..e207554
--- /dev/null
@@ -0,0 +1,10 @@
+#include <string>
+
+using std::string;
+
+// list the contents of the specified tar file
+bool tarlist( char *tarfile, char *destdir, bool verbose );
+
+// extract the specified tar file into the specified destination
+// directory
+int tarextract( char *tarfile, char *destdir, bool verbose );