chiark / gitweb /
Import release 0.1.9 v0.1.9
authorStephen Early <steve@greenend.org.uk>
Sat, 20 Oct 2001 17:03:00 +0000 (18:03 +0100)
committerStephen Early <steve@greenend.org.uk>
Wed, 18 May 2011 12:41:22 +0000 (13:41 +0100)
27 files changed:
CREDITS
INSTALL
LICENSE.txt [new file with mode: 0644]
Makefile.in
NEWS
README
alloca.c [new file with mode: 0644]
config.h.bot
config.h.in
configure
configure.in
debian/changelog
debian/control
debian/files
debian/init
debian/rules
getopt.c [new file with mode: 0644]
getopt.h [new file with mode: 0644]
getopt1.c [new file with mode: 0644]
log.c
make-secnet-sites [moved from make-secnet-sites.py with 99% similarity]
netlink.c
secnet.c
sha1.c
snprintf.c [new file with mode: 0644]
snprintf.h [new file with mode: 0644]
tun.c

diff --git a/CREDITS b/CREDITS
index 484c8ef5e0fa126afdff32e39bda42a9aa07a7d3..05a92a1e058ae02651fd4a07c359d7acf93d89f4 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -4,3 +4,4 @@ Colin Plumb, Ian Jackson - MD5 implementation
 Steve Reid <sreid@sea-to-sky.net>, James H. Brown <jbrown@burgoyne.com> - 
   SHA1 implementation
 Cendio Systems AB - ipaddr.py
 Steve Reid <sreid@sea-to-sky.net>, James H. Brown <jbrown@burgoyne.com> - 
   SHA1 implementation
 Cendio Systems AB - ipaddr.py
+Mark Martinec <mark.martinec@ijs.si> - portable snprintf
diff --git a/INSTALL b/INSTALL
index c8d90281e181e8ac592702657778655bd6ec3b3a..ab4debdc87ab6f59e04b0741ed64c024a85fbbf0 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -16,7 +16,7 @@ THERE WILL BE ANOTHER CHANGE IN PROTOCOL IN THE secnet-0.1.x SERIES
 Ensure that you have libgmp2-dev and adns installed (and bison and
 flex, and for that matter gcc...).
 
 Ensure that you have libgmp2-dev and adns installed (and bison and
 flex, and for that matter gcc...).
 
-[On BSD install /usr/ports/devel/bison and /usr/ports/devel/libgnugetopt]
+[On BSD install /usr/ports/devel/bison]
 
 If you intend to configure secnet to obtain packets from the kernel
 through userv-ipif, install and configure userv-ipif.  It is part of
 
 If you intend to configure secnet to obtain packets from the kernel
 through userv-ipif, install and configure userv-ipif.  It is part of
@@ -107,11 +107,11 @@ Generate a site file fragment for your site (see below), and submit it
 for inclusion in your VPN's 'sites' file.  Download the vpn-sites file
 to /etc/secnet/sites - MAKE SURE YOU GET AN AUTHENTIC COPY because the
 sites file contains public keys for all the sites in the VPN.  Use the
 for inclusion in your VPN's 'sites' file.  Download the vpn-sites file
 to /etc/secnet/sites - MAKE SURE YOU GET AN AUTHENTIC COPY because the
 sites file contains public keys for all the sites in the VPN.  Use the
-make-secnet-sites.py program provided with the secnet distribution to
+make-secnet-sites program provided with the secnet distribution to
 convert the distributed sites file into one that can be included in a
 secnet configuration file:
 
 convert the distributed sites file into one that can be included in a
 secnet configuration file:
 
-# make-secnet-sites.py sites sites.conf
+# make-secnet-sites sites sites.conf
 
 * Configuration
 
 
 * Configuration
 
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..aeb06a7
--- /dev/null
@@ -0,0 +1,121 @@
+The Frontier Artistic License Version 1.0
+Derived from the Artistic License at OpenSource.org.
+Submitted to OpenSource.org for Open Source Initiative certification.
+   
+Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to
+make reasonable modifications.
+   
+Definitions
+
+  "Package" refers to the script, suite, file, or collection of
+  scripts, suites, and/or files distributed by the Copyright Holder,
+  and to derivatives of that Package created through textual modification.
+
+  "Standard Version" refers to such a Package if it has not been
+  modified, or has been modified in accordance with the wishes of
+  the Copyright Holder.
+
+  "Copyright Holder" is whoever is named in the copyright statement
+  or statements for the package.
+
+  "You" is you, if you're thinking about copying or distributing
+  this Package.
+
+  "Reasonable copying fee" is whatever you can justify on the basis
+  of media cost, duplication charges, time of people involved, and
+  so on. (You will not be required to justify it to the Copyright
+  Holder, but only to the computing community at large as a market
+  that must bear the fee.)
+
+  "Freely Available" means that no fee is charged for the item
+  itself, though there may be fees involved in handling the item.
+  It also means that recipients of the item may redistribute it under
+  the same conditions they received it.
+       
+
+Terms
+
+1. You may make and give away verbatim copies of the source form of
+the Standard Version of this Package without restriction, provided
+that you duplicate all of the original copyright notices and
+associated disclaimers.
+   
+2. You may apply bug fixes, portability fixes, and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+   
+3. You may otherwise modify your copy of this Package in any way,
+provided that you insert a prominent notice in each changed script,
+suite, or file stating how and when you changed that script, suite,
+or file, and provided that you do at least ONE of the following:
+   
+  a) Use the modified Package only within your corporation or
+  organization, or retain the modified Package solely for personal use.
+     
+  b) Place your modifications in the Public Domain or otherwise make
+  them Freely Available, such as by posting said modifications to Usenet
+  or an equivalent medium, or placing the modifications on a major archive
+  site such as ftp.uu.net, or by allowing the Copyright Holder to include
+  your modifications in the Standard Version of the Package.
+     
+  c) Rename any non-standard executables so the names do not conflict
+  with standard executables, which must also be provided, and provide
+  a separate manual page (or equivalent) for each non-standard executable
+  that clearly documents how it differs from the Standard Version.
+     
+  d) Make other distribution arrangements with the Copyright Holder.
+     
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+   
+  a) Distribute a Standard Version of the executables and library
+  files, together with instructions (in the manual page or
+  equivalent) on where to get the Standard Version.
+     
+  b) Accompany the distribution with the machine-readable source of
+  the Package with your modifications.
+     
+  c) Accompany any non-standard executables with their corresponding
+  Standard Version executables, give the non-standard executables
+  non-standard names, and clearly document the differences in manual
+  pages (or equivalent), together with instructions on where to get
+  the Standard Version.
+     
+  d) Make other distribution arrangements with the Copyright Holder.
+     
+5. You may charge a reasonable copying fee for any distribution of
+this Package. You may charge any fee you choose for support of this
+Package. You may not charge a fee for this Package itself. However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial)
+software distribution provided that you do not advertise this Package
+as a product of your own.
+   
+6. The scripts and library files supplied as input to or produced as
+output from the programs of this Package do not automatically fall
+under the copyright of this Package, but belong to whomever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.
+   
+7. Scripts, suites, or programs supplied by you that depend on or
+otherwise make use of this Package shall not be considered part of
+this Package.
+   
+8. The name of the Copyright Holder may not be used to endorse or
+promote products derived from this software without specific prior
+written permission.
+   
+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+   
+                        The End
+
+
+http://www.spinwardstars.com/frontier/fal.html
index 5faf2f6292e50fdb20d6fd17ef722fc7a18a1479..c8a67ad3a7e0885f9691a80d01caae95746169f8 100644 (file)
@@ -18,7 +18,7 @@
 .PHONY:        all clean realclean dist install
 
 PACKAGE:=secnet
 .PHONY:        all clean realclean dist install
 
 PACKAGE:=secnet
-VERSION:=0.1.8
+VERSION:=0.1.9
 
 @SET_MAKE@
 
 
 @SET_MAKE@
 
@@ -46,18 +46,23 @@ TARGETS:=secnet
 OBJECTS:=secnet.o util.o conffile.yy.o conffile.tab.o conffile.o modules.o \
        resolver.o random.o udp.o site.o transform.o netlink.o rsa.o dh.o \
        serpent.o md5.o version.o tun.o slip.o sha1.o ipaddr.o log.o \
 OBJECTS:=secnet.o util.o conffile.yy.o conffile.tab.o conffile.o modules.o \
        resolver.o random.o udp.o site.o transform.o netlink.o rsa.o dh.o \
        serpent.o md5.o version.o tun.o slip.o sha1.o ipaddr.o log.o \
-       process.o
+       process.o @LIBOBJS@
 
 
-DISTFILES:=COPYING CREDITS INSTALL Makefile.in NEWS NOTES README TODO \
+DISTFILES:=COPYING CREDITS INSTALL LICENSE.txt Makefile.in \
+       NEWS NOTES README TODO \
+       alloca.c \
        conffile.c conffile.fl conffile.h conffile.y \
        conffile_internal.h config.h.bot \
        config.h.in config.h.top configure \
        configure.in debian dh.c \
        conffile.c conffile.fl conffile.h conffile.y \
        conffile_internal.h config.h.bot \
        config.h.in config.h.top configure \
        configure.in debian dh.c \
-       example.conf make-secnet-sites.py \
+       example.conf \
+       getopt.c getopt1.c getopt.h \
        install.sh ipaddr.c ipaddr.h ipaddr.py linux log.c md5.c md5.h \
        install.sh ipaddr.c ipaddr.h ipaddr.py linux log.c md5.c md5.h \
+       make-secnet-sites \
        modules.c netlink.c netlink.h process.c process.h \
        random.c resolver.c rsa.c \
        secnet.c secnet.h serpent.c serpent.h serpentsboxes.h \
        modules.c netlink.c netlink.h process.c process.h \
        random.c resolver.c rsa.c \
        secnet.c secnet.h serpent.c serpent.h serpentsboxes.h \
+       snprintf.c snprintf.h \
        sha1.c site.c slip.c stamp-h.in transform.c tun.c udp.c \
        unaligned.h util.c util.h
 
        sha1.c site.c slip.c stamp-h.in transform.c tun.c udp.c \
        unaligned.h util.c util.h
 
@@ -116,6 +121,8 @@ version.c: Makefile
 
 install: all
        $(INSTALL_PROGRAM) -D secnet $(sbindir)/`echo secnet|sed '$(transform)'`
 
 install: all
        $(INSTALL_PROGRAM) -D secnet $(sbindir)/`echo secnet|sed '$(transform)'`
+       $(INSTALL_PROGRAM) -D make-secnet-sites $(sbindir)/`echo make-secnet-sites|sed '$(transform)'`
+       $(INSTALL) -D ipaddr.py $(prefix)/share/secnet/ipaddr.py
 
 clean:
        $(RM) -f *.o *.yy.c *.tab.[ch] $(TARGETS) core version.c
 
 clean:
        $(RM) -f *.o *.yy.c *.tab.[ch] $(TARGETS) core version.c
