--- /dev/null
+SUBDIRS = src
--- /dev/null
+#!/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 "======================================"
--- /dev/null
+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, µ );
+
+ 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
--- /dev/null
+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
+
--- /dev/null
+/* 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 */
--- /dev/null
+// 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();
+ }
+}
--- /dev/null
+# 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;} {}
+}
--- /dev/null
+// 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
--- /dev/null
+// 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();
+
+}
--- /dev/null
+// 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();
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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 );