Browse Source

Import upstream version 3.1.1

Aaron Turner 17 years ago
parent
commit
20feef3563
100 changed files with 4256 additions and 1190 deletions
  1. 234 0
      INSTALL
  2. 2 2
      Makefile.in
  3. 388 180
      aclocal.m4
  4. 929 515
      configure
  5. 103 26
      configure.in
  6. 21 1
      docs/CHANGELOG
  7. 1 1
      docs/Makefile.in
  8. 1 1
      lib/Makefile.in
  9. 1 1
      lib/tree.h
  10. 4 2
      libopts/Makefile.am
  11. 5 3
      libopts/Makefile.in
  12. 1 1
      libopts/README
  13. 29 10
      libopts/autoopts.c
  14. 43 33
      libopts/autoopts.h
  15. 60 47
      libopts/autoopts/options.h
  16. 1 1
      libopts/autoopts/usage-txt.h
  17. 319 0
      libopts/compat.h
  18. 16 14
      libopts/configfile.c
  19. 74 55
      libopts/environment.c
  20. 20 11
      libopts/genshell.c
  21. 5 5
      libopts/genshell.h
  22. 22 2
      libopts/m4/libopts.m4
  23. 339 0
      libopts/pathfind.c
  24. 2 2
      libopts/pgusage.c
  25. 1 1
      libopts/proto.h
  26. 2 2
      libopts/save.c
  27. 60 0
      libopts/snprintf.c
  28. 2 2
      libopts/sort.c
  29. 60 0
      libopts/strchr.c
  30. 19 0
      libopts/strdup.c
  31. 2 2
      libopts/streqvcmp.c
  32. 20 11
      libopts/usage.c
  33. 12 10
      libopts/version.c
  34. 130 0
      libopts/windows-config.h
  35. 1 1
      scripts/Makefile.in
  36. BIN
      src/._defines.h.in
  37. BIN
      src/._send_packets.c
  38. BIN
      src/._tcpprep.c
  39. BIN
      src/._tcpreplay.c
  40. BIN
      src/._tcpreplay.h
  41. 1 1
      src/Makefile.in
  42. BIN
      src/common/._cidr.c
  43. BIN
      src/common/._cidr.h
  44. BIN
      src/common/._timer.h
  45. BIN
      src/common/._xX.c
  46. 1 1
      src/common/Makefile.in
  47. 2 5
      src/common/cache.c
  48. 1 1
      src/common/cidr.c
  49. 1 1
      src/common/cidr.h
  50. 1 1
      src/common/get.c
  51. 1 1
      src/common/interface.c
  52. 7 7
      src/common/sendpacket.c
  53. 1 1
      src/common/svn_version.c
  54. 1 1
      src/common/timer.h
  55. 2 2
      src/common/xX.c
  56. 3 0
      src/config.h.in
  57. BIN
      src/flow/._flownode.c
  58. 1 1
      src/flow/Makefile.in
  59. 1 1
      src/flow/flownode.c
  60. 3 3
      src/flowreplay.1
  61. 11 11
      src/flowreplay_opts.c
  62. 1 1
      src/flowreplay_opts.def
  63. 6 6
      src/flowreplay_opts.h
  64. 8 8
      src/send_packets.c
  65. 23 4
      src/tcpbridge.1
  66. 2 2
      src/tcpbridge.c
  67. 130 74
      src/tcpbridge_opts.c
  68. 1 1
      src/tcpbridge_opts.def
  69. 58 54
      src/tcpbridge_opts.h
  70. BIN
      src/tcpedit/._edit_packet.c
  71. 108 15
      src/tcpedit/Makefile.in
  72. 18 2
      src/tcpedit/edit_packet.c
  73. 21 1
      src/tcpedit/parse_args.c
  74. 2 0
      src/tcpedit/plugins/Makefile.am
  75. BIN
      src/tcpedit/plugins/dlt_en10mb/._en10mb.c
  76. BIN
      src/tcpedit/plugins/dlt_en10mb/._en10mb.h
  77. 1 1
      src/tcpedit/plugins/dlt_en10mb/Makefile.am
  78. 34 9
      src/tcpedit/plugins/dlt_en10mb/en10mb.c
  79. 2 2
      src/tcpedit/plugins/dlt_en10mb/en10mb.h
  80. 1 1
      src/tcpedit/plugins/dlt_hdlc/Makefile.am
  81. 32 4
      src/tcpedit/plugins/dlt_hdlc/hdlc.c
  82. 3 2
      src/tcpedit/plugins/dlt_hdlc/hdlc.h
  83. 26 0
      src/tcpedit/plugins/dlt_ieee80211/Makefile.am
  84. 382 0
      src/tcpedit/plugins/dlt_ieee80211/ieee80211.c
  85. 115 0
      src/tcpedit/plugins/dlt_ieee80211/ieee80211.h
  86. 188 0
      src/tcpedit/plugins/dlt_ieee80211/ieee80211_hdr.c
  87. 46 0
      src/tcpedit/plugins/dlt_ieee80211/ieee80211_hdr.h
  88. 1 0
      src/tcpedit/plugins/dlt_ieee80211/ieee80211_opts.def
  89. 1 1
      src/tcpedit/plugins/dlt_linuxsll/Makefile.am
  90. 32 4
      src/tcpedit/plugins/dlt_linuxsll/linuxsll.c
  91. 3 2
      src/tcpedit/plugins/dlt_linuxsll/linuxsll.h
  92. 1 1
      src/tcpedit/plugins/dlt_loop/Makefile.am
  93. 5 4
      src/tcpedit/plugins/dlt_loop/loop.c
  94. 1 1
      src/tcpedit/plugins/dlt_loop/loop.h
  95. 1 1
      src/tcpedit/plugins/dlt_null/Makefile.am
  96. 17 3
      src/tcpedit/plugins/dlt_null/null.c
  97. 3 2
      src/tcpedit/plugins/dlt_null/null.h
  98. 1 2
      src/tcpedit/plugins/dlt_opts.def
  99. 15 2
      src/tcpedit/plugins/dlt_plugins-int.h
  100. 0 0
      src/tcpedit/plugins/dlt_plugins.c

+ 234 - 0
INSTALL

@@ -0,0 +1,234 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+

+ 2 - 2
Makefile.in

@@ -35,7 +35,7 @@ target_triplet = @target@
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/doxygen.cfg.in \
-	$(srcdir)/tcpreplay.spec.in $(top_srcdir)/configure \
+	$(srcdir)/tcpreplay.spec.in $(top_srcdir)/configure INSTALL \
 	config/compile config/config.guess config/config.sub \
 	config/depcomp config/install-sh config/ltmain.sh \
 	config/missing config/mkinstalldirs
@@ -199,7 +199,7 @@ target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
-td = @td@
+tcpdump_path = @tcpdump_path@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 

File diff suppressed because it is too large
+ 388 - 180
aclocal.m4


File diff suppressed because it is too large
+ 929 - 515
configure


+ 103 - 26
configure.in

@@ -1,5 +1,5 @@
 
-dnl $Id: configure.in 1857 2007-05-02 05:07:52Z aturner $
+dnl $Id: configure.in 1886 2007-07-19 16:09:41Z aturner $
 
 AC_INIT(tcpreplay)
 AC_CONFIG_SRCDIR(src/tcpreplay.c)
@@ -10,7 +10,7 @@ AM_WITH_DMALLOC
 
 dnl Set version info here!
 MAJOR_VERSION=3
-MINOR_VERSION=0
+MINOR_VERSION=1
 MICRO_VERSION=1
 TCPREPLAY_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
 
@@ -151,6 +151,7 @@ dnl Checks for libraries.
 AC_CHECK_LIB(socket, socket)
 AC_CHECK_LIB(nsl, gethostbyname)
 AC_CHECK_LIB(rt, nanosleep)
+AC_CHECK_LIB(resolv, resolv)
 
 dnl Checks for library functions.
 AC_FUNC_MALLOC
@@ -211,17 +212,31 @@ AC_ARG_ENABLE(gprof,
       fi])
 
 dnl Use 64bits for packet counters
+use64bit_counters=no
 AC_ARG_ENABLE(64bits,
     AC_HELP_STRING([--enable-64bits], [Use 64bit packet counters]),
     [ if test x$enableval = xyes; then
          AC_DEFINE([ENABLE_64BITS], [1], [Use 64bit packet counters])
          AC_MSG_NOTICE([Using u_int64_t for packet counters])
+         use64bit_counters=yes
       else
          AC_MSG_NOTICE([Using u_int32_t for packet counters])
       fi
     ])
 
 
+# If we're running gcc add '-D_U_="__attribute__((unused))"' to CFLAGS as well,
+# so we can use _U_ to flag unused function arguments and not get warnings
+# about them. Otherwise, add '-D_U_=""', so that _U_ used to flag an unused
+# function argument will compile with non-GCC compilers.
+#
+if test "x$GCC" = "xyes" ; then
+    CFLAGS="-D_U_=\"__attribute__((unused))\" $CFLAGS"
+else
+    CFLAGS="-D_U_=\"\" $CFLAGS"
+fi
+
+
 AC_ARG_ENABLE(force-bpf,
 	AC_HELP_STRING([--enable-force-bpf], [Force using BPF for sending packets]),
 	[ AC_DEFINE([FORCE_INJECT_BPF], [1], [Force using BPF for sending packet])])
@@ -333,17 +348,17 @@ if test x$use_libnet = xyes ; then
         	LNETINC="${testdir}/include/libnet.h"
 	        LNETINCDIR="${testdir}/include"
 	        if test $dynamic_link = yes; then
-				if test -f "${testdir}/lib64/libnet.a" ; then
+				if test -f "${testdir}/lib64/libnet${shrext_cmds}" ; then
 		            LNETLIB="-L${testdir}/lib64 -lnet"
-				elif test -f "${testdir}/lib/libnet.a" ; then
+				elif test -f "${testdir}/lib/libnet${shrext_cmds}" ; then
 					LNETLIB="-L${testdir}/lib -lnet"
 				else
 					AC_ERROR([Unable to find libnet in ${testdir}])
 				fi
-	        elif test -f "${testdir}/lib64/libnet.a" ; then
-	            LNETLIB="${testdir}/lib64/libnet.a"
-	        elif test -f "${testdir}/lib/libnet.a" ; then
-	            LNETLIB="${testdir}/lib/libnet.a"
+	        elif test -f "${testdir}/lib64/libnet.${libext}" ; then
+	            LNETLIB="${testdir}/lib64/libnet.${libext}"
+	        elif test -f "${testdir}/lib/libnet.${libext}" ; then
+	            LNETLIB="${testdir}/lib/libnet.${libext}"
 		 	else
 				AC_ERROR([Unable to find matching library for header file in ${testdir}])
 			fi