diff --git a/NEWS b/NEWS
index d605fe5c5f0baf5951dc852ad9e6086d45af4a37..c26e086b55834ec383f74ba80318a24e1f39b6b4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,44 @@
+* Planned for the future
+
+New configuration syntax for netlinks: basic 'netlink' closure yields
+a pure closure that can be applied in each site() to generate a
+netlink for that site (with routes, options, etc.).  Works well for
+point-to-point: that netlink can be used directly by just one site.
+Much cleaner separation between site() and netlink code this way.
+
+(Backward compatibility will be kept for a while.)
+
+* New in version 0.1.9
+
+The netlink code may now generate ICMP responses to ICMP messages that
+are not errors, eg. ICMP echo-request.  This makes Windows NT
+traceroute output look a little less strange.
+
+configure.in and config.h.bot now define uint32_t etc. even on systems
+without stdint.h and inttypes.h (needed for Solaris 2.5.1)
+
+GNU getopt is included for systems that lack it.
+
+We check for LOG_AUTHPRIV before trying to use it in log.c (Solaris
+2.5.1 doesn't have it.)
+
+Portable snprintf.c from http://www.ijs.si/software/snprintf/ is
+included for systems that lack snprintf/vsnprintf.
+
+make-secnet-sites.py renamed to make-secnet-sites and now installed in
+$prefix/sbin/make-secnet-sites; ipaddr.py library installed in
+$prefix/share/secnet/ipaddr.py.  make-secnet-sites searches
+/usr/local/share/secnet and /usr/share/secnet for ipaddr.py
+
 * New in version 0.1.8
 
 Netlink devices now support a 'point-to-point' mode.  In this mode the
 netlink device does not require an IP address; instead, the IP address
 of the other end of the tunnel is specified using the 'ptp-address'
 option.  Precisely one site must be configured to use the netlink
 * New in version 0.1.8
 
 Netlink devices now support a 'point-to-point' mode.  In this mode the
 netlink device does not require an IP address; instead, the IP address
 of the other end of the tunnel is specified using the 'ptp-address'
 option.  Precisely one site must be configured to use the netlink
-device.
+device. (I haven't had a chance to test this because 0.1.8 turned into
+a 'quick' release to enable secnet to cope with the network problems
+affecting connections going via LINX on 2001-10-16.)
 
 The tunnel code in site.c now initiates a key setup if the
 reverse-transform function fails (wrong key, bad MAC, too much skew,
 
 The tunnel code in site.c now initiates a key setup if the
 reverse-transform function fails (wrong key, bad MAC, too much skew,
@@ -12,7 +46,7 @@ etc.) - this should make secnet more reliable on dodgy links, which
 are much more common than links with active attackers...  (an attacker
 can now force a new key setup by replaying an old packet, but apart
 from minor denial of service on slow links or machines this won't
 are much more common than links with active attackers...  (an attacker
 can now force a new key setup by replaying an old packet, but apart
 from minor denial of service on slow links or machines this won't
-achieve them much).
+achieve them much).  This should eventually be made configurable.
 
 The sequence number skew detection code in transform.c now only
 complains about 'reverse skew' - replays of packets that are too
 
 The sequence number skew detection code in transform.c now only
 complains about 'reverse skew' - replays of packets that are too
diff --git a/README b/README
index 79b5447a6726ff5b6e8c7ed53a7e42a89b2e4405..255892d9eebb32cf9d336e2c57d3bfc8c1f12852 100644 (file)
--- a/README
+++ b/README
@@ -1,5 +1,20 @@
 secnet - flexible VPN software
 
 secnet - flexible VPN software
 
+* Copying
+
+secnet is Copyright (C) 1995--2001 Stephen Early <steve@greenend.org.uk>
+It is distributed under the terms of the GNU General Public License,
+version 2 or later.  See the file COPYING for more information.
+
+The portable snprintf implementation in snprintf.c is Copyright (C)
+1999 Mark Martinec <mark.martinec@ijs.si> and is distributed under the
+terms of the Frontier Artistic License.  You can find the standard
+version of snprintf.c at http://www.ijs.si/software/snprintf/
+
+The IP address handling library in ipaddr.py is Copyright (C)
+1996--2000 Cendio Systems AB, and is distributed under the terms of
+the GPL.
+
 * Introduction
 
 secnet allows large virtual private networks to be constructed
 * Introduction
 
 secnet allows large virtual private networks to be constructed
diff --git a/alloca.c b/alloca.c
new file mode 100644 (file)
index 0000000..bc34529
--- /dev/null
+++ b/alloca.c
@@ -0,0 +1,460 @@
+/* alloca.c -- allocate automatically reclaimed memory
+   (Mostly) portable public-domain implementation -- D A Gwyn
+
+   This implementation of the PWB library alloca function,
+   which is used to allocate space off the run-time stack so
+   that it is automatically reclaimed upon procedure exit,
+   was inspired by discussions with J. Q. Johnson of Cornell.
+   J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+   There are some preprocessor constants that can
+   be defined when compiling for your specific system, for
+   improved efficiency; however, the defaults should be okay.
+
+   The general concept of this implementation is to keep
+   track of all alloca-allocated blocks, and reclaim any
+   that are found to be deeper in the stack than the current
+   invocation.  This heuristic does not reclaim storage as
+   soon as it becomes invalid, but it will do so eventually.
+
+   As a special case, alloca(0) reclaims storage without
+   allocating any.  It is a good idea to use alloca(0) in
+   your main control loop, etc. to force garbage collection.  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* If compiling with GCC, this file's not needed.  */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+   -- this is for usg, in which emacs must undefine static
+   in order to make unexec workable
+   */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+/* If your stack is a linked list of frames, you have to
+   provide an "address metric" ADDRESS_FUNCTION macro.  */
+
+#ifdef CRAY
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#define        NULL    0
+
+/* Define STACK_DIRECTION if you know the direction of stack
+   growth for your system; otherwise it will be automatically
+   deduced at run-time.
+
+   STACK_DIRECTION > 0 => grows toward higher addresses
+   STACK_DIRECTION < 0 => grows toward lower addresses
+   STACK_DIRECTION = 0 => direction of growth unknown  */
+
+#ifndef STACK_DIRECTION
+#define        STACK_DIRECTION 0       /* Direction unknown.  */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define        STACK_DIR       STACK_DIRECTION /* Known at compile-time.  */
+
+#else /* STACK_DIRECTION == 0; need run-time code.  */
+
+static int stack_dir;          /* 1 or -1 once known.  */
+#define        STACK_DIR       stack_dir
+
+static void
+find_stack_direction ()
+{
+  static char *addr = NULL;    /* Address of first `dummy', once known.  */
+  auto char dummy;             /* To get stack address.  */
+
+  if (addr == NULL)
+    {                          /* Initial entry.  */
+      addr = ADDRESS_FUNCTION (dummy);
+
+      find_stack_direction (); /* Recurse once.  */
+    }
+  else
+    {
+      /* Second entry.  */
+      if (ADDRESS_FUNCTION (dummy) > addr)
+       stack_dir = 1;          /* Stack grew upward.  */
+      else
+       stack_dir = -1;         /* Stack grew downward.  */
+    }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+   (a) chain together all alloca'ed blocks;
+   (b) keep track of stack depth.
+
+   It is very important that sizeof(header) agree with malloc
+   alignment chunk size.  The following default should work okay.  */
+
+#ifndef        ALIGN_SIZE
+#define        ALIGN_SIZE      sizeof(double)
+#endif
+
+typedef union hdr
+{
+  char align[ALIGN_SIZE];      /* To force sizeof(header).  */
+  struct
+    {
+      union hdr *next;         /* For chaining headers.  */
+      char *deep;              /* For stack depth measure.  */
+    } h;
+} header;
+
+static header *last_alloca_header = NULL;      /* -> last alloca header.  */
+
+/* Return a pointer to at least SIZE bytes of storage,
+   which will be automatically reclaimed upon exit from
+   the procedure that called alloca.  Originally, this space
+   was supposed to be taken from the current stack frame of the
+   caller, but that method cannot be made to work for some
+   implementations of C, for example under Gould's UTX/32.  */
+
+pointer
+alloca (size)
+     unsigned size;
+{
+  auto char probe;             /* Probes stack depth: */
+  register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+  if (STACK_DIR == 0)          /* Unknown growth direction.  */
+    find_stack_direction ();
+#endif
+
+  /* Reclaim garbage, defined as all alloca'd storage that
+     was allocated from deeper in the stack than currently. */
+
+  {
+    register header *hp;       /* Traverses linked list.  */
+
+    for (hp = last_alloca_header; hp != NULL;)
+      if ((STACK_DIR > 0 && hp->h.deep > depth)
+         || (STACK_DIR < 0 && hp->h.deep < depth))
+       {
+         register header *np = hp->h.next;
+
+         free ((pointer) hp);  /* Collect garbage.  */
+
+         hp = np;              /* -> next header.  */
+       }
+      else
+       break;                  /* Rest are not deeper.  */
+
+    last_alloca_header = hp;   /* -> last valid storage.  */
+  }
+
+  if (size == 0)
+    return NULL;               /* No allocation required.  */
+
+  /* Allocate combined header + user data storage.  */
+
+  {
+    register pointer new = malloc (sizeof (header) + size);
+    /* Address of header.  */
+
+    ((header *) new)->h.next = last_alloca_header;
+    ((header *) new)->h.deep = depth;
+
+    last_alloca_header = (header *) new;
+
+    /* User storage begins just after header.  */
+
+    return (pointer) ((char *) new + sizeof (header));
+  }
+}
+
+#ifdef CRAY
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+  {
+    long shgrow:32;            /* Number of times stack has grown.  */
+    long shaseg:32;            /* Size of increments to stack.  */
+    long shhwm:32;             /* High water mark of stack.  */
+    long shsize:32;            /* Current size of stack (all segments).  */
+  };
+
+/* The stack segment linkage control information occurs at
+   the high-address end of a stack segment.  (The stack
+   grows from low addresses to high addresses.)  The initial
+   part of the stack segment linkage control information is
+   0200 (octal) words.  This provides for register storage
+   for the routine which overflows the stack.  */
+
+struct stack_segment_linkage
+  {
+    long ss[0200];             /* 0200 overflow words.  */
+    long sssize:32;            /* Number of words in this segment.  */
+    long ssbase:32;            /* Offset to stack base.  */
+    long:32;
+    long sspseg:32;            /* Offset to linkage control of previous
+                                  segment of stack.  */
+    long:32;
+    long sstcpt:32;            /* Pointer to task common address block.  */
+    long sscsnm;               /* Private control structure number for
+                                  microtasking.  */
+    long ssusr1;               /* Reserved for user.  */
+    long ssusr2;               /* Reserved for user.  */
+    long sstpid;               /* Process ID for pid based multi-tasking.  */
+    long ssgvup;               /* Pointer to multitasking thread giveup.  */
+    long sscray[7];            /* Reserved for Cray Research.  */
+    long ssa0;
+    long ssa1;
+    long ssa2;
+    long ssa3;
+    long ssa4;
+    long ssa5;
+    long ssa6;
+    long ssa7;
+    long sss0;
+    long sss1;
+    long sss2;
+    long sss3;
+    long sss4;
+    long sss5;
+    long sss6;
+    long sss7;
+  };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+   returned by the STKSTAT library routine.  */
+struct stk_stat
+  {
+    long now;                  /* Current total stack size.  */
+    long maxc;                 /* Amount of contiguous space which would
+                                  be required to satisfy the maximum
+                                  stack demand to date.  */
+    long high_water;           /* Stack high-water mark.  */
+    long overflows;            /* Number of stack overflow ($STKOFEN) calls.  */
+    long hits;                 /* Number of internal buffer hits.  */
+    long extends;              /* Number of block extensions.  */
+    long stko_mallocs;         /* Block allocations by $STKOFEN.  */
+    long underflows;           /* Number of stack underflow calls ($STKRETN).  */
+    long stko_free;            /* Number of deallocations by $STKRETN.  */
+    long stkm_free;            /* Number of deallocations by $STKMRET.  */
+    long segments;             /* Current number of stack segments.  */
+    long maxs;                 /* Maximum number of stack segments so far.  */
+    long pad_size;             /* Stack pad size.  */
+    long current_address;      /* Current stack segment address.  */
+    long current_size;         /* Current stack segment size.  This
+                                  number is actually corrupted by STKSTAT to
+                                  include the fifteen word trailer area.  */
+    long initial_address;      /* Address of initial segment.  */
+    long initial_size;         /* Size of initial segment.  */
+  };
+
+/* The following structure describes the data structure which trails
+   any stack segment.  I think that the description in 'asdef' is
+   out of date.  I only describe the parts that I am sure about.  */
+
+struct stk_trailer
+  {
+    long this_address;         /* Address of this block.  */
+    long this_size;            /* Size of this block (does not include
+                                  this trailer).  */
+    long unknown2;
+    long unknown3;
+    long link;                 /* Address of trailer block of previous
+                                  segment.  */
+    long unknown5;
+    long unknown6;
+    long unknown7;
+    long unknown8;
+    long unknown9;
+    long unknown10;
+    long unknown11;
+    long unknown12;
+    long unknown13;
+    long unknown14;
+  };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+   I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+  struct stk_stat status;
+  struct stk_trailer *trailer;
+  long *block, size;
+  long result = 0;
+
+  /* We want to iterate through all of the segments.  The first
+     step is to get the stack status structure.  We could do this
+     more quickly and more directly, perhaps, by referencing the
+     $LM00 common block, but I know that this works.  */
+
+  STKSTAT (&status);
+
+  /* Set up the iteration.  */
+
+  trailer = (struct stk_trailer *) (status.current_address
+                                   + status.current_size
+                                   - 15);
+
+  /* There must be at least one stack segment.  Therefore it is
+     a fatal error if "trailer" is null.  */
+
+  if (trailer == 0)
+    abort ();
+
+  /* Discard segments that do not contain our argument address.  */
+
+  while (trailer != 0)
+    {
+      block = (long *) trailer->this_address;
+      size = trailer->this_size;
+      if (block == 0 || size == 0)
+       abort ();
+      trailer = (struct stk_trailer *) trailer->link;
+      if ((block <= address) && (address < (block + size)))
+       break;
+    }
+
+  /* Set the result to the offset in this segment and add the sizes
+     of all predecessor segments.  */
+
+  result = address - block;
+
+  if (trailer == 0)
+    {
+      return result;
+    }
+
+  do
+    {
+      if (trailer->this_size <= 0)
+       abort ();
+      result += trailer->this_size;
+      trailer = (struct stk_trailer *) trailer->link;
+    }
+  while (trailer != 0);
+
+  /* We are done.  Note that if you present a bogus address (one
+     not in any segment), you will get a different number back, formed
+     from subtracting the address of the first block.  This is probably
+     not what you want.  */
+
+  return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+   Determine the number of the cell within the stack,
+   given the address of the cell.  The purpose of this
+   routine is to linearize, in some sense, stack addresses
+   for alloca.  */
+
+static long
+i00afunc (long address)
+{
+  long stkl = 0;
+
+  long size, pseg, this_segment, stack;
+  long result = 0;
+
+  struct stack_segment_linkage *ssptr;
+
+  /* Register B67 contains the address of the end of the
+     current stack segment.  If you (as a subprogram) store
+     your registers on the stack and find that you are past
+     the contents of B67, you have overflowed the segment.
+
+     B67 also points to the stack segment linkage control
+     area, which is what we are really interested in.  */
+
+  stkl = CRAY_STACKSEG_END ();
+  ssptr = (struct stack_segment_linkage *) stkl;
+
+  /* If one subtracts 'size' from the end of the segment,
+     one has the address of the first word of the segment.
+
+     If this is not the first segment, 'pseg' will be
+     nonzero.  */
+
+  pseg = ssptr->sspseg;
+  size = ssptr->sssize;
+
+  this_segment = stkl - size;
+
+  /* It is possible that calling this routine itself caused
+     a stack overflow.  Discard stack segments which do not
+     contain the target address.  */
+
+  while (!(this_segment <= address && address <= stkl))
+    {
+#ifdef DEBUG_I00AFUNC
+      fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+      if (pseg == 0)
+       break;
+      stkl = stkl - pseg;
+      ssptr = (struct stack_segment_linkage *) stkl;
+      size = ssptr->sssize;
+      pseg = ssptr->sspseg;
+      this_segment = stkl - size;
+    }
+
+  result = address - this_segment;
+
+  /* If you subtract pseg from the current end of the stack,
+     you get the address of the previous stack segment's end.
+     This seems a little convoluted to me, but I'll bet you save
+     a cycle somewhere.  */
+
+  while (pseg != 0)
+    {
+#ifdef DEBUG_I00AFUNC
+      fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+      stkl = stkl - pseg;
+      ssptr = (struct stack_segment_linkage *) stkl;
+      size = ssptr->sssize;
+      pseg = ssptr->sspseg;
+      result += size;
+    }
+  return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
index 47befcbc7771f3223bbd78bd0535f18700ad6cf5..68a2684566da0891d37b506e973b470fec3b6b04 100644 (file)
@@ -8,8 +8,43 @@
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #else
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #else
-#error you must define uint32_t, uint16_t etc.
+#if SIZEOF_UNSIGNED_LONG_LONG==8
+typedef unsigned long long uint64_t;
+#elif SIZEOF_UNSIGNED_LONG==8
+typedef unsigned long uint64_t;
+#else
+#error I do not know what to use for a uint64_t.
+#endif
+
+/* Give us an unsigned 32-bit data type. */
+#if SIZEOF_UNSIGNED_LONG==4
+typedef unsigned long uint32_t;
+#elif SIZEOF_UNSIGNED_INT==4
+typedef unsigned int uint32_t;
+#else
+#error I do not know what to use for a uint32_t.
+#endif
+
+/* An unsigned 16-bit data type. */
+#if SIZEOF_UNSIGNED_INT==2
+typedef unsigned int uint16_t;
+#elif SIZEOF_UNSIGNED_SHORT==2
+typedef unsigned short uint16_t;
+#else
+#error I do not know what to use for a uint16_t.
 #endif
 #endif
+
+/* An unsigned 8-bit data type */
+#if SIZEOF_UNSIGNED_CHAR==1
+typedef unsigned char uint8_t;
+#else
+#error I do not know what to use for a uint8_t.
+#endif
+#endif
+#endif
+
+#ifndef HAVE_SNPRINTF
+#include "snprintf.h"
 #endif
 
 #endif /* _CONFIG_H */
 #endif
 
 #endif /* _CONFIG_H */
index 54e8a6fcfe06e5706bb15ab4ba932b9f0810b02a..1984cee58db302bc3c587915535b3fc0c1a6cdc9 100644 (file)
@@ -3,6 +3,28 @@
 #define _CONFIG_H
 
 
 #define _CONFIG_H
 
 
+/* Define if using alloca.c.  */
+#undef C_ALLOCA
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro.  */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#undef HAVE_ALLOCA_H
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
 /* Define if you have the ANSI C header files.  */
 #undef STDC_HEADERS
 
 /* Define if you have the ANSI C header files.  */
 #undef STDC_HEADERS
 
    byte first (like Motorola and SPARC, unlike Intel and VAX).  */
 #undef WORDS_BIGENDIAN
 
    byte first (like Motorola and SPARC, unlike Intel and VAX).  */
 #undef WORDS_BIGENDIAN
 
+/* The number of bytes in a unsigned char.  */
+#undef SIZEOF_UNSIGNED_CHAR
+
+/* The number of bytes in a unsigned int.  */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The number of bytes in a unsigned long.  */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The number of bytes in a unsigned long long.  */
+#undef SIZEOF_UNSIGNED_LONG_LONG
+
+/* The number of bytes in a unsigned short.  */
+#undef SIZEOF_UNSIGNED_SHORT
+
+/* Define if you have the getopt_long function.  */
+#undef HAVE_GETOPT_LONG
+
+/* Define if you have the snprintf function.  */
+#undef HAVE_SNPRINTF
+
 /* Define if you have the <inttypes.h> header file.  */
 #undef HAVE_INTTYPES_H
 
 /* Define if you have the <inttypes.h> header file.  */
 #undef HAVE_INTTYPES_H
 
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #else
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #else
-#error you must define uint32_t, uint16_t etc.
+#if SIZEOF_UNSIGNED_LONG_LONG==8
+typedef unsigned long long uint64_t;
+#elif SIZEOF_UNSIGNED_LONG==8
+typedef unsigned long uint64_t;
+#else
+#error I do not know what to use for a uint64_t.
 #endif
 #endif
+
+/* Give us an unsigned 32-bit data type. */
+#if SIZEOF_UNSIGNED_LONG==4
+typedef unsigned long uint32_t;
+#elif SIZEOF_UNSIGNED_INT==4
+typedef unsigned int uint32_t;
+#else
+#error I do not know what to use for a uint32_t.
+#endif
+
+/* An unsigned 16-bit data type. */
+#if SIZEOF_UNSIGNED_INT==2
+typedef unsigned int uint16_t;
+#elif SIZEOF_UNSIGNED_SHORT==2
+typedef unsigned short uint16_t;
+#else
+#error I do not know what to use for a uint16_t.
+#endif
+
+/* An unsigned 8-bit data type */
+#if SIZEOF_UNSIGNED_CHAR==1
+typedef unsigned char uint8_t;
+#else
+#error I do not know what to use for a uint8_t.
+#endif
+#endif
+#endif
+
+#ifndef HAVE_SNPRINTF
+#include "snprintf.h"
 #endif
 
 #endif /* _CONFIG_H */
 #endif
 
 #endif /* _CONFIG_H */
index b834570c20d1f4ad38c8b774324ce8fcafc81692..fb7aef33e0afca7bff1d361a28f1e1b9a2a0c87f 100755 (executable)
--- a/configure
+++ b/configure
@@ -1254,9 +1254,209 @@ EOF
 
 fi
 
 
 fi
 
+echo $ac_n "checking size of unsigned long long""... $ac_c" 1>&6
+echo "configure:1259: checking size of unsigned long long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_long_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1267 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned long long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_long_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_long_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+EOF
+
+
+echo $ac_n "checking size of unsigned long""... $ac_c" 1>&6
+echo "configure:1299: checking size of unsigned long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1307 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+EOF
+
+
+echo $ac_n "checking size of unsigned int""... $ac_c" 1>&6
+echo "configure:1339: checking size of unsigned int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1347 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+EOF
+
+
+echo $ac_n "checking size of unsigned short""... $ac_c" 1>&6
+echo "configure:1379: checking size of unsigned short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_short'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1387 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned short));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_short=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+EOF
+
+
+echo $ac_n "checking size of unsigned char""... $ac_c" 1>&6
+echo "configure:1419: checking size of unsigned char" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_char'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1427 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(unsigned char));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_unsigned_char=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_unsigned_char=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_char" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_CHAR $ac_cv_sizeof_unsigned_char
+EOF
+
+
 
 echo $ac_n "checking for mpz_init_set_str in -lgmp""... $ac_c" 1>&6
 
 echo $ac_n "checking for mpz_init_set_str in -lgmp""... $ac_c" 1>&6
-echo "configure:1260: checking for mpz_init_set_str in -lgmp" >&5
+echo "configure:1460: checking for mpz_init_set_str in -lgmp" >&5
 ac_lib_var=`echo gmp'_'mpz_init_set_str | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo gmp'_'mpz_init_set_str | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1264,7 +1464,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgmp  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-lgmp  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1268 "configure"
+#line 1468 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1275,7 +1475,7 @@ int main() {
 mpz_init_set_str()
 ; return 0; }
 EOF
 mpz_init_set_str()
 ; return 0; }
 EOF
-if { (eval echo configure:1279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1303,7 +1503,7 @@ else
 fi
 
 echo $ac_n "checking for mpz_init_set_str in -lgmp2""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking for mpz_init_set_str in -lgmp2""... $ac_c" 1>&6
-echo "configure:1307: checking for mpz_init_set_str in -lgmp2" >&5
+echo "configure:1507: checking for mpz_init_set_str in -lgmp2" >&5
 ac_lib_var=`echo gmp2'_'mpz_init_set_str | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo gmp2'_'mpz_init_set_str | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1311,7 +1511,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgmp2  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-lgmp2  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1315 "configure"
+#line 1515 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1322,7 +1522,7 @@ int main() {
 mpz_init_set_str()
 ; return 0; }
 EOF
 mpz_init_set_str()
 ; return 0; }
 EOF
-if { (eval echo configure:1326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1350,7 +1550,7 @@ else
 fi
 
 echo $ac_n "checking for yywrap in -lfl""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking for yywrap in -lfl""... $ac_c" 1>&6
-echo "configure:1354: checking for yywrap in -lfl" >&5
+echo "configure:1554: checking for yywrap in -lfl" >&5
 ac_lib_var=`echo fl'_'yywrap | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo fl'_'yywrap | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1358,7 +1558,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lfl  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-lfl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1362 "configure"
+#line 1562 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1369,7 +1569,7 @@ int main() {
 yywrap()
 ; return 0; }
 EOF
 yywrap()
 ; return 0; }
 EOF
-if { (eval echo configure:1373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1397,7 +1597,7 @@ else
 fi
 
 echo $ac_n "checking for adns_init in -ladns""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking for adns_init in -ladns""... $ac_c" 1>&6
-echo "configure:1401: checking for adns_init in -ladns" >&5
+echo "configure:1601: checking for adns_init in -ladns" >&5
 ac_lib_var=`echo adns'_'adns_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo adns'_'adns_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1405,7 +1605,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ladns  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-ladns  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1409 "configure"
+#line 1609 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1416,7 +1616,7 @@ int main() {
 adns_init()
 ; return 0; }
 EOF
 adns_init()
 ; return 0; }
 EOF
-if { (eval echo configure:1420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1444,7 +1644,7 @@ else
 fi
 
 echo $ac_n "checking for getopt_long in -lgetopt""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking for getopt_long in -lgetopt""... $ac_c" 1>&6
-echo "configure:1448: checking for getopt_long in -lgetopt" >&5
+echo "configure:1648: checking for getopt_long in -lgetopt" >&5
 ac_lib_var=`echo getopt'_'getopt_long | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo getopt'_'getopt_long | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1452,7 +1652,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgetopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-lgetopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1456 "configure"
+#line 1656 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1463,7 +1663,7 @@ int main() {
 getopt_long()
 ; return 0; }
 EOF
 getopt_long()
 ; return 0; }
 EOF
-if { (eval echo configure:1467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1491,7 +1691,7 @@ else
 fi
 
 echo $ac_n "checking for getopt_long in -lgnugetopt""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking for getopt_long in -lgnugetopt""... $ac_c" 1>&6
-echo "configure:1495: checking for getopt_long in -lgnugetopt" >&5
+echo "configure:1695: checking for getopt_long in -lgnugetopt" >&5
 ac_lib_var=`echo gnugetopt'_'getopt_long | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo gnugetopt'_'getopt_long | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1499,7 +1699,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgnugetopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-lgnugetopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1503 "configure"
+#line 1703 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1510,7 +1710,7 @@ int main() {
 getopt_long()
 ; return 0; }
 EOF
 getopt_long()
 ; return 0; }
 EOF
-if { (eval echo configure:1514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1538,6 +1738,354 @@ else
 fi
 
 
 fi
 
 
+
+for ac_func in getopt_long 
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1746: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1751 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS getopt.o getopt1.o" 
+fi
+done
+for ac_func in snprintf 
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1802: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1807 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS snprintf.o" 
+fi
+done
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:1858: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1863 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:1870: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_header_alloca_h=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:1891: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1896 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:1924: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_func_alloca_works=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+  # that cause trouble.  Some versions do not even contain alloca or
+  # contain a buggy version.  If you still want to use their alloca,
+  # use ar to extract alloca.o from them instead of compiling alloca.c.
+  ALLOCA=alloca.${ac_objext}
+  cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:1956: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1961 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "webecray" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_os_cray=yes
+else
+  rm -rf conftest*
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+  echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1986: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1991 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2014: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+  break
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:2041: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_stack_direction=0
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2049 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+  exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:2068: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_stack_direction=1
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+
 trap '' 1 2 15
 cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
 trap '' 1 2 15
 cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
@@ -1678,6 +2226,8 @@ s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
 s%@RM@%$RM%g
 s%@CPP@%$CPP%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
 s%@RM@%$RM%g
 s%@CPP@%$CPP%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@ALLOCA@%$ALLOCA%g
 
 CEOF
 EOF
 
 CEOF
 EOF
index 8cffe5eed2ceae7b627d5756b83ccba99f7a385c..3fc0cd21f2404f6c750eea1dfd9cde615a9a0b95 100644 (file)
@@ -15,6 +15,11 @@ AC_STDC_HEADERS
 AC_CHECK_HEADERS(stdint.h inttypes.h)
 AC_CHECK_HEADERS(linux/if.h)
 AC_C_BIGENDIAN
 AC_CHECK_HEADERS(stdint.h inttypes.h)
 AC_CHECK_HEADERS(linux/if.h)
 AC_C_BIGENDIAN
+AC_CHECK_SIZEOF(unsigned long long)
+AC_CHECK_SIZEOF(unsigned long)
+AC_CHECK_SIZEOF(unsigned int)
+AC_CHECK_SIZEOF(unsigned short)
+AC_CHECK_SIZEOF(unsigned char)
 
 AC_CHECK_LIB(gmp,mpz_init_set_str)
 AC_CHECK_LIB(gmp2,mpz_init_set_str)
 
 AC_CHECK_LIB(gmp,mpz_init_set_str)
 AC_CHECK_LIB(gmp2,mpz_init_set_str)
@@ -23,4 +28,11 @@ AC_CHECK_LIB(adns,adns_init)
 AC_CHECK_LIB(getopt,getopt_long)
 AC_CHECK_LIB(gnugetopt,getopt_long)
 
 AC_CHECK_LIB(getopt,getopt_long)
 AC_CHECK_LIB(gnugetopt,getopt_long)
 
+dnl check for getopt in standard library
+AC_SUBST(LIBOBJS)
+AC_CHECK_FUNCS(getopt_long , , [LIBOBJS="$LIBOBJS getopt.o getopt1.o"] ) 
+dnl check for alloca
+AC_CHECK_FUNCS(snprintf , , [LIBOBJS="$LIBOBJS snprintf.o"] )
+AC_FUNC_ALLOCA()
+
 AC_OUTPUT(Makefile,echo timestamp >stamp-h)
 AC_OUTPUT(Makefile,echo timestamp >stamp-h)
index 4c42dd4bc110269c5f5e88995bf79179320695c5..23f75aed314a696a9e7040cdb24c7d40e84919f2 100644 (file)
@@ -1,4 +1,4 @@
-secnet (0.1.7-1) unstable; urgency=low
+secnet (0.1.9-1) unstable; urgency=low
 
   * New upstream version.
 
 
   * New upstream version.
 
index 461d52a9caed122fa0713e6e8cbee96ebfa7b8c9..3062ed1559ced62b984089dc0cb7b05a323c7005 100644 (file)
@@ -6,7 +6,7 @@ Standards-Version: 3.0.1
 
 Package: secnet
 Architecture: any
 
 Package: secnet
 Architecture: any
-Depends: ${shlibs:Depends}
+Depends: ${shlibs:Depends}, python-base
 Description: VPN software for distributed networks
  secnet allows multiple private networks, each 'hidden' behind a single
  globally-routable IP address, to be bridged together.
 Description: VPN software for distributed networks
  secnet allows multiple private networks, each 'hidden' behind a single
  globally-routable IP address, to be bridged together.
index e8219237d54e3c25ae8b7ff217b39c914d2ed3d5..1638b952225a3f48722a2e53d8603a4de64eb13a 100644 (file)
@@ -1 +1 @@
-secnet_0.1.1-1_i386.deb net extra
+secnet_0.1.9-1_i386.deb net extra
index 761c122f9d4b9781ea072c2db5165e0b2e336f62..c22b55f4c59392bdaf985a337c537cb55a2741db 100644 (file)
@@ -14,9 +14,9 @@
 set -e
 
 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 set -e
 
 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-DAEMON=/usr/sbin/bnetd
+DAEMON=/usr/sbin/secnet
 NAME=secnet
 NAME=secnet
-DESC=VPN server
+DESC="VPN server"
 
 test -f $DAEMON || exit 0
 test -f /etc/secnet/secnet.conf || exit 0
 
 test -f $DAEMON || exit 0
 test -f /etc/secnet/secnet.conf || exit 0
index ca7a449db29bdb93949b24b8126d17aabbbb23a3..a85db21905e6704de6645a4342bd1fbab0d53b73 100755 (executable)
@@ -7,7 +7,7 @@
 #export DH_VERBOSE=1
 
 # This is the debhelper compatibility version to use.
 #export DH_VERBOSE=1
 
 # This is the debhelper compatibility version to use.
-export DH_COMPAT=3
+export DH_COMPAT=2
 
 build: build-stamp
 build-stamp:
 
 build: build-stamp
 build-stamp:
@@ -46,8 +46,8 @@ binary-arch: build install
        dh_testdir
        dh_testroot
 #      dh_installdebconf       
        dh_testdir
        dh_testroot
 #      dh_installdebconf       
-       dh_installdocs INSTALL README NOTES TODO
-       dh_installexamples example.conf make-secnet-sites.py ipaddr.py
+       dh_installdocs INSTALL README NOTES TODO NEWS
+       dh_installexamples example.conf
 #      dh_installmenu
 #      dh_installlogrotate
 #      dh_installemacsen
 #      dh_installmenu
 #      dh_installlogrotate
 #      dh_installemacsen
diff --git a/getopt.c b/getopt.c
new file mode 100644 (file)
index 0000000..a59a013
--- /dev/null
+++ b/getopt.c
@@ -0,0 +1,731 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+       Free Software Foundation, Inc.
+
+   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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+\f
+/* NOTE!!!  AIX requires this to be the first thing in the file.
+   Do not put ANYTHING before it!  */
+#if !defined (__GNUC__) && defined (_AIX)
+ #pragma alloca
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
+#include <alloca.h>
+#else
+#ifndef _AIX
+char *alloca ();
+#endif
+#endif /* alloca.h */
+#endif /* not __GNUC__ */
+
+#if !__STDC__ && !defined(const) && IN_GCC
+#define const
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#undef alloca
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#else  /* Not GNU C library.  */
+#define        __alloca        alloca
+#endif /* GNU C library.  */
+
+/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
+   long-named option.  Because this is not POSIX.2 compliant, it is
+   being phased out.  */
+/* #define GETOPT_COMPAT */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define        my_index        strchr
+#define        my_bcopy(src, dst, n)   memcpy ((dst), (src), (n))
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+static void
+my_bcopy (from, to, size)
+     const char *from;
+     char *to;
+     int size;
+{
+  int i;
+  for (i = 0; i < size; i++)
+    to[i] = from[i];
+}
+#endif                         /* GNU C library.  */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
+  char **temp = (char **) __alloca (nonopts_size);
+
+  /* Interchange the two blocks of data in ARGV.  */
+
+  my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
+  my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
+           (optind - last_nonopt) * sizeof (char *));
+  my_bcopy ((char *) temp,
+           (char *) &argv[first_nonopt + optind - last_nonopt],
+           nonopts_size);
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int option_index;
+
+  optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (optind == 0)
+    {
+      first_nonopt = last_nonopt = optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+       {
+         ordering = RETURN_IN_ORDER;
+         ++optstring;
+       }
+      else if (optstring[0] == '+')
+       {
+         ordering = REQUIRE_ORDER;
+         ++optstring;
+       }
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+       ordering = REQUIRE_ORDER;
+      else
+       ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+       {
+         /* If we have just processed some options following some non-options,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Now skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc
+                && (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+                && (longopts == NULL
+                    || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif                         /* GETOPT_COMPAT */
+                )
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* Special ARGV-element `--' means premature end of options.
+        Skip it like a null option,
+        then exchange with previous non-options as if it were an option,
+        then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           optind = first_nonopt;
+         return EOF;
+       }
+
+      /* If we have come to a non-option and did not permute it,
+        either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+         && (longopts == NULL
+             || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif                         /* GETOPT_COMPAT */
+         )
+       {
+         if (ordering == REQUIRE_ORDER)
+           return EOF;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Start decoding its characters.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[optind][0] == '-'
+          && (argv[optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+         || argv[optind][0] == '+'
+#endif                         /* GETOPT_COMPAT */
+         ))
+    {
+      const struct option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct option *pfound = NULL;
+      int indfound;
+
+      while (*s && *s != '=')
+       s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+          p++, option_index++)
+       if (!strncmp (p->name, nextchar, s - nextchar))
+         {
+           if (s - nextchar == strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else
+             /* Second nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (opterr)
+           fprintf (stderr, "%s: option `%s' is ambiguous\n",
+                    argv[0], argv[optind]);
+         nextchar += strlen (nextchar);
+         optind++;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*s)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = s + 1;
+             else
+               {
+                 if (opterr)
+                   {
+                     if (argv[optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                "%s: option `--%s' doesn't allow an argument\n",
+                                argv[0], pfound->name);
+                     else
+                       /* +option or -option */
+                       fprintf (stderr,
+                            "%s: option `%c%s' doesn't allow an argument\n",
+                            argv[0], argv[optind - 1][0], pfound->name);
+                   }
+                 nextchar += strlen (nextchar);
+                 return '?';
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (optind < argc)
+               optarg = argv[optind++];
+             else
+               {
+                 if (opterr)
+                   fprintf (stderr, "%s: option `%s' requires an argument\n",
+                            argv[0], argv[optind - 1]);
+                 nextchar += strlen (nextchar);
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+#ifdef GETOPT_COMPAT
+         || argv[optind][0] == '+'
+#endif                         /* GETOPT_COMPAT */
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (opterr)
+           {
+             if (argv[optind][1] == '-')
+               /* --option */
+               fprintf (stderr, "%s: unrecognized option `--%s'\n",
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+                        argv[0], argv[optind][0], nextchar);
+           }
+         nextchar = (char *) "";
+         optind++;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (opterr)
+         {
+#if 0
+           if (c < 040 || c >= 0177)
+             fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+                      argv[0], c);
+           else
+             fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+           /* 1003.2 specifies the format of this message.  */
+           fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+         }
+       optopt = c;
+       return '?';
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = 0;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* This is an option that requires an argument.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               /* If we end this ARGV-element by taking the rest as an arg,
+                  we must advance to the next element now.  */
+               optind++;
+             }
+           else if (optind == argc)
+             {
+               if (opterr)
+                 {
+#if 0
+                   fprintf (stderr, "%s: option `-%c' requires an argument\n",
+                            argv[0], c);
+#else
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr, "%s: option requires an argument -- %c\n",
+                            argv[0], c);
+#endif
+                 }
+               optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/getopt.h b/getopt.h
new file mode 100644 (file)
index 0000000..45541f5
--- /dev/null
+++ b/getopt.h
@@ -0,0 +1,129 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+   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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if    __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define        no_argument             0
+#define required_argument      1
+#define optional_argument      2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+                       const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/getopt1.c b/getopt1.c
new file mode 100644 (file)
index 0000000..a32615c
--- /dev/null
+++ b/getopt1.c
@@ -0,0 +1,176 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+       Free Software Foundation, Inc.
+
+   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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+\f
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "getopt.h"
+
+#if !__STDC__ && !defined(const) && IN_GCC
+#define const
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#else
+char *getenv ();
+#endif
+
+#ifndef        NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* _LIBC or not __GNU_LIBRARY__.  */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+       {"add", 1, 0, 0},
+       {"append", 0, 0, 0},
+       {"delete", 1, 0, 0},
+       {"verbose", 0, 0, 0},
+       {"create", 0, 0, 0},
+       {"file", 1, 0, 0},
+       {0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+                      long_options, &option_index);
+      if (c == EOF)
+       break;
+
+      switch (c)
+       {
+       case 0:
+         printf ("option %s", long_options[option_index].name);
+         if (optarg)
+           printf (" with arg %s", optarg);
+         printf ("\n");
+         break;
+
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case 'd':
+         printf ("option d with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/log.c b/log.c
index 0981506cc696116a5223a5d783cdcd3d08e53d4e..dd51b25984028a513f7308c9da3d9bc139f7f104 100644 (file)
--- a/log.c
+++ b/log.c
@@ -364,7 +364,12 @@ static void syslog_log(void *sst, int priority, char *message, ...)
 }
 
 static struct flagstr syslog_facility_table[]={
 }
 
 static struct flagstr syslog_facility_table[]={
+#ifdef LOG_AUTH
+    { "auth", LOG_AUTH },
+#endif
+#ifdef LOG_AUTHPRIV
     { "authpriv", LOG_AUTHPRIV },
     { "authpriv", LOG_AUTHPRIV },
+#endif
     { "cron", LOG_CRON },
     { "daemon", LOG_DAEMON },
     { "kern", LOG_KERN },
     { "cron", LOG_CRON },
     { "daemon", LOG_DAEMON },
     { "kern", LOG_KERN },
similarity index 99%
rename from make-secnet-sites.py
rename to make-secnet-sites
index cb2b9e88054159be7dbfc88238604ac8111d3054..fb8802863adeaacacb2760a407e18f9d2e778300 100755 (executable)
@@ -53,9 +53,12 @@ import string
 import time
 import sys
 import os
 import time
 import sys
 import os
+
+sys.path.append("/usr/local/share/secnet")
+sys.path.append("/usr/share/secnet")
 import ipaddr
 
 import ipaddr
 
-VERSION="0.1.5"
+VERSION="0.1.9"
 
 class vpn:
        def __init__(self,name):
 
 class vpn:
        def __init__(self,name):
index f77d6bd8ff4ddd9813723b4ac3de12ea4822bb6f..b7cdb4cdef4a4ca6496f18b2ffa0cd08f3900f57 100644 (file)
--- a/netlink.c
+++ b/netlink.c
@@ -177,11 +177,19 @@ static void netlink_icmp_csum(struct icmphdr *h)
 static bool_t netlink_icmp_may_reply(struct buffer_if *buf)
 {
     struct iphdr *iph;
 static bool_t netlink_icmp_may_reply(struct buffer_if *buf)
 {
     struct iphdr *iph;
+    struct icmphdr *icmph;
     uint32_t source;
 
     iph=(struct iphdr *)buf->start;
     uint32_t source;
 
     iph=(struct iphdr *)buf->start;
-    if (iph->protocol==1) return False; /* Overly-broad; we may reply to
-                                          eg. icmp echo-request */
+    icmph=(struct icmphdr *)buf->start;
+    if (iph->protocol==1) {
+       switch(icmph->type) {
+       case 3: /* Destination unreachable */
+       case 11: /* Time Exceeded */
+       case 12: /* Parameter Problem */
+           return False;
+       }
+    }
     /* How do we spot broadcast destination addresses? */
     if (ntohs(iph->frag_off)&0x1fff) return False; /* Non-initial fragment */
     source=ntohl(iph->saddr);
     /* How do we spot broadcast destination addresses? */
     if (ntohs(iph->frag_off)&0x1fff) return False; /* Non-initial fragment */
     source=ntohl(iph->saddr);
index 489e0bf381e3686acb28433d4077dab953c78e66..57b4f052074d8a471c4936cd8b4952d3407f9759 100644 (file)
--- a/secnet.c
+++ b/secnet.c
@@ -342,6 +342,10 @@ static void droppriv(void)
        } else if (p==0) {
            /* Child process - all done, just carry on */
            if (pf) fclose(pf);
        } else if (p==0) {
            /* Child process - all done, just carry on */
            if (pf) fclose(pf);
+           /* Close stdin, stdout and stderr; we don't need them any more */
+           close(0);
+           close(1);
+           close(2);
            secnet_is_daemon=True;
        } else {
            /* Error */
            secnet_is_daemon=True;
        } else {
            /* Error */
diff --git a/sha1.c b/sha1.c
index c378a9d5aa80082b4ff438e7a95ac288b7850a8b..d85e0a83975f15f9089bf02d7081c57d48ddb68a 100644 (file)
--- a/sha1.c
+++ b/sha1.c
@@ -97,9 +97,9 @@ typedef unsigned long int uint32;
 #endif /* 0 */
 
 /* Get types and defines from the secnet configuration */
 #endif /* 0 */
 
 /* Get types and defines from the secnet configuration */
-typedef int64_t int64;
+/* typedef int64_t int64; */
 typedef uint64_t uint64;
 typedef uint64_t uint64;
-typedef int32_t int32;
+/* typedef int32_t int32; */
 typedef uint32_t uint32;
 
 /* #include <process.h> */     /* prototype for exit() - JHB */
 typedef uint32_t uint32;
 
 /* #include <process.h> */     /* prototype for exit() - JHB */
diff --git a/snprintf.c b/snprintf.c
new file mode 100644 (file)
index 0000000..86f42e9
--- /dev/null
@@ -0,0 +1,1025 @@
+/*
+ * snprintf.c - a portable implementation of snprintf
+ *
+ * AUTHOR
+ *   Mark Martinec <mark.martinec@ijs.si>, April 1999.
+ *
+ *   Copyright 1999, Mark Martinec. All rights reserved.
+ *
+ * TERMS AND CONDITIONS
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the "Frontier Artistic License" which comes
+ *   with this Kit.
+ *
+ *   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 Frontier Artistic License for more details.
+ *
+ *   You should have received a copy of the Frontier Artistic License
+ *   with this Kit in the file named LICENSE.txt .
+ *   If not, I'll be glad to provide one.
+ *
+ * FEATURES
+ * - careful adherence to specs regarding flags, field width and precision;
+ * - good performance for large string handling (large format, large
+ *   argument or large paddings). Performance is similar to system's sprintf
+ *   and in several cases significantly better (make sure you compile with
+ *   optimizations turned on, tell the compiler the code is strict ANSI
+ *   if necessary to give it more freedom for optimizations);
+ * - return value semantics per ISO/IEC 9899:1999 ("ISO C99");
+ * - written in standard ISO/ANSI C - requires an ANSI C compiler.
+ *
+ * SUPPORTED CONVERSION SPECIFIERS AND DATA TYPES
+ *
+ * This snprintf only supports the following conversion specifiers:
+ * s, c, d, u, o, x, X, p  (and synonyms: i, D, U, O - see below)
+ * with flags: '-', '+', ' ', '0' and '#'.
+ * An asterisk is supported for field width as well as precision.
+ *
+ * Length modifiers 'h' (short int), 'l' (long int),
+ * and 'll' (long long int) are supported.
+ * NOTE:
+ *   If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default) the
+ *   length modifier 'll' is recognized but treated the same as 'l',
+ *   which may cause argument value truncation! Defining
+ *   SNPRINTF_LONGLONG_SUPPORT requires that your system's sprintf also
+ *   handles length modifier 'll'.  long long int is a language extension
+ *   which may not be portable.
+ *
+ * Conversion of numeric data (conversion specifiers d, u, o, x, X, p)
+ * with length modifiers (none or h, l, ll) is left to the system routine
+ * sprintf, but all handling of flags, field width and precision as well as
+ * c and s conversions is done very carefully by this portable routine.
+ * If a string precision (truncation) is specified (e.g. %.8s) it is
+ * guaranteed the string beyond the specified precision will not be referenced.
+ *
+ * Length modifiers h, l and ll are ignored for c and s conversions (data
+ * types wint_t and wchar_t are not supported).
+ *
+ * The following common synonyms for conversion characters are supported:
+ *   - i is a synonym for d
+ *   - D is a synonym for ld, explicit length modifiers are ignored
+ *   - U is a synonym for lu, explicit length modifiers are ignored
+ *   - O is a synonym for lo, explicit length modifiers are ignored
+ * The D, O and U conversion characters are nonstandard, they are supported
+ * for backward compatibility only, and should not be used for new code.
+ *
+ * The following is specifically NOT supported:
+ *   - flag ' (thousands' grouping character) is recognized but ignored
+ *   - numeric conversion specifiers: f, e, E, g, G and synonym F,
+ *     as well as the new a and A conversion specifiers
+ *   - length modifier 'L' (long double) and 'q' (quad - use 'll' instead)
+ *   - wide character/string conversions: lc, ls, and nonstandard
+ *     synonyms C and S
+ *   - writeback of converted string length: conversion character n
+ *   - the n$ specification for direct reference to n-th argument
+ *   - locales
+ *
+ * It is permitted for str_m to be zero, and it is permitted to specify NULL
+ * pointer for resulting string argument if str_m is zero (as per ISO C99).
+ *
+ * The return value is the number of characters which would be generated
+ * for the given input, excluding the trailing null. If this value
+ * is greater or equal to str_m, not all characters from the result
+ * have been stored in str, output bytes beyond the (str_m-1) -th character
+ * are discarded. If str_m is greater than zero it is guaranteed
+ * the resulting string will be null-terminated.
+ *
+ * NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1,
+ * but is different from some older and vendor implementations,
+ * and is also different from XPG, XSH5, SUSv2 specifications.
+ * For historical discussion on changes in the semantics and standards
+ * of snprintf see printf(3) man page in the Linux programmers manual.
+ *
+ * Routines asprintf and vasprintf return a pointer (in the ptr argument)
+ * to a buffer sufficiently large to hold the resulting string. This pointer
+ * should be passed to free(3) to release the allocated storage when it is
+ * no longer needed. If sufficient space cannot be allocated, these functions
+ * will return -1 and set ptr to be a NULL pointer. These two routines are a
+ * GNU C library extensions (glibc).
+ *
+ * Routines asnprintf and vasnprintf are similar to asprintf and vasprintf,
+ * yet, like snprintf and vsnprintf counterparts, will write at most str_m-1
+ * characters into the allocated output string, the last character in the
+ * allocated buffer then gets the terminating null. If the formatted string
+ * length (the return value) is greater than or equal to the str_m argument,
+ * the resulting string was truncated and some of the formatted characters
+ * were discarded. These routines present a handy way to limit the amount
+ * of allocated memory to some sane value.
+ *
+ * AVAILABILITY
+ *   http://www.ijs.si/software/snprintf/
+ *
+ * REVISION HISTORY
+ * 1999-04     V0.9  Mark Martinec
+ *             - initial version, some modifications after comparing printf
+ *               man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10,
+ *               and checking how Perl handles sprintf (differently!);
+ * 1999-04-09  V1.0  Mark Martinec <mark.martinec@ijs.si>
+ *             - added main test program, fixed remaining inconsistencies,
+ *               added optional (long long int) support;
+ * 1999-04-12  V1.1  Mark Martinec <mark.martinec@ijs.si>
+ *             - support the 'p' conversion (pointer to void);
+ *             - if a string precision is specified
+ *               make sure the string beyond the specified precision
+ *               will not be referenced (e.g. by strlen);
+ * 1999-04-13  V1.2  Mark Martinec <mark.martinec@ijs.si>
+ *             - support synonyms %D=%ld, %U=%lu, %O=%lo;
+ *             - speed up the case of long format string with few conversions;
+ * 1999-06-30  V1.3  Mark Martinec <mark.martinec@ijs.si>
+ *             - fixed runaway loop (eventually crashing when str_l wraps
+ *               beyond 2^31) while copying format string without
+ *               conversion specifiers to a buffer that is too short
+ *               (thanks to Edwin Young <edwiny@autonomy.com> for
+ *               spotting the problem);
+ *             - added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR)
+ *               to snprintf.h
+ * 2000-02-14  V2.0 (never released) Mark Martinec <mark.martinec@ijs.si>
+ *             - relaxed license terms: The Artistic License now applies.
+ *               You may still apply the GNU GENERAL PUBLIC LICENSE
+ *               as was distributed with previous versions, if you prefer;
+ *             - changed REVISION HISTORY dates to use ISO 8601 date format;
+ *             - added vsnprintf (patch also independently proposed by
+ *               Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01)
+ * 2000-06-27  V2.1  Mark Martinec <mark.martinec@ijs.si>
+ *             - removed POSIX check for str_m<1; value 0 for str_m is
+ *               allowed by ISO C99 (and GNU C library 2.1) - (pointed out
+ *               on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie).
+ *               Besides relaxed license this change in standards adherence
+ *               is the main reason to bump up the major version number;
+ *             - added nonstandard routines asnprintf, vasnprintf, asprintf,
+ *               vasprintf that dynamically allocate storage for the
+ *               resulting string; these routines are not compiled by default,
+ *               see comments where NEED_V?ASN?PRINTF macros are defined;
+ *             - autoconf contributed by Caolan McNamara
+ * 2000-10-06  V2.2  Mark Martinec <mark.martinec@ijs.si>
+ *             - BUG FIX: the %c conversion used a temporary variable
+ *               that was no longer in scope when referenced,
+ *               possibly causing incorrect resulting character;
+ *             - BUG FIX: make precision and minimal field width unsigned
+ *               to handle huge values (2^31 <= n < 2^32) correctly;
+ *               also be more careful in the use of signed/unsigned/size_t
+ *               internal variables - probably more careful than many
+ *               vendor implementations, but there may still be a case
+ *               where huge values of str_m, precision or minimal field
+ *               could cause incorrect behaviour;
+ *             - use separate variables for signed/unsigned arguments,
+ *               and for short/int, long, and long long argument lengths
+ *               to avoid possible incompatibilities on certain
+ *               computer architectures. Also use separate variable
+ *               arg_sign to hold sign of a numeric argument,
+ *               to make code more transparent;
+ *             - some fiddling with zero padding and "0x" to make it
+ *               Linux compatible;
+ *             - systematically use macros fast_memcpy and fast_memset
+ *               instead of case-by-case hand optimization; determine some
+ *               breakeven string lengths for different architectures;
+ *             - terminology change: 'format' -> 'conversion specifier',
+ *               'C9x' -> 'ISO/IEC 9899:1999 ("ISO C99")',
+ *               'alternative form' -> 'alternate form',
+ *               'data type modifier' -> 'length modifier';
+ *             - several comments rephrased and new ones added;
+ *             - make compiler not complain about 'credits' defined but
+ *               not used;
+ */
+
+
+/* Define HAVE_SNPRINTF if your system already has snprintf and vsnprintf.
+ *
+ * If HAVE_SNPRINTF is defined this module will not produce code for
+ * snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well,
+ * causing this portable version of snprintf to be called portable_snprintf
+ * (and portable_vsnprintf).
+ */
+/* #define HAVE_SNPRINTF */
+
+/* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and
+ * vsnprintf but you would prefer to use the portable routine(s) instead.
+ * In this case the portable routine is declared as portable_snprintf
+ * (and portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf')
+ * is defined to expand to 'portable_v?snprintf' - see file snprintf.h .
+ * Defining this macro is only useful if HAVE_SNPRINTF is also defined,
+ * but does does no harm if defined nevertheless.
+ */
+/* #define PREFER_PORTABLE_SNPRINTF */
+
+/* Define SNPRINTF_LONGLONG_SUPPORT if you want to support
+ * data type (long long int) and length modifier 'll' (e.g. %lld).
+ * If undefined, 'll' is recognized but treated as a single 'l'.
+ *
+ * If the system's sprintf does not handle 'll'
+ * the SNPRINTF_LONGLONG_SUPPORT must not be defined!
+ *
+ * This is off by default as (long long int) is a language extension.
+ */
+/* #define SNPRINTF_LONGLONG_SUPPORT */
+
+/* Define NEED_SNPRINTF_ONLY if you only need snprintf, and not vsnprintf.
+ * If NEED_SNPRINTF_ONLY is defined, the snprintf will be defined directly,
+ * otherwise both snprintf and vsnprintf routines will be defined
+ * and snprintf will be a simple wrapper around vsnprintf, at the expense
+ * of an extra procedure call.
+ */
+/* #define NEED_SNPRINTF_ONLY */
+
+/* Define NEED_V?ASN?PRINTF macros if you need library extension
+ * routines asprintf, vasprintf, asnprintf, vasnprintf respectively,
+ * and your system library does not provide them. They are all small
+ * wrapper routines around portable_vsnprintf. Defining any of the four
+ * NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY
+ * and turns on PREFER_PORTABLE_SNPRINTF.
+ *
+ * Watch for name conflicts with the system library if these routines
+ * are already present there.
+ *
+ * NOTE: vasprintf and vasnprintf routines need va_copy() from stdarg.h, as
+ * specified by C99, to be able to traverse the same list of arguments twice.
+ * I don't know of any other standard and portable way of achieving the same.
+ * With some versions of gcc you may use __va_copy(). You might even get away
+ * with "ap2 = ap", in this case you must not call va_end(ap2) !
+ *   #define va_copy(ap2,ap) ap2 = ap
+ */
+/* #define NEED_ASPRINTF   */
+/* #define NEED_ASNPRINTF  */
+/* #define NEED_VASPRINTF  */
+/* #define NEED_VASNPRINTF */
+
+
+/* Define the following macros if desired:
+ *   SOLARIS_COMPATIBLE, SOLARIS_BUG_COMPATIBLE,
+ *   HPUX_COMPATIBLE, HPUX_BUG_COMPATIBLE, LINUX_COMPATIBLE,
+ *   DIGITAL_UNIX_COMPATIBLE, DIGITAL_UNIX_BUG_COMPATIBLE,
+ *   PERL_COMPATIBLE, PERL_BUG_COMPATIBLE,
+ *
+ * - For portable applications it is best not to rely on peculiarities
+ *   of a given implementation so it may be best not to define any
+ *   of the macros that select compatibility and to avoid features
+ *   that vary among the systems.
+ *
+ * - Selecting compatibility with more than one operating system
+ *   is not strictly forbidden but is not recommended.
+ *
+ * - 'x'_BUG_COMPATIBLE implies 'x'_COMPATIBLE .
+ *
+ * - 'x'_COMPATIBLE refers to (and enables) a behaviour that is
+ *   documented in a sprintf man page on a given operating system
+ *   and actually adhered to by the system's sprintf (but not on
+ *   most other operating systems). It may also refer to and enable
+ *   a behaviour that is declared 'undefined' or 'implementation specific'
+ *   in the man page but a given implementation behaves predictably
+ *   in a certain way.
+ *
+ * - 'x'_BUG_COMPATIBLE refers to (and enables) a behaviour of system's sprintf
+ *   that contradicts the sprintf man page on the same operating system.
+ *
+ * - I do not claim that the 'x'_COMPATIBLE and 'x'_BUG_COMPATIBLE
+ *   conditionals take into account all idiosyncrasies of a particular
+ *   implementation, there may be other incompatibilities.
+ */
+
+
+\f
+/* ============================================= */
+/* NO USER SERVICABLE PARTS FOLLOWING THIS POINT */
+/* ============================================= */
+
+#define PORTABLE_SNPRINTF_VERSION_MAJOR 2
+#define PORTABLE_SNPRINTF_VERSION_MINOR 2
+
+#if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF)
+# if defined(NEED_SNPRINTF_ONLY)
+# undef NEED_SNPRINTF_ONLY
+# endif
+# if !defined(PREFER_PORTABLE_SNPRINTF)
+# define PREFER_PORTABLE_SNPRINTF
+# endif
+#endif
+
+#if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE)
+#define SOLARIS_COMPATIBLE
+#endif
+
+#if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE)
+#define HPUX_COMPATIBLE
+#endif
+
+#if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE)
+#define DIGITAL_UNIX_COMPATIBLE
+#endif
+
+#if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE)
+#define PERL_COMPATIBLE
+#endif
+
+#if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE)
+#define LINUX_COMPATIBLE
+#endif
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <errno.h>
+
+#ifdef isdigit
+#undef isdigit
+#endif
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+
+/* For copying strings longer or equal to 'breakeven_point'
+ * it is more efficient to call memcpy() than to do it inline.
+ * The value depends mostly on the processor architecture,
+ * but also on the compiler and its optimization capabilities.
+ * The value is not critical, some small value greater than zero
+ * will be just fine if you don't care to squeeze every drop
+ * of performance out of the code.
+ *
+ * Small values favor memcpy, large values favor inline code.
+ */
+#if defined(__alpha__) || defined(__alpha)
+#  define breakeven_point   2  /* AXP (DEC Alpha)     - gcc or cc or egcs */
+#endif
+#if defined(__i386__)  || defined(__i386)
+#  define breakeven_point  12  /* Intel Pentium/Linux - gcc 2.96 */
+#endif
+#if defined(__hppa)
+#  define breakeven_point  10  /* HP-PA               - gcc */
+#endif
+#if defined(__sparc__) || defined(__sparc)
+#  define breakeven_point  33  /* Sun Sparc 5         - gcc 2.8.1 */
+#endif
+
+/* some other values of possible interest: */
+/* #define breakeven_point  8 */  /* VAX 4000          - vaxc */
+/* #define breakeven_point 19 */  /* VAX 4000          - gcc 2.7.0 */
+
+#ifndef breakeven_point
+#  define breakeven_point   6  /* some reasonable one-size-fits-all value */
+#endif
+
+#define fast_memcpy(d,s,n) \
+  { register size_t nn = (size_t)(n); \
+    if (nn >= breakeven_point) memcpy((d), (s), nn); \
+    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\
+      register char *dd; register const char *ss; \
+      for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } }
+
+#define fast_memset(d,c,n) \
+  { register size_t nn = (size_t)(n); \
+    if (nn >= breakeven_point) memset((d), (int)(c), nn); \
+    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\
+      register char *dd; register const int cc=(int)(c); \
+      for (dd=(d); nn>0; nn--) *dd++ = cc; } }
+
+/* prototypes */
+
+#if defined(NEED_ASPRINTF)
+int asprintf   (char **ptr, const char *fmt, /*args*/ ...);
+#endif
+#if defined(NEED_VASPRINTF)
+int vasprintf  (char **ptr, const char *fmt, va_list ap);
+#endif
+#if defined(NEED_ASNPRINTF)
+int asnprintf  (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);
+#endif
+#if defined(NEED_VASNPRINTF)
+int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap);
+#endif
+
+#if defined(HAVE_SNPRINTF)
+/* declare our portable snprintf  routine under name portable_snprintf  */
+/* declare our portable vsnprintf routine under name portable_vsnprintf */
+#else
+/* declare our portable routines under names snprintf and vsnprintf */
+#define portable_snprintf snprintf
+#if !defined(NEED_SNPRINTF_ONLY)
+#define portable_vsnprintf vsnprintf
+#endif
+#endif
+
+#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);
+#if !defined(NEED_SNPRINTF_ONLY)
+int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);
+#endif
+#endif
+
+/* declarations */
+
+static char credits[] = "\n\
+@(#)snprintf.c, v2.2: Mark Martinec, <mark.martinec@ijs.si>\n\
+@(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\
+@(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n";
+
+#if defined(NEED_ASPRINTF)
+int asprintf(char **ptr, const char *fmt, /*args*/ ...) {
+  va_list ap;
+  size_t str_m;
+  int str_l;
+
+  *ptr = NULL;
+  va_start(ap, fmt);                            /* measure the required size */
+  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);
+  va_end(ap);
+  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
+  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);
+  if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
+  else {
+    int str_l2;
+    va_start(ap, fmt);
+    str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
+    va_end(ap);
+    assert(str_l2 == str_l);
+  }
+  return str_l;
+}
+#endif
+
+#if defined(NEED_VASPRINTF)
+int vasprintf(char **ptr, const char *fmt, va_list ap) {
+  size_t str_m;
+  int str_l;
+
+  *ptr = NULL;
+  { va_list ap2;
+    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */
+    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/
+    va_end(ap2);
+  }
+  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
+  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);
+  if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
+  else {
+    int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
+    assert(str_l2 == str_l);
+  }
+  return str_l;
+}
+#endif
+
+#if defined(NEED_ASNPRINTF)
+int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) {
+  va_list ap;
+  int str_l;
+
+  *ptr = NULL;
+  va_start(ap, fmt);                            /* measure the required size */
+  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);
+  va_end(ap);
+  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
+  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */
+  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */
+  if (str_m == 0) {  /* not interested in resulting string, just return size */
+  } else {
+    *ptr = (char *) malloc(str_m);
+    if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
+    else {
+      int str_l2;
+      va_start(ap, fmt);
+      str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
+      va_end(ap);
+      assert(str_l2 == str_l);
+    }
+  }
+  return str_l;
+}
+#endif
+
+#if defined(NEED_VASNPRINTF)
+int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) {
+  int str_l;
+
+  *ptr = NULL;
+  { va_list ap2;
+    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */
+    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/
+    va_end(ap2);
+  }
+  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
+  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */
+  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */
+  if (str_m == 0) {  /* not interested in resulting string, just return size */
+  } else {
+    *ptr = (char *) malloc(str_m);
+    if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
+    else {
+      int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
+      assert(str_l2 == str_l);
+    }
+  }
+  return str_l;
+}
+#endif
+
+/*
+ * If the system does have snprintf and the portable routine is not
+ * specifically required, this module produces no code for snprintf/vsnprintf.
+ */
+#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+
+#if !defined(NEED_SNPRINTF_ONLY)
+int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {
+  va_list ap;
+  int str_l;
+
+  va_start(ap, fmt);
+  str_l = portable_vsnprintf(str, str_m, fmt, ap);
+  va_end(ap);
+  return str_l;
+}
+#endif
+
+#if defined(NEED_SNPRINTF_ONLY)
+int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {
+#else
+int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) {
+#endif
+
+#if defined(NEED_SNPRINTF_ONLY)
+  va_list ap;
+#endif
+  size_t str_l = 0;
+  const char *p = fmt;
+
+/* In contrast with POSIX, the ISO C99 now says
+ * that str can be NULL and str_m can be 0.
+ * This is more useful than the old:  if (str_m < 1) return -1; */
+
+#if defined(NEED_SNPRINTF_ONLY)
+  va_start(ap, fmt);
+#endif
+  if (!p) p = "";
+  while (*p) {
+    if (*p != '%') {
+   /* if (str_l < str_m) str[str_l++] = *p++;    -- this would be sufficient */
+   /* but the following code achieves better performance for cases
+    * where format string is long and contains few conversions */
+      const char *q = strchr(p+1,'%');
+      size_t n = !q ? strlen(p) : (q-p);
+      if (str_l < str_m) {
+        size_t avail = str_m-str_l;
+        fast_memcpy(str+str_l, p, (n>avail?avail:n));
+      }
+      p += n; str_l += n;
+    } else {
+      const char *starting_p;
+      size_t min_field_width = 0, precision = 0;
+      int zero_padding = 0, precision_specified = 0, justify_left = 0;
+      int alternate_form = 0, force_sign = 0;
+      int space_for_positive = 1; /* If both the ' ' and '+' flags appear,
+                                     the ' ' flag should be ignored. */
+      char length_modifier = '\0';            /* allowed values: \0, h, l, L */
+      char tmp[32];/* temporary buffer for simple numeric->string conversion */
+
+      const char *str_arg;      /* string address in case of string argument */
+      size_t str_arg_l;         /* natural field width of arg without padding
+                                   and sign */
+      unsigned char uchar_arg;
+        /* unsigned char argument value - only defined for c conversion.
+           N.B. standard explicitly states the char argument for
+           the c conversion is unsigned */
+
+      size_t number_of_zeros_to_pad = 0;
+        /* number of zeros to be inserted for numeric conversions
+           as required by the precision or minimal field width */
+
+      size_t zero_padding_insertion_ind = 0;
+        /* index into tmp where zero padding is to be inserted */
+
+      char fmt_spec = '\0';
+        /* current conversion specifier character */
+
+      str_arg = credits;/* just to make compiler happy (defined but not used)*/
+      str_arg = NULL;
+      starting_p = p; p++;  /* skip '%' */
+   /* parse flags */
+      while (*p == '0' || *p == '-' || *p == '+' ||
+             *p == ' ' || *p == '#' || *p == '\'') {
+        switch (*p) {
+        case '0': zero_padding = 1; break;
+        case '-': justify_left = 1; break;
+        case '+': force_sign = 1; space_for_positive = 0; break;
+        case ' ': force_sign = 1;
+     /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */
+#ifdef PERL_COMPATIBLE
+     /* ... but in Perl the last of ' ' and '+' applies */
+                  space_for_positive = 1;
+#endif
+                  break;
+        case '#': alternate_form = 1; break;
+        case '\'': break;
+        }
+        p++;
+      }
+   /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */
+
+   /* parse field width */
+      if (*p == '*') {
+        int j;
+        p++; j = va_arg(ap, int);
+        if (j >= 0) min_field_width = j;
+        else { min_field_width = -j; justify_left = 1; }
+      } else if (isdigit((int)(*p))) {
+        /* size_t could be wider than unsigned int;
+           make sure we treat argument like common implementations do */
+        unsigned int uj = *p++ - '0';
+        while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');
+        min_field_width = uj;
+      }
+   /* parse precision */
+      if (*p == '.') {
+        p++; precision_specified = 1;
+        if (*p == '*') {
+          int j = va_arg(ap, int);
+          p++;
+          if (j >= 0) precision = j;
+          else {
+            precision_specified = 0; precision = 0;
+         /* NOTE:
+          *   Solaris 2.6 man page claims that in this case the precision
+          *   should be set to 0.  Digital Unix 4.0, HPUX 10 and BSD man page
+          *   claim that this case should be treated as unspecified precision,
+          *   which is what we do here.
+          */
+          }
+        } else if (isdigit((int)(*p))) {
+          /* size_t could be wider than unsigned int;
+             make sure we treat argument like common implementations do */
+          unsigned int uj = *p++ - '0';
+          while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');
+          precision = uj;
+        }
+      }
+   /* parse 'h', 'l' and 'll' length modifiers */
+      if (*p == 'h' || *p == 'l') {
+        length_modifier = *p; p++;
+        if (length_modifier == 'l' && *p == 'l') {   /* double l = long long */
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+          length_modifier = '2';                  /* double l encoded as '2' */
+#else
+          length_modifier = 'l';                 /* treat it as a single 'l' */
+#endif
+          p++;
+        }
+      }
+      fmt_spec = *p;
+   /* common synonyms: */
+      switch (fmt_spec) {
+      case 'i': fmt_spec = 'd'; break;
+      case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
+      case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
+      case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+      default: break;
+      }
+   /* get parameter value, do initial processing */
+      switch (fmt_spec) {
+      case '%': /* % behaves similar to 's' regarding flags and field widths */
+      case 'c': /* c behaves similar to 's' regarding flags and field widths */
+      case 's':
+        length_modifier = '\0';          /* wint_t and wchar_t not supported */
+     /* the result of zero padding flag with non-numeric conversion specifier*/
+     /* is undefined. Solaris and HPUX 10 does zero padding in this case,    */
+     /* Digital Unix and Linux does not. */
+#if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE)
+        zero_padding = 0;    /* turn zero padding off for string conversions */
+#endif
+        str_arg_l = 1;
+        switch (fmt_spec) {
+        case '%':
+          str_arg = p; break;
+        case 'c': {
+          int j = va_arg(ap, int);
+          uchar_arg = (unsigned char) j;   /* standard demands unsigned char */
+          str_arg = (const char *) &uchar_arg;
+          break;
+        }
+        case 's':
+          str_arg = va_arg(ap, const char *);
+          if (!str_arg) str_arg_l = 0;
+       /* make sure not to address string beyond the specified precision !!! */
+          else if (!precision_specified) str_arg_l = strlen(str_arg);
+       /* truncate string if necessary as requested by precision */
+          else if (precision == 0) str_arg_l = 0;
+          else {
+       /* memchr on HP does not like n > 2^31  !!! */
+            const char *q = memchr(str_arg, '\0',
+                             precision <= 0x7fffffff ? precision : 0x7fffffff);
+            str_arg_l = !q ? precision : (q-str_arg);
+          }
+          break;
+        default: break;
+        }
+        break;
+      case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': {
+        /* NOTE: the u, o, x, X and p conversion specifiers imply
+                 the value is unsigned;  d implies a signed value */
+
+        int arg_sign = 0;
+          /* 0 if numeric argument is zero (or if pointer is NULL for 'p'),
+            +1 if greater than zero (or nonzero for unsigned arguments),
+            -1 if negative (unsigned argument is never negative) */
+
+        int int_arg = 0;  unsigned int uint_arg = 0;
+          /* only defined for length modifier h, or for no length modifiers */
+
+        long int long_arg = 0;  unsigned long int ulong_arg = 0;
+          /* only defined for length modifier l */
+
+        void *ptr_arg = NULL;
+          /* pointer argument value -only defined for p conversion */
+
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+        long long int long_long_arg = 0;
+        unsigned long long int ulong_long_arg = 0;
+          /* only defined for length modifier ll */
+#endif
+        if (fmt_spec == 'p') {
+        /* HPUX 10: An l, h, ll or L before any other conversion character
+         *   (other than d, i, u, o, x, or X) is ignored.
+         * Digital Unix:
+         *   not specified, but seems to behave as HPUX does.
+         * Solaris: If an h, l, or L appears before any other conversion
+         *   specifier (other than d, i, u, o, x, or X), the behavior
+         *   is undefined. (Actually %hp converts only 16-bits of address
+         *   and %llp treats address as 64-bit data which is incompatible
+         *   with (void *) argument on a 32-bit system).
+         */
+#ifdef SOLARIS_COMPATIBLE
+#  ifdef SOLARIS_BUG_COMPATIBLE
+          /* keep length modifiers even if it represents 'll' */
+#  else
+          if (length_modifier == '2') length_modifier = '\0';
+#  endif
+#else
+          length_modifier = '\0';
+#endif
+          ptr_arg = va_arg(ap, void *);
+          if (ptr_arg != NULL) arg_sign = 1;
+        } else if (fmt_spec == 'd') {  /* signed */
+          switch (length_modifier) {
+          case '\0':
+          case 'h':
+         /* It is non-portable to specify a second argument of char or short
+          * to va_arg, because arguments seen by the called function
+          * are not char or short.  C converts char and short arguments
+          * to int before passing them to a function.
+          */
+            int_arg = va_arg(ap, int);
+            if      (int_arg > 0) arg_sign =  1;
+            else if (int_arg < 0) arg_sign = -1;
+            break;
+          case 'l':
+            long_arg = va_arg(ap, long int);
+            if      (long_arg > 0) arg_sign =  1;
+            else if (long_arg < 0) arg_sign = -1;
+            break;
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+          case '2':
+            long_long_arg = va_arg(ap, long long int);
+            if      (long_long_arg > 0) arg_sign =  1;
+            else if (long_long_arg < 0) arg_sign = -1;
+            break;
+#endif
+          }
+        } else {  /* unsigned */
+          switch (length_modifier) {
+          case '\0':
+          case 'h':
+            uint_arg = va_arg(ap, unsigned int);
+            if (uint_arg) arg_sign = 1;
+            break;
+          case 'l':
+            ulong_arg = va_arg(ap, unsigned long int);
+            if (ulong_arg) arg_sign = 1;
+            break;
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+          case '2':
+            ulong_long_arg = va_arg(ap, unsigned long long int);
+            if (ulong_long_arg) arg_sign = 1;
+            break;
+#endif
+          }
+        }
+        str_arg = tmp; str_arg_l = 0;
+     /* NOTE:
+      *   For d, i, u, o, x, and X conversions, if precision is specified,
+      *   the '0' flag should be ignored. This is so with Solaris 2.6,
+      *   Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
+      */
+#ifndef PERL_COMPATIBLE
+        if (precision_specified) zero_padding = 0;
+#endif
+        if (fmt_spec == 'd') {
+          if (force_sign && arg_sign >= 0)
+            tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+         /* leave negative numbers for sprintf to handle,
+            to avoid handling tricky cases like (short int)(-32768) */
+#ifdef LINUX_COMPATIBLE
+        } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) {
+          tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+#endif
+        } else if (alternate_form) {
+          if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') )
+            { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; }
+         /* alternate form should have no effect for p conversion, but ... */
+#ifdef HPUX_COMPATIBLE
+          else if (fmt_spec == 'p'
+         /* HPUX 10: for an alternate form of p conversion,
+          *          a nonzero result is prefixed by 0x. */
+#ifndef HPUX_BUG_COMPATIBLE
+         /* Actually it uses 0x prefix even for a zero value. */
+                   && arg_sign != 0
+#endif
+                  ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; }
+#endif
+        }
+        zero_padding_insertion_ind = str_arg_l;
+        if (!precision_specified) precision = 1;   /* default precision is 1 */
+        if (precision == 0 && arg_sign == 0
+#if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE)
+            && fmt_spec != 'p'
+         /* HPUX 10 man page claims: With conversion character p the result of
+          * converting a zero value with a precision of zero is a null string.
+          * Actually HP returns all zeroes, and Linux returns "(nil)". */
+#endif
+        ) {
+         /* converted to null string */
+         /* When zero value is formatted with an explicit precision 0,
+            the resulting formatted string is empty (d, i, u, o, x, X, p).   */
+        } else {
+          char f[5]; int f_l = 0;
+          f[f_l++] = '%';    /* construct a simple format string for sprintf */
+          if (!length_modifier) { }
+          else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; }
+          else f[f_l++] = length_modifier;
+          f[f_l++] = fmt_spec; f[f_l++] = '\0';
+          if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg);
+          else if (fmt_spec == 'd') {  /* signed */
+            switch (length_modifier) {
+            case '\0':
+            case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg);  break;
+            case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break;
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+            case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break;
+#endif
+            }
+          } else {  /* unsigned */
+            switch (length_modifier) {
+            case '\0':
+            case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg);  break;
+            case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break;
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+            case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break;
+#endif
+            }
+          }
+         /* include the optional minus sign and possible "0x"
+            in the region before the zero padding insertion point */
+          if (zero_padding_insertion_ind < str_arg_l &&
+              tmp[zero_padding_insertion_ind] == '-') {
+            zero_padding_insertion_ind++;
+          }
+          if (zero_padding_insertion_ind+1 < str_arg_l &&
+              tmp[zero_padding_insertion_ind]   == '0' &&
+             (tmp[zero_padding_insertion_ind+1] == 'x' ||
+              tmp[zero_padding_insertion_ind+1] == 'X') ) {
+            zero_padding_insertion_ind += 2;
+          }
+        }
+        { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
+          if (alternate_form && fmt_spec == 'o'
+#ifdef HPUX_COMPATIBLE                                  /* ("%#.o",0) -> ""  */
+              && (str_arg_l > 0)
+#endif
+#ifdef DIGITAL_UNIX_BUG_COMPATIBLE                      /* ("%#o",0) -> "00" */
+#else
+              /* unless zero is already the first character */
+              && !(zero_padding_insertion_ind < str_arg_l
+                   && tmp[zero_padding_insertion_ind] == '0')
+#endif
+          ) {        /* assure leading zero for alternate-form octal numbers */
+            if (!precision_specified || precision < num_of_digits+1) {
+             /* precision is increased to force the first character to be zero,
+                except if a zero value is formatted with an explicit precision
+                of zero */
+              precision = num_of_digits+1; precision_specified = 1;
+            }
+          }
+       /* zero padding to specified precision? */
+          if (num_of_digits < precision) 
+            number_of_zeros_to_pad = precision - num_of_digits;
+        }
+     /* zero padding to specified minimal field width? */
+        if (!justify_left && zero_padding) {
+          int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
+          if (n > 0) number_of_zeros_to_pad += n;
+        }
+        break;
+      }
+      default: /* unrecognized conversion specifier, keep format string as-is*/
+        zero_padding = 0;  /* turn zero padding off for non-numeric convers. */
+#ifndef DIGITAL_UNIX_COMPATIBLE
+        justify_left = 1; min_field_width = 0;                /* reset flags */
+#endif
+#if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE)
+     /* keep the entire format string unchanged */
+        str_arg = starting_p; str_arg_l = p - starting_p;
+     /* well, not exactly so for Linux, which does something inbetween,
+      * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y"  */
+#else
+     /* discard the unrecognized conversion, just keep *
+      * the unrecognized conversion character          */
+        str_arg = p; str_arg_l = 0;
+#endif
+        if (*p) str_arg_l++;  /* include invalid conversion specifier unchanged
+                                 if not at end-of-string */
+        break;
+      }
+      if (*p) p++;      /* step over the just processed conversion specifier */
+   /* insert padding to the left as requested by min_field_width;
+      this does not include the zero padding in case of numerical conversions*/
+      if (!justify_left) {                /* left padding with blank or zero */
+        int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+      }
+   /* zero padding as requested by the precision or by the minimal field width
+    * for numeric conversions required? */
+      if (number_of_zeros_to_pad <= 0) {
+     /* will not copy first part of numeric right now, *
+      * force it to be copied later in its entirety    */
+        zero_padding_insertion_ind = 0;
+      } else {
+     /* insert first part of numerics (sign or '0x') before zero padding */
+        int n = zero_padding_insertion_ind;
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memcpy(str+str_l, str_arg, (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+     /* insert zero padding as requested by the precision or min field width */
+        n = number_of_zeros_to_pad;
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memset(str+str_l, '0', (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+      }
+   /* insert formatted string
+    * (or as-is conversion specifier for unknown conversions) */
+      { int n = str_arg_l - zero_padding_insertion_ind;
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind,
+                        (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+      }
+   /* insert right padding */
+      if (justify_left) {          /* right blank padding to the field width */
+        int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memset(str+str_l, ' ', (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+      }
+    }
+  }
+#if defined(NEED_SNPRINTF_ONLY)
+  va_end(ap);
+#endif
+  if (str_m > 0) { /* make sure the string is null-terminated
+                      even at the expense of overwriting the last character
+                      (shouldn't happen, but just in case) */
+    str[str_l <= str_m-1 ? str_l : str_m-1] = '\0';
+  }
+  /* Return the number of characters formatted (excluding trailing null
+   * character), that is, the number of characters that would have been
+   * written to the buffer if it were large enough.
+   *
+   * The value of str_l should be returned, but str_l is of unsigned type
+   * size_t, and snprintf is int, possibly leading to an undetected
+   * integer overflow, resulting in a negative return value, which is illegal.
+   * Both XSH5 and ISO C99 (at least the draft) are silent on this issue.
+   * Should errno be set to EOVERFLOW and EOF returned in this case???
+   */
+  return (int) str_l;
+}
+#endif
diff --git a/snprintf.h b/snprintf.h
new file mode 100644 (file)
index 0000000..70ec841
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef _PORTABLE_SNPRINTF_H_
+#define _PORTABLE_SNPRINTF_H_
+
+#define PORTABLE_SNPRINTF_VERSION_MAJOR 2
+#define PORTABLE_SNPRINTF_VERSION_MINOR 2
+
+#ifdef HAVE_SNPRINTF
+#include <stdio.h>
+#else
+extern int snprintf(char *, size_t, const char *, /*args*/ ...);
+extern int vsnprintf(char *, size_t, const char *, va_list);
+#endif
+
+#if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF)
+extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);
+extern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);
+#define snprintf  portable_snprintf
+#define vsnprintf portable_vsnprintf
+#endif
+
+extern int asprintf  (char **ptr, const char *fmt, /*args*/ ...);
+extern int vasprintf (char **ptr, const char *fmt, va_list ap);
+extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);
+extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap);
+
+#endif
diff --git a/tun.c b/tun.c
index 6f42dd2116c9016fc5fe637bb381acb5418dc843..0f88791703c68a2d06e1fe122b3c6e12b6a73e92 100644 (file)
--- a/tun.c
+++ b/tun.c
@@ -252,9 +252,6 @@ static list_t *tun_old_apply(closure_t *self, struct cloc loc, dict_t *context,
 
     st=safe_malloc(sizeof(*st),"tun_old_apply");
 
 
     st=safe_malloc(sizeof(*st),"tun_old_apply");
 
-    Message(M_WARNING,"the tun-old code has never been tested. Please report "
-           "success or failure to steve@greenend.org.uk\n");
-
     /* First parameter must be a dict */
     item=list_elem(args,0);
     if (!item || item->type!=t_dict)
     /* First parameter must be a dict */
     item=list_elem(args,0);
     if (!item || item->type!=t_dict)