@@ -458,19 +473,19 @@ AC_ARG_WITH(libpcap,
         	LPCAPINC="${testdir}/include/pcap.h"
 	        LPCAPINCDIR="${testdir}/include"
 	        if test $dynamic_link = yes; then
-				if test -f "${testdir}/lib64/libpcap.a" ; then
+				if test -f "${testdir}/lib64/libpcap${shrext_cmds}" ; then
 		            LPCAPLIB="-L${testdir}/lib64 -lpcap"
-				elif test -f "${testdir}/lib/libpcap.a" ; then
+				elif test -f "${testdir}/lib/libpcap${shrext_cmds}" ; then
 					LPCAPLIB="-L${testdir}/lib -lpcap"
 				else
 					AC_ERROR([Unable to find libpcap in ${testdir}])
 				fi
-	        elif test -f "${testdir}/lib64/libpcap.a" ; then
-	            LPCAPLIB="${testdir}/lib64/libpcap.a"
-	        elif test -f "${testdir}/lib/libpcap.a" ; then
-	            LPCAPLIB="${testdir}/lib/libpcap.a"
-	        elif test -f "${testdir}/lib/libwpcap.a" ; then
-	            LPCAPLIB="${testdir}/lib/libwpcap.a"
+	        elif test -f "${testdir}/lib64/libpcap.${libext}" ; then
+	            LPCAPLIB="${testdir}/lib64/libpcap.${libext}"
+	        elif test -f "${testdir}/lib/libpcap.${libext}" ; then
+	            LPCAPLIB="${testdir}/lib/libpcap.${libext}"
+	        elif test -f "${testdir}/lib/libwpcap.${libext}" ; then
+	            LPCAPLIB="${testdir}/lib/libwpcap.${libext}"
 				AC_DEFINE([HAVE_WINPCAP], [1], [Do we have WinPcap?])
 		 	else
 				AC_ERROR([Unable to find matching library for header file in ${testdir}])
@@ -501,6 +516,29 @@ dnl this code has been reduced a lot, but probably still could be
 dnl reduced quite a bit more if we chose too
 AC_MSG_CHECKING(for libpcap version)
 
+dnl 0.9.6 (which is still thinks it is 0.9.5 due to a bug) introduces an important
+dnl fix for OSX.  See: http://tcpreplay.synfin.net/trac/ticket/167
+libpcap_version_096=no
+AC_RUN_IFELSE(AC_LANG_PROGRAM([[
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "$LPCAPINC"
+#define PCAP_TEST "0.9.6"
+]], [[
+/* 
+ * simple proggy to test the version of libpcap
+ * returns zero if version >= 0.9.6
+ * or one otherwise
+ */
+    if (strncmp(pcap_lib_version(), PCAP_TEST, 5) >= 0)
+            exit(0);
+
+    exit(1);
+]]), [
+    libpcap_version_096=yes
+])
+
 AC_RUN_IFELSE(AC_LANG_PROGRAM([[
 #include <string.h>
 #include <stdlib.h>
@@ -560,6 +598,15 @@ else
     Please upgrade to version 0.7.2 or better])
 fi
 
+libpcap_version=unknown
+if test $libpcap_version_096 = yes ; then
+    libpcap_version=">= 0.9.6"
+elif test $libpcap_ver8 = yes ; then
+    libpcap_version=">= 0.8.0"
+elif test $libcap_ver7 = yes ; then
+    libpcap_version=">= 0.7.0"
+fi
+
 dnl Check to see if we've got pcap_datalink_val_to_name()
 AC_MSG_CHECKING(for pcap_datalink_val_to_description)
 AC_LINK_IFELSE(AC_LANG_PROGRAM([[
@@ -952,29 +999,29 @@ dnl ##################################################
 dnl # Check for tcpdump.
 dnl ##################################################
 
-td=no
+tcpdump_path=no
 AC_ARG_WITH(tcpdump,
     AC_HELP_STRING([--with-tcpdump=FILE], [Path to tcpdump binary]),
     [ if test -x $withval ; then
           td=$withval
-          AC_MSG_RESULT([Using tcpdump in $td])
+          AC_MSG_RESULT([Using tcpdump in $tcpdump_path])
       else
           AC_MSG_RESULT([Error: $withval does not exist or is not executable])
       fi ],
-    [ AC_PATH_PROG(td, tcpdump, "no", [$PATH:/usr/sbin:/sbin:/usr/local/sbin]) ])
+    [ AC_PATH_PROG(tcpdump_path, tcpdump, "no", [$PATH:/usr/sbin:/sbin:/usr/local/sbin]) ])
            
 
-if test "$td" = "no"; then
+if test "$tcpdump_path" = "no"; then
     AC_MSG_WARN([Unable to find tcpdump.  Please specify --with-tcpdump.
                  Disabling --verbose])
 else
     AC_DEFINE([HAVE_TCPDUMP], [1], [Do we have tcpdump?])
-    AC_DEFINE_UNQUOTED(TCPDUMP_BINARY, "$td", [The tcpdump binary initially used])
+    AC_DEFINE_UNQUOTED(TCPDUMP_BINARY, "$tcpdump_path", [The tcpdump binary initially used])
 fi
 
 
-AM_CONDITIONAL([ENABLE_TCPDUMP], test "$td" != "no" -a x$have_pcap_dump_fopen = xyes)
-if test x$td != xno -a x$have_pcap_dump_fopen = xyes ; then
+AM_CONDITIONAL([ENABLE_TCPDUMP], test "$tcpdump_path" != "no" -a x$have_pcap_dump_fopen = xyes)
+if test x$tcpdump_path != xno -a x$have_pcap_dump_fopen = xyes ; then
 	AC_DEFINE([ENABLE_VERBOSE], [1], [Do we have tcpdump and pcap_dump_fopen()?])
 else
 	AC_MSG_WARN([Your version of libpcap is too old for --verbose support])
@@ -1023,7 +1070,9 @@ case $host in
 	*-apple-darwin*)
 	nic1=en0
 	nic2=en0
-	disable_pcap_findalldevs=yes
+	if test x$libpcap_version_096 = xno ; then
+    	disable_pcap_findalldevs=yes
+    fi
 	AC_MSG_RESULT(Apple OS X)
 	;;
 
@@ -1067,6 +1116,7 @@ fi
 
 LIBOPTS_CHECK
 
+
 AC_OUTPUT([Makefile
            doxygen.cfg
            lib/Makefile
@@ -1081,12 +1131,39 @@ AC_OUTPUT([Makefile
            scripts/Makefile
            tcpreplay.spec])
 
+# Configuration results
+AC_MSG_RESULT(
+##########################################################################
+             TCPREPLAY Suite Configuration Results (${TCPREPLAY_VERSION})
+##########################################################################
+libpcap:                    ${foundpcap} (${libpcap_version})
+libnet:                     ${foundnet}
+autogen:                    ${AUTOGEN}
+64bit counter support:      ${use64bit_counters}
+tcpdump binary path:        ${tcpdump_path}
+tcpreplay edit support:     ${tcpreplay_edit}
+tcpbridge support:          ${enable_tcpbridge}
+
+Supported Packet Injection Methods (*):
+Linux PF_PACKET:            ${have_pf}
+BSD BPF:                    ${have_bpf}
+libnet:                     ${have_libnet}
+pcap_inject:                ${have_pcap_inject}
+pcap_sendpacket:            ${have_pcap_sendpacket}
+
+* In order of preference; see configure --help to override
+)
+
+
 case $host in
 	*-apple-darwin*)
-	AC_MSG_WARN([OS X <= 10.4.9 has a serious problem.  Please see: http://tcpreplay.synfin.net/trac/ticket/142])
+	AC_MSG_WARN([Apple OS X has a serious problem!
+	Please see: http://tcpreplay.synfin.net/trac/ticket/142 for more details])
 	;;
 	
 	*-*-cygwin)
-	AC_MSG_WARN([Windows/Cygwin support is still somewhat experimental.  Please report any bugs!])
+	AC_MSG_WARN([Windows/Cygwin support is still somewhat experimental.  Please report any bugs!
+	http://tcpreplay.synfin.net/trac/newticket])
 	;;
 esac
+

+ 21 - 1
docs/CHANGELOG

@@ -1,4 +1,24 @@
-$Id: CHANGELOG 1860 2007-05-02 05:18:08Z aturner $
+$Id: CHANGELOG 1886 2007-07-19 16:09:41Z aturner $
+
+07/19/2007: Version 3.1.1
+    - Upgrade libopts tearoff to 29:0:4 so that everyone else in the world can
+      compile tcpreplay (#189)
+
+07/18/2007: Version 3.1.0
+    - Add tcprewrite --srcmap & --dstmap for rewriting only source or destination IP's (#185)
+    - ./configure now reports configuration at end (#155)
+    - Fix svn:keywords (#160)
+    - Optimize performance of dlt_en10mb plugin (#161)
+    - Performance improvements on strictly aligned systems (#162)
+    - Improve tcpprep error messages and handling (#163)
+    - Add support for warnings in libtcpedit (#165)
+    - Only use __attribute__((unused)) w/ GCC (#168)
+    - Fix compile issues under Solaris (#178)
+    - Gracefully handle systems w/o static libraries (#179)
+    - Fix segfault when using BPF filters (#182)
+    - Add additional DLT Plugins:
+        - 802.11 (#103)
+        - 802.11 w/ Radiotap (#177)
 
 05/01/2007: Version 3.0.1
 	- Stop tcpreplay causing OS X WiFi from disassociating (#167)

+ 1 - 1
docs/Makefile.in

@@ -171,7 +171,7 @@ target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
-td = @td@
+tcpdump_path = @tcpdump_path@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 MAKEFLAGS = -s

+ 1 - 1
lib/Makefile.in

@@ -195,7 +195,7 @@ target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
-td = @td@
+tcpdump_path = @tcpdump_path@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 noinst_LIBRARIES = libstrl.a

+ 1 - 1
lib/tree.h

@@ -622,7 +622,7 @@ name##_RB_FIND(struct name *head, struct type *elm)			\
 }									\
 									\
 struct type *								\
-name##_RB_NEXT(struct name *head, struct type *elm)			\
+name##_RB_NEXT(_U_ struct name *head, struct type *elm)			\
 {									\
 	if (RB_RIGHT(elm, field)) {					\
 		elm = RB_RIGHT(elm, field);				\

+ 4 - 2
libopts/Makefile.am

@@ -7,7 +7,7 @@ noinst_LTLIBRARIES      = libopts.la
 endif
 libopts_la_SOURCES      = libopts.c
 libopts_la_CPPFLAGS     = -I$(top_srcdir)
-libopts_la_LDFLAGS      = -version-info  28:0:3
+libopts_la_LDFLAGS      = -version-info  29:0:4
 EXTRA_DIST              = \
     COPYING.lgpl            COPYING.mbsd            MakeDefs.inc  \
     README                  autoopts/options.h      autoopts/usage-txt.h  \
@@ -21,4 +21,6 @@ EXTRA_DIST              = \
     pgusage.c               proto.h                 putshell.c  \
     restore.c               save.c                  sort.c  \
     stack.c                 streqvcmp.c             text_mmap.c  \
-    tokenize.c              usage.c                 version.c
+    tokenize.c              usage.c                 version.c \
+    snprintf.c              strchr.c                pathfind.c \
+    windows-config.h        strdup.c                compat.h

+ 5 - 3
libopts/Makefile.in

@@ -203,7 +203,7 @@ target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
-td = @td@
+tcpdump_path = @tcpdump_path@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 MAINTAINERCLEANFILES = Makefile.in
@@ -211,7 +211,7 @@ MAINTAINERCLEANFILES = Makefile.in
 @INSTALL_LIBOPTS_FALSE@noinst_LTLIBRARIES = libopts.la
 libopts_la_SOURCES = libopts.c
 libopts_la_CPPFLAGS = -I$(top_srcdir)
-libopts_la_LDFLAGS = -version-info  28:0:3
+libopts_la_LDFLAGS = -version-info  29:0:4
 EXTRA_DIST = \
     COPYING.lgpl            COPYING.mbsd            MakeDefs.inc  \
     README                  autoopts/options.h      autoopts/usage-txt.h  \
@@ -225,7 +225,9 @@ EXTRA_DIST = \
     pgusage.c               proto.h                 putshell.c  \
     restore.c               save.c                  sort.c  \
     stack.c                 streqvcmp.c             text_mmap.c  \
-    tokenize.c              usage.c                 version.c
+    tokenize.c              usage.c                 version.c \
+    snprintf.c              strchr.c                pathfind.c \
+    windows-config.h        strdup.c                compat.h
 
 all: all-am
 

+ 1 - 1
libopts/README

@@ -85,7 +85,7 @@ will need to hand craft the rules for building the library.
 
 LICENSING:
 
-This material is copyright 1993-2006 by Bruce Korb.
+This material is copyright 1993-2007 by Bruce Korb.
 You are licensed to use this under the terms of either
 the GNU Lesser General Public License (see: COPYING.lgpl), or,
 at your option, the modified Berkeley Software Distribution

+ 29 - 10
libopts/autoopts.c

@@ -1,7 +1,7 @@
 
 /*
- *  $Id: autoopts.c,v 4.23 2007/02/13 19:43:46 bkorb Exp $
- *  Time-stamp:      "2007-02-13 11:26:59 bkorb"
+ *  $Id: autoopts.c,v 4.25 2007/04/15 19:01:18 bkorb Exp $
+ *  Time-stamp:      "2007-04-15 11:10:40 bkorb"
  *
  *  This file contains all of the routines that must be linked into
  *  an executable to use the generated option processing.  The optional
@@ -54,9 +54,6 @@
 
 static char const zNil[] = "";
 
-#define SKIP_RC_FILES(po) \
-    DISABLED_OPT(&((po)->pOptDesc[ (po)->specOptIdx.save_opts+1]))
-
 /* = = = START-STATIC-FORWARD = = = */
 /* static forward declarations maintained by :mkfwd */
 static tSuccess
@@ -697,7 +694,7 @@ nextOption( tOptions* pOpts, tOptState* pOptState )
         case TOPT_DEFAULT:
             fputs( "AutoOpts lib error: defaulted to option with optional arg\n",
                    stderr );
-            exit( EXIT_FAILURE );
+            exit( EX_SOFTWARE );
         }
 
         /*
@@ -830,10 +827,23 @@ doRegularOpts( tOptions* pOpts )
 static tSuccess
 doPresets( tOptions* pOpts )
 {
+    tOptDesc * pOD = NULL;
+
     if (! SUCCESSFUL( doImmediateOpts( pOpts )))
         return FAILURE;
 
     /*
+     *  IF this option set has a --save-opts option, then it also
+     *  has a --load-opts option.  See if a command line option has disabled
+     *  option presetting.
+     */
+    if (pOpts->specOptIdx.save_opts != 0) {
+        pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
+        if (DISABLED_OPT(pOD))
+            return SUCCESS;
+    }
+
+    /*
      *  Until we return from this procedure, disable non-presettable opts
      */
     pOpts->fOptSet |= OPTPROC_PRESETTING;
@@ -841,13 +851,22 @@ doPresets( tOptions* pOpts )
      *  IF there are no config files,
      *  THEN do any environment presets and leave.
      */
-    if (  (pOpts->papzHomeList == NULL)
-       || SKIP_RC_FILES(pOpts) )  {
+    if (pOpts->papzHomeList == NULL) {
         doEnvPresets( pOpts, ENV_ALL );
     }
     else {
         doEnvPresets( pOpts, ENV_IMM );
-        internalFileLoad( pOpts );
+
+        /*
+         *  Check to see if environment variables have disabled presetting.
+         */
+        if ((pOD != NULL) && ! DISABLED_OPT(pOD))
+            internalFileLoad( pOpts );
+
+        /*
+         *  ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
+         *  variable options.  Only the loading of .rc files.
+         */
         doEnvPresets( pOpts, ENV_NON_IMM );
     }
     pOpts->fOptSet &= ~OPTPROC_PRESETTING;
@@ -1031,7 +1050,7 @@ optionProcess(
     char**     argVect )
 {
     if (! SUCCESSFUL( validateOptionsStruct( pOpts, argVect[0] )))
-        exit( EXIT_FAILURE );
+        exit( EX_SOFTWARE );
 
     /*
      *  Establish the real program name, the program full path,

+ 43 - 33
libopts/autoopts.h

@@ -1,8 +1,8 @@
 
 /*
- *  Time-stamp:      "2007-01-17 16:37:34 bkorb"
+ *  Time-stamp:      "2007-04-15 09:59:39 bkorb"
  *
- *  autoopts.h  $Id: autoopts.h,v 4.22 2007/02/04 17:44:12 bkorb Exp $
+ *  autoopts.h  $Id: autoopts.h,v 4.23 2007/04/15 19:01:18 bkorb Exp $
  *  Time-stamp:      "2005-02-14 05:59:50 bkorb"
  *
  *  This file defines all the global structures and special values
@@ -57,19 +57,19 @@
 
 #include "compat/compat.h"
 
-#define AO_NAME_LIMIT    127
-#define AO_NAME_SIZE     ((size_t)(AO_NAME_LIMIT + 1))
+#define AO_NAME_LIMIT           127
+#define AO_NAME_SIZE            ((size_t)(AO_NAME_LIMIT + 1))
 
 #ifndef AG_PATH_MAX
 #  ifdef PATH_MAX
-#    define AG_PATH_MAX   ((size_t)PATH_MAX)
+#    define AG_PATH_MAX         ((size_t)PATH_MAX)
 #  else
-#    define AG_PATH_MAX   ((size_t)4096)
+#    define AG_PATH_MAX         ((size_t)4096)
 #  endif
 #else
 #  if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN)
 #     undef  AG_PATH_MAX
-#     define AG_PATH_MAX  ((size_t)PATH_MAX)
+#     define AG_PATH_MAX        ((size_t)PATH_MAX)
 #  endif
 #endif
 
@@ -77,15 +77,25 @@
 #define EXPORT
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-# define DIRCH '\\'
+# define DIRCH                  '\\'
 #else
-# define DIRCH '/'
+# define DIRCH                  '/'
+#endif
+
+#ifndef EX_NOINPUT
+#  define EX_NOINPUT            66
+#endif
+#ifndef EX_SOFTWARE
+#  define EX_SOFTWARE           70
+#endif
+#ifndef EX_CONFIG
+#  define EX_CONFIG             78
 #endif
 
 /*
  *  Convert the number to a list usable in a printf call
  */
-#define NUM_TO_VER(n)       ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F
+#define NUM_TO_VER(n)           ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F
 
 #define NAMED_OPTS(po) \
         (((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0)
@@ -93,14 +103,14 @@
 #define SKIP_OPT(p)  (((p)->fOptState & (OPTST_DOCUMENT|OPTST_OMITTED)) != 0)
 
 typedef int tDirection;
-#define DIRECTION_PRESET  -1
-#define DIRECTION_PROCESS  1
-#define DIRECTION_CALLED   0
+#define DIRECTION_PRESET        -1
+#define DIRECTION_PROCESS       1
+#define DIRECTION_CALLED        0
 
-#define PROCESSING(d)     ((d)>0)
-#define PRESETTING(d)     ((d)<0)
+#define PROCESSING(d)           ((d)>0)
+#define PRESETTING(d)           ((d)<0)
 
-#define ISNAMECHAR( c )    (isalnum(c) || ((c) == '_') || ((c) == '-'))
+#define ISNAMECHAR( c )         (isalnum(c) || ((c) == '_') || ((c) == '-'))
 
 /*
  *  Procedure success codes
@@ -119,16 +129,16 @@ typedef int tDirection;
 #undef  FAILED
 #undef  HADGLITCH
 
-#define SUCCESS  ((tSuccess) 0)
-#define FAILURE  ((tSuccess)-1)
-#define PROBLEM  ((tSuccess) 1)
+#define SUCCESS                 ((tSuccess) 0)
+#define FAILURE                 ((tSuccess)-1)
+#define PROBLEM                 ((tSuccess) 1)
 
 typedef int tSuccess;
 
-#define SUCCEEDED( p )     ((p) == SUCCESS)
-#define SUCCESSFUL( p )    SUCCEEDED( p )
-#define FAILED( p )        ((p) <  SUCCESS)
-#define HADGLITCH( p )     ((p) >  SUCCESS)
+#define SUCCEEDED( p )          ((p) == SUCCESS)
+#define SUCCESSFUL( p )         SUCCEEDED( p )
+#define FAILED( p )             ((p) <  SUCCESS)
+#define HADGLITCH( p )          ((p) >  SUCCESS)
 
 /*
  *  When loading a line (or block) of text as an option, the value can
@@ -224,10 +234,10 @@ typedef struct {
     tCC*    pzOptFmt;
 } arg_types_t;
 
-#define AGALOC( c, w )        ao_malloc((size_t)c)
-#define AGREALOC( p, c, w )   ao_realloc((void*)p, (size_t)c)
-#define AGFREE( p )           ao_free((void*)p)
-#define AGDUPSTR( p, s, w )   (p = ao_strdup(s))
+#define AGALOC( c, w )          ao_malloc((size_t)c)
+#define AGREALOC( p, c, w )     ao_realloc((void*)p, (size_t)c)
+#define AGFREE( p )             ao_free((void*)p)
+#define AGDUPSTR( p, s, w )     (p = ao_strdup(s))
 
 static void *
 ao_malloc( size_t sz );
@@ -324,26 +334,26 @@ ao_strdup( char const *str );
 #  include <sys/mman.h>
 #else
 #  ifndef  PROT_READ
-#   define PROT_READ    0x01
+#   define PROT_READ            0x01
 #  endif
 #  ifndef  PROT_WRITE
-#   define PROT_WRITE   0x02
+#   define PROT_WRITE           0x02
 #  endif
 #  ifndef  MAP_SHARED
-#   define MAP_SHARED   0x01
+#   define MAP_SHARED           0x01
 #  endif
 #  ifndef  MAP_PRIVATE
-#   define MAP_PRIVATE  0x02
+#   define MAP_PRIVATE          0x02
 #  endif
 #endif
 
 #ifndef MAP_FAILED
-#  define  MAP_FAILED   ((void*)-1)
+#  define  MAP_FAILED           ((void*)-1)
 #endif
 
 #ifndef  _SC_PAGESIZE
 # ifdef  _SC_PAGE_SIZE
-#  define _SC_PAGESIZE _SC_PAGE_SIZE
+#  define _SC_PAGESIZE          _SC_PAGE_SIZE
 # endif
 #endif
 

+ 60 - 47
libopts/autoopts/options.h

@@ -2,7 +2,7 @@
  *  
  *  DO NOT EDIT THIS FILE   (options.h)
  *  
- *  It has been AutoGen-ed  Saturday February 17, 2007 at 12:49:35 PM PST
+ *  It has been AutoGen-ed  Saturday May  5, 2007 at 12:02:34 PM PDT
  *  From the definitions    funcs.def
  *  and the template file   options_h
  *
@@ -43,6 +43,14 @@
 # include <sys/limits.h>
 #endif /* HAVE_LIMITS/SYS_LIMITS_H */
 
+#if defined(HAVE_SYSEXITS_H)
+#  include <sysexits.h>
+#endif /* HAVE_SYSEXITS_H */
+
+#ifndef EX_USAGE
+#  define EX_USAGE              64
+#endif
+
 /*
  *  PUBLIC DEFINES
  *
@@ -60,8 +68,8 @@
  *  values for "opt_name" are available.
  */
 
-#define  OPTIONS_STRUCT_VERSION  114688
-#define  OPTIONS_VERSION_STRING  "28:0:3"
+#define  OPTIONS_STRUCT_VERSION  118784
+#define  OPTIONS_VERSION_STRING  "29:0:4"
 #define  OPTIONS_MINIMUM_VERSION 102400
 #define  OPTIONS_MIN_VER_STRING  "25:0:0"
 
@@ -92,28 +100,28 @@ typedef struct optionValue {
  *  Bits in the fOptState option descriptor field.
  */
 typedef enum {
-        OPTST_SET_ID             =   0, /* Set via the "SET_OPT()" macro */
-        OPTST_PRESET_ID          =   1, /* Set via an RC/INI file        */
-        OPTST_DEFINED_ID         =   2, /* Set via a command line option */
-        OPTST_EQUIVALENCE_ID     =   4, /* selected by equiv'ed option   */
-        OPTST_DISABLED_ID        =   5, /* option is in disabled state   */
-        OPTST_ALLOC_ARG_ID       =   6, /* pzOptArg was allocated        */
-        OPTST_NO_INIT_ID         =   8, /* option cannot be preset       */
-        OPTST_NUMBER_OPT_ID      =   9, /* opt value (flag) is any digit */
-        OPTST_STACKED_ID         =  10, /* opt uses optionStackArg proc  */
-        OPTST_INITENABLED_ID     =  11, /* option defaults to enabled    */
-        OPTST_ARG_TYPE_1_ID      =  12, /* bit 1 of arg type enum        */
-        OPTST_ARG_TYPE_2_ID      =  13, /* bit 2 of arg type enum        */
-        OPTST_ARG_TYPE_3_ID      =  14, /* bit 3 of arg type enum        */
-        OPTST_ARG_TYPE_4_ID      =  15, /* bit 4 of arg type enum        */
-        OPTST_ARG_OPTIONAL_ID    =  16, /* the option arg not required   */
-        OPTST_IMM_ID             =  17, /* process opt on first pass     */
-        OPTST_DISABLE_IMM_ID     =  18, /* process disablement immed.    */
-        OPTST_OMITTED_ID         =  19, /* compiled out of program       */
-        OPTST_MUST_SET_ID        =  20, /* must be set or pre-set        */
-        OPTST_DOCUMENT_ID        =  21, /* opt is for doc only           */
-        OPTST_TWICE_ID           =  22, /* process opt twice - imm + reg */
-        OPTST_DISABLE_TWICE_ID   =  23  /* process disabled option twice */
+    OPTST_SET_ID             =   0, /* Set via the "SET_OPT()" macro */
+    OPTST_PRESET_ID          =   1, /* Set via an RC/INI file        */
+    OPTST_DEFINED_ID         =   2, /* Set via a command line option */
+    OPTST_EQUIVALENCE_ID     =   4, /* selected by equiv'ed option   */
+    OPTST_DISABLED_ID        =   5, /* option is in disabled state   */
+    OPTST_ALLOC_ARG_ID       =   6, /* pzOptArg was allocated        */
+    OPTST_NO_INIT_ID         =   8, /* option cannot be preset       */
+    OPTST_NUMBER_OPT_ID      =   9, /* opt value (flag) is any digit */
+    OPTST_STACKED_ID         =  10, /* opt uses optionStackArg proc  */
+    OPTST_INITENABLED_ID     =  11, /* option defaults to enabled    */
+    OPTST_ARG_TYPE_1_ID      =  12, /* bit 1 of arg type enum        */
+    OPTST_ARG_TYPE_2_ID      =  13, /* bit 2 of arg type enum        */
+    OPTST_ARG_TYPE_3_ID      =  14, /* bit 3 of arg type enum        */
+    OPTST_ARG_TYPE_4_ID      =  15, /* bit 4 of arg type enum        */
+    OPTST_ARG_OPTIONAL_ID    =  16, /* the option arg not required   */
+    OPTST_IMM_ID             =  17, /* process opt on first pass     */
+    OPTST_DISABLE_IMM_ID     =  18, /* process disablement immed.    */
+    OPTST_OMITTED_ID         =  19, /* compiled out of program       */
+    OPTST_MUST_SET_ID        =  20, /* must be set or pre-set        */
+    OPTST_DOCUMENT_ID        =  21, /* opt is for doc only           */
+    OPTST_TWICE_ID           =  22, /* process opt twice - imm + reg */
+    OPTST_DISABLE_TWICE_ID   =  23  /* process disabled option twice */
 } opt_state_enum_t;
 
 #define OPTST_INIT           0U
@@ -164,6 +172,11 @@ typedef enum {
         OPTST_ARG_TYPE_3 | \
         OPTST_ARG_TYPE_4 )
 
+#ifdef NO_OPTIONAL_OPT_ARGS
+# undef  OPTST_ARG_OPTIONAL
+# define OPTST_ARG_OPTIONAL   0
+#endif
+
 #define OPTST_PERSISTENT_MASK (~OPTST_MUTABLE_MASK)
 
 #define SELECTED_OPT( pod )   ((pod)->fOptState  & OPTST_SELECTED_MASK)
@@ -186,22 +199,22 @@ typedef enum {
  *  Define the processing state flags
  */
 typedef enum {
-        OPTPROC_LONGOPT_ID       =   0, /* Process long style options      */
-        OPTPROC_SHORTOPT_ID      =   1, /* Process short style "flags"     */
-        OPTPROC_ERRSTOP_ID       =   2, /* Stop on argument errors         */
-        OPTPROC_DISABLEDOPT_ID   =   3, /* Current option is disabled      */
-        OPTPROC_NO_REQ_OPT_ID    =   4, /* no options are required         */
-        OPTPROC_NUM_OPT_ID       =   5, /* there is a number option        */
-        OPTPROC_INITDONE_ID      =   6, /* have initializations been done? */
-        OPTPROC_NEGATIONS_ID     =   7, /* any negation options?           */
-        OPTPROC_ENVIRON_ID       =   8, /* check environment?              */
-        OPTPROC_NO_ARGS_ID       =   9, /* Disallow remaining arguments    */
-        OPTPROC_ARGS_REQ_ID      =  10, /* Require arguments after options */
-        OPTPROC_REORDER_ID       =  11, /* reorder operands after options  */
-        OPTPROC_GNUUSAGE_ID      =  12, /* emit usage in GNU style         */
-        OPTPROC_TRANSLATE_ID     =  13, /* Translate strings in tOptions   */
-        OPTPROC_HAS_IMMED_ID     =  14, /* program defines immed options   */
-        OPTPROC_PRESETTING_ID    =  19  /* opt processing in preset state  */
+    OPTPROC_LONGOPT_ID       =   0, /* Process long style options      */
+    OPTPROC_SHORTOPT_ID      =   1, /* Process short style "flags"     */
+    OPTPROC_ERRSTOP_ID       =   2, /* Stop on argument errors         */
+    OPTPROC_DISABLEDOPT_ID   =   3, /* Current option is disabled      */
+    OPTPROC_NO_REQ_OPT_ID    =   4, /* no options are required         */
+    OPTPROC_NUM_OPT_ID       =   5, /* there is a number option        */
+    OPTPROC_INITDONE_ID      =   6, /* have initializations been done? */
+    OPTPROC_NEGATIONS_ID     =   7, /* any negation options?           */
+    OPTPROC_ENVIRON_ID       =   8, /* check environment?              */
+    OPTPROC_NO_ARGS_ID       =   9, /* Disallow remaining arguments    */
+    OPTPROC_ARGS_REQ_ID      =  10, /* Require arguments after options */
+    OPTPROC_REORDER_ID       =  11, /* reorder operands after options  */
+    OPTPROC_GNUUSAGE_ID      =  12, /* emit usage in GNU style         */
+    OPTPROC_TRANSLATE_ID     =  13, /* Translate strings in tOptions   */
+    OPTPROC_HAS_IMMED_ID     =  14, /* program defines immed options   */
+    OPTPROC_PRESETTING_ID    =  19  /* opt processing in preset state  */
 } optproc_state_enum_t;
 
 #define OPTPROC_NONE         0U
@@ -350,7 +363,7 @@ struct optSpecIndex {
 typedef void (tOptionXlateProc)(void);
 
 struct options {
-    const int           structVersion;
+    int const           structVersion;
     int                 origArgCt;
     char**              origArgVect;
     unsigned int        fOptSet;
@@ -364,7 +377,7 @@ struct options {
     char const* const   pzCopyright;
     char const* const   pzCopyNotice;
     char const* const   pzFullVersion;
-    char const* const*  papzHomeList;
+    char const* const* const papzHomeList;
     char const* const   pzUsageTitle;
     char const* const   pzExplain;
     char const* const   pzDetail;
@@ -378,8 +391,8 @@ struct options {
     tOptionXlateProc*   pTransProc;
 
     tOptSpecIndex       specOptIdx;
-    const int           optCt;
-    const int           presetOptCt;
+    int const           optCt;
+    int const           presetOptCt;
 };
 
 /*
@@ -498,7 +511,7 @@ extern token_list_t* ao_string_tokenize( char const* );
 extern const tOptionValue* configFileLoad( char const* );
 
 
-/* From: configfile.c line 880
+/* From: configfile.c line 883
  *
  * optionFileLoad - Load the locatable config files, in order
  *
@@ -653,7 +666,7 @@ extern const tOptionValue* optionNextValue( const tOptionValue*, const tOptionVa
 extern void optionOnlyUsage( tOptions*, int );
 
 
-/* From: autoopts.c line 993
+/* From: autoopts.c line 1012
  *
  * optionProcess - this is the main option processing routine
  *

+ 1 - 1
libopts/autoopts/usage-txt.h

@@ -2,7 +2,7 @@
  *  
  *  DO NOT EDIT THIS FILE   (usage-txt.h)
  *  
- *  It has been AutoGen-ed  Saturday February 17, 2007 at 12:49:33 PM PST
+ *  It has been AutoGen-ed  Saturday May  5, 2007 at 12:02:33 PM PDT
  *  From the definitions    usage-txt.def
  *  and the template file   usage-txt.tpl
  *

+ 319 - 0
libopts/compat.h

@@ -0,0 +1,319 @@
+/*  -*- Mode: C -*-  */
+
+/* --- fake the preprocessor into handlng portability */
+/*
+ *  Time-stamp:      "2007-02-03 17:41:06 bkorb"
+ *
+ * Author:           Gary V Vaughan <gvaughan@oranda.demon.co.uk>
+ * Created:          Mon Jun 30 15:54:46 1997
+ *
+ * $Id: compat.h,v 4.16 2007/04/27 01:10:47 bkorb Exp $
+ */
+#ifndef COMPAT_H_GUARD
+#define COMPAT_H_GUARD 1
+
+#if defined(HAVE_CONFIG_H)
+#  include <config.h>
+
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+#  include "windows-config.h"
+
+#else
+#  error "compat.h" requires "config.h"
+   choke me.
+#endif
+
+
+#ifndef HAVE_STRSIGNAL
+   char * strsignal( int signo );
+#endif
+
+#define  _GNU_SOURCE    1 /* for strsignal in GNU's libc */
+#define  __USE_GNU      1 /* exact same thing as above   */
+#define  __EXTENSIONS__ 1 /* and another way to call for it */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ *  SYSTEM HEADERS:
+ */
+#include <sys/types.h>
+#ifdef HAVE_SYS_MMAN_H
+#  include <sys/mman.h>
+#endif
+#include <sys/param.h>
+#if HAVE_SYS_PROCSET_H
+#  include <sys/procset.h>
+#endif
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#if defined( HAVE_SOLARIS_SYSINFO )
+#  include <sys/systeminfo.h>
+#elif defined( HAVE_UNAME_SYSCALL )
+#  include <sys/utsname.h>
+#endif
+
+#ifdef DAEMON_ENABLED
+#  if HAVE_SYS_STROPTS_H
+#  include <sys/stropts.h>
+#  endif
+
+#  if HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#  endif
+
+#  if ! defined(HAVE_SYS_POLL_H) && ! defined(HAVE_SYS_SELECT_H)
+#    error This system cannot support daemon processing
+     Choke Me.
+#  endif
+
+#  if HAVE_SYS_POLL_H
+#  include <sys/poll.h>
+#  endif
+
+#  if HAVE_SYS_SELECT_H
+#  include <sys/select.h>
+#  endif
+
+#  if HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#  endif
+
+#  if HAVE_SYS_UN_H
+#  include <sys/un.h>
+#  endif
+#endif
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ *  USER HEADERS:
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+
+/*
+ *  Directory opening stuff:
+ */
+# if defined (_POSIX_SOURCE)
+/* Posix does not require that the d_ino field be present, and some
+   systems do not provide it. */
+#    define REAL_DIR_ENTRY(dp) 1
+# else /* !_POSIX_SOURCE */
+#    define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
+# endif /* !_POSIX_SOURCE */
+
+# if defined (HAVE_DIRENT_H)
+#   include <dirent.h>
+#   define D_NAMLEN(dirent) strlen((dirent)->d_name)
+# else /* !HAVE_DIRENT_H */
+#   define dirent direct
+#   define D_NAMLEN(dirent) (dirent)->d_namlen
+#   if defined (HAVE_SYS_NDIR_H)
+#     include <sys/ndir.h>
+#   endif /* HAVE_SYS_NDIR_H */
+#   if defined (HAVE_SYS_DIR_H)
+#     include <sys/dir.h>
+#   endif /* HAVE_SYS_DIR_H */
+#   if defined (HAVE_NDIR_H)
+#     include <ndir.h>
+#   endif /* HAVE_NDIR_H */
+# endif /* !HAVE_DIRENT_H */
+
+#include <errno.h>
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifndef O_NONBLOCK
+# define O_NONBLOCK FNDELAY
+#endif
+
+#if defined(HAVE_LIBGEN) && defined(HAVE_LIBGEN_H)
+#  include <libgen.h>
+#endif
+
+#if defined(HAVE_LIMITS_H)  /* this is also in options.h */
+#  include <limits.h>
+#elif defined(HAVE_SYS_LIMITS_H)
+#  include <sys/limits.h>
+#endif /* HAVE_LIMITS/SYS_LIMITS_H */
+
+#include <memory.h>
+#include <setjmp.h>
+#include <signal.h>
+
+#if defined( HAVE_STDINT_H )
+#  include <stdint.h>
+#elif defined( HAVE_INTTYPES_H )
+#  include <inttypes.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <time.h>
+
+#ifdef HAVE_UTIME_H
+#  include <utime.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ *  FIXUPS and CONVIENCE STUFF:
+ */
+#ifdef __cplusplus
+#   define EXTERN extern "C"
+#else
+#   define EXTERN extern
+#endif
+
+/* some systems #def errno! and others do not declare it!! */
+#ifndef errno
+   extern int errno;
+#endif
+
+/* Some machines forget this! */
+
+# ifndef EXIT_FAILURE
+#   define EXIT_SUCCESS 0
+#   define EXIT_FAILURE 1
+# endif
+
+#ifndef NUL
+#  define NUL '\0'
+#endif
+
+#ifndef NULL
+#  define NULL 0
+#endif
+
+#if !defined (MAXPATHLEN) && defined (HAVE_SYS_PARAM_H)
+#  include <sys/param.h>
+#endif /* !MAXPATHLEN && HAVE_SYS_PARAM_H */
+
+#if !defined (MAXPATHLEN) && defined (PATH_MAX)
+#  define MAXPATHLEN PATH_MAX
+#endif /* !MAXPATHLEN && PATH_MAX */
+
+#if !defined (MAXPATHLEN) && defined(_MAX_PATH)
+#  define PATH_MAX _MAX_PATH
+#  define MAXPATHLEN _MAX_PATH
+#endif
+
+#if !defined (MAXPATHLEN)
+#  define MAXPATHLEN ((size_t)4096)
+#endif /* MAXPATHLEN */
+
+#define AG_PATH_MAX  ((size_t)MAXPATHLEN)
+
+#ifndef LONG_MAX
+#  define LONG_MAX      ~(1L << (8*sizeof(long) -1))
+#  define INT_MAX       ~(1 << (8*sizeof(int) -1))
+#endif
+
+#ifndef ULONG_MAX
+#  define ULONG_MAX     ~(OUL)
+#  define UINT_MAX      ~(OU)
+#endif
+
+#ifndef SHORT_MAX
+#  define SHORT_MAX     ~(1 << (8*sizeof(short) -1))
+#else
+#  define USHORT_MAX    ~(OUS)
+#endif
+
+#ifndef HAVE_INT8_T
+  typedef signed char       int8_t;
+#endif
+#ifndef HAVE_UINT8_T
+  typedef unsigned char     uint8_t;
+#endif
+#ifndef HAVE_INT16_T
+  typedef signed short      int16_t;
+#endif
+#ifndef HAVE_UINT16_T
+  typedef unsigned short    uint16_t;
+#endif
+#ifndef HAVE_UINT_T
+  typedef unsigned int      uint_t;
+#endif
+
+#ifndef HAVE_INT32_T
+# if SIZEOF_INT == 4
+        typedef signed int      int32_t;
+# elif SIZEOF_LONG == 4
+        typedef signed long     int32_t;
+# endif
+#endif
+
+#ifndef HAVE_UINT32_T
+# if SIZEOF_INT == 4
+        typedef unsigned int    uint32_t;
+# elif SIZEOF_LONG == 4
+        typedef unsigned long   uint32_t;
+# else
+#   error Cannot create a uint32_t type.
+    Choke Me.
+# endif
+#endif
+
+#ifndef HAVE_INTPTR_T
+  typedef signed long   intptr_t;
+#endif
+#ifndef HAVE_UINTPTR_T
+  typedef unsigned long uintptr_t;
+#endif
+
+/* redefine these for BSD style string libraries */
+#ifndef HAVE_STRCHR
+#  define strchr        index
+#  define strrchr       rindex
+#endif
+
+#ifdef USE_FOPEN_BINARY
+#  ifndef FOPEN_BINARY_FLAG
+#    define FOPEN_BINARY_FLAG   "b"
+#  endif
+#  ifndef FOPEN_TEXT_FLAG
+#    define FOPEN_TEXT_FLAG     "t"
+#  endif
+#else
+#  ifndef FOPEN_BINARY_FLAG
+#    define FOPEN_BINARY_FLAG
+#  endif
+#  ifndef FOPEN_TEXT_FLAG
+#    define FOPEN_TEXT_FLAG
+#  endif
+#endif
+
+#ifndef STR
+#  define _STR(s) #s
+#  define STR(s)  _STR(s)
+#endif
+
+/* ##### Pointer sized word ##### */
+
+/* FIXME:  the MAX stuff in here is broken! */
+#if SIZEOF_CHARP > SIZEOF_INT
+   typedef long t_word;
+   #define WORD_MAX  LONG_MAX
+   #define WORD_MIN  LONG_MIN
+#else /* SIZEOF_CHARP <= SIZEOF_INT */
+   typedef int t_word;
+   #define WORD_MAX  INT_MAX
+   #define WORD_MIN  INT_MIN
+#endif
+
+#endif /* COMPAT_H_GUARD */
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of compat/compat.h */

+ 16 - 14
libopts/configfile.c

@@ -1,6 +1,6 @@
 /*
- *  $Id: configfile.c,v 1.20 2007/02/04 17:44:12 bkorb Exp $
- *  Time-stamp:      "2007-01-13 12:49:10 bkorb"
+ *  $Id: configfile.c,v 1.21 2007/04/15 19:01:18 bkorb Exp $
+ *  Time-stamp:      "2007-04-15 11:22:46 bkorb"
  *
  *  configuration/rc/ini file handling.
  */
@@ -869,11 +869,14 @@ internalFileLoad( tOptions* pOpts )
          *  IF we are now to skip config files AND we are presetting,
          *  THEN change direction.  We must go the other way.
          */
-        if (SKIP_RC_FILES(pOpts) && PRESETTING(inc)) {
-            idx -= inc;  /* go back and reprocess current file */
-            inc =  DIRECTION_PROCESS;
+        {
+            tOptDesc * pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts+1;
+            if (DISABLED_OPT(pOD) && PRESETTING(inc)) {
+                idx -= inc;  /* go back and reprocess current file */
+                inc =  DIRECTION_PROCESS;
+            }
         }
-    } /* For every path in the home list, ... */
+    } /* twice for every path in the home list, ... */
 }
 
 
@@ -937,11 +940,10 @@ void
 optionLoadOpt( tOptions* pOpts, tOptDesc* pOptDesc )
 {
     /*
-     *  IF the option is not being disabled,
-     *  THEN load the file.  There must be a file.
-     *  (If it is being disabled, then the disablement processing
-     *  already took place.  It must be done to suppress preloading
-     *  of ini/rc files.)
+     *  IF the option is not being disabled, THEN load the file.  There must
+     *  be a file.  (If it is being disabled, then the disablement processing
+     *  already took place.  It must be done to suppress preloading of ini/rc
+     *  files.)
      */
     if (! DISABLED_OPT( pOptDesc )) {
         struct stat sb;
@@ -951,7 +953,7 @@ optionLoadOpt( tOptions* pOpts, tOptDesc* pOptDesc )
 
             fprintf( stderr, zFSErrOptLoad, errno, strerror( errno ),
                      pOptDesc->optArg.argString );
-            (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE );
+            exit(EX_NOINPUT);
             /* NOT REACHED */
         }
 
@@ -960,7 +962,7 @@ optionLoadOpt( tOptions* pOpts, tOptDesc* pOptDesc )
                 return;
 
             fprintf( stderr, zNotFile, pOptDesc->optArg.argString );
-            (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE );
+            exit(EX_NOINPUT);
             /* NOT REACHED */
         }
 
@@ -1223,7 +1225,7 @@ validateOptionsStruct( tOptions* pOpts, char const* pzProgram )
 {
     if (pOpts == NULL) {
         fputs( zAO_Bad, stderr );
-        exit( EXIT_FAILURE );
+        exit( EX_CONFIG );
     }
 
     /*

+ 74 - 55
libopts/environment.c

@@ -1,7 +1,7 @@
 
 /*
- *  $Id: environment.c,v 4.12 2007/02/04 17:44:12 bkorb Exp $
- * Time-stamp:      "2007-01-13 10:02:07 bkorb"
+ *  $Id: environment.c,v 4.13 2007/04/15 19:01:18 bkorb Exp $
+ * Time-stamp:      "2007-04-15 11:50:35 bkorb"
  *
  *  This file contains all of the routines that must be linked into
  *  an executable to use the generated option processing.  The optional
@@ -54,6 +54,9 @@
 
 /* = = = START-STATIC-FORWARD = = = */
 /* static forward declarations maintained by :mkfwd */
+static void
+checkEnvOpt(tOptState * os, char * env_name,
+            tOptions* pOpts, teEnvPresetType type);
 /* = = = END-STATIC-FORWARD = = = */
 
 /*
@@ -145,6 +148,66 @@ doPrognameEnv( tOptions* pOpts, teEnvPresetType type )
     pOpts->fOptSet     = sv_flag;
 }
 
+static void
+checkEnvOpt(tOptState * os, char * env_name,
+            tOptions* pOpts, teEnvPresetType type)
+{
+    os->pzOptArg = getenv( env_name );
+    if (os->pzOptArg == NULL)
+        return;
+
+    os->flags    = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState;
+    os->optType  = TOPT_UNDEFINED;
+
+    if (  (os->pOD->pz_DisablePfx != NULL)
+       && (streqvcmp( os->pzOptArg, os->pOD->pz_DisablePfx ) == 0)) {
+        os->flags |= OPTST_DISABLED;
+        os->pzOptArg = NULL;
+    }
+
+    switch (type) {
+    case ENV_IMM:
+        /*
+         *  Process only immediate actions
+         */
+        if (DO_IMMEDIATELY(os->flags))
+            break;
+        return;
+
+    case ENV_NON_IMM:
+        /*
+         *  Process only NON immediate actions
+         */
+        if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags))
+            break;
+        return;
+
+    default: /* process everything */
+        break;
+    }
+
+    /*
+     *  Make sure the option value string is persistent and consistent.
+     *
+     *  The interpretation of the option value depends
+     *  on the type of value argument the option takes
+     */
+    if (os->pzOptArg != NULL) {
+        if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
+            os->pzOptArg = NULL;
+        } else if (  (os->pOD->fOptState & OPTST_ARG_OPTIONAL)
+                     && (*os->pzOptArg == NUL)) {
+            os->pzOptArg = NULL;
+        } else if (*os->pzOptArg == NUL) {
+            os->pzOptArg = zNil;
+        } else {
+            AGDUPSTR( os->pzOptArg, os->pzOptArg, "option argument" );
+            os->flags |= OPTST_ALLOC_ARG;
+        }
+    }
+
+    handleOption( pOpts, os );
+}
 
 /*
  *  doEnvPresets - check for preset values from the envrionment
@@ -194,60 +257,16 @@ doEnvPresets( tOptions* pOpts, teEnvPresetType type )
          *  Set up the option state
          */
         strcpy( pzFlagName, st.pOD->pz_NAME );
-        st.pzOptArg = getenv( zEnvName );
-        if (st.pzOptArg == NULL)
-            continue;
-        st.flags    = OPTST_PRESET | OPTST_ALLOC_ARG | st.pOD->fOptState;
-        st.optType  = TOPT_UNDEFINED;
-
-        if (  (st.pOD->pz_DisablePfx != NULL)
-           && (streqvcmp( st.pzOptArg, st.pOD->pz_DisablePfx ) == 0)) {
-            st.flags |= OPTST_DISABLED;
-            st.pzOptArg = NULL;
-        }
-
-        switch (type) {
-        case ENV_IMM:
-            /*
-             *  Process only immediate actions
-             */
-            if (DO_IMMEDIATELY(st.flags))
-                break;
-            continue;
-
-        case ENV_NON_IMM:
-            /*
-             *  Process only NON immediate actions
-             */
-            if (DO_NORMALLY(st.flags) || DO_SECOND_TIME(st.flags))
-                break;
-            continue;
-
-        default: /* process everything */
-            break;
-        }
-
-        /*
-         *  Make sure the option value string is persistent and consistent.
-         *
-         *  The interpretation of the option value depends
-         *  on the type of value argument the option takes
-         */
-        if (st.pzOptArg != NULL) {
-            if (OPTST_GET_ARGTYPE(st.pOD->fOptState) == OPARG_TYPE_NONE) {
-                st.pzOptArg = NULL;
-            } else if (  (st.pOD->fOptState & OPTST_ARG_OPTIONAL)
-                      && (*st.pzOptArg == NUL)) {
-                    st.pzOptArg = NULL;
-            } else if (*st.pzOptArg == NUL) {
-                st.pzOptArg = zNil;
-            } else {
-                AGDUPSTR( st.pzOptArg, st.pzOptArg, "option argument" );
-                st.flags |= OPTST_ALLOC_ARG;
-            }
-        }
+        checkEnvOpt(&st, zEnvName, pOpts, type);
+    }
 
-        handleOption( pOpts, &st );
+    /*
+     *  Special handling for ${PROGNAME_LOAD_OPTS}
+     */
+    if (pOpts->specOptIdx.save_opts != 0) {
+        st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
+        strcpy( pzFlagName, st.pOD->pz_NAME );
+        checkEnvOpt(&st, zEnvName, pOpts, type);
     }
 }
 

+ 20 - 11
libopts/genshell.c

@@ -2,11 +2,11 @@
  *  
  *  DO NOT EDIT THIS FILE   (genshell.c)
  *  
- *  It has been AutoGen-ed  Saturday February 17, 2007 at 12:49:35 PM PST
+ *  It has been AutoGen-ed  Saturday May  5, 2007 at 12:02:35 PM PDT
  *  From the definitions    genshell.def
  *  and the template file   options
  *
- * Generated from AutoOpts 28:0:3 templates.
+ * Generated from AutoOpts 29:0:4 templates.
  */
 
 /*
@@ -20,7 +20,7 @@
  *
  * This source file is copyrighted and licensed under the following terms:
  *
- * genshellopt copyright 1999-2006 Bruce Korb - all rights reserved
+ * genshellopt copyright 1999-2007 Bruce Korb - all rights reserved
  *
  * genshellopt is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -49,7 +49,7 @@
 extern "C" {
 #endif
 tSCC zCopyright[] =
-       "genshellopt copyright (c) 1999-2006 Bruce Korb, all rights reserved";
+       "genshellopt copyright (c) 1999-2007 Bruce Korb, all rights reserved";
 tSCC zCopyrightNotice[] =
        "genshellopt is free software; you can redistribute it and/or\n\
 modify it under the terms of the GNU Lesser General Public\n\
@@ -145,12 +145,18 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zShellText, zShell_NAME, zShell_Name,
      /* disablement strs */ zNotShell_Name, zNotShell_Pfx },
 
+#ifdef NO_OPTIONAL_OPT_ARGS
+#  define VERSION_OPT_FLAGS     OPTST_IMM | OPTST_NO_INIT
+#else
+#  define VERSION_OPT_FLAGS     OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \
+                                OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT
+#endif
+
   {  /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION,
      /* equiv idx value  */ NO_EQUIVALENT, 0,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
-     /* opt state flags  */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)
-                          | OPTST_ARG_OPTIONAL | OPTST_IMM, 0,
+     /* opt state flags  */ VERSION_OPT_FLAGS, 0,
      /* last opt argumnt */ { NULL },
      /* arg list/cookie  */ NULL,
      /* must/cannot opts */ NULL, NULL,
@@ -158,11 +164,14 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zVersionText, NULL, zVersion_Name,
      /* disablement strs */ NULL, NULL },
 
+#undef VERSION_OPT_FLAGS
+
+
   {  /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP,
      /* equiv idx value  */ NO_EQUIVALENT, 0,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
-     /* opt state flags  */ OPTST_IMM, 0,
+     /* opt state flags  */ OPTST_IMM | OPTST_NO_INIT, 0,
      /* last opt argumnt */ { NULL },
      /* arg list/cookie  */ NULL,
      /* must/cannot opts */ NULL, NULL,
@@ -174,7 +183,7 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* equiv idx value  */ NO_EQUIVALENT, 0,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
-     /* opt state flags  */ OPTST_IMM, 0,
+     /* opt state flags  */ OPTST_IMM | OPTST_NO_INIT, 0,
      /* last opt argumnt */ { NULL },
      /* arg list/cookie  */ NULL,
      /* must/cannot opts */ NULL,  NULL,
@@ -204,7 +213,7 @@ If the script file already exists and contains Automated Option Processing\n\
 text, the second line of the file through the ending tag will be replaced\n\
 by the newly generated text.  The first `#!' line will be regenerated.\n";
 tSCC    zFullVersion[] = GENSHELLOPT_FULL_VERSION;
-/* extracted from optcode.tpl near line 378 */
+/* extracted from optcode.tpl near line 408 */
 
 #if defined(ENABLE_NLS)
 # define OPTPROC_BASE OPTPROC_TRANSLATE
@@ -241,7 +250,7 @@ tOptions genshelloptOptions = {
       NO_EQUIVALENT /* index of '-#' option */,
       NO_EQUIVALENT /* index of default opt */
     },
-    OPTION_CT, 2 /* user option count */
+    5 /* full option count */, 2 /* user option count */
 };
 
 /*
@@ -254,7 +263,7 @@ doUsageOpt(
 {
     USAGE( EXIT_SUCCESS );
 }
-/* extracted from optcode.tpl near line 475 */
+/* extracted from optcode.tpl near line 514 */
 
 #if ENABLE_NLS
 #include <stdio.h>

+ 5 - 5
libopts/genshell.h

@@ -2,11 +2,11 @@
  *  
  *  DO NOT EDIT THIS FILE   (genshell.h)
  *  
- *  It has been AutoGen-ed  Saturday February 17, 2007 at 12:49:35 PM PST
+ *  It has been AutoGen-ed  Saturday May  5, 2007 at 12:02:35 PM PDT
  *  From the definitions    genshell.def
  *  and the template file   options
  *
- * Generated from AutoOpts 28:0:3 templates.
+ * Generated from AutoOpts 29:0:4 templates.
  */
 
 /*
@@ -20,7 +20,7 @@
  *
  * This source file is copyrighted and licensed under the following terms:
  *
- * genshellopt copyright 1999-2006 Bruce Korb - all rights reserved
+ * genshellopt copyright 1999-2007 Bruce Korb - all rights reserved
  *
  * genshellopt is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -55,7 +55,7 @@
  *  tolerable version is at least as old as what was current when the header
  *  template was released.
  */
-#define AO_TEMPLATE_VERSION 114688
+#define AO_TEMPLATE_VERSION 118784
 #if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \
  || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION)
 # error option template version mismatches autoopts/options.h header
@@ -117,7 +117,7 @@ typedef enum {
                 genshelloptOptions.pzCurOpt  = NULL )
 #define START_OPT       RESTART_OPT(1)
 #define USAGE(c)        (*genshelloptOptions.pUsageProc)( &genshelloptOptions, c )
-/* extracted from opthead.tpl near line 345 */
+/* extracted from opthead.tpl near line 360 */
 
 /* * * * * *
  *

+ 22 - 2
libopts/m4/libopts.m4

@@ -2,7 +2,7 @@ dnl  -*- buffer-read-only: t -*- vi: set ro:
 dnl 
 dnl DO NOT EDIT THIS FILE   (libopts.m4)
 dnl 
-dnl It has been AutoGen-ed  Saturday February 17, 2007 at 12:49:37 PM PST
+dnl It has been AutoGen-ed  Saturday May  5, 2007 at 12:02:37 PM PDT
 dnl From the definitions    libopts.def
 dnl and the template file   conftest.tpl
 dnl
@@ -25,7 +25,7 @@ AC_DEFUN([INVOKE_LIBOPTS_MACROS_FIRST],[
   AC_CHECK_HEADERS(dlfcn.h errno.h fcntl.h libgen.h memory.h netinet/in.h \
     setjmp.h sys/mman.h sys/param.h sys/poll.h sys/procset.h sys/select.h \
     sys/socket.h sys/stropts.h sys/time.h sys/un.h sys/wait.h unistd.h    \
-    utime.h )
+    utime.h sysexits.h)
   
   # --------------------------------------------
   # Verify certain entries from AC_CHECK_HEADERS
@@ -370,6 +370,23 @@ return (fp == NULL) ? 1 : fclose(fp); }],
 ]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_TEXT
 
 
+AC_DEFUN([LIBOPTS_DISABLE_OPTIONAL_ARGS],[
+  AC_ARG_ENABLE([optional-args],
+    AC_HELP_STRING([--disable-optional-args], [not wanting optional option args]),
+    [libopts_cv_enable_optional_args=${enable_optional_args}],
+    AC_CACHE_CHECK([whether not wanting optional option args], libopts_cv_enable_optional_args,
+      libopts_cv_enable_optional_args=yes)
+  ) # end of AC_ARG_ENABLE
+
+  if test "X${libopts_cv_enable_optional_args}" = Xno
+  then
+    AC_DEFINE([NO_OPTIONAL_OPT_ARGS], [1],
+          [Define this if optional arguments are disallowed])
+  fi
+  
+]) # end of AC_DEFUN of LIBOPTS_DISABLE_OPTIONAL_ARGS
+
+
 AC_DEFUN([INVOKE_LIBOPTS_MACROS],[
   INVOKE_LIBOPTS_MACROS_FIRST
   # Check to see if a reg expr header is specified.
@@ -396,6 +413,9 @@ AC_DEFUN([INVOKE_LIBOPTS_MACROS],[
   # Check to see if fopen accepts "t" mode.
   LIBOPTS_RUN_FOPEN_TEXT
 
+  # Check to see if not wanting optional option args.
+  LIBOPTS_DISABLE_OPTIONAL_ARGS
+
 ]) # end AC_DEFUN of INVOKE_LIBOPTS_MACROS
 
 dnl @synopsis  LIBOPTS_CHECK

+ 339 - 0
libopts/pathfind.c

@@ -0,0 +1,339 @@
+/*  -*- Mode: C -*-  */
+
+/* pathfind.c --- find a FILE  MODE along PATH */
+
+/*
+ * Author:           Gary V Vaughan <gvaughan@oranda.demon.co.uk>
+ * Time-stamp:       "2006-09-23 19:46:16 bkorb"
+ * Created:          Tue Jun 24 15:07:31 1997
+ * Last Modified:    $Date: 2006/11/27 01:52:23 $
+ *            by: bkorb
+ *
+ * $Id: pathfind.c,v 4.10 2006/11/27 01:52:23 bkorb Exp $
+ */
+
+/* Code: */
+
+#include "compat.h"
+#ifndef HAVE_PATHFIND
+#if defined(__windows__) && !defined(__CYGWIN__)
+char*
+pathfind( char const*  path,
+          char const*  fileName,
+          char const*  mode )
+{
+    return NULL;
+}
+#else
+
+static char* make_absolute( char const *string, char const *dot_path );
+static char* canonicalize_pathname( char *path );
+static char* extract_colon_unit( char* dir, char const *string, int *p_index );
+
+
+/*=export_func pathfind
+ *
+ * what: fild a file in a list of directories
+ *
+ * ifndef: HAVE_PATHFIND
+ *
+ * arg:  + char const* + path + colon separated list of search directories +
+ * arg:  + char const* + file + the name of the file to look for +
+ * arg:  + char const* + mode + the mode bits that must be set to match +
+ *
+ * ret_type:  char*
+ * ret_desc:  the path to the located file
+ *
+ * doc:
+ *
+ * pathfind looks for a a file with name "FILE" and "MODE" access
+ * along colon delimited "PATH", and returns the full pathname as a
+ * string, or NULL if not found.  If "FILE" contains a slash, then
+ * it is treated as a relative or absolute path and "PATH" is ignored.
+ *
+ * @strong{NOTE}: this function is compiled into @file{libopts} only if
+ * it is not natively supplied.
+ *
+ * The "MODE" argument is a string of option letters chosen from the
+ * list below:
+ * @example
+ *          Letter    Meaning
+ *          r         readable
+ *          w         writable
+ *          x         executable
+ *          f         normal file       (NOT IMPLEMENTED)
+ *          b         block special     (NOT IMPLEMENTED)
+ *          c         character special (NOT IMPLEMENTED)
+ *          d         directory         (NOT IMPLEMENTED)
+ *          p         FIFO (pipe)       (NOT IMPLEMENTED)
+ *          u         set user ID bit   (NOT IMPLEMENTED)
+ *          g         set group ID bit  (NOT IMPLEMENTED)
+ *          k         sticky bit        (NOT IMPLEMENTED)
+ *          s         size nonzero      (NOT IMPLEMENTED)
+ * @end example
+ *
+ * example:
+ * To find the "ls" command using the "PATH" environment variable:
+ * @example
+ *    #include <stdlib.h>
+ *    char* pz_ls = pathfind( getenv("PATH"), "ls", "rx" );
+ *    <<do whatever with pz_ls>>
+ *    free( pz_ls );
+ * @end example
+ * The path is allocated with @code{malloc(3C)}, so you must @code{free(3C)}
+ * the result.  Also, do not use unimplemented file modes.  :-)
+ *
+ * err:  returns NULL if the file is not found.
+=*/
+char*
+pathfind( char const*  path,
+          char const*  fileName,
+          char const*  mode )
+{
+    int   p_index   = 0;
+    int   mode_bits = 0;
+    char* pathName  = NULL;
+    char  zPath[ AG_PATH_MAX + 1 ];
+
+    if (strchr( mode, 'r' )) mode_bits |= R_OK;
+    if (strchr( mode, 'w' )) mode_bits |= W_OK;
+    if (strchr( mode, 'x' )) mode_bits |= X_OK;
+
+    /*
+     *  FOR each non-null entry in the colon-separated path, DO ...
+     */
+    for (;;) {
+        DIR*  dirP;
+        char* colon_unit = extract_colon_unit( zPath, path, &p_index );
+
+        /*
+         *  IF no more entries, THEN quit
+         */
+        if (colon_unit == NULL)
+            break;
+
+        dirP = opendir( colon_unit );
+
+        /*
+         *  IF the directory is inaccessable, THEN next directory
+         */
+        if (dirP == NULL)
+            continue;
+
+        /*
+         *  FOR every entry in the given directory, ...
+         */
+        for (;;) {
+            struct dirent *entP = readdir( dirP );
+
+            if (entP == (struct dirent*)NULL)
+                break;
+
+            /*
+             *  IF the file name matches the one we are looking for, ...
+             */
+            if (strcmp( entP->d_name, fileName ) == 0) {
+                char* pzFullName = make_absolute( fileName, colon_unit);
+
+                /*
+                 *  Make sure we can access it in the way we want
+                 */
+                if (access( pzFullName, mode_bits ) >= 0) {
+                    /*
+                     *  We can, so normalize the name and return it below
+                     */
+                    pathName = canonicalize_pathname( pzFullName );
+                }
+
+                free( (void*)pzFullName );
+                break;
+            }
+        }
+
+        closedir( dirP );
+
+        if (pathName != NULL)
+            break;
+    }
+
+    return pathName;
+}
+
+/*
+ * Turn STRING  (a pathname) into an  absolute  pathname, assuming  that
+ * DOT_PATH contains the symbolic location of  `.'.  This always returns
+ * a new string, even if STRING was an absolute pathname to begin with.
+ */
+static char*
+make_absolute( char const *string, char const *dot_path )
+{
+    char *result;
+    int result_len;
+
+    if (!dot_path || *string == '/') {
+        result = strdup( string );
+    } else {
+        if (dot_path && dot_path[0]) {
+            result = malloc( 2 + strlen( dot_path ) + strlen( string ) );
+            strcpy( result, dot_path );
+            result_len = strlen( result );
+            if (result[result_len - 1] != '/') {
+                result[result_len++] = '/';
+                result[result_len] = '\0';
+            }
+        } else {
+            result = malloc( 3 + strlen( string ) );
+            result[0] = '.'; result[1] = '/'; result[2] = '\0';
+            result_len = 2;
+        }
+
+        strcpy( result + result_len, string );
+    }
+
+    return result;
+}
+
+/*
+ * Canonicalize PATH, and return a  new path.  The new path differs from
+ * PATH in that:
+ *
+ *    Multiple `/'s     are collapsed to a single `/'.
+ *    Leading `./'s     are removed.
+ *    Trailing `/.'s    are removed.
+ *    Trailing `/'s     are removed.
+ *    Non-leading `../'s and trailing `..'s are handled by removing
+ *                    portions of the path.
+ */
+static char*
+canonicalize_pathname( char *path )
+{
+    int i, start;
+    char stub_char, *result;
+
+    /* The result cannot be larger than the input PATH. */
+    result = strdup( path );
+
+    stub_char = (*path == '/') ? '/' : '.';
+
+    /* Walk along RESULT looking for things to compact. */
+    i = 0;
+    while (result[i]) {
+        while (result[i] != '\0' && result[i] != '/')
+            i++;
+
+        start = i++;
+
+        /* If we didn't find any  slashes, then there is nothing left to
+         * do.
+         */
+        if (!result[start])
+            break;
+
+        /* Handle multiple `/'s in a row. */
+        while (result[i] == '/')
+            i++;
+
+#if !defined (apollo)
+        if ((start + 1) != i)
+#else
+        if ((start + 1) != i && (start != 0 || i != 2))
+#endif /* apollo */
+        {
+            strcpy( result + start + 1, result + i );
+            i = start + 1;
+        }
+
+        /* Handle backquoted `/'. */
+        if (start > 0 && result[start - 1] == '\\')
+            continue;
+
+        /* Check for trailing `/', and `.' by itself. */
+        if ((start && !result[i])
+            || (result[i] == '.' && !result[i+1])) {
+            result[--i] = '\0';
+            break;
+        }
+
+        /* Check for `../', `./' or trailing `.' by itself. */
+        if (result[i] == '.') {
+            /* Handle `./'. */
+            if (result[i + 1] == '/') {
+                strcpy( result + i, result + i + 1 );
+                i = (start < 0) ? 0 : start;
+                continue;
+            }
+
+            /* Handle `../' or trailing `..' by itself. */
+            if (result[i + 1] == '.' &&
+                (result[i + 2] == '/' || !result[i + 2])) {
+                while (--start > -1 && result[start] != '/')
+                    ;
+                strcpy( result + start + 1, result + i + 2 );
+                i = (start < 0) ? 0 : start;
+                continue;
+            }
+        }
+    }
+
+    if (!*result) {
+        *result = stub_char;
+        result[1] = '\0';
+    }
+
+    return result;
+}
+
+/*
+ * Given a  string containing units of information separated  by colons,
+ * return the next one  pointed to by (P_INDEX), or NULL if there are no
+ * more.  Advance (P_INDEX) to the character after the colon.
+ */
+static char*
+extract_colon_unit( char* pzDir, char const *string, int *p_index )
+{
+    char*  pzDest = pzDir;
+    int    ix     = *p_index;
+
+    if (string == NULL)
+        return NULL;
+
+    if ((unsigned)ix >= strlen( string ))
+        return NULL;
+
+    {
+        char const* pzSrc = string + ix;
+
+        while (*pzSrc == ':')  pzSrc++;
+
+        for (;;) {
+            char ch = (*(pzDest++) = *(pzSrc++));
+            switch (ch) {
+            case ':':
+                pzDest[-1] = NUL;
+            case NUL:
+                goto copy_done;
+            }
+
+            if ((pzDest - pzDir) >= AG_PATH_MAX)
+                break;
+        } copy_done:;
+
+        ix = pzSrc - string;
+    }
+
+    if (*pzDir == NUL)
+        return NULL;
+
+    *p_index = ix;
+    return pzDir;
+}
+#endif /* __windows__ / __CYGWIN__ */
+#endif /* HAVE_PATHFIND */
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of compat/pathfind.c */

+ 2 - 2
libopts/pgusage.c

@@ -1,6 +1,6 @@
 
 /*
- *  $Id: pgusage.c,v 4.11 2006/09/24 02:11:16 bkorb Exp $
+ *  $Id: pgusage.c,v 4.12 2007/04/28 22:19:23 bkorb Exp $
  * Time-stamp:      "2006-07-16 08:13:26 bkorb"
  *
  *   Automated Options Paged Usage module.
@@ -10,7 +10,7 @@
  */
 
 /*
- *  Automated Options copyright 1992-2006 Bruce Korb
+ *  Automated Options copyright 1992-2007 Bruce Korb
  *
  *  Automated Options is free software.
  *  You may redistribute it and/or modify it under the terms of the

+ 1 - 1
libopts/proto.h

@@ -1,7 +1,7 @@
 /* -*- buffer-read-only: t -*- vi: set ro:
  *
  * Prototypes for autoopts
- * Generated Sat Feb 17 12:49:36 PST 2007
+ * Generated Sat May  5 12:02:36 PDT 2007
  */
 #ifndef AUTOOPTS_PROTO_H_GUARD
 #define AUTOOPTS_PROTO_H_GUARD 1

+ 2 - 2
libopts/save.c

@@ -1,7 +1,7 @@
 
 /*
- *  save.c  $Id: save.c,v 4.17 2007/02/04 17:44:12 bkorb Exp $
- * Time-stamp:      "2007-01-13 10:32:27 bkorb"
+ *  save.c  $Id: save.c,v 4.18 2007/04/15 19:01:18 bkorb Exp $
+ * Time-stamp:      "2007-04-15 11:11:10 bkorb"
  *
  *  This module's routines will take the currently set options and
  *  store them into an ".rc" file for re-interpretation the next

+ 60 - 0
libopts/snprintf.c

@@ -0,0 +1,60 @@
+
+#ifndef HAVE_VPRINTF
+#include "choke-me: no vprintf and no snprintf"
+#endif
+
+#if defined(HAVE_STDARG_H)
+#  include <stdarg.h>
+#  ifndef   VA_START
+#    define VA_START(a, f)  va_start(a, f)
+#    define VA_END(a)       va_end(a)
+#  endif /* VA_START */
+#  define SNV_USING_STDARG_H
+
+#elif defined(HAVE_VARARGS_H)
+#  include <varargs.h>
+#  ifndef   VA_START
+#    define VA_START(a, f) va_start(a)
+#    define VA_END(a)    va_end(a)
+#  endif /* VA_START */
+#  undef  SNV_USING_STDARG_H
+
+#else
+#  include "must-have-stdarg-or-varargs"
+#endif
+
+static int
+snprintf(char *str, size_t n, char const *fmt, ...)
+{
+    va_list ap;
+    int rval;
+
+#ifdef VSPRINTF_CHARSTAR
+    char *rp;
+    VA_START(ap, fmt);
+    rp = vsprintf(str, fmt, ap);
+    VA_END(ap);
+    rval = strlen(rp);
+
+#else
+    VA_START(ap, fmt);
+    rval = vsprintf(str, fmt, ap);
+    VA_END(ap);
+#endif
+
+    if (rval > n) {
+        fprintf(stderr, "snprintf buffer overrun %d > %d\n", rval, (int)n);
+        abort();
+    }
+    return rval;
+}
+
+static int
+vsnprintf( char *str, size_t n, char const *fmt, va_list ap )
+{
+#ifdef VSPRINTF_CHARSTAR
+    return (strlen(vsprintf(str, fmt, ap)));
+#else
+    return (vsprintf(str, fmt, ap));
+#endif
+}

+ 2 - 2
libopts/sort.c

@@ -1,13 +1,13 @@
 
 /*
- *  sort.c  $Id: sort.c,v 4.9 2006/10/21 15:42:49 bkorb Exp $
+ *  sort.c  $Id: sort.c,v 4.10 2007/04/28 22:19:23 bkorb Exp $
  * Time-stamp:      "2006-10-18 11:29:04 bkorb"
  *
  *  This module implements argument sorting.
  */
 
 /*
- *  Automated Options copyright 1992-2006 Bruce Korb
+ *  Automated Options copyright 1992-2007 Bruce Korb
  *
  *  Automated Options is free software.
  *  You may redistribute it and/or modify it under the terms of the

+ 60 - 0
libopts/strchr.c

@@ -0,0 +1,60 @@
+/*
+   SYNOPSIS
+       #include <string.h>
+
+       char *strchr(char const *s, int c);
+
+       char *strrchr(char const *s, int c);
+
+   DESCRIPTION
+       The  strchr() function returns a pointer to the first occurrence of the
+       character c in the string s.
+
+       The strrchr() function returns a pointer to the last occurrence of  the
+       character c in the string s.
+
+       Here  "character"  means "byte" - these functions do not work with wide
+       or multi-byte characters.
+
+   RETURN VALUE
+       The strchr() and strrchr() functions return a pointer  to  the  matched
+       character or NULL if the character is not found.
+
+   CONFORMING TO
+       SVID 3, POSIX, BSD 4.3, ISO 9899
+*/
+
+char*
+strchr( char const *s, int c)
+{
+    do {
+        if ((unsigned)*s == (unsigned)c)
+            return s;
+
+    } while (*(++s) != NUL);
+
+    return NULL;
+}
+
+char*
+strrchr( char const *s, int c)
+{
+    char const *e = s + strlen(s);
+
+    for (;;) {
+        if (--e < s)
+            break;
+
+        if ((unsigned)*e == (unsigned)c)
+            return e;
+    }
+    return NULL;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of compat/strsignal.c */

+ 19 - 0
libopts/strdup.c

@@ -0,0 +1,19 @@
+/*
+ * Platforms without strdup ?!?!?!
+ */
+
+static char *
+strdup( char const *s )
+{
+    char *cp;
+
+    if (s == NULL)
+        return NULL;
+
+    cp = (char *) AGALOC((unsigned) (strlen(s)+1), "strdup");
+
+    if (cp != NULL)
+        (void) strcpy(cp, s);
+
+    return cp;
+}

+ 2 - 2
libopts/streqvcmp.c

@@ -1,6 +1,6 @@
 
 /*
- *  $Id: streqvcmp.c,v 4.9 2006/09/24 02:11:16 bkorb Exp $
+ *  $Id: streqvcmp.c,v 4.10 2007/04/28 22:19:23 bkorb Exp $
  * Time-stamp:      "2006-07-26 18:25:53 bkorb"
  *
  *  String Equivalence Comparison
@@ -12,7 +12,7 @@
  */
 
 /*
- *  Automated Options copyright 1992-2006 Bruce Korb
+ *  Automated Options copyright 1992-2007 Bruce Korb
  *
  *  Automated Options is free software.
  *  You may redistribute it and/or modify it under the terms of the

+ 20 - 11
libopts/usage.c

@@ -1,7 +1,7 @@
 
 /*
- *  usage.c  $Id: usage.c,v 4.13 2006/11/27 01:52:23 bkorb Exp $
- * Time-stamp:      "2006-07-01 12:41:02 bkorb"
+ *  usage.c  $Id: usage.c,v 4.15 2007/04/28 22:19:23 bkorb Exp $
+ * Time-stamp:      "2007-04-15 11:02:46 bkorb"
  *
  *  This module implements the default usage procedure for
  *  Automated Options.  It may be overridden, of course.
@@ -13,7 +13,7 @@
  */
 
 /*
- *  Automated Options copyright 1992-2006 Bruce Korb
+ *  Automated Options copyright 1992-2007 Bruce Korb
  *
  *  Automated Options is free software.
  *  You may redistribute it and/or modify it under the terms of the
@@ -169,12 +169,18 @@ optionOnlyUsage(
  *  formats.  The descriptor specifies the default, but AUTOOPTS_USAGE will
  *  over-ride this, providing the value of it is set to either "gnu" or
  *  "autoopts".  This routine will @strong{not} return.
+ *
+ *  If "exitCode" is "EX_USAGE" (normally 64), then output will to to stdout
+ *  and the actual exit code will be "EXIT_SUCCESS".
 =*/
 void
 optionUsage(
     tOptions* pOptions,
-    int       exitCode )
+    int       usage_exit_code )
 {
+    int actual_exit_code =
+        (usage_exit_code == EX_USAGE) ? EXIT_SUCCESS : usage_exit_code;
+
     displayEnum = AG_FALSE;
 
     /*
@@ -183,7 +189,7 @@ optionUsage(
      *  on successful exit (help was requested), otherwise error out.
      */
     if (option_usage_fp == NULL)
-        option_usage_fp = (exitCode != EXIT_SUCCESS) ? stderr : stdout;
+        option_usage_fp = (actual_exit_code != EXIT_SUCCESS) ? stderr : stdout;
 
     fprintf( option_usage_fp, pOptions->pzUsageTitle, pOptions->pzProgName );
 
@@ -207,13 +213,13 @@ optionUsage(
              *  option, we do *NOT* want to emit the column headers.
              *  Otherwise, we do.
              */
-            if (  (exitCode != EXIT_SUCCESS)
+            if (  (usage_exit_code != EXIT_SUCCESS)
                || ((pOptions->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) )
 
                 fputs( pOptTitle, option_usage_fp );
         }
 
-        printOptionUsage( pOptions, exitCode, pOptTitle );
+        printOptionUsage( pOptions, usage_exit_code, pOptTitle );
     }
 
     /*
@@ -241,14 +247,14 @@ optionUsage(
      *  IF the user is asking for help (thus exiting with SUCCESS),
      *  THEN see what additional information we can provide.
      */
-    if (exitCode == EXIT_SUCCESS)
+    if (usage_exit_code == EXIT_SUCCESS)
         printProgramDetails( pOptions );
 
     if (pOptions->pzBugAddr != NULL)
         fprintf( option_usage_fp, zPlsSendBugs, pOptions->pzBugAddr );
     fflush( option_usage_fp );
 
-    exit( exitCode );
+    exit( actual_exit_code );
 }
 
 
@@ -344,12 +350,15 @@ printExtendedUsage(
     /*
      *  IF this particular option can NOT be preset
      *    AND some form of presetting IS allowed,
+     *    AND it is not an auto-managed option (e.g. --help, et al.)
      *  THEN advise that this option may not be preset.
      */
     if (  ((pOD->fOptState & OPTST_NO_INIT) != 0)
        && (  (pOptions->papzHomeList != NULL)
           || (pOptions->pzPROGNAME != NULL)
-       )  )
+          )
+       && (pOD->optIndex < pOptions->presetOptCt)
+       )
 
         fputs( zNoPreset, option_usage_fp );
 
@@ -509,7 +518,7 @@ printOneUsage(
 
  bogus_desc:
     fprintf( stderr, zInvalOptDesc, pOD->pz_Name );
-    exit( EXIT_FAILURE );
+    exit( EX_SOFTWARE );
 }
 
 

+ 12 - 10
libopts/version.c

@@ -1,13 +1,13 @@
 
-/*  $Id: version.c,v 4.9 2006/09/24 02:11:16 bkorb Exp $
- * Time-stamp:      "2006-09-22 18:15:00 bkorb"
+/*  $Id: version.c,v 4.10 2007/04/28 22:19:23 bkorb Exp $
+ * Time-stamp:      "2007-04-28 10:08:34 bkorb"
  *
  *  This module implements the default usage procedure for
  *  Automated Options.  It may be overridden, of course.
  */
 
 static char const zAOV[] =
-    "Automated Options version %s, copyright (c) 1999-2006 Bruce Korb\n";
+    "Automated Options version %s, copyright (c) 1999-2007 Bruce Korb\n";
 
 /*  Automated Options is free software.
  *  You may redistribute it and/or modify it under the terms of the
@@ -79,9 +79,14 @@ printVersion( tOptions* pOpts, tOptDesc* pOD, FILE* fp )
 {
     char swCh;
 
-    if (pOD->optArg.argString == NULL)
+    /*
+     *  IF the optional argument flag is off, or the argument is not provided,
+     *  then just print the version.
+     */
+    if (  ((pOD->fOptState & OPTST_ARG_OPTIONAL) == 0)
+       || (pOD->optArg.argString == NULL))
          swCh = 'v';
-    else swCh = pOD->optArg.argString[0];
+    else swCh = tolower(pOD->optArg.argString[0]);
 
     if (pOpts->pzFullVersion != NULL) {
         fputs( pOpts->pzFullVersion, fp );
@@ -89,17 +94,15 @@ printVersion( tOptions* pOpts, tOptDesc* pOD, FILE* fp )
 
     } else {
         char const *pz = pOpts->pzUsageTitle;
-        do { fputc( *pz, fp ); } while (*(pz++) != '\n');
+        do { fputc(*pz, fp); } while (*(pz++) != '\n');
     }
 
     switch (swCh) {
-    case NUL:
+    case NUL: /* arg provided, but empty */
     case 'v':
-    case 'V':
         break;
 
     case 'c':
-    case 'C':
         if (pOpts->pzCopyright != NULL) {
             fputs( pOpts->pzCopyright, fp );
             fputc( '\n', fp );
@@ -110,7 +113,6 @@ printVersion( tOptions* pOpts, tOptDesc* pOD, FILE* fp )
         break;
 
     case 'n':
-    case 'N':
         if (pOpts->pzCopyright != NULL) {
             fputs( pOpts->pzCopyright, fp );
             fputc( '\n', fp );

+ 130 - 0
libopts/windows-config.h

@@ -0,0 +1,130 @@
+
+/*
+ * Time-stamp:        "2006-10-14 14:55:09 bkorb"
+ *             by: bkorb
+ * Last Committed:    $Date: 2007/04/28 22:19:23 $
+ */
+#ifndef WINDOWS_CONFIG_HACKERY
+#define WINDOWS_CONFIG_HACKERY 1
+
+/*
+ * The definitions below have been stolen from NTP's config.h for Windows.
+ * However, they may be kept here in order to keep libopts independent from
+ * the NTP project.
+ */
+#ifndef __windows__
+#  define __windows__ 4
+#endif
+
+/*
+ * Miscellaneous functions that Microsoft maps
+ * to other names
+ *
+ * #define inline __inline
+ * #define vsnprintf _vsnprintf
+ */
+#define snprintf _snprintf
+/*
+ * #define stricmp _stricmp
+ * #define strcasecmp _stricmp
+ * #define isascii __isascii
+ * #define finite _finite
+ * #define random      rand
+ * #define srandom     srand
+ */
+
+#define SIZEOF_INT   4
+#define SIZEOF_CHARP 4
+#define SIZEOF_LONG  4
+#define SIZEOF_SHORT 2
+
+typedef unsigned long uintptr_t;
+
+/*
+ * # define HAVE_NET_IF_H
+ * # define QSORT_USES_VOID_P
+ * # define HAVE_SETVBUF
+ * # define HAVE_VSPRINTF
+ * # define HAVE_SNPRINTF
+ * # define HAVE_VSNPRINTF
+ * # define HAVE_PROTOTYPES             /* from ntpq.mak * /
+ * # define HAVE_MEMMOVE
+ * # define HAVE_TERMIOS_H
+ * # define HAVE_ERRNO_H
+ * # define HAVE_STDARG_H
+ * # define HAVE_NO_NICE
+ * # define HAVE_MKTIME
+ * # define TIME_WITH_SYS_TIME
+ * # define HAVE_IO_COMPLETION_PORT
+ * # define ISC_PLATFORM_NEEDNTOP
+ * # define ISC_PLATFORM_NEEDPTON
+ * # define NEED_S_CHAR_TYPEDEF
+ * # define USE_PROTOTYPES              /* for ntp_types.h * /
+ *
+ * #define ULONG_CONST(a) a ## UL
+ */
+
+#define HAVE_LIMITS_H   1
+#define HAVE_STRDUP     1
+#define HAVE_STRCHR     1
+#define HAVE_FCNTL_H    1
+
+/*
+ * VS.NET's version of wspiapi.h has a bug in it
+ * where it assigns a value to a variable inside
+ * an if statement. It should be comparing them.
+ * We prevent inclusion since we are not using this
+ * code so we don't have to see the warning messages
+ */
+#ifndef _WSPIAPI_H_
+#define _WSPIAPI_H_
+#endif
+
+/* Prevent inclusion of winsock.h in windows.h */
+#ifndef _WINSOCKAPI_
+#define _WINSOCKAPI_
+#endif
+
+#ifndef __RPCASYNC_H__
+#define __RPCASYNC_H__
+#endif
+
+/* Include Windows headers */
+#include <windows.h>
+#include <winsock2.h>
+#include <limits.h>
+
+/*
+ * Compatibility declarations for Windows, assuming SYS_WINNT
+ * has been defined.
+ */
+#define strdup  _strdup
+#define stat    _stat       /* struct stat from <sys/stat.h> */
+#define unlink  _unlink
+#define fchmod( _x, _y );
+#define ssize_t SSIZE_T
+
+#include <io.h>
+#define open    _open
+#define close   _close
+#define read    _read
+#define write   _write
+#define lseek   _lseek
+#define pipe    _pipe
+#define dup2    _dup2
+
+#define O_RDWR     _O_RDWR
+#define O_RDONLY   _O_RDONLY
+#define O_EXCL     _O_EXCL
+
+#ifndef S_ISREG
+#  define S_IFREG _S_IFREG
+#  define       S_ISREG(mode)   (((mode) & S_IFREG) == S_IFREG)
+#endif
+
+#ifndef S_ISDIR
+#  define S_IFDIR _S_IFDIR