]> git.meshlink.io Git - meshlink/commitdiff
Move source from lib/ to src/.
authorGuus Sliepen <guus@tinc-vpn.org>
Thu, 31 Dec 2009 12:19:13 +0000 (13:19 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Thu, 31 Dec 2009 12:19:13 +0000 (13:19 +0100)
The utility functions in the lib/ directory do not really form a library.
Also, now that we build two binaries, tincctl does not need everything that was
in libvpn.a, so it is wasteful to link to it.

53 files changed:
lib/Makefile.am
lib/alloca.c [deleted file]
lib/dropin.c [deleted file]
lib/dropin.h [deleted file]
lib/ethernet.h [deleted file]
lib/fake-gai-errnos.h [deleted file]
lib/fake-getaddrinfo.c [deleted file]
lib/fake-getaddrinfo.h [deleted file]
lib/fake-getnameinfo.c [deleted file]
lib/fake-getnameinfo.h [deleted file]
lib/getopt.c [deleted file]
lib/getopt.h [deleted file]
lib/getopt1.c [deleted file]
lib/ipv4.h [deleted file]
lib/ipv6.h [deleted file]
lib/list.c [deleted file]
lib/list.h [deleted file]
lib/malloc.c [deleted file]
lib/memcmp.c [deleted file]
lib/realloc.c [deleted file]
lib/splay_tree.c [deleted file]
lib/splay_tree.h [deleted file]
lib/utils.c [deleted file]
lib/utils.h [deleted file]
lib/xalloc.h [deleted file]
lib/xmalloc.c [deleted file]
src/Makefile.am
src/alloca.c [new file with mode: 0644]
src/dropin.c [new file with mode: 0644]
src/dropin.h [new file with mode: 0644]
src/ethernet.h [new file with mode: 0644]
src/fake-gai-errnos.h [new file with mode: 0644]
src/fake-getaddrinfo.c [new file with mode: 0644]
src/fake-getaddrinfo.h [new file with mode: 0644]
src/fake-getnameinfo.c [new file with mode: 0644]
src/fake-getnameinfo.h [new file with mode: 0644]
src/getopt.c [new file with mode: 0644]
src/getopt.h [new file with mode: 0644]
src/getopt1.c [new file with mode: 0644]
src/ipv4.h [new file with mode: 0644]
src/ipv6.h [new file with mode: 0644]
src/list.c [new file with mode: 0644]
src/list.h [new file with mode: 0644]
src/malloc.c [new file with mode: 0644]
src/memcmp.c [new file with mode: 0644]
src/realloc.c [new file with mode: 0644]
src/splay_tree.c [new file with mode: 0644]
src/splay_tree.h [new file with mode: 0644]
src/utils.c [new file with mode: 0644]
src/utils.h [new file with mode: 0644]
src/xalloc.h [new file with mode: 0644]
src/xmalloc.c [new file with mode: 0644]
system.h

index c96e1760c5f1933267cc7b9be2ff408e1a4edf7d..96d7a6ab7be97d76a370e2b8666595b4e77cec11 100644 (file)
@@ -1,14 +1 @@
 ## Process this file with automake to produce Makefile.in
-
-noinst_LIBRARIES = libvpn.a
-
-INCLUDES = @INCLUDES@ -I. -I$(top_builddir)
-
-libvpn_a_SOURCES = xmalloc.c utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c
-
-libvpn_a_LIBADD = @LIBOBJS@ @ALLOCA@
-libvpn_a_DEPENDENCIES = $(libvpn_a_LIBADD)
-
-noinst_HEADERS = xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h
-
-EXTRA_DIST = 
diff --git a/lib/alloca.c b/lib/alloca.c
deleted file mode 100644 (file)
index 10e5d65..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/* 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
-
-#ifdef emacs
-# include "blockinput.h"
-#endif
-
-/* If compiling with GCC 2, this file's not needed.  */
-#if !defined (__GNUC__) || __GNUC__ < 2
-
-/* If someone has defined alloca as a macro,
-   there must be some other way alloca is supposed to work.  */
-# 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.  */
-
-#  if defined (CRAY) && defined (CRAY_STACKSEG_END)
-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
-
-#  ifndef NULL
-#   define NULL 0
-#  endif
-
-/* Different portions of Emacs need to call different versions of
-   malloc.  The Emacs executable needs alloca to call xmalloc, because
-   ordinary malloc isn't protected from input signals.  On the other
-   hand, the utilities in lib-src need alloca to call malloc; some of
-   them are very simple, and don't have an xmalloc routine.
-
-   Non-Emacs programs expect this to call xmalloc.
-
-   Callers below should use malloc.  */
-
-#  ifndef emacs
-#   define malloc xmalloc
-#  endif
-extern pointer malloc ();
-
-/* 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.  */
-
-#  ifdef emacs
-    BLOCK_INPUT;
-#  endif
-
-    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.  */
-
-#  ifdef emacs
-    UNBLOCK_INPUT;
-#  endif
-  }
-
-  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));
-  }
-}
-
-#  if defined (CRAY) && defined (CRAY_STACKSEG_END)
-
-#   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 */
-#endif /* not GCC version 2 */
diff --git a/lib/dropin.c b/lib/dropin.c
deleted file mode 100644 (file)
index 89039da..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-    dropin.c -- a set of drop-in replacements for libc functions
-    Copyright (C) 2000-2005 Ivo Timmermans,
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include "xalloc.h"
-
-#ifndef HAVE_DAEMON
-/*
-  Replacement for the daemon() function.
-  
-  The daemon() function is for programs wishing to detach themselves
-  from the controlling terminal and run in the background as system
-  daemons.
-
-  Unless the argument nochdir is non-zero, daemon() changes the
-  current working directory to the root (``/'').
-
-  Unless the argument noclose is non-zero, daemon() will redirect
-  standard input, standard output and standard error to /dev/null.
-*/
-int daemon(int nochdir, int noclose) {
-#ifdef HAVE_FORK
-       pid_t pid;
-       int fd;
-
-       pid = fork();
-
-       /* Check if forking failed */
-       if(pid < 0) {
-               perror("fork");
-               exit(-1);
-       }
-
-       /* If we are the parent, terminate */
-       if(pid)
-               exit(0);
-
-       /* Detach by becoming the new process group leader */
-       if(setsid() < 0) {
-               perror("setsid");
-               return -1;
-       }
-
-       /* Change working directory to the root (to avoid keeping mount
-          points busy) */
-       if(!nochdir) {
-               chdir("/");
-       }
-
-       /* Redirect stdin/out/err to /dev/null */
-       if(!noclose) {
-               fd = open("/dev/null", O_RDWR);
-
-               if(fd < 0) {
-                       perror("opening /dev/null");
-                       return -1;
-               } else {
-                       dup2(fd, 0);
-                       dup2(fd, 1);
-                       dup2(fd, 2);
-               }
-       }
-
-       return 0;
-#else
-       return -1;
-#endif
-}
-#endif
-
-#ifndef HAVE_GET_CURRENT_DIR_NAME
-/*
-  Replacement for the GNU get_current_dir_name function:
-
-  get_current_dir_name will malloc(3) an array big enough to hold the
-  current directory name.  If the environment variable PWD is set, and
-  its value is correct, then that value will be returned.
-*/
-char *get_current_dir_name(void) {
-       size_t size;
-       char *buf;
-       char *r;
-
-       /* Start with 100 bytes.  If this turns out to be insufficient to
-          contain the working directory, double the size.  */
-       size = 100;
-       buf = xmalloc(size);
-
-       errno = 0;                                      /* Success */
-       r = getcwd(buf, size);
-
-       /* getcwd returns NULL and sets errno to ERANGE if the bufferspace
-          is insufficient to contain the entire working directory.  */
-       while(r == NULL && errno == ERANGE) {
-               free(buf);
-               size <<= 1;                             /* double the size */
-               buf = xmalloc(size);
-               r = getcwd(buf, size);
-       }
-
-       return buf;
-}
-#endif
-
-#ifndef HAVE_ASPRINTF
-int asprintf(char **buf, const char *fmt, ...) {
-       int result;
-       va_list ap;
-       va_start(ap, fmt);
-       result = vasprintf(buf, fmt, ap);
-       va_end(ap);
-       return result;
-}
-
-int vasprintf(char **buf, const char *fmt, va_list ap) {
-       int status;
-       va_list aq;
-       int len;
-
-       len = 4096;
-       *buf = xmalloc(len);
-
-       va_copy(aq, ap);
-       status = vsnprintf(*buf, len, fmt, aq);
-       va_end(aq);
-
-       if(status >= 0)
-               *buf = xrealloc(*buf, status + 1);
-
-       if(status > len - 1) {
-               len = status;
-               va_copy(aq, ap);
-               status = vsnprintf(*buf, len, fmt, aq);
-               va_end(aq);
-       }
-
-       return status;
-}
-#endif
-
-#ifndef HAVE_GETTIMEOFDAY
-int gettimeofday(struct timeval *tv, void *tz) {
-       tv->tv_sec = time(NULL);
-       tv->tv_usec = 0;
-       return 0;
-}
-#endif
diff --git a/lib/dropin.h b/lib/dropin.h
deleted file mode 100644 (file)
index e9d1353..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-    dropin.h -- header file for dropin.c
-    Copyright (C) 2000-2005 Ivo Timmermans,
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __DROPIN_H__
-#define __DROPIN_H__
-
-#include "fake-getaddrinfo.h"
-#include "fake-getnameinfo.h"
-
-#ifndef HAVE_DAEMON
-extern int daemon(int, int);
-#endif
-
-#ifndef HAVE_GET_CURRENT_DIR_NAME
-extern char *get_current_dir_name(void);
-#endif
-
-#ifndef HAVE_ASPRINTF
-extern int asprintf(char **, const char *, ...);
-extern int vasprintf(char **, const char *, va_list ap);
-#endif
-
-#ifndef HAVE_GETTIMEOFDAY
-extern int gettimeofday(struct timeval *, void *);
-#endif
-
-#endif                                                 /* __DROPIN_H__ */
diff --git a/lib/ethernet.h b/lib/ethernet.h
deleted file mode 100644 (file)
index eef5f42..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-    ethernet.h -- missing Ethernet related definitions
-    Copyright (C) 2005 Ivo Timmermans
-                  2006 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_ETHERNET_H__
-#define __TINC_ETHERNET_H__
-
-#ifndef ETH_ALEN
-#define ETH_ALEN 6
-#endif
-
-#ifndef ARPHRD_ETHER
-#define ARPHRD_ETHER 1
-#endif
-
-#ifndef ETH_P_IP
-#define ETH_P_IP 0x0800
-#endif
-
-#ifndef ETH_P_ARP
-#define ETH_P_ARP 0x0806
-#endif
-
-#ifndef ETH_P_IPV6
-#define ETH_P_IPV6 0x86DD
-#endif
-
-#ifndef HAVE_STRUCT_ETHER_HEADER
-struct ether_header {
-       uint8_t ether_dhost[ETH_ALEN];
-       uint8_t ether_shost[ETH_ALEN];
-       uint16_t ether_type;
-} __attribute__ ((__packed__));
-#endif
-
-#ifndef HAVE_STRUCT_ARPHDR
-struct arphdr {
-       uint16_t ar_hrd;
-       uint16_t ar_pro;
-       uint8_t ar_hln;
-       uint8_t ar_pln; 
-       uint16_t ar_op; 
-} __attribute__ ((__packed__));
-
-#define ARPOP_REQUEST 1 
-#define ARPOP_REPLY 2 
-#define ARPOP_RREQUEST 3 
-#define ARPOP_RREPLY 4 
-#define ARPOP_InREQUEST 8 
-#define ARPOP_InREPLY 9 
-#define ARPOP_NAK 10 
-#endif
-
-#ifndef HAVE_STRUCT_ETHER_ARP
-struct  ether_arp {
-       struct  arphdr ea_hdr;
-       uint8_t arp_sha[ETH_ALEN];
-       uint8_t arp_spa[4];
-       uint8_t arp_tha[ETH_ALEN];
-       uint8_t arp_tpa[4];
-} __attribute__ ((__packed__));
-#define arp_hrd ea_hdr.ar_hrd
-#define arp_pro ea_hdr.ar_pro
-#define arp_hln ea_hdr.ar_hln
-#define arp_pln ea_hdr.ar_pln
-#define arp_op ea_hdr.ar_op
-#endif
-
-#endif /* __TINC_ETHERNET_H__ */
diff --git a/lib/fake-gai-errnos.h b/lib/fake-gai-errnos.h
deleted file mode 100644 (file)
index 4ffabb6..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * fake library for ssh
- *
- * This file is included in getaddrinfo.c and getnameinfo.c.
- * See getaddrinfo.c and getnameinfo.c.
- */
-
-/* for old netdb.h */
-#ifndef EAI_NODATA
-#define EAI_NODATA     1
-#endif
-
-#ifndef EAI_MEMORY
-#define EAI_MEMORY     2
-#endif
-
-#ifndef EAI_FAMILY
-#define EAI_FAMILY     3
-#endif
diff --git a/lib/fake-getaddrinfo.c b/lib/fake-getaddrinfo.c
deleted file mode 100644 (file)
index df3d347..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * fake library for ssh
- *
- * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
- * These funtions are defined in rfc2133.
- *
- * But these functions are not implemented correctly. The minimum subset
- * is implemented for ssh use only. For exapmle, this routine assumes
- * that ai_family is AF_INET. Don't use it for another purpose.
- */
-
-#include "system.h"
-
-#include "ipv4.h"
-#include "ipv6.h"
-#include "fake-getaddrinfo.h"
-#include "xalloc.h"
-
-
-#if !HAVE_DECL_GAI_STRERROR
-char *gai_strerror(int ecode) {
-       switch (ecode) {
-               case EAI_NODATA:
-                       return "No address associated with hostname";
-               case EAI_MEMORY:
-                       return "Memory allocation failure";
-               case EAI_FAMILY:
-                       return "Address family not supported";
-               default:
-                       return "Unknown error";
-       }
-}    
-#endif /* !HAVE_GAI_STRERROR */
-
-#if !HAVE_DECL_FREEADDRINFO
-void freeaddrinfo(struct addrinfo *ai) {
-       struct addrinfo *next;
-
-       while(ai) {
-               next = ai->ai_next;
-               free(ai);
-               ai = next;
-       }
-}
-#endif /* !HAVE_FREEADDRINFO */
-
-#if !HAVE_DECL_GETADDRINFO
-static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr) {
-       struct addrinfo *ai;
-
-       ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
-       
-       ai->ai_addr = (struct sockaddr *)(ai + 1);
-       ai->ai_addrlen = sizeof(struct sockaddr_in);
-       ai->ai_addr->sa_family = ai->ai_family = AF_INET;
-
-       ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
-       ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
-       
-       return ai;
-}
-
-int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) {
-       struct addrinfo *prev = NULL;
-       struct hostent *hp;
-       struct in_addr in = {0};
-       int i;
-       uint16_t port = 0;
-
-       if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)
-               return EAI_FAMILY;
-
-       if (servname)
-               port = htons(atoi(servname));
-
-       if (hints && hints->ai_flags & AI_PASSIVE) {
-               *res = malloc_ai(port, htonl(0x00000000));
-               return 0;
-       }
-               
-       if (!hostname) {
-               *res = malloc_ai(port, htonl(0x7f000001));
-               return 0;
-       }
-       
-       hp = gethostbyname(hostname);
-
-       if(!hp || !hp->h_addr_list || !hp->h_addr_list[0])
-               return EAI_NODATA;
-
-       for (i = 0; hp->h_addr_list[i]; i++) {
-               *res = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
-
-               if(prev)
-                       prev->ai_next = *res;
-
-               prev = *res;
-       }
-
-       return 0;
-}
-#endif /* !HAVE_GETADDRINFO */
diff --git a/lib/fake-getaddrinfo.h b/lib/fake-getaddrinfo.h
deleted file mode 100644 (file)
index 5af7491..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef _FAKE_GETADDRINFO_H
-#define _FAKE_GETADDRINFO_H
-
-#include "fake-gai-errnos.h"
-
-#ifndef AI_PASSIVE
-# define AI_PASSIVE        1
-# define AI_CANONNAME      2
-#endif
-
-#ifndef NI_NUMERICHOST
-# define NI_NUMERICHOST    2
-# define NI_NAMEREQD       4
-# define NI_NUMERICSERV    8
-#endif
-
-#ifndef AI_NUMERICHOST
-#define AI_NUMERICHOST 4
-#endif
-
-#ifndef HAVE_STRUCT_ADDRINFO
-struct addrinfo {
-       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
-       int     ai_family;      /* PF_xxx */
-       int     ai_socktype;    /* SOCK_xxx */
-       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
-       size_t  ai_addrlen;     /* length of ai_addr */
-       char    *ai_canonname;  /* canonical name for hostname */
-       struct sockaddr *ai_addr;       /* binary address */
-       struct addrinfo *ai_next;       /* next structure in linked list */
-};
-#endif /* !HAVE_STRUCT_ADDRINFO */
-
-#if !HAVE_DECL_GETADDRINFO
-int getaddrinfo(const char *hostname, const char *servname, 
-                const struct addrinfo *hints, struct addrinfo **res);
-#endif /* !HAVE_GETADDRINFO */
-
-#if !HAVE_DECL_GAI_STRERROR
-char *gai_strerror(int ecode);
-#endif /* !HAVE_GAI_STRERROR */
-
-#if !HAVE_DECL_FREEADDRINFO
-void freeaddrinfo(struct addrinfo *ai);
-#endif /* !HAVE_FREEADDRINFO */
-
-#endif /* _FAKE_GETADDRINFO_H */
diff --git a/lib/fake-getnameinfo.c b/lib/fake-getnameinfo.c
deleted file mode 100644 (file)
index 1eba492..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * fake library for ssh
- *
- * This file includes getnameinfo().
- * These funtions are defined in rfc2133.
- *
- * But these functions are not implemented correctly. The minimum subset
- * is implemented for ssh use only. For exapmle, this routine assumes
- * that ai_family is AF_INET. Don't use it for another purpose.
- */
-
-#include "system.h"
-
-#include "fake-getnameinfo.h"
-#include "fake-getaddrinfo.h"
-
-#if !HAVE_DECL_GETNAMEINFO
-
-int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) {
-       struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-       struct hostent *hp;
-       int len;
-
-       if(sa->sa_family != AF_INET)
-               return EAI_FAMILY;
-
-       if(serv && servlen) {
-               len = snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
-               if(len < 0 || len >= servlen)
-                       return EAI_MEMORY;
-       }
-
-       if(!host || !hostlen)
-               return 0;
-
-       if(flags & NI_NUMERICHOST) {
-               len = snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr));
-               if(len < 0 || len >= hostlen)
-                       return EAI_MEMORY;
-               return 0;
-       }
-
-       hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET);
-       
-       if(!hp || !hp->h_name || !hp->h_name[0])
-               return EAI_NODATA;
-       
-       len = snprintf(host, hostlen, "%s", hp->h_name);
-       if(len < 0 || len >= hostlen)
-               return EAI_MEMORY;
-
-       return 0;
-}
-#endif /* !HAVE_GETNAMEINFO */
diff --git a/lib/fake-getnameinfo.h b/lib/fake-getnameinfo.h
deleted file mode 100644 (file)
index 4389a8f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _FAKE_GETNAMEINFO_H
-#define _FAKE_GETNAMEINFO_H
-
-#if !HAVE_DECL_GETNAMEINFO
-int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 
-                size_t hostlen, char *serv, size_t servlen, int flags);
-#endif /* !HAVE_GETNAMEINFO */
-
-#ifndef NI_MAXSERV
-# define NI_MAXSERV 32
-#endif /* !NI_MAXSERV */
-#ifndef NI_MAXHOST
-# define NI_MAXHOST 1025
-#endif /* !NI_MAXHOST */
-
-#endif /* _FAKE_GETNAMEINFO_H */
diff --git a/lib/getopt.c b/lib/getopt.c
deleted file mode 100644 (file)
index b2f88b4..0000000
+++ /dev/null
@@ -1,1042 +0,0 @@
-/* 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, 93, 94, 95, 96, 97
-       Free Software Foundation, Inc.
-
-NOTE: The canonical source of this file is maintained with the GNU C Library.
-Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
-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, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-\f
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
-   Ditto for AIX 3.2 and <stdlib.h>.  */
-#ifndef _NO_PROTO
-#define _NO_PROTO
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if !defined (__STDC__) || !__STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-#ifndef const
-#define const
-#endif
-#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.  */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
-   contain conflicting prototypes for getopt.  */
-#include <stdlib.h>
-#include <unistd.h>
-#endif /* GNU C library.  */
-
-#ifdef VMS
-#include <unixlib.h>
-#if HAVE_STRING_H - 0
-#include <string.h>
-#endif
-#endif
-
-#if defined (WIN32) && !defined (__CYGWIN32__)
-/* It's not Unix, really.  See?  Capital letters.  */
-#include <windows.h>
-#define getpid() GetCurrentProcessId()
-#endif
-
-/* 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 = NULL;
-
-/* 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 -1, 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.  */
-
-/* 1003.2 says this must be 1 before any call.  */
-int optind = 1;
-
-/* Formerly, initialization of getopt depended on optind==0, which
-   causes problems with re-calling getopt as programs generally don't
-   know that. */
-
-int __getopt_initialized = 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 -1 with `optind' != ARGC.  */
-
-static enum
-{
-  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable.  */
-static char *posixly_correct;
-\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
-#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;
-}
-
-/* If using GCC, we can safely declare strlen this way.
-   If not using GCC, it is ok not to declare it.  */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
-   That was relevant to code that was here before.  */
-#if !defined (__STDC__) || !__STDC__
-/* gcc with -traditional declares the built-in strlen to return int,
-   and has done so at least since version 2.4.5. -- rms.  */
-extern int strlen (const char *);
-#endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_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;
-
-#ifdef _LIBC
-/* Bash 2.0 gives us an environment variable containing flags
-   indicating ARGV elements that should not be considered arguments.  */
-
-/* Defined in getopt_init.c  */
-extern char *__getopt_nonoption_flags;
-
-static int nonoption_flags_max_len;
-static int nonoption_flags_len;
-
-static int original_argc;
-static char *const *original_argv;
-
-extern pid_t __libc_pid;
-
-/* Make sure the environment variable bash 2.0 puts in the environment
-   is valid for the getopt call we must make sure that the ARGV passed
-   to getopt is that one passed to the process.  */
-static void
-__attribute__ ((__unused__))
-store_args_and_env (int argc, char *const *argv)
-{
-  /* XXX This is no good solution.  We should rather copy the args so
-     that we can compare them later.  But we must not use malloc(3).  */
-  original_argc = argc;
-  original_argv = argv;
-}
-text_set_element (__libc_subinit, store_args_and_env);
-
-# define SWAP_FLAGS(ch1, ch2) \
-  if (nonoption_flags_len > 0)                                               \
-    {                                                                        \
-      char __tmp = __getopt_nonoption_flags[ch1];                            \
-      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
-      __getopt_nonoption_flags[ch2] = __tmp;                                 \
-    }
-#else  /* !_LIBC */
-# define SWAP_FLAGS(ch1, ch2)
-#endif /* _LIBC */
-
-/* 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.  */
-
-#if defined (__STDC__) && __STDC__
-static void exchange (char **);
-#endif
-
-static void
-exchange (argv)
-     char **argv;
-{
-  int bottom = first_nonopt;
-  int middle = last_nonopt;
-  int top = optind;
-  char *tem;
-
-  /* Exchange the shorter segment with the far end of the longer segment.
-     That puts the shorter segment into the right place.
-     It leaves the longer segment in the right place overall,
-     but it consists of two parts that need to be swapped next.  */
-
-#ifdef _LIBC
-  /* First make sure the handling of the `__getopt_nonoption_flags'
-     string can work normally.  Our top argument must be in the range
-     of the string.  */
-  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
-    {
-      /* We must extend the array.  The user plays games with us and
-        presents new arguments.  */
-      char *new_str = malloc (top + 1);
-      if (new_str == NULL)
-       nonoption_flags_len = nonoption_flags_max_len = 0;
-      else
-       {
-         memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
-         memset (&new_str[nonoption_flags_max_len], '\0',
-                 top + 1 - nonoption_flags_max_len);
-         nonoption_flags_max_len = top + 1;
-         __getopt_nonoption_flags = new_str;
-       }
-    }
-#endif
-
-  while (top > middle && middle > bottom)
-    {
-      if (top - middle > middle - bottom)
-       {
-         /* Bottom segment is the short one.  */
-         int len = middle - bottom;
-         register int i;
-
-         /* Swap it with the top part of the top segment.  */
-         for (i = 0; i < len; i++)
-           {
-             tem = argv[bottom + i];
-             argv[bottom + i] = argv[top - (middle - bottom) + i];
-             argv[top - (middle - bottom) + i] = tem;
-             SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
-           }
-         /* Exclude the moved bottom segment from further swapping.  */
-         top -= len;
-       }
-      else
-       {
-         /* Top segment is the short one.  */
-         int len = top - middle;
-         register int i;
-
-         /* Swap it with the bottom part of the bottom segment.  */
-         for (i = 0; i < len; i++)
-           {
-             tem = argv[bottom + i];
-             argv[bottom + i] = argv[middle + i];
-             argv[middle + i] = tem;
-             SWAP_FLAGS (bottom + i, middle + i);
-           }
-         /* Exclude the moved top segment from further swapping.  */
-         bottom += len;
-       }
-    }
-
-  /* Update records for the slots the non-options now occupy.  */
-
-  first_nonopt += (optind - last_nonopt);
-  last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made.  */
-
-#if defined (__STDC__) && __STDC__
-static const char *_getopt_initialize (int, char *const *, const char *);
-#endif
-static const char *
-_getopt_initialize (argc, argv, optstring)
-     int argc;
-     char *const *argv;
-     const char *optstring;
-{
-  /* 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.  */
-
-  first_nonopt = last_nonopt = optind;
-
-  nextchar = NULL;
-
-  posixly_correct = getenv ("POSIXLY_CORRECT");
-
-  /* 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 (posixly_correct != NULL)
-    ordering = REQUIRE_ORDER;
-  else
-    ordering = PERMUTE;
-
-#ifdef _LIBC
-  if (posixly_correct == NULL
-      && argc == original_argc && argv == original_argv)
-    {
-      if (nonoption_flags_max_len == 0)
-       {
-         if (__getopt_nonoption_flags == NULL
-             || __getopt_nonoption_flags[0] == '\0')
-           nonoption_flags_max_len = -1;
-         else
-           {
-             const char *orig_str = __getopt_nonoption_flags;
-             int len = nonoption_flags_max_len = strlen (orig_str);
-             if (nonoption_flags_max_len < argc)
-               nonoption_flags_max_len = argc;
-             __getopt_nonoption_flags =
-               (char *) malloc (nonoption_flags_max_len);
-             if (__getopt_nonoption_flags == NULL)
-               nonoption_flags_max_len = -1;
-             else
-               {
-                 memcpy (__getopt_nonoption_flags, orig_str, len);
-                 memset (&__getopt_nonoption_flags[len], '\0',
-                         nonoption_flags_max_len - len);
-               }
-           }
-       }
-      nonoption_flags_len = nonoption_flags_max_len;
-    }
-  else
-    nonoption_flags_len = 0;
-#endif
-
-  return optstring;
-}
-\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 -1.
-   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;
-{
-  optarg = NULL;
-
-  if (optind == 0 || !__getopt_initialized)
-    {
-      if (optind == 0)
-       optind = 1;     /* Don't scan ARGV[0], the program name.  */
-      optstring = _getopt_initialize (argc, argv, optstring);
-      __getopt_initialized = 1;
-    }
-
-  /* Test whether ARGV[optind] points to a non-option argument.
-     Either it does not have option syntax, or there is an environment flag
-     from the shell indicating it is not an option.  The later information
-     is only used when the used in the GNU libc.  */
-#ifdef _LIBC
-#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
-                    || (optind < nonoption_flags_len                         \
-                        && __getopt_nonoption_flags[optind] == '1'))
-#else
-#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
-#endif
-
-  if (nextchar == NULL || *nextchar == '\0')
-    {
-      /* Advance to the next ARGV-element.  */
-
-      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
-        moved back by the user (who may also have changed the arguments).  */
-      if (last_nonopt > optind)
-       last_nonopt = optind;
-      if (first_nonopt > optind)
-       first_nonopt = optind;
-
-      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;
-
-         /* Skip any additional non-options
-            and extend the range of non-options previously skipped.  */
-
-         while (optind < argc && NONOPTION_P)
-           optind++;
-         last_nonopt = optind;
-       }
-
-      /* The 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 -1;
-       }
-
-      /* 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 (NONOPTION_P)
-       {
-         if (ordering == REQUIRE_ORDER)
-           return -1;
-         optarg = argv[optind++];
-         return 1;
-       }
-
-      /* We have found another option-ARGV-element.
-        Skip the initial punctuation.  */
-
-      nextchar = (argv[optind] + 1
-                 + (longopts != NULL && argv[optind][1] == '-'));
-    }
-
-  /* Decode the current option-ARGV-element.  */
-
-  /* Check whether the ARGV-element is a long option.
-
-     If long_only and the ARGV-element has the form "-f", where f is
-     a valid short option, don't consider it an abbreviated form of
-     a long option that starts with f.  Otherwise there would be no
-     way to give the -f short option.
-
-     On the other hand, if there's a long option "fubar" and
-     the ARGV-element is "-fu", do consider that an abbreviation of
-     the long option, just like "--fu", and not "-f" with arg "u".
-
-     This distinction seems to be the most useful approach.  */
-
-  if (longopts != NULL
-      && (argv[optind][1] == '-'
-         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
-    {
-      char *nameend;
-      const struct option *p;
-      const struct option *pfound = NULL;
-      int exact = 0;
-      int ambig = 0;
-      int indfound = -1;
-      int option_index;
-
-      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
-       /* Do nothing.  */ ;
-
-      /* Test all long options for either exact match
-        or abbreviated matches.  */
-      for (p = longopts, option_index = 0; p->name; p++, option_index++)
-       if (!strncmp (p->name, nextchar, nameend - nextchar))
-         {
-           if ((unsigned int) (nameend - nextchar)
-               == (unsigned int) 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 or later 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++;
-         optopt = 0;
-         return '?';
-       }
-
-      if (pfound != NULL)
-       {
-         option_index = indfound;
-         optind++;
-         if (*nameend)
-           {
-             /* Don't test has_arg with >, because some C compilers don't
-                allow it to be used on enums.  */
-             if (pfound->has_arg)
-               optarg = nameend + 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);
-
-                 optopt = pfound->val;
-                 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);
-                 optopt = pfound->val;
-                 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] == '-'
-         || 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++;
-         optopt = 0;
-         return '?';
-       }
-    }
-
-  /* Look at and handle the next short 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 (posixly_correct)
-             /* 1003.2 specifies the format of this message.  */
-             fprintf (stderr, "%s: illegal option -- %c\n",
-                      argv[0], c);
-           else
-             fprintf (stderr, "%s: invalid option -- %c\n",
-                      argv[0], c);
-         }
-       optopt = c;
-       return '?';
-      }
-    /* Convenience. Treat POSIX -W foo same as long option --foo */
-    if (temp[0] == 'W' && temp[1] == ';')
-      {
-       char *nameend;
-       const struct option *p;
-       const struct option *pfound = NULL;
-       int exact = 0;
-       int ambig = 0;
-       int indfound = 0;
-       int option_index;
-
-       /* 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)
-             {
-               /* 1003.2 specifies the format of this message.  */
-               fprintf (stderr, "%s: option requires an argument -- %c\n",
-                        argv[0], c);
-             }
-           optopt = c;
-           if (optstring[0] == ':')
-             c = ':';
-           else
-             c = '?';
-           return c;
-         }
-       else
-         /* We already incremented `optind' once;
-            increment it again when taking next ARGV-elt as argument.  */
-         optarg = argv[optind++];
-
-       /* optarg is now the argument, see if it's in the
-          table of longopts.  */
-
-       for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
-         /* Do nothing.  */ ;
-
-       /* Test all long options for either exact match
-          or abbreviated matches.  */
-       for (p = longopts, option_index = 0; p->name; p++, option_index++)
-         if (!strncmp (p->name, nextchar, nameend - nextchar))
-           {
-             if ((unsigned int) (nameend - 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 or later nonexact match found.  */
-               ambig = 1;
-           }
-       if (ambig && !exact)
-         {
-           if (opterr)
-             fprintf (stderr, "%s: option `-W %s' is ambiguous\n",
-                      argv[0], argv[optind]);
-           nextchar += strlen (nextchar);
-           optind++;
-           return '?';
-         }
-       if (pfound != NULL)
-         {
-           option_index = indfound;
-           if (*nameend)
-             {
-               /* Don't test has_arg with >, because some C compilers don't
-                  allow it to be used on enums.  */
-               if (pfound->has_arg)
-                 optarg = nameend + 1;
-               else
-                 {
-                   if (opterr)
-                     fprintf (stderr,
-                              "%s: option `-W %s' doesn't allow an argument\n",
-                              argv[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;
-         }
-         nextchar = NULL;
-         return 'W';   /* Let the application handle it.   */
-      }
-    if (temp[1] == ':')
-      {
-       if (temp[2] == ':')
-         {
-           /* This is an option that accepts an argument optionally.  */
-           if (*nextchar != '\0')
-             {
-               optarg = nextchar;
-               optind++;
-             }
-           else
-             optarg = NULL;
-           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)
-                 {
-                   /* 1003.2 specifies the format of this message.  */
-                   fprintf (stderr,
-                          "%s: option requires an argument -- %c\n",
-                          argv[0], c);
-                 }
-               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 /* Not ELIDE_CODE.  */
-\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 == -1)
-       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/lib/getopt.h b/lib/getopt.h
deleted file mode 100644 (file)
index ddf6fdd..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Declarations for getopt.
-   Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
-
-NOTE: The canonical source of this file is maintained with the GNU C Library.
-Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
-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, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 -1, 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 defined (__STDC__) && __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 defined (__STDC__) && __STDC__
-#ifdef __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 /* __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 /* __STDC__ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GETOPT_H */
diff --git a/lib/getopt1.c b/lib/getopt1.c
deleted file mode 100644 (file)
index 86545f2..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
-   Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
-
-NOTE: The canonical source of this file is maintained with the GNU C Library.
-Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
-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, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-\f
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "getopt.h"
-
-#if !defined (__STDC__) || !__STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-#ifndef const
-#define const
-#endif
-#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.  */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#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 /* Not ELIDE_CODE.  */
-\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 == -1)
-       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/lib/ipv4.h b/lib/ipv4.h
deleted file mode 100644 (file)
index 80ab17c..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-    ipv4.h -- missing IPv4 related definitions
-    Copyright (C) 2005 Ivo Timmermans
-                  2006 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_IPV4_H__
-#define __TINC_IPV4_H__
-
-#ifndef AF_INET
-#define AF_INET 2
-#endif
-
-#ifndef IPPROTO_ICMP
-#define IPPROTO_ICMP 1
-#endif
-
-#ifndef ICMP_DEST_UNREACH
-#define ICMP_DEST_UNREACH 3
-#endif
-
-#ifndef ICMP_FRAG_NEEDED
-#define ICMP_FRAG_NEEDED 4
-#endif
-
-#ifndef ICMP_NET_UNKNOWN
-#define ICMP_NET_UNKNOWN 6
-#endif
-
-#ifndef ICMP_NET_UNREACH
-#define ICMP_NET_UNREACH 0
-#endif
-
-#ifndef IP_MSS
-#define       IP_MSS          576
-#endif
-
-#ifndef HAVE_STRUCT_IP
-struct ip {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-       unsigned int ip_hl:4;
-       unsigned int ip_v:4;
-#else
-       unsigned int ip_v:4;
-       unsigned int ip_hl:4;
-#endif
-       uint8_t ip_tos;
-       uint16_t ip_len;
-       uint16_t ip_id; 
-       uint16_t ip_off;
-#define IP_RF 0x8000
-#define IP_DF 0x4000
-#define IP_MF 0x2000
-       uint8_t ip_ttl;
-       uint8_t ip_p;
-       uint16_t ip_sum;
-       struct in_addr ip_src, ip_dst;
-} __attribute__ ((__packed__));
-#endif
-
-#ifndef IP_OFFMASK
-#define IP_OFFMASK 0x1fff
-#endif
-
-#ifndef HAVE_STRUCT_ICMP
-struct icmp {
-       uint8_t icmp_type;
-       uint8_t icmp_code;
-       uint16_t icmp_cksum;
-       union {
-               uint8_t ih_pptr;
-               struct in_addr ih_gwaddr;
-               struct ih_idseq {
-                       uint16_t icd_id;
-                       uint16_t icd_seq;
-               } ih_idseq;
-               uint32_t ih_void;
-
-
-               struct ih_pmtu {
-                       uint16_t ipm_void;
-                       uint16_t ipm_nextmtu;
-               } ih_pmtu;
-
-               struct ih_rtradv {
-                       uint8_t irt_num_addrs;
-                       uint8_t irt_wpa;
-                       uint16_t irt_lifetime;
-               } ih_rtradv;
-       } icmp_hun;
-#define icmp_pptr icmp_hun.ih_pptr
-#define icmp_gwaddr icmp_hun.ih_gwaddr
-#define icmp_id icmp_hun.ih_idseq.icd_id
-#define icmp_seq icmp_hun.ih_idseq.icd_seq
-#define icmp_void icmp_hun.ih_void
-#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
-#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
-#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
-#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
-#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
-       union {
-               struct {
-                       uint32_t its_otime;
-                       uint32_t its_rtime;
-                       uint32_t its_ttime;
-               } id_ts;
-               struct {
-                       struct ip idi_ip;
-               } id_ip;
-               uint32_t id_mask;
-               uint8_t id_data[1];
-       } icmp_dun;
-#define icmp_otime icmp_dun.id_ts.its_otime
-#define icmp_rtime icmp_dun.id_ts.its_rtime
-#define icmp_ttime icmp_dun.id_ts.its_ttime
-#define icmp_ip icmp_dun.id_ip.idi_ip
-#define icmp_radv icmp_dun.id_radv
-#define icmp_mask icmp_dun.id_mask
-#define icmp_data icmp_dun.id_data
-} __attribute__ ((__packed__));
-#endif
-
-#endif /* __TINC_IPV4_H__ */
diff --git a/lib/ipv6.h b/lib/ipv6.h
deleted file mode 100644 (file)
index fee74f5..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-    ipv6.h -- missing IPv6 related definitions
-    Copyright (C) 2005 Ivo Timmermans
-                  2006 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_IPV6_H__
-#define __TINC_IPV6_H__
-
-#ifndef AF_INET6
-#define AF_INET6 10
-#endif
-
-#ifndef IPPROTO_ICMPV6
-#define IPPROTO_ICMPV6 58
-#endif
-
-#ifndef HAVE_STRUCT_IN6_ADDR
-struct in6_addr {
-       union {
-               uint8_t u6_addr8[16];
-               uint16_t u6_addr16[8];
-               uint32_t u6_addr32[4];
-       } in6_u;
-} __attribute__ ((__packed__));
-#define s6_addr in6_u.u6_addr8
-#define s6_addr16 in6_u.u6_addr16
-#define s6_addr32 in6_u.u6_addr32
-#endif
-
-#ifndef HAVE_STRUCT_SOCKADDR_IN6
-struct sockaddr_in6 {
-       uint16_t sin6_family;
-       uint16_t sin6_port;
-       uint32_t sin6_flowinfo;
-       struct in6_addr sin6_addr;
-       uint32_t sin6_scope_id;
-} __attribute__ ((__packed__));
-#endif
-
-#ifndef IN6_IS_ADDR_V4MAPPED
-#define IN6_IS_ADDR_V4MAPPED(a) \
-        ((((__const uint32_t *) (a))[0] == 0) \
-        && (((__const uint32_t *) (a))[1] == 0) \
-        && (((__const uint32_t *) (a))[2] == htonl (0xffff)))
-#endif
-
-#ifndef HAVE_STRUCT_IP6_HDR
-struct ip6_hdr {
-       union {
-               struct ip6_hdrctl {
-                       uint32_t ip6_un1_flow;
-                       uint16_t ip6_un1_plen;
-                       uint8_t ip6_un1_nxt;
-                       uint8_t ip6_un1_hlim;
-               } ip6_un1;
-               uint8_t ip6_un2_vfc;
-       } ip6_ctlun;
-       struct in6_addr ip6_src;
-       struct in6_addr ip6_dst;
-} __attribute__ ((__packed__));
-#define ip6_vfc ip6_ctlun.ip6_un2_vfc
-#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
-#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
-#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
-#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
-#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
-#endif
-
-#ifndef HAVE_STRUCT_ICMP6_HDR
-struct icmp6_hdr {
-       uint8_t icmp6_type;
-       uint8_t icmp6_code;
-       uint16_t icmp6_cksum;
-       union {
-               uint32_t icmp6_un_data32[1];
-               uint16_t icmp6_un_data16[2];
-               uint8_t icmp6_un_data8[4];
-       } icmp6_dataun;
-} __attribute__ ((__packed__));
-#define ICMP6_DST_UNREACH_NOROUTE 0
-#define ICMP6_DST_UNREACH 1
-#define ICMP6_PACKET_TOO_BIG 2
-#define ICMP6_DST_UNREACH_ADDR 3
-#define ND_NEIGHBOR_SOLICIT 135
-#define ND_NEIGHBOR_ADVERT 136
-#define icmp6_data32 icmp6_dataun.icmp6_un_data32
-#define icmp6_data16 icmp6_dataun.icmp6_un_data16
-#define icmp6_data8 icmp6_dataun.icmp6_un_data8
-#define icmp6_mtu icmp6_data32[0]
-#endif
-
-#ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
-struct nd_neighbor_solicit {
-       struct icmp6_hdr nd_ns_hdr;
-       struct in6_addr nd_ns_target;
-} __attribute__ ((__packed__));
-#define ND_OPT_SOURCE_LINKADDR 1
-#define ND_OPT_TARGET_LINKADDR 2
-#define nd_ns_type nd_ns_hdr.icmp6_type
-#define nd_ns_code nd_ns_hdr.icmp6_code
-#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
-#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
-#endif
-
-#ifndef HAVE_STRUCT_ND_OPT_HDR
-struct nd_opt_hdr {
-       uint8_t nd_opt_type;
-       uint8_t nd_opt_len;
-} __attribute__ ((__packed__));
-#endif
-
-#endif /* __TINC_IPV6_H__ */
diff --git a/lib/list.c b/lib/list.c
deleted file mode 100644 (file)
index a26c58d..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-    list.c -- functions to deal with double linked lists
-    Copyright (C) 2000-2005 Ivo Timmermans
-                  2000-2006 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include "list.h"
-#include "xalloc.h"
-
-/* (De)constructors */
-
-list_t *list_alloc(list_action_t delete) {
-       list_t *list;
-
-       list = xmalloc_and_zero(sizeof(list_t));
-       list->delete = delete;
-
-       return list;
-}
-
-void list_free(list_t *list) {
-       free(list);
-}
-
-list_node_t *list_alloc_node(void) {
-       return xmalloc_and_zero(sizeof(list_node_t));
-}
-
-void list_free_node(list_t *list, list_node_t *node) {
-       if(node->data && list->delete)
-               list->delete(node->data);
-
-       free(node);
-}
-
-/* Insertion and deletion */
-
-list_node_t *list_insert_head(list_t *list, void *data) {
-       list_node_t *node;
-
-       node = list_alloc_node();
-
-       node->data = data;
-       node->prev = NULL;
-       node->next = list->head;
-       list->head = node;
-
-       if(node->next)
-               node->next->prev = node;
-       else
-               list->tail = node;
-
-       list->count++;
-
-       return node;
-}
-
-list_node_t *list_insert_tail(list_t *list, void *data) {
-       list_node_t *node;
-
-       node = list_alloc_node();
-
-       node->data = data;
-       node->next = NULL;
-       node->prev = list->tail;
-       list->tail = node;
-
-       if(node->prev)
-               node->prev->next = node;
-       else
-               list->head = node;
-
-       list->count++;
-
-       return node;
-}
-
-void list_unlink_node(list_t *list, list_node_t *node) {
-       if(node->prev)
-               node->prev->next = node->next;
-       else
-               list->head = node->next;
-
-       if(node->next)
-               node->next->prev = node->prev;
-       else
-               list->tail = node->prev;
-
-       list->count--;
-}
-
-void list_delete_node(list_t *list, list_node_t *node) {
-       list_unlink_node(list, node);
-       list_free_node(list, node);
-}
-
-void list_delete_head(list_t *list) {
-       list_delete_node(list, list->head);
-}
-
-void list_delete_tail(list_t *list) {
-       list_delete_node(list, list->tail);
-}
-
-/* Head/tail lookup */
-
-void *list_get_head(list_t *list) {
-       if(list->head)
-               return list->head->data;
-       else
-               return NULL;
-}
-
-void *list_get_tail(list_t *list) {
-       if(list->tail)
-               return list->tail->data;
-       else
-               return NULL;
-}
-
-/* Fast list deletion */
-
-void list_delete_list(list_t *list) {
-       list_node_t *node, *next;
-
-       for(node = list->head; node; node = next) {
-               next = node->next;
-               list_free_node(list, node);
-       }
-
-       list_free(list);
-}
-
-/* Traversing */
-
-void list_foreach_node(list_t *list, list_action_node_t action) {
-       list_node_t *node, *next;
-
-       for(node = list->head; node; node = next) {
-               next = node->next;
-               action(node);
-       }
-}
-
-void list_foreach(list_t *list, list_action_t action) {
-       list_node_t *node, *next;
-
-       for(node = list->head; node; node = next) {
-               next = node->next;
-               if(node->data)
-                       action(node->data);
-       }
-}
diff --git a/lib/list.h b/lib/list.h
deleted file mode 100644 (file)
index 197fbb8..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-    list.h -- header file for list.c
-    Copyright (C) 2000-2005 Ivo Timmermans
-                  2000-2006 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_LIST_H__
-#define __TINC_LIST_H__
-
-typedef struct list_node_t {
-       struct list_node_t *prev;
-       struct list_node_t *next;
-
-       /* Payload */
-
-       void *data;
-} list_node_t;
-
-typedef void (*list_action_t)(const void *);
-typedef void (*list_action_node_t)(const list_node_t *);
-
-typedef struct list_t {
-       list_node_t *head;
-       list_node_t *tail;
-       int count;
-
-       /* Callbacks */
-
-       list_action_t delete;
-} list_t;
-
-/* (De)constructors */
-
-extern list_t *list_alloc(list_action_t) __attribute__ ((__malloc__));
-extern void list_free(list_t *);
-extern list_node_t *list_alloc_node(void);
-extern void list_free_node(list_t *, list_node_t *);
-
-/* Insertion and deletion */
-
-extern list_node_t *list_insert_head(list_t *, void *);
-extern list_node_t *list_insert_tail(list_t *, void *);
-
-extern void list_unlink_node(list_t *, list_node_t *);
-extern void list_delete_node(list_t *, list_node_t *);
-
-extern void list_delete_head(list_t *);
-extern void list_delete_tail(list_t *);
-
-/* Head/tail lookup */
-
-extern void *list_get_head(list_t *);
-extern void *list_get_tail(list_t *);
-
-/* Fast list deletion */
-
-extern void list_delete_list(list_t *);
-
-/* Traversing */
-
-extern void list_foreach(list_t *, list_action_t);
-extern void list_foreach_node(list_t *, list_action_node_t);
-
-#endif                                                 /* __TINC_LIST_H__ */
diff --git a/lib/malloc.c b/lib/malloc.c
deleted file mode 100644 (file)
index 2a996d4..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Work around bug on some systems where malloc (0) fails.
-   Copyright (C) 1997 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, Inc., Foundation,
-   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
-
-/* written by Jim Meyering */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-#undef malloc
-
-#include <sys/types.h>
-
-char *malloc ();
-
-/* Allocate an N-byte block of memory from the heap.
-   If N is zero, allocate a 1-byte block.  */
-
-char *
-rpl_malloc (n)
-     size_t n;
-{
-  if (n == 0)
-    n = 1;
-  return malloc (n);
-}
diff --git a/lib/memcmp.c b/lib/memcmp.c
deleted file mode 100644 (file)
index 9d80833..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-/* Copyright (C) 1991, 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
-   Contributed by Torbjorn Granlund (tege@sics.se).
-
-   NOTE: The canonical source of this file is maintained with the GNU C Library.
-   Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
-   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, Inc.,
-   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#undef __ptr_t
-#if defined __cplusplus || (defined __STDC__ && __STDC__)
-# define __ptr_t       void *
-#else /* Not C++ or ANSI C.  */
-# undef        const
-# define const
-# define __ptr_t       char *
-#endif /* C++ or ANSI C.  */
-
-#ifndef __P
-# if defined __GNUC__ || (defined __STDC__ && __STDC__)
-#  define __P(args) args
-# else
-#  define __P(args) ()
-# endif  /* GCC.  */
-#endif  /* Not __P.  */
-
-#if defined HAVE_STRING_H || defined _LIBC
-# include <string.h>
-#endif
-
-#undef memcmp
-
-#ifdef _LIBC
-
-# include <memcopy.h>
-
-#else  /* Not in the GNU C library.  */
-
-# include <sys/types.h>
-
-/* Type to use for aligned memory operations.
-   This should normally be the biggest type supported by a single load
-   and store.  Must be an unsigned type.  */
-# define op_t  unsigned long int
-# define OPSIZ (sizeof(op_t))
-
-/* Threshold value for when to enter the unrolled loops.  */
-# define OP_T_THRES    16
-
-/* Type to use for unaligned operations.  */
-typedef unsigned char byte;
-
-# ifndef WORDS_BIGENDIAN
-#  define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
-# else
-#  define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
-# endif
-
-#endif /* In the GNU C library.  */
-
-#ifdef WORDS_BIGENDIAN
-# define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
-#else
-# define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b))
-#endif
-
-/* BE VERY CAREFUL IF YOU CHANGE THIS CODE!  */
-
-/* The strategy of this memcmp is:
-
-   1. Compare bytes until one of the block pointers is aligned.
-
-   2. Compare using memcmp_common_alignment or
-      memcmp_not_common_alignment, regarding the alignment of the other
-      block after the initial byte operations.  The maximum number of
-      full words (of type op_t) are compared in this way.
-
-   3. Compare the few remaining bytes.  */
-
-#ifndef WORDS_BIGENDIAN
-/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine.
-   A and B are known to be different.
-   This is needed only on little-endian machines.  */
-
-static int memcmp_bytes __P((op_t, op_t));
-
-# ifdef  __GNUC__
-__inline
-# endif
-static int
-memcmp_bytes (a, b)
-     op_t a, b;
-{
-  long int srcp1 = (long int) &a;
-  long int srcp2 = (long int) &b;
-  op_t a0, b0;
-
-  do
-    {
-      a0 = ((byte *) srcp1)[0];
-      b0 = ((byte *) srcp2)[0];
-      srcp1 += 1;
-      srcp2 += 1;
-    }
-  while (a0 == b0);
-  return a0 - b0;
-}
-#endif
-
-static int memcmp_common_alignment __P((long, long, size_t));
-
-/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
-   objects (not LEN bytes!).  Both SRCP1 and SRCP2 should be aligned for
-   memory operations on `op_t's.  */
-#ifdef __GNUC__
-__inline
-#endif
-static int
-memcmp_common_alignment (srcp1, srcp2, len)
-     long int srcp1;
-     long int srcp2;
-     size_t len;
-{
-  op_t a0, a1;
-  op_t b0, b1;
-
-  switch (len % 4)
-    {
-    default: /* Avoid warning about uninitialized local variables.  */
-    case 2:
-      a0 = ((op_t *) srcp1)[0];
-      b0 = ((op_t *) srcp2)[0];
-      srcp1 -= 2 * OPSIZ;
-      srcp2 -= 2 * OPSIZ;
-      len += 2;
-      goto do1;
-    case 3:
-      a1 = ((op_t *) srcp1)[0];
-      b1 = ((op_t *) srcp2)[0];
-      srcp1 -= OPSIZ;
-      srcp2 -= OPSIZ;
-      len += 1;
-      goto do2;
-    case 0:
-      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
-       return 0;
-      a0 = ((op_t *) srcp1)[0];
-      b0 = ((op_t *) srcp2)[0];
-      goto do3;
-    case 1:
-      a1 = ((op_t *) srcp1)[0];
-      b1 = ((op_t *) srcp2)[0];
-      srcp1 += OPSIZ;
-      srcp2 += OPSIZ;
-      len -= 1;
-      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
-       goto do0;
-      /* Fall through.  */
-    }
-
-  do
-    {
-      a0 = ((op_t *) srcp1)[0];
-      b0 = ((op_t *) srcp2)[0];
-      if (a1 != b1)
-       return CMP_LT_OR_GT (a1, b1);
-
-    do3:
-      a1 = ((op_t *) srcp1)[1];
-      b1 = ((op_t *) srcp2)[1];
-      if (a0 != b0)
-       return CMP_LT_OR_GT (a0, b0);
-
-    do2:
-      a0 = ((op_t *) srcp1)[2];
-      b0 = ((op_t *) srcp2)[2];
-      if (a1 != b1)
-       return CMP_LT_OR_GT (a1, b1);
-
-    do1:
-      a1 = ((op_t *) srcp1)[3];
-      b1 = ((op_t *) srcp2)[3];
-      if (a0 != b0)
-       return CMP_LT_OR_GT (a0, b0);
-
-      srcp1 += 4 * OPSIZ;
-      srcp2 += 4 * OPSIZ;
-      len -= 4;
-    }
-  while (len != 0);
-
-  /* This is the right position for do0.  Please don't move
-     it into the loop.  */
- do0:
-  if (a1 != b1)
-    return CMP_LT_OR_GT (a1, b1);
-  return 0;
-}
-
-static int memcmp_not_common_alignment __P((long, long, size_t));
-
-/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
-   `op_t' objects (not LEN bytes!).  SRCP2 should be aligned for memory
-   operations on `op_t', but SRCP1 *should be unaligned*.  */
-#ifdef __GNUC__
-__inline
-#endif
-static int
-memcmp_not_common_alignment (srcp1, srcp2, len)
-     long int srcp1;
-     long int srcp2;
-     size_t len;
-{
-  op_t a0, a1, a2, a3;
-  op_t b0, b1, b2, b3;
-  op_t x;
-  int shl, shr;
-
-  /* Calculate how to shift a word read at the memory operation
-     aligned srcp1 to make it aligned for comparison.  */
-
-  shl = 8 * (srcp1 % OPSIZ);
-  shr = 8 * OPSIZ - shl;
-
-  /* Make SRCP1 aligned by rounding it down to the beginning of the `op_t'
-     it points in the middle of.  */
-  srcp1 &= -OPSIZ;
-
-  switch (len % 4)
-    {
-    default: /* Avoid warning about uninitialized local variables.  */
-    case 2:
-      a1 = ((op_t *) srcp1)[0];
-      a2 = ((op_t *) srcp1)[1];
-      b2 = ((op_t *) srcp2)[0];
-      srcp1 -= 1 * OPSIZ;
-      srcp2 -= 2 * OPSIZ;
-      len += 2;
-      goto do1;
-    case 3:
-      a0 = ((op_t *) srcp1)[0];
-      a1 = ((op_t *) srcp1)[1];
-      b1 = ((op_t *) srcp2)[0];
-      srcp2 -= 1 * OPSIZ;
-      len += 1;
-      goto do2;
-    case 0:
-      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
-       return 0;
-      a3 = ((op_t *) srcp1)[0];
-      a0 = ((op_t *) srcp1)[1];
-      b0 = ((op_t *) srcp2)[0];
-      srcp1 += 1 * OPSIZ;
-      goto do3;
-    case 1:
-      a2 = ((op_t *) srcp1)[0];
-      a3 = ((op_t *) srcp1)[1];
-      b3 = ((op_t *) srcp2)[0];
-      srcp1 += 2 * OPSIZ;
-      srcp2 += 1 * OPSIZ;
-      len -= 1;
-      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
-       goto do0;
-      /* Fall through.  */
-    }
-
-  do
-    {
-      a0 = ((op_t *) srcp1)[0];
-      b0 = ((op_t *) srcp2)[0];
-      x = MERGE(a2, shl, a3, shr);
-      if (x != b3)
-       return CMP_LT_OR_GT (x, b3);
-
-    do3:
-      a1 = ((op_t *) srcp1)[1];
-      b1 = ((op_t *) srcp2)[1];
-      x = MERGE(a3, shl, a0, shr);
-      if (x != b0)
-       return CMP_LT_OR_GT (x, b0);
-
-    do2:
-      a2 = ((op_t *) srcp1)[2];
-      b2 = ((op_t *) srcp2)[2];
-      x = MERGE(a0, shl, a1, shr);
-      if (x != b1)
-       return CMP_LT_OR_GT (x, b1);
-
-    do1:
-      a3 = ((op_t *) srcp1)[3];
-      b3 = ((op_t *) srcp2)[3];
-      x = MERGE(a1, shl, a2, shr);
-      if (x != b2)
-       return CMP_LT_OR_GT (x, b2);
-
-      srcp1 += 4 * OPSIZ;
-      srcp2 += 4 * OPSIZ;
-      len -= 4;
-    }
-  while (len != 0);
-
-  /* This is the right position for do0.  Please don't move
-     it into the loop.  */
- do0:
-  x = MERGE(a2, shl, a3, shr);
-  if (x != b3)
-    return CMP_LT_OR_GT (x, b3);
-  return 0;
-}
-
-int
-rpl_memcmp (s1, s2, len)
-     const __ptr_t s1;
-     const __ptr_t s2;
-     size_t len;
-{
-  op_t a0;
-  op_t b0;
-  long int srcp1 = (long int) s1;
-  long int srcp2 = (long int) s2;
-  op_t res;
-
-  if (len >= OP_T_THRES)
-    {
-      /* There are at least some bytes to compare.  No need to test
-        for LEN == 0 in this alignment loop.  */
-      while (srcp2 % OPSIZ != 0)
-       {
-         a0 = ((byte *) srcp1)[0];
-         b0 = ((byte *) srcp2)[0];
-         srcp1 += 1;
-         srcp2 += 1;
-         res = a0 - b0;
-         if (res != 0)
-           return res;
-         len -= 1;
-       }
-
-      /* SRCP2 is now aligned for memory operations on `op_t'.
-        SRCP1 alignment determines if we can do a simple,
-        aligned compare or need to shuffle bits.  */
-
-      if (srcp1 % OPSIZ == 0)
-       res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
-      else
-       res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
-      if (res != 0)
-       return res;
-
-      /* Number of bytes remaining in the interval [0..OPSIZ-1].  */
-      srcp1 += len & -OPSIZ;
-      srcp2 += len & -OPSIZ;
-      len %= OPSIZ;
-    }
-
-  /* There are just a few bytes to compare.  Use byte memory operations.  */
-  while (len != 0)
-    {
-      a0 = ((byte *) srcp1)[0];
-      b0 = ((byte *) srcp2)[0];
-      srcp1 += 1;
-      srcp2 += 1;
-      res = a0 - b0;
-      if (res != 0)
-       return res;
-      len -= 1;
-    }
-
-  return 0;
-}
-
-#ifdef weak_alias
-# undef bcmp
-weak_alias (memcmp, bcmp)
-#endif
diff --git a/lib/realloc.c b/lib/realloc.c
deleted file mode 100644 (file)
index 4971b28..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Work around bug on some systems where realloc (NULL, 0) fails.
-   Copyright (C) 1997 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, Inc., Foundation,
-   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
-
-/* written by Jim Meyering */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-#undef realloc
-
-#include <sys/types.h>
-
-char *malloc ();
-char *realloc ();
-
-/* Change the size of an allocated block of memory P to N bytes,
-   with error checking.  If N is zero, change it to 1.  If P is NULL,
-   use malloc.  */
-
-char *
-rpl_realloc (p, n)
-     char *p;
-     size_t n;
-{
-  if (n == 0)
-    n = 1;
-  if (p == 0)
-    return malloc (n);
-  return realloc (p, n);
-}
diff --git a/lib/splay_tree.c b/lib/splay_tree.c
deleted file mode 100644 (file)
index 3a792e8..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
-    splay_tree.c -- splay tree and linked list convenience
-    Copyright (C) 2004-2006 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include "splay_tree.h"
-#include "xalloc.h"
-
-/* Splay operation */
-
-static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *result) {
-       splay_node_t left = {0}, right = {0};
-       splay_node_t *leftbottom = &left, *rightbottom = &right, *child, *grandchild;
-       splay_node_t *root = tree->root;
-       int c;
-
-       if(!root) {
-               if(result)
-                       *result = 0;
-               return NULL;
-       }
-
-       while((c = tree->compare(data, root->data))) {
-               if(c < 0 && (child = root->left)) {
-                       c = tree->compare(data, child->data);
-
-                       if(c < 0 && (grandchild = child->left)) {
-                               rightbottom->left = child;
-                               child->parent = rightbottom;
-                               rightbottom = child;
-                               
-                               if((root->left = child->right))
-                                       child->right->parent = root;
-                               
-                               child->right = root;
-                               root->parent = child;
-
-                               child->left = NULL;
-                               grandchild->parent = NULL;
-
-                               root = grandchild;
-                       } else if (c > 0 && (grandchild = child->right)) {
-                               leftbottom->right = child;
-                               child->parent = leftbottom;
-                               leftbottom = child;
-
-                               child->right = NULL;
-                               grandchild->parent = NULL;
-
-                               rightbottom->left = root;
-                               root->parent = rightbottom;
-                               rightbottom = root;
-
-                               root->left = NULL;
-
-                               root = grandchild;
-                       } else {
-                               rightbottom->left = root;
-                               root->parent = rightbottom;
-                               rightbottom = root;
-                               
-                               root->left = NULL;
-                               child->parent = NULL;
-
-                               root = child;
-                               break;
-                       }
-               } else if(c > 0 && (child = root->right)) {
-                       c = tree->compare(data, child->data);
-
-                       if(c > 0 && (grandchild = child->right)) {
-                               leftbottom->right = child;
-                               child->parent = leftbottom;
-                               leftbottom = child;
-                               
-                               if((root->right = child->left))
-                                       child->left->parent = root;
-                               
-                               child->left = root;
-                               root->parent = child;
-
-                               child->right = NULL;
-                               grandchild->parent = NULL;
-
-                               root = grandchild;
-                       } else if (c < 0 && (grandchild = child->left)) {
-                               rightbottom->left = child;
-                               child->parent = rightbottom;
-                               rightbottom = child;
-
-                               child->left = NULL;
-                               grandchild->parent = NULL;
-
-                               leftbottom->right = root;
-                               root->parent = leftbottom;
-                               leftbottom = root;
-
-                               root->right = NULL;
-
-                               root = grandchild;
-                       } else {
-                               leftbottom->right = root;
-                               root->parent = leftbottom;
-                               leftbottom = root;
-
-                               root->right = NULL;
-                               child->parent = NULL;
-
-                               root = child;
-                               break;
-                       }
-               } else {
-                       break;
-               }
-       }
-
-       /* Merge trees */
-
-       if(left.right) {
-               if(root->left) {
-                       leftbottom->right = root->left;
-                       root->left->parent = leftbottom;
-               }
-               root->left = left.right;
-               left.right->parent = root;
-       }
-
-       if(right.left) {
-               if(root->right) {
-                       rightbottom->left = root->right;
-                       root->right->parent = rightbottom;
-               }
-               root->right = right.left;
-               right.left->parent = root;
-       }
-
-       /* Return result */
-
-       tree->root = root;
-       if(result)
-               *result = c;
-
-       return tree->root;
-}
-                       
-static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) {
-       splay_node_t *parent, *grandparent, *greatgrandparent;
-
-       while((parent = node->parent)) {
-               if(!(grandparent = parent->parent)) { /* zig */
-                       if(node == parent->left) {
-                               if((parent->left = node->right))                                
-                                       parent->left->parent = parent;
-                               node->right = parent;
-                       } else {
-                               if((parent->right = node->left))
-                                       parent->right->parent = parent;
-                               node->left = parent;
-                       }
-
-                       parent->parent = node;
-                       node->parent = NULL;
-               } else {
-                       greatgrandparent = grandparent->parent;
-
-                       if(node == parent->left && parent == grandparent->left) { /* left zig-zig */
-                               if((grandparent->left = parent->right))
-                                       grandparent->left->parent = grandparent;
-                               parent->right = grandparent;
-                               grandparent->parent = parent;
-
-                               if((parent->left = node->right))
-                                       parent->left->parent = parent;
-                               node->right = parent;
-                               parent->parent = node;
-                       } else if(node == parent->right && parent == grandparent->right) { /* right zig-zig */
-                               if((grandparent->right = parent->left))
-                                       grandparent->right->parent = grandparent;
-                               parent->left = grandparent;
-                               grandparent->parent = parent;
-
-                               if((parent->right = node->left))
-                                       parent->right->parent = parent;
-                               node->left = parent;
-                               parent->parent = node;
-                       } else if(node == parent->right && parent == grandparent->left) { /* left-right zig-zag */
-                               if((parent->right = node->left))
-                                       parent->right->parent = parent;
-                               node->left = parent;
-                               parent->parent = node;
-
-                               if((grandparent->left = node->right))
-                                       grandparent->left->parent = grandparent;
-                               node->right = grandparent;
-                               grandparent->parent = node;
-                       } else { /* right-left zig-zag */
-                               if((parent->left = node->right))
-                                       parent->left->parent = parent;
-                               node->right = parent;
-                               parent->parent = node;
-
-                               if((grandparent->right = node->left))
-                                       grandparent->right->parent = grandparent;
-                               node->left = grandparent;
-                               grandparent->parent = node;
-                       }
-
-                       if((node->parent = greatgrandparent)) {
-                               if(grandparent == greatgrandparent->left)
-                                       greatgrandparent->left = node;
-                               else
-                                       greatgrandparent->right = node;
-                       }
-               }
-       }
-
-       tree->root = node;
-}
-
-/* (De)constructors */
-
-splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) {
-       splay_tree_t *tree;
-
-       tree = xmalloc_and_zero(sizeof(splay_tree_t));
-       tree->compare = compare;
-       tree->delete = delete;
-
-       return tree;
-}
-
-void splay_free_tree(splay_tree_t *tree) {
-       free(tree);
-}
-
-splay_node_t *splay_alloc_node(void) {
-       return xmalloc_and_zero(sizeof(splay_node_t));
-}
-
-void splay_free_node(splay_tree_t *tree, splay_node_t *node) {
-       if(node->data && tree->delete)
-               tree->delete(node->data);
-
-       free(node);
-}
-
-/* Searching */
-
-void *splay_search(splay_tree_t *tree, const void *data) {
-       splay_node_t *node;
-
-       node = splay_search_node(tree, data);
-
-       return node ? node->data : NULL;
-}
-
-void *splay_search_closest(splay_tree_t *tree, const void *data, int *result) {
-       splay_node_t *node;
-
-       node = splay_search_closest_node(tree, data, result);
-
-       return node ? node->data : NULL;
-}
-
-void *splay_search_closest_smaller(splay_tree_t *tree, const void *data) {
-       splay_node_t *node;
-
-       node = splay_search_closest_smaller_node(tree, data);
-
-       return node ? node->data : NULL;
-}
-
-void *splay_search_closest_greater(splay_tree_t *tree, const void *data) {
-       splay_node_t *node;
-
-       node = splay_search_closest_greater_node(tree, data);
-
-       return node ? node->data : NULL;
-}
-
-splay_node_t *splay_search_node(splay_tree_t *tree, const void *data) {
-       splay_node_t *node;
-       int result;
-
-       node = splay_search_closest_node(tree, data, &result);
-
-       return result ? NULL : node;
-}
-
-splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const void *data, int *result) {
-       splay_node_t *node;
-       int c;
-
-       node = tree->root;
-
-       if(!node) {
-               if(result)
-                       *result = 0;
-               return NULL;
-       }
-
-       for(;;) {
-               c = tree->compare(data, node->data);
-
-               if(c < 0) {
-                       if(node->left)
-                               node = node->left;
-                       else
-                               break;
-               } else if(c > 0) {
-                       if(node->right)
-                               node = node->right;
-                       else 
-                               break;
-               } else {
-                       break;
-               }
-       }
-
-       if(result)
-               *result = c;
-       return node;
-}
-
-splay_node_t *splay_search_closest_node(splay_tree_t *tree, const void *data, int *result) {
-       return splay_top_down(tree, data, result);
-}
-
-splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void *data) {
-       splay_node_t *node;
-       int result;
-
-       node = splay_search_closest_node(tree, data, &result);
-
-       if(result < 0)
-               node = node->prev;
-
-       return node;
-}
-
-splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void *data) {
-       splay_node_t *node;
-       int result;
-
-       node = splay_search_closest_node(tree, data, &result);
-
-       if(result > 0)
-               node = node->next;
-
-       return node;
-}
-
-/* Insertion and deletion */
-
-splay_node_t *splay_insert(splay_tree_t *tree, void *data) {
-       splay_node_t *closest, *new;
-       int result;
-
-       if(!tree->root) {
-               new = splay_alloc_node();
-               new->data = data;
-               splay_insert_top(tree, new);
-       } else {
-               closest = splay_search_closest_node(tree, data, &result);
-
-               if(!result)
-                       return NULL;
-
-               new = splay_alloc_node();
-               new->data = data;
-               
-               if(result < 0)
-                       splay_insert_before(tree, closest, new);
-               else
-                       splay_insert_after(tree, closest, new);
-       }                       
-
-       return new;
-}
-
-splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) {
-       splay_node_t *closest;
-       int result;
-
-       if(!tree->root)
-               splay_insert_top(tree, node);
-       else {
-               closest = splay_search_closest_node(tree, node->data, &result);
-               
-               if(!result)
-                       return NULL;
-
-               if(result < 0)
-                       splay_insert_before(tree, closest, node);
-               else
-                       splay_insert_after(tree, closest, node);
-       }
-
-       return node;
-}
-
-void splay_insert_top(splay_tree_t *tree, splay_node_t *node) {
-       node->prev = node->next = node->left = node->right = node->parent = NULL;
-       tree->head = tree->tail = tree->root = node;
-}
-
-void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) {
-       if(!before) {
-               if(tree->tail)
-                       splay_insert_after(tree, tree->tail, node);
-               else
-                       splay_insert_top(tree, node);
-               return;
-       }
-
-       node->next = before;
-       if((node->prev = before->prev))
-               before->prev->next = node;
-       else
-               tree->head = node;
-       before->prev = node;
-
-       splay_bottom_up(tree, before);
-
-       node->right = before;
-       before->parent = node;
-       if((node->left = before->left))
-               before->left->parent = node;
-       before->left = NULL;
-
-       node->parent = NULL;
-       tree->root = node;
-}
-
-void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) {
-       if(!after) {
-               if(tree->head)
-                       splay_insert_before(tree, tree->head, node);
-               else
-                       splay_insert_top(tree, node);
-               return;
-       }
-
-       node->prev = after;
-       if((node->next = after->next))
-               after->next->prev = node;
-       else
-               tree->tail = node;
-       after->next = node;
-
-       splay_bottom_up(tree, after);
-
-       node->left = after;
-       after->parent = node;
-       if((node->right = after->right))
-               after->right->parent = node;
-       after->right = NULL;
-
-       node->parent = NULL;
-       tree->root = node;
-}
-
-splay_node_t *splay_unlink(splay_tree_t *tree, void *data) {
-       splay_node_t *node;
-
-       node = splay_search_node(tree, data);
-
-       if(node)
-               splay_unlink_node(tree, node);
-
-       return node;
-}
-
-void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) {
-       if(node->prev)
-               node->prev->next = node->next;
-       else
-               tree->head = node->next;
-
-       if(node->next)
-               node->next->prev = node->prev;
-       else
-               tree->tail = node->prev;
-
-       splay_bottom_up(tree, node);
-
-       if(node->prev) {
-               node->left->parent = NULL;
-               tree->root = node->left;
-               if((node->prev->right = node->right))
-                       node->right->parent = node->prev;
-       } else if(node->next) {
-               tree->root = node->right;
-               node->right->parent = NULL;
-       } else {
-               tree->root = NULL;
-       }
-}
-
-void splay_delete_node(splay_tree_t *tree, splay_node_t *node) {
-       splay_unlink_node(tree, node);
-       splay_free_node(tree, node);
-}
-
-void splay_delete(splay_tree_t *tree, void *data) {
-       splay_node_t *node;
-
-       node = splay_search_node(tree, data);
-
-       if(node)
-               splay_delete_node(tree, node);
-}
-
-/* Fast tree cleanup */
-
-void splay_delete_tree(splay_tree_t *tree) {
-       splay_node_t *node, *next;
-
-       for(node = tree->head; node; node = next) {
-               next = node->next;
-               splay_free_node(tree, node);
-       }
-
-       splay_free_tree(tree);
-}
-
-/* Tree walking */
-
-void splay_foreach(const splay_tree_t *tree, splay_action_t action) {
-       splay_node_t *node, *next;
-
-       for(node = tree->head; node; node = next) {
-               next = node->next;
-               action(node->data);
-       }
-}
-
-void splay_foreach_node(const splay_tree_t *tree, splay_action_t action) {
-       splay_node_t *node, *next;
-
-       for(node = tree->head; node; node = next) {
-               next = node->next;
-               action(node);
-       }
-}
diff --git a/lib/splay_tree.h b/lib/splay_tree.h
deleted file mode 100644 (file)
index e4af0c4..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-    splay_tree.h -- header file for splay_tree.c
-    Copyright (C) 2004-2006 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-
-#ifndef __SPLAY_TREE_H__
-#define __SPLAY_TREE_H__
-
-typedef struct splay_node_t {
-
-       /* Linked list part */
-
-       struct splay_node_t *next;
-       struct splay_node_t *prev;
-
-       /* Tree part */
-
-       struct splay_node_t *parent;
-       struct splay_node_t *left;
-       struct splay_node_t *right;
-
-       /* Payload */
-
-       void *data;
-
-} splay_node_t;
-
-typedef int (*splay_compare_t)(const void *, const void *);
-typedef void (*splay_action_t)(const void *);
-typedef void (*splay_action_node_t)(const splay_node_t *);
-
-typedef struct splay_tree_t {
-
-       /* Linked list part */
-
-       splay_node_t *head;
-       splay_node_t *tail;
-
-       /* Tree part */
-
-       splay_node_t *root;
-
-       splay_compare_t compare;
-       splay_action_t delete;
-
-} splay_tree_t;
-
-/* (De)constructors */
-
-extern splay_tree_t *splay_alloc_tree(splay_compare_t, splay_action_t);
-extern void splay_free_tree(splay_tree_t *);
-
-extern splay_node_t *splay_alloc_node(void);
-extern void splay_free_node(splay_tree_t *tree, splay_node_t *);
-
-/* Insertion and deletion */
-
-extern splay_node_t *splay_insert(splay_tree_t *, void *);
-extern splay_node_t *splay_insert_node(splay_tree_t *, splay_node_t *);
-
-extern void splay_insert_top(splay_tree_t *, splay_node_t *);
-extern void splay_insert_before(splay_tree_t *, splay_node_t *, splay_node_t *);
-extern void splay_insert_after(splay_tree_t *, splay_node_t *, splay_node_t *);
-
-extern splay_node_t *splay_unlink(splay_tree_t *, void *);
-extern void splay_unlink_node(splay_tree_t *tree, splay_node_t *);
-extern void splay_delete(splay_tree_t *, void *);
-extern void splay_delete_node(splay_tree_t *, splay_node_t *);
-
-/* Fast tree cleanup */
-
-extern void splay_delete_tree(splay_tree_t *);
-
-/* Searching */
-
-extern void *splay_search(splay_tree_t *, const void *);
-extern void *splay_search_closest(splay_tree_t *, const void *, int *);
-extern void *splay_search_closest_smaller(splay_tree_t *, const void *);
-extern void *splay_search_closest_greater(splay_tree_t *, const void *);
-
-extern splay_node_t *splay_search_node(splay_tree_t *, const void *);
-extern splay_node_t *splay_search_closest_node(splay_tree_t *, const void *, int *);
-extern splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *, const void *, int *);
-extern splay_node_t *splay_search_closest_smaller_node(splay_tree_t *, const void *);
-extern splay_node_t *splay_search_closest_greater_node(splay_tree_t *, const void *);
-
-/* Tree walking */
-
-extern void splay_foreach(const splay_tree_t *, splay_action_t);
-extern void splay_foreach_node(const splay_tree_t *, splay_action_t);
-
-#endif
diff --git a/lib/utils.c b/lib/utils.c
deleted file mode 100644 (file)
index dd7e4de..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-    utils.c -- gathering of some stupid small functions
-    Copyright (C) 1999-2005 Ivo Timmermans
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include "../src/logger.h"
-#include "utils.h"
-
-const char hexadecimals[] = "0123456789ABCDEF";
-
-int charhex2bin(char c) {
-       if(isdigit(c))
-               return c - '0';
-       else
-               return toupper(c) - 'A' + 10;
-}
-
-
-void hex2bin(char *src, char *dst, int length) {
-       int i;
-       for(i = 0; i < length; i++)
-               dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]);
-}
-
-void bin2hex(char *src, char *dst, int length) {
-       int i;
-       for(i = length - 1; i >= 0; i--) {
-               dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15];
-               dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4];
-       }
-}
-
-#if defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
-#ifdef HAVE_CYGWIN
-#include <w32api/windows.h>
-#endif
-
-const char *winerror(int err) {
-       static char buf[1024], *newline;
-
-       if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
-               NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof(buf), NULL)) {
-               strncpy(buf, "(unable to format errormessage)", sizeof(buf));
-       };
-
-       if((newline = strchr(buf, '\r')))
-               *newline = '\0';
-
-       return buf;
-}
-#endif
-
-unsigned int bitfield_to_int(void *bitfield, size_t size) {
-       unsigned int value = 0;
-       if(size > sizeof value)
-               size = sizeof value;
-       memcpy(&value, bitfield, size);
-       return value;
-}
diff --git a/lib/utils.h b/lib/utils.h
deleted file mode 100644 (file)
index fddb8a6..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-    utils.h -- header file for utils.c
-    Copyright (C) 1999-2005 Ivo Timmermans
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_UTILS_H__
-#define __TINC_UTILS_H__
-
-extern void hex2bin(char *src, char *dst, int length);
-extern void bin2hex(char *src, char *dst, int length);
-
-#ifdef HAVE_MINGW
-extern const char *winerror(int);
-#define strerror(x) ((x)>0?strerror(x):winerror(GetLastError()))
-#define sockerrno WSAGetLastError()
-#define sockstrerror(x) winerror(x)
-#define sockwouldblock(x) ((x) == WSAEWOULDBLOCK || (x) == WSAEINTR)
-#define sockmsgsize(x) ((x) == WSAEMSGSIZE)
-#define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK)
-#define sockinuse(x) ((x) == WSAEADDRINUSE)
-#else
-#define sockerrno errno
-#define sockstrerror(x) strerror(x)
-#define sockwouldblock(x) ((x) == EWOULDBLOCK || (x) == EINTR)
-#define sockmsgsize(x) ((x) == EMSGSIZE)
-#define sockinprogress(x) ((x) == EINPROGRESS)
-#define sockinuse(x) ((x) == EADDRINUSE)
-#endif
-
-extern unsigned int bitfield_to_int(void *bitfield, size_t size);
-
-#endif                                                 /* __TINC_UTILS_H__ */
diff --git a/lib/xalloc.h b/lib/xalloc.h
deleted file mode 100644 (file)
index 51f99bd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <sys/types.h>
-
-#ifndef PARAMS
-# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
-#  define PARAMS(Args) Args
-# else
-#  define PARAMS(Args) ()
-# endif
-#endif
-
-/* Exit value when the requested amount of memory is not available.
-   The caller may set it to some other value.  */
-extern int xalloc_exit_failure;
-
-/* FIXME: describe */
-extern char *const xalloc_msg_memory_exhausted;
-
-/* FIXME: describe */
-extern void (*xalloc_fail_func) ();
-
-void *xmalloc PARAMS ((size_t n)) __attribute__ ((__malloc__));
-void *xmalloc_and_zero PARAMS ((size_t n)) __attribute__ ((__malloc__));
-void *xcalloc PARAMS ((size_t n, size_t s));
-void *xrealloc PARAMS ((void *p, size_t n)) __attribute__ ((__malloc__));
-
-char *xstrdup PARAMS ((const char *s)) __attribute__ ((__malloc__));
-
-extern int xasprintf(char **strp, const char *fmt, ...);
-extern int xvasprintf(char **strp, const char *fmt, va_list ap);
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
deleted file mode 100644 (file)
index 4e79aff..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/* xmalloc.c -- malloc with out of memory checking
-   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97 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, Inc., Foundation,
-   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <errno.h>
-
-#if STDC_HEADERS
-# include <stdlib.h>
-#else
-void *calloc ();
-void *malloc ();
-void *realloc ();
-void free ();
-#endif
-
-#include "dropin.h"
-#include "xalloc.h"
-
-#ifndef EXIT_FAILURE
-# define EXIT_FAILURE 1
-#endif
-
-/* Prototypes for functions defined here.  */
-#if defined (__STDC__) && __STDC__
-void *xmalloc (size_t n);
-void *xcalloc (size_t n, size_t s);
-void *xrealloc (void *p, size_t n);
-#endif
-
-/* Exit value when the requested amount of memory is not available.
-   The caller may set it to some other value.  */
-int xalloc_exit_failure = EXIT_FAILURE;
-
-/* FIXME: describe */
-char *const xalloc_msg_memory_exhausted = "Memory exhausted";
-
-/* FIXME: describe */
-void (*xalloc_fail_func) (int) = 0;
-
-static void
-xalloc_fail (int size)
-{
-  if (xalloc_fail_func)
-    (*xalloc_fail_func) (size);
-  fprintf(stderr, "%s\n", xalloc_msg_memory_exhausted);
-  exit(xalloc_exit_failure);
-}
-
-/* Allocate N bytes of memory dynamically, with error checking.  */
-
-void *
-xmalloc (n)
-     size_t n;
-{
-  void *p;
-
-  p = malloc (n);
-  if (p == 0)
-    xalloc_fail ((int)n);
-  return p;
-}
-
-/* Allocate N bytes of memory dynamically, and set it all to zero. */
-
-void *
-xmalloc_and_zero (n)
-     size_t n;
-{
-  void *p;
-
-  p = malloc (n);
-  if (p == 0)
-    xalloc_fail ((int)n);
-  memset (p, '\0', n);
-  return p;
-}
-
-/* Change the size of an allocated block of memory P to N bytes,
-   with error checking.
-   If P is NULL, run xmalloc.  */
-
-void *
-xrealloc (p, n)
-     void *p;
-     size_t n;
-{
-  p = realloc (p, n);
-  if (p == 0)
-    xalloc_fail (n);
-  return p;
-}
-
-/* Duplicate a string */
-
-char *xstrdup(const char *s)
-{
-  char *p;
-  
-  p = strdup(s);
-  if(!p)
-    xalloc_fail ((int)strlen(s));
-  return p;
-}
-
-#ifdef NOT_USED
-
-/* Allocate memory for N elements of S bytes, with error checking.  */
-
-void *
-xcalloc (n, s)
-     size_t n, s;
-{
-  void *p;
-
-  p = calloc (n, s);
-  if (p == 0)
-    xalloc_fail ();
-  return p;
-}
-
-#endif /* NOT_USED */
-
-int xasprintf(char **strp, const char *fmt, ...) {
-       int result;
-       va_list ap;
-       va_start(ap, fmt);
-       result = xvasprintf(strp, fmt, ap);
-       va_end(ap);
-       return result;
-}
-
-int xvasprintf(char **strp, const char *fmt, va_list ap) {
-       int result = vasprintf(strp, fmt, ap);
-       if(result < 0) {
-               fprintf(stderr, "vasprintf() failed: %s\n", strerror(errno));
-               exit(xalloc_exit_failure);
-       }
-       return result;
-}
index 7be9f5c577226d79de0468e6ef1f9cbd63e53969..20e438f1387f26a081137ee95d23c451fdc64606 100644 (file)
@@ -4,11 +4,15 @@ sbin_PROGRAMS = tincd tincctl
 
 EXTRA_DIST = linux bsd solaris cygwin mingw raw_socket uml_socket openssl gcrypt
 
-tincd_SOURCES = cipher.c conf.c connection.c control.c crypto.c digest.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \
-       net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c       \
+tincd_SOURCES = \
+       xmalloc.c utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c \
+       cipher.c conf.c connection.c control.c crypto.c digest.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \
+       net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \
        protocol_key.c protocol_subnet.c route.c rsa.c subnet.c tincd.c
 
-tincctl_SOURCES = tincctl.c rsagen.c
+tincctl_SOURCES = \
+       xmalloc.c utils.c getopt.c getopt1.c \
+       tincctl.c rsagen.c
 
 if TUNEMU
 tincd_SOURCES += bsd/tunemu.c
@@ -18,9 +22,11 @@ nodist_tincd_SOURCES = device.c
 
 DEFAULT_INCLUDES =
 
-INCLUDES = @INCLUDES@ -I$(top_builddir) -I$(top_srcdir)/lib
+INCLUDES = @INCLUDES@ -I$(top_builddir)
 
-noinst_HEADERS = cipher.h conf.h connection.h control.h control_common.h crypto.h device.h digest.h edge.h graph.h logger.h meta.h net.h netutl.h node.h process.h     \
+noinst_HEADERS = \
+       xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \
+       cipher.h conf.h connection.h control.h control_common.h crypto.h device.h digest.h edge.h graph.h logger.h meta.h net.h netutl.h node.h process.h \
        protocol.h route.h rsa.h rsagen.h subnet.h bsd/tunemu.h
 
 LIBS = @LIBS@ @LIBGCRYPT_LIBS@
@@ -29,12 +35,6 @@ if TUNEMU
 LIBS += -lpcap
 endif
 
-tincd_LDADD = \
-       $(top_builddir)/lib/libvpn.a
-
-tincctl_LDADD = \
-       $(top_builddir)/lib/libvpn.a
-
 AM_CFLAGS = @CFLAGS@ -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\"
 
 dist-hook:
diff --git a/src/alloca.c b/src/alloca.c
new file mode 100644 (file)
index 0000000..10e5d65
--- /dev/null
@@ -0,0 +1,494 @@
+/* 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
+
+#ifdef emacs
+# include "blockinput.h"
+#endif
+
+/* If compiling with GCC 2, this file's not needed.  */
+#if !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+   there must be some other way alloca is supposed to work.  */
+# 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.  */
+
+#  if defined (CRAY) && defined (CRAY_STACKSEG_END)
+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
+
+#  ifndef NULL
+#   define NULL 0
+#  endif
+
+/* Different portions of Emacs need to call different versions of
+   malloc.  The Emacs executable needs alloca to call xmalloc, because
+   ordinary malloc isn't protected from input signals.  On the other
+   hand, the utilities in lib-src need alloca to call malloc; some of
+   them are very simple, and don't have an xmalloc routine.
+
+   Non-Emacs programs expect this to call xmalloc.
+
+   Callers below should use malloc.  */
+
+#  ifndef emacs
+#   define malloc xmalloc
+#  endif
+extern pointer malloc ();
+
+/* 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.  */
+
+#  ifdef emacs
+    BLOCK_INPUT;
+#  endif
+
+    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.  */
+
+#  ifdef emacs
+    UNBLOCK_INPUT;
+#  endif
+  }
+
+  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));
+  }
+}
+
+#  if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#   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 */
+#endif /* not GCC version 2 */
diff --git a/src/dropin.c b/src/dropin.c
new file mode 100644 (file)
index 0000000..89039da
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+    dropin.c -- a set of drop-in replacements for libc functions
+    Copyright (C) 2000-2005 Ivo Timmermans,
+                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "system.h"
+
+#include "xalloc.h"
+
+#ifndef HAVE_DAEMON
+/*
+  Replacement for the daemon() function.
+  
+  The daemon() function is for programs wishing to detach themselves
+  from the controlling terminal and run in the background as system
+  daemons.
+
+  Unless the argument nochdir is non-zero, daemon() changes the
+  current working directory to the root (``/'').
+
+  Unless the argument noclose is non-zero, daemon() will redirect
+  standard input, standard output and standard error to /dev/null.
+*/
+int daemon(int nochdir, int noclose) {
+#ifdef HAVE_FORK
+       pid_t pid;
+       int fd;
+
+       pid = fork();
+
+       /* Check if forking failed */
+       if(pid < 0) {
+               perror("fork");
+               exit(-1);
+       }
+
+       /* If we are the parent, terminate */
+       if(pid)
+               exit(0);
+
+       /* Detach by becoming the new process group leader */
+       if(setsid() < 0) {
+               perror("setsid");
+               return -1;
+       }
+
+       /* Change working directory to the root (to avoid keeping mount
+          points busy) */
+       if(!nochdir) {
+               chdir("/");
+       }
+
+       /* Redirect stdin/out/err to /dev/null */
+       if(!noclose) {
+               fd = open("/dev/null", O_RDWR);
+
+               if(fd < 0) {
+                       perror("opening /dev/null");
+                       return -1;
+               } else {
+                       dup2(fd, 0);
+                       dup2(fd, 1);
+                       dup2(fd, 2);
+               }
+       }
+
+       return 0;
+#else
+       return -1;
+#endif
+}
+#endif
+
+#ifndef HAVE_GET_CURRENT_DIR_NAME
+/*
+  Replacement for the GNU get_current_dir_name function:
+
+  get_current_dir_name will malloc(3) an array big enough to hold the
+  current directory name.  If the environment variable PWD is set, and
+  its value is correct, then that value will be returned.
+*/
+char *get_current_dir_name(void) {
+       size_t size;
+       char *buf;
+       char *r;
+
+       /* Start with 100 bytes.  If this turns out to be insufficient to
+          contain the working directory, double the size.  */
+       size = 100;
+       buf = xmalloc(size);
+
+       errno = 0;                                      /* Success */
+       r = getcwd(buf, size);
+
+       /* getcwd returns NULL and sets errno to ERANGE if the bufferspace
+          is insufficient to contain the entire working directory.  */
+       while(r == NULL && errno == ERANGE) {
+               free(buf);
+               size <<= 1;                             /* double the size */
+               buf = xmalloc(size);
+               r = getcwd(buf, size);
+       }
+
+       return buf;
+}
+#endif
+
+#ifndef HAVE_ASPRINTF
+int asprintf(char **buf, const char *fmt, ...) {
+       int result;
+       va_list ap;
+       va_start(ap, fmt);
+       result = vasprintf(buf, fmt, ap);
+       va_end(ap);
+       return result;
+}
+
+int vasprintf(char **buf, const char *fmt, va_list ap) {
+       int status;
+       va_list aq;
+       int len;
+
+       len = 4096;
+       *buf = xmalloc(len);
+
+       va_copy(aq, ap);
+       status = vsnprintf(*buf, len, fmt, aq);
+       va_end(aq);
+
+       if(status >= 0)
+               *buf = xrealloc(*buf, status + 1);
+
+       if(status > len - 1) {
+               len = status;
+               va_copy(aq, ap);
+               status = vsnprintf(*buf, len, fmt, aq);
+               va_end(aq);
+       }
+
+       return status;
+}
+#endif
+
+#ifndef HAVE_GETTIMEOFDAY
+int gettimeofday(struct timeval *tv, void *tz) {
+       tv->tv_sec = time(NULL);
+       tv->tv_usec = 0;
+       return 0;
+}
+#endif
diff --git a/src/dropin.h b/src/dropin.h
new file mode 100644 (file)
index 0000000..e9d1353
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+    dropin.h -- header file for dropin.c
+    Copyright (C) 2000-2005 Ivo Timmermans,
+                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __DROPIN_H__
+#define __DROPIN_H__
+
+#include "fake-getaddrinfo.h"
+#include "fake-getnameinfo.h"
+
+#ifndef HAVE_DAEMON
+extern int daemon(int, int);
+#endif
+
+#ifndef HAVE_GET_CURRENT_DIR_NAME
+extern char *get_current_dir_name(void);
+#endif
+
+#ifndef HAVE_ASPRINTF
+extern int asprintf(char **, const char *, ...);
+extern int vasprintf(char **, const char *, va_list ap);
+#endif
+
+#ifndef HAVE_GETTIMEOFDAY
+extern int gettimeofday(struct timeval *, void *);
+#endif
+
+#endif                                                 /* __DROPIN_H__ */
diff --git a/src/ethernet.h b/src/ethernet.h
new file mode 100644 (file)
index 0000000..eef5f42
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+    ethernet.h -- missing Ethernet related definitions
+    Copyright (C) 2005 Ivo Timmermans
+                  2006 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __TINC_ETHERNET_H__
+#define __TINC_ETHERNET_H__
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#ifndef ARPHRD_ETHER
+#define ARPHRD_ETHER 1
+#endif
+
+#ifndef ETH_P_IP
+#define ETH_P_IP 0x0800
+#endif
+
+#ifndef ETH_P_ARP
+#define ETH_P_ARP 0x0806
+#endif
+
+#ifndef ETH_P_IPV6
+#define ETH_P_IPV6 0x86DD
+#endif
+
+#ifndef HAVE_STRUCT_ETHER_HEADER
+struct ether_header {
+       uint8_t ether_dhost[ETH_ALEN];
+       uint8_t ether_shost[ETH_ALEN];
+       uint16_t ether_type;
+} __attribute__ ((__packed__));
+#endif
+
+#ifndef HAVE_STRUCT_ARPHDR
+struct arphdr {
+       uint16_t ar_hrd;
+       uint16_t ar_pro;
+       uint8_t ar_hln;
+       uint8_t ar_pln; 
+       uint16_t ar_op; 
+} __attribute__ ((__packed__));
+
+#define ARPOP_REQUEST 1 
+#define ARPOP_REPLY 2 
+#define ARPOP_RREQUEST 3 
+#define ARPOP_RREPLY 4 
+#define ARPOP_InREQUEST 8 
+#define ARPOP_InREPLY 9 
+#define ARPOP_NAK 10 
+#endif
+
+#ifndef HAVE_STRUCT_ETHER_ARP
+struct  ether_arp {
+       struct  arphdr ea_hdr;
+       uint8_t arp_sha[ETH_ALEN];
+       uint8_t arp_spa[4];
+       uint8_t arp_tha[ETH_ALEN];
+       uint8_t arp_tpa[4];
+} __attribute__ ((__packed__));
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+#endif
+
+#endif /* __TINC_ETHERNET_H__ */
diff --git a/src/fake-gai-errnos.h b/src/fake-gai-errnos.h
new file mode 100644 (file)
index 0000000..4ffabb6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * fake library for ssh
+ *
+ * This file is included in getaddrinfo.c and getnameinfo.c.
+ * See getaddrinfo.c and getnameinfo.c.
+ */
+
+/* for old netdb.h */
+#ifndef EAI_NODATA
+#define EAI_NODATA     1
+#endif
+
+#ifndef EAI_MEMORY
+#define EAI_MEMORY     2
+#endif
+
+#ifndef EAI_FAMILY
+#define EAI_FAMILY     3
+#endif
diff --git a/src/fake-getaddrinfo.c b/src/fake-getaddrinfo.c
new file mode 100644 (file)
index 0000000..df3d347
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * fake library for ssh
+ *
+ * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
+ * These funtions are defined in rfc2133.
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For exapmle, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ */
+
+#include "system.h"
+
+#include "ipv4.h"
+#include "ipv6.h"
+#include "fake-getaddrinfo.h"
+#include "xalloc.h"
+
+
+#if !HAVE_DECL_GAI_STRERROR
+char *gai_strerror(int ecode) {
+       switch (ecode) {
+               case EAI_NODATA:
+                       return "No address associated with hostname";
+               case EAI_MEMORY:
+                       return "Memory allocation failure";
+               case EAI_FAMILY:
+                       return "Address family not supported";
+               default:
+                       return "Unknown error";
+       }
+}    
+#endif /* !HAVE_GAI_STRERROR */
+
+#if !HAVE_DECL_FREEADDRINFO
+void freeaddrinfo(struct addrinfo *ai) {
+       struct addrinfo *next;
+
+       while(ai) {
+               next = ai->ai_next;
+               free(ai);
+               ai = next;
+       }
+}
+#endif /* !HAVE_FREEADDRINFO */
+
+#if !HAVE_DECL_GETADDRINFO
+static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr) {
+       struct addrinfo *ai;
+
+       ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
+       
+       ai->ai_addr = (struct sockaddr *)(ai + 1);
+       ai->ai_addrlen = sizeof(struct sockaddr_in);
+       ai->ai_addr->sa_family = ai->ai_family = AF_INET;
+
+       ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
+       ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
+       
+       return ai;
+}
+
+int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) {
+       struct addrinfo *prev = NULL;
+       struct hostent *hp;
+       struct in_addr in = {0};
+       int i;
+       uint16_t port = 0;
+
+       if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)
+               return EAI_FAMILY;
+
+       if (servname)
+               port = htons(atoi(servname));
+
+       if (hints && hints->ai_flags & AI_PASSIVE) {
+               *res = malloc_ai(port, htonl(0x00000000));
+               return 0;
+       }
+               
+       if (!hostname) {
+               *res = malloc_ai(port, htonl(0x7f000001));
+               return 0;
+       }
+       
+       hp = gethostbyname(hostname);
+
+       if(!hp || !hp->h_addr_list || !hp->h_addr_list[0])
+               return EAI_NODATA;
+
+       for (i = 0; hp->h_addr_list[i]; i++) {
+               *res = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
+
+               if(prev)
+                       prev->ai_next = *res;
+
+               prev = *res;
+       }
+
+       return 0;
+}
+#endif /* !HAVE_GETADDRINFO */
diff --git a/src/fake-getaddrinfo.h b/src/fake-getaddrinfo.h
new file mode 100644 (file)
index 0000000..5af7491
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _FAKE_GETADDRINFO_H
+#define _FAKE_GETADDRINFO_H
+
+#include "fake-gai-errnos.h"
+
+#ifndef AI_PASSIVE
+# define AI_PASSIVE        1
+# define AI_CANONNAME      2
+#endif
+
+#ifndef NI_NUMERICHOST
+# define NI_NUMERICHOST    2
+# define NI_NAMEREQD       4
+# define NI_NUMERICSERV    8
+#endif
+
+#ifndef AI_NUMERICHOST
+#define AI_NUMERICHOST 4
+#endif
+
+#ifndef HAVE_STRUCT_ADDRINFO
+struct addrinfo {
+       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
+       int     ai_family;      /* PF_xxx */
+       int     ai_socktype;    /* SOCK_xxx */
+       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+       size_t  ai_addrlen;     /* length of ai_addr */
+       char    *ai_canonname;  /* canonical name for hostname */
+       struct sockaddr *ai_addr;       /* binary address */
+       struct addrinfo *ai_next;       /* next structure in linked list */
+};
+#endif /* !HAVE_STRUCT_ADDRINFO */
+
+#if !HAVE_DECL_GETADDRINFO
+int getaddrinfo(const char *hostname, const char *servname, 
+                const struct addrinfo *hints, struct addrinfo **res);
+#endif /* !HAVE_GETADDRINFO */
+
+#if !HAVE_DECL_GAI_STRERROR
+char *gai_strerror(int ecode);
+#endif /* !HAVE_GAI_STRERROR */
+
+#if !HAVE_DECL_FREEADDRINFO
+void freeaddrinfo(struct addrinfo *ai);
+#endif /* !HAVE_FREEADDRINFO */
+
+#endif /* _FAKE_GETADDRINFO_H */
diff --git a/src/fake-getnameinfo.c b/src/fake-getnameinfo.c
new file mode 100644 (file)
index 0000000..1eba492
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * fake library for ssh
+ *
+ * This file includes getnameinfo().
+ * These funtions are defined in rfc2133.
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For exapmle, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ */
+
+#include "system.h"
+
+#include "fake-getnameinfo.h"
+#include "fake-getaddrinfo.h"
+
+#if !HAVE_DECL_GETNAMEINFO
+
+int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) {
+       struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+       struct hostent *hp;
+       int len;
+
+       if(sa->sa_family != AF_INET)
+               return EAI_FAMILY;
+
+       if(serv && servlen) {
+               len = snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
+               if(len < 0 || len >= servlen)
+                       return EAI_MEMORY;
+       }
+
+       if(!host || !hostlen)
+               return 0;
+
+       if(flags & NI_NUMERICHOST) {
+               len = snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr));
+               if(len < 0 || len >= hostlen)
+                       return EAI_MEMORY;
+               return 0;
+       }
+
+       hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET);
+       
+       if(!hp || !hp->h_name || !hp->h_name[0])
+               return EAI_NODATA;
+       
+       len = snprintf(host, hostlen, "%s", hp->h_name);
+       if(len < 0 || len >= hostlen)
+               return EAI_MEMORY;
+
+       return 0;
+}
+#endif /* !HAVE_GETNAMEINFO */
diff --git a/src/fake-getnameinfo.h b/src/fake-getnameinfo.h
new file mode 100644 (file)
index 0000000..4389a8f
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _FAKE_GETNAMEINFO_H
+#define _FAKE_GETNAMEINFO_H
+
+#if !HAVE_DECL_GETNAMEINFO
+int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 
+                size_t hostlen, char *serv, size_t servlen, int flags);
+#endif /* !HAVE_GETNAMEINFO */
+
+#ifndef NI_MAXSERV
+# define NI_MAXSERV 32
+#endif /* !NI_MAXSERV */
+#ifndef NI_MAXHOST
+# define NI_MAXHOST 1025
+#endif /* !NI_MAXHOST */
+
+#endif /* _FAKE_GETNAMEINFO_H */
diff --git a/src/getopt.c b/src/getopt.c
new file mode 100644 (file)
index 0000000..b2f88b4
--- /dev/null
@@ -0,0 +1,1042 @@
+/* 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, 93, 94, 95, 96, 97
+       Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+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, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+\f
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#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.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#include <unistd.h>
+#endif /* GNU C library.  */
+
+#ifdef VMS
+#include <unixlib.h>
+#if HAVE_STRING_H - 0
+#include <string.h>
+#endif
+#endif
+
+#if defined (WIN32) && !defined (__CYGWIN32__)
+/* It's not Unix, really.  See?  Capital letters.  */
+#include <windows.h>
+#define getpid() GetCurrentProcessId()
+#endif
+
+/* 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 = NULL;
+
+/* 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 -1, 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.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+int __getopt_initialized = 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 -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+\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
+#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;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.  */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+   That was relevant to code that was here before.  */
+#if !defined (__STDC__) || !__STDC__
+/* gcc with -traditional declares the built-in strlen to return int,
+   and has done so at least since version 2.4.5. -- rms.  */
+extern int strlen (const char *);
+#endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_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;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+extern pid_t __libc_pid;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+   is valid for the getopt call we must make sure that the ARGV passed
+   to getopt is that one passed to the process.  */
+static void
+__attribute__ ((__unused__))
+store_args_and_env (int argc, char *const *argv)
+{
+  /* XXX This is no good solution.  We should rather copy the args so
+     that we can compare them later.  But we must not use malloc(3).  */
+  original_argc = argc;
+  original_argv = argv;
+}
+text_set_element (__libc_subinit, store_args_and_env);
+
+# define SWAP_FLAGS(ch1, ch2) \
+  if (nonoption_flags_len > 0)                                               \
+    {                                                                        \
+      char __tmp = __getopt_nonoption_flags[ch1];                            \
+      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
+      __getopt_nonoption_flags[ch2] = __tmp;                                 \
+    }
+#else  /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* 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.  */
+
+#if defined (__STDC__) && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+#ifdef _LIBC
+  /* First make sure the handling of the `__getopt_nonoption_flags'
+     string can work normally.  Our top argument must be in the range
+     of the string.  */
+  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+    {
+      /* We must extend the array.  The user plays games with us and
+        presents new arguments.  */
+      char *new_str = malloc (top + 1);
+      if (new_str == NULL)
+       nonoption_flags_len = nonoption_flags_max_len = 0;
+      else
+       {
+         memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
+         memset (&new_str[nonoption_flags_max_len], '\0',
+                 top + 1 - nonoption_flags_max_len);
+         nonoption_flags_max_len = top + 1;
+         __getopt_nonoption_flags = new_str;
+       }
+    }
+#endif
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+       {
+         /* Bottom segment is the short one.  */
+         int len = middle - bottom;
+         register int i;
+
+         /* Swap it with the top part of the top segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[top - (middle - bottom) + i];
+             argv[top - (middle - bottom) + i] = tem;
+             SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+           }
+         /* Exclude the moved bottom segment from further swapping.  */
+         top -= len;
+       }
+      else
+       {
+         /* Top segment is the short one.  */
+         int len = top - middle;
+         register int i;
+
+         /* Swap it with the bottom part of the bottom segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[middle + i];
+             argv[middle + i] = tem;
+             SWAP_FLAGS (bottom + i, middle + i);
+           }
+         /* Exclude the moved top segment from further swapping.  */
+         bottom += len;
+       }
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+#if defined (__STDC__) && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  /* 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.  */
+
+  first_nonopt = last_nonopt = optind;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* 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 (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#ifdef _LIBC
+  if (posixly_correct == NULL
+      && argc == original_argc && argv == original_argv)
+    {
+      if (nonoption_flags_max_len == 0)
+       {
+         if (__getopt_nonoption_flags == NULL
+             || __getopt_nonoption_flags[0] == '\0')
+           nonoption_flags_max_len = -1;
+         else
+           {
+             const char *orig_str = __getopt_nonoption_flags;
+             int len = nonoption_flags_max_len = strlen (orig_str);
+             if (nonoption_flags_max_len < argc)
+               nonoption_flags_max_len = argc;
+             __getopt_nonoption_flags =
+               (char *) malloc (nonoption_flags_max_len);
+             if (__getopt_nonoption_flags == NULL)
+               nonoption_flags_max_len = -1;
+             else
+               {
+                 memcpy (__getopt_nonoption_flags, orig_str, len);
+                 memset (&__getopt_nonoption_flags[len], '\0',
+                         nonoption_flags_max_len - len);
+               }
+           }
+       }
+      nonoption_flags_len = nonoption_flags_max_len;
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+\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 -1.
+   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;
+{
+  optarg = NULL;
+
+  if (optind == 0 || !__getopt_initialized)
+    {
+      if (optind == 0)
+       optind = 1;     /* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring);
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#ifdef _LIBC
+#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
+                    || (optind < nonoption_flags_len                         \
+                        && __getopt_nonoption_flags[optind] == '1'))
+#else
+#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+        moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > optind)
+       last_nonopt = optind;
+      if (first_nonopt > optind)
+       first_nonopt = optind;
+
+      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;
+
+         /* Skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc && NONOPTION_P)
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* The 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 -1;
+       }
+
+      /* 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 (NONOPTION_P)
+       {
+         if (ordering == REQUIRE_ORDER)
+           return -1;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Skip the initial punctuation.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[optind][1] == '-'
+         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+       /* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+        or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+       if (!strncmp (p->name, nextchar, nameend - nextchar))
+         {
+           if ((unsigned int) (nameend - nextchar)
+               == (unsigned int) 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 or later 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++;
+         optopt = 0;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*nameend)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = nameend + 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);
+
+                 optopt = pfound->val;
+                 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);
+                 optopt = pfound->val;
+                 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] == '-'
+         || 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++;
+         optopt = 0;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next short 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 (posixly_correct)
+             /* 1003.2 specifies the format of this message.  */
+             fprintf (stderr, "%s: illegal option -- %c\n",
+                      argv[0], c);
+           else
+             fprintf (stderr, "%s: invalid option -- %c\n",
+                      argv[0], c);
+         }
+       optopt = c;
+       return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+       char *nameend;
+       const struct option *p;
+       const struct option *pfound = NULL;
+       int exact = 0;
+       int ambig = 0;
+       int indfound = 0;
+       int option_index;
+
+       /* 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)
+             {
+               /* 1003.2 specifies the format of this message.  */
+               fprintf (stderr, "%s: option requires an argument -- %c\n",
+                        argv[0], c);
+             }
+           optopt = c;
+           if (optstring[0] == ':')
+             c = ':';
+           else
+             c = '?';
+           return c;
+         }
+       else
+         /* We already incremented `optind' once;
+            increment it again when taking next ARGV-elt as argument.  */
+         optarg = argv[optind++];
+
+       /* optarg is now the argument, see if it's in the
+          table of longopts.  */
+
+       for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+         /* Do nothing.  */ ;
+
+       /* Test all long options for either exact match
+          or abbreviated matches.  */
+       for (p = longopts, option_index = 0; p->name; p++, option_index++)
+         if (!strncmp (p->name, nextchar, nameend - nextchar))
+           {
+             if ((unsigned int) (nameend - 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 or later nonexact match found.  */
+               ambig = 1;
+           }
+       if (ambig && !exact)
+         {
+           if (opterr)
+             fprintf (stderr, "%s: option `-W %s' is ambiguous\n",
+                      argv[0], argv[optind]);
+           nextchar += strlen (nextchar);
+           optind++;
+           return '?';
+         }
+       if (pfound != NULL)
+         {
+           option_index = indfound;
+           if (*nameend)
+             {
+               /* Don't test has_arg with >, because some C compilers don't
+                  allow it to be used on enums.  */
+               if (pfound->has_arg)
+                 optarg = nameend + 1;
+               else
+                 {
+                   if (opterr)
+                     fprintf (stderr,
+                              "%s: option `-W %s' doesn't allow an argument\n",
+                              argv[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;
+         }
+         nextchar = NULL;
+         return 'W';   /* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = NULL;
+           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)
+                 {
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr,
+                          "%s: option requires an argument -- %c\n",
+                          argv[0], c);
+                 }
+               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 /* Not ELIDE_CODE.  */
+\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 == -1)
+       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/src/getopt.h b/src/getopt.h
new file mode 100644 (file)
index 0000000..ddf6fdd
--- /dev/null
@@ -0,0 +1,133 @@
+/* Declarations for getopt.
+   Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+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, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 -1, 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 defined (__STDC__) && __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 defined (__STDC__) && __STDC__
+#ifdef __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 /* __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 /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/src/getopt1.c b/src/getopt1.c
new file mode 100644 (file)
index 0000000..86545f2
--- /dev/null
@@ -0,0 +1,189 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+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, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+\f
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#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.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#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 /* Not ELIDE_CODE.  */
+\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 == -1)
+       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/src/ipv4.h b/src/ipv4.h
new file mode 100644 (file)
index 0000000..80ab17c
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+    ipv4.h -- missing IPv4 related definitions
+    Copyright (C) 2005 Ivo Timmermans
+                  2006 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __TINC_IPV4_H__
+#define __TINC_IPV4_H__
+
+#ifndef AF_INET
+#define AF_INET 2
+#endif
+
+#ifndef IPPROTO_ICMP
+#define IPPROTO_ICMP 1
+#endif
+
+#ifndef ICMP_DEST_UNREACH
+#define ICMP_DEST_UNREACH 3
+#endif
+
+#ifndef ICMP_FRAG_NEEDED
+#define ICMP_FRAG_NEEDED 4
+#endif
+
+#ifndef ICMP_NET_UNKNOWN
+#define ICMP_NET_UNKNOWN 6
+#endif
+
+#ifndef ICMP_NET_UNREACH
+#define ICMP_NET_UNREACH 0
+#endif
+
+#ifndef IP_MSS
+#define       IP_MSS          576
+#endif
+
+#ifndef HAVE_STRUCT_IP
+struct ip {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+       unsigned int ip_hl:4;
+       unsigned int ip_v:4;
+#else
+       unsigned int ip_v:4;
+       unsigned int ip_hl:4;
+#endif
+       uint8_t ip_tos;
+       uint16_t ip_len;
+       uint16_t ip_id; 
+       uint16_t ip_off;
+#define IP_RF 0x8000
+#define IP_DF 0x4000
+#define IP_MF 0x2000
+       uint8_t ip_ttl;
+       uint8_t ip_p;
+       uint16_t ip_sum;
+       struct in_addr ip_src, ip_dst;
+} __attribute__ ((__packed__));
+#endif
+
+#ifndef IP_OFFMASK
+#define IP_OFFMASK 0x1fff
+#endif
+
+#ifndef HAVE_STRUCT_ICMP
+struct icmp {
+       uint8_t icmp_type;
+       uint8_t icmp_code;
+       uint16_t icmp_cksum;
+       union {
+               uint8_t ih_pptr;
+               struct in_addr ih_gwaddr;
+               struct ih_idseq {
+                       uint16_t icd_id;
+                       uint16_t icd_seq;
+               } ih_idseq;
+               uint32_t ih_void;
+
+
+               struct ih_pmtu {
+                       uint16_t ipm_void;
+                       uint16_t ipm_nextmtu;
+               } ih_pmtu;
+
+               struct ih_rtradv {
+                       uint8_t irt_num_addrs;
+                       uint8_t irt_wpa;
+                       uint16_t irt_lifetime;
+               } ih_rtradv;
+       } icmp_hun;
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
+#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
+#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
+#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
+       union {
+               struct {
+                       uint32_t its_otime;
+                       uint32_t its_rtime;
+                       uint32_t its_ttime;
+               } id_ts;
+               struct {
+                       struct ip idi_ip;
+               } id_ip;
+               uint32_t id_mask;
+               uint8_t id_data[1];
+       } icmp_dun;
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_radv icmp_dun.id_radv
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+} __attribute__ ((__packed__));
+#endif
+
+#endif /* __TINC_IPV4_H__ */
diff --git a/src/ipv6.h b/src/ipv6.h
new file mode 100644 (file)
index 0000000..fee74f5
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+    ipv6.h -- missing IPv6 related definitions
+    Copyright (C) 2005 Ivo Timmermans
+                  2006 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __TINC_IPV6_H__
+#define __TINC_IPV6_H__
+
+#ifndef AF_INET6
+#define AF_INET6 10
+#endif
+
+#ifndef IPPROTO_ICMPV6
+#define IPPROTO_ICMPV6 58
+#endif
+
+#ifndef HAVE_STRUCT_IN6_ADDR
+struct in6_addr {
+       union {
+               uint8_t u6_addr8[16];
+               uint16_t u6_addr16[8];
+               uint32_t u6_addr32[4];
+       } in6_u;
+} __attribute__ ((__packed__));
+#define s6_addr in6_u.u6_addr8
+#define s6_addr16 in6_u.u6_addr16
+#define s6_addr32 in6_u.u6_addr32
+#endif
+
+#ifndef HAVE_STRUCT_SOCKADDR_IN6
+struct sockaddr_in6 {
+       uint16_t sin6_family;
+       uint16_t sin6_port;
+       uint32_t sin6_flowinfo;
+       struct in6_addr sin6_addr;
+       uint32_t sin6_scope_id;
+} __attribute__ ((__packed__));
+#endif
+
+#ifndef IN6_IS_ADDR_V4MAPPED
+#define IN6_IS_ADDR_V4MAPPED(a) \
+        ((((__const uint32_t *) (a))[0] == 0) \
+        && (((__const uint32_t *) (a))[1] == 0) \
+        && (((__const uint32_t *) (a))[2] == htonl (0xffff)))
+#endif
+
+#ifndef HAVE_STRUCT_IP6_HDR
+struct ip6_hdr {
+       union {
+               struct ip6_hdrctl {
+                       uint32_t ip6_un1_flow;
+                       uint16_t ip6_un1_plen;
+                       uint8_t ip6_un1_nxt;
+                       uint8_t ip6_un1_hlim;
+               } ip6_un1;
+               uint8_t ip6_un2_vfc;
+       } ip6_ctlun;
+       struct in6_addr ip6_src;
+       struct in6_addr ip6_dst;
+} __attribute__ ((__packed__));
+#define ip6_vfc ip6_ctlun.ip6_un2_vfc
+#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+#endif
+
+#ifndef HAVE_STRUCT_ICMP6_HDR
+struct icmp6_hdr {
+       uint8_t icmp6_type;
+       uint8_t icmp6_code;
+       uint16_t icmp6_cksum;
+       union {
+               uint32_t icmp6_un_data32[1];
+               uint16_t icmp6_un_data16[2];
+               uint8_t icmp6_un_data8[4];
+       } icmp6_dataun;
+} __attribute__ ((__packed__));
+#define ICMP6_DST_UNREACH_NOROUTE 0
+#define ICMP6_DST_UNREACH 1
+#define ICMP6_PACKET_TOO_BIG 2
+#define ICMP6_DST_UNREACH_ADDR 3
+#define ND_NEIGHBOR_SOLICIT 135
+#define ND_NEIGHBOR_ADVERT 136
+#define icmp6_data32 icmp6_dataun.icmp6_un_data32
+#define icmp6_data16 icmp6_dataun.icmp6_un_data16
+#define icmp6_data8 icmp6_dataun.icmp6_un_data8
+#define icmp6_mtu icmp6_data32[0]
+#endif
+
+#ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
+struct nd_neighbor_solicit {
+       struct icmp6_hdr nd_ns_hdr;
+       struct in6_addr nd_ns_target;
+} __attribute__ ((__packed__));
+#define ND_OPT_SOURCE_LINKADDR 1
+#define ND_OPT_TARGET_LINKADDR 2
+#define nd_ns_type nd_ns_hdr.icmp6_type
+#define nd_ns_code nd_ns_hdr.icmp6_code
+#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
+#endif
+
+#ifndef HAVE_STRUCT_ND_OPT_HDR
+struct nd_opt_hdr {
+       uint8_t nd_opt_type;
+       uint8_t nd_opt_len;
+} __attribute__ ((__packed__));
+#endif
+
+#endif /* __TINC_IPV6_H__ */
diff --git a/src/list.c b/src/list.c
new file mode 100644 (file)
index 0000000..a26c58d
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+    list.c -- functions to deal with double linked lists
+    Copyright (C) 2000-2005 Ivo Timmermans
+                  2000-2006 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "system.h"
+
+#include "list.h"
+#include "xalloc.h"
+
+/* (De)constructors */
+
+list_t *list_alloc(list_action_t delete) {
+       list_t *list;
+
+       list = xmalloc_and_zero(sizeof(list_t));
+       list->delete = delete;
+
+       return list;
+}
+
+void list_free(list_t *list) {
+       free(list);
+}
+
+list_node_t *list_alloc_node(void) {
+       return xmalloc_and_zero(sizeof(list_node_t));
+}
+
+void list_free_node(list_t *list, list_node_t *node) {
+       if(node->data && list->delete)
+               list->delete(node->data);
+
+       free(node);
+}
+
+/* Insertion and deletion */
+
+list_node_t *list_insert_head(list_t *list, void *data) {
+       list_node_t *node;
+
+       node = list_alloc_node();
+
+       node->data = data;
+       node->prev = NULL;
+       node->next = list->head;
+       list->head = node;
+
+       if(node->next)
+               node->next->prev = node;
+       else
+               list->tail = node;
+
+       list->count++;
+
+       return node;
+}
+
+list_node_t *list_insert_tail(list_t *list, void *data) {
+       list_node_t *node;
+
+       node = list_alloc_node();
+
+       node->data = data;
+       node->next = NULL;
+       node->prev = list->tail;
+       list->tail = node;
+
+       if(node->prev)
+               node->prev->next = node;
+       else
+               list->head = node;
+
+       list->count++;
+
+       return node;
+}
+
+void list_unlink_node(list_t *list, list_node_t *node) {
+       if(node->prev)
+               node->prev->next = node->next;
+       else
+               list->head = node->next;
+
+       if(node->next)
+               node->next->prev = node->prev;
+       else
+               list->tail = node->prev;
+
+       list->count--;
+}
+
+void list_delete_node(list_t *list, list_node_t *node) {
+       list_unlink_node(list, node);
+       list_free_node(list, node);
+}
+
+void list_delete_head(list_t *list) {
+       list_delete_node(list, list->head);
+}
+
+void list_delete_tail(list_t *list) {
+       list_delete_node(list, list->tail);
+}
+
+/* Head/tail lookup */
+
+void *list_get_head(list_t *list) {
+       if(list->head)
+               return list->head->data;
+       else
+               return NULL;
+}
+
+void *list_get_tail(list_t *list) {
+       if(list->tail)
+               return list->tail->data;
+       else
+               return NULL;
+}
+
+/* Fast list deletion */
+
+void list_delete_list(list_t *list) {
+       list_node_t *node, *next;
+
+       for(node = list->head; node; node = next) {
+               next = node->next;
+               list_free_node(list, node);
+       }
+
+       list_free(list);
+}
+
+/* Traversing */
+
+void list_foreach_node(list_t *list, list_action_node_t action) {
+       list_node_t *node, *next;
+
+       for(node = list->head; node; node = next) {
+               next = node->next;
+               action(node);
+       }
+}
+
+void list_foreach(list_t *list, list_action_t action) {
+       list_node_t *node, *next;
+
+       for(node = list->head; node; node = next) {
+               next = node->next;
+               if(node->data)
+                       action(node->data);
+       }
+}
diff --git a/src/list.h b/src/list.h
new file mode 100644 (file)
index 0000000..197fbb8
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+    list.h -- header file for list.c
+    Copyright (C) 2000-2005 Ivo Timmermans
+                  2000-2006 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __TINC_LIST_H__
+#define __TINC_LIST_H__
+
+typedef struct list_node_t {
+       struct list_node_t *prev;
+       struct list_node_t *next;
+
+       /* Payload */
+
+       void *data;
+} list_node_t;
+
+typedef void (*list_action_t)(const void *);
+typedef void (*list_action_node_t)(const list_node_t *);
+
+typedef struct list_t {
+       list_node_t *head;
+       list_node_t *tail;
+       int count;
+
+       /* Callbacks */
+
+       list_action_t delete;
+} list_t;
+
+/* (De)constructors */
+
+extern list_t *list_alloc(list_action_t) __attribute__ ((__malloc__));
+extern void list_free(list_t *);
+extern list_node_t *list_alloc_node(void);
+extern void list_free_node(list_t *, list_node_t *);
+
+/* Insertion and deletion */
+
+extern list_node_t *list_insert_head(list_t *, void *);
+extern list_node_t *list_insert_tail(list_t *, void *);
+
+extern void list_unlink_node(list_t *, list_node_t *);
+extern void list_delete_node(list_t *, list_node_t *);
+
+extern void list_delete_head(list_t *);
+extern void list_delete_tail(list_t *);
+
+/* Head/tail lookup */
+
+extern void *list_get_head(list_t *);
+extern void *list_get_tail(list_t *);
+
+/* Fast list deletion */
+
+extern void list_delete_list(list_t *);
+
+/* Traversing */
+
+extern void list_foreach(list_t *, list_action_t);
+extern void list_foreach_node(list_t *, list_action_node_t);
+
+#endif                                                 /* __TINC_LIST_H__ */
diff --git a/src/malloc.c b/src/malloc.c
new file mode 100644 (file)
index 0000000..2a996d4
--- /dev/null
@@ -0,0 +1,39 @@
+/* Work around bug on some systems where malloc (0) fails.
+   Copyright (C) 1997 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, Inc., Foundation,
+   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+/* written by Jim Meyering */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#undef malloc
+
+#include <sys/types.h>
+
+char *malloc ();
+
+/* Allocate an N-byte block of memory from the heap.
+   If N is zero, allocate a 1-byte block.  */
+
+char *
+rpl_malloc (n)
+     size_t n;
+{
+  if (n == 0)
+    n = 1;
+  return malloc (n);
+}
diff --git a/src/memcmp.c b/src/memcmp.c
new file mode 100644 (file)
index 0000000..9d80833
--- /dev/null
@@ -0,0 +1,391 @@
+/* Copyright (C) 1991, 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   NOTE: The canonical source of this file is maintained with the GNU C Library.
+   Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+   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, Inc.,
+   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#undef __ptr_t
+#if defined __cplusplus || (defined __STDC__ && __STDC__)
+# define __ptr_t       void *
+#else /* Not C++ or ANSI C.  */
+# undef        const
+# define const
+# define __ptr_t       char *
+#endif /* C++ or ANSI C.  */
+
+#ifndef __P
+# if defined __GNUC__ || (defined __STDC__ && __STDC__)
+#  define __P(args) args
+# else
+#  define __P(args) ()
+# endif  /* GCC.  */
+#endif  /* Not __P.  */
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#endif
+
+#undef memcmp
+
+#ifdef _LIBC
+
+# include <memcopy.h>
+
+#else  /* Not in the GNU C library.  */
+
+# include <sys/types.h>
+
+/* Type to use for aligned memory operations.
+   This should normally be the biggest type supported by a single load
+   and store.  Must be an unsigned type.  */
+# define op_t  unsigned long int
+# define OPSIZ (sizeof(op_t))
+
+/* Threshold value for when to enter the unrolled loops.  */
+# define OP_T_THRES    16
+
+/* Type to use for unaligned operations.  */
+typedef unsigned char byte;
+
+# ifndef WORDS_BIGENDIAN
+#  define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
+# else
+#  define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
+# endif
+
+#endif /* In the GNU C library.  */
+
+#ifdef WORDS_BIGENDIAN
+# define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
+#else
+# define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b))
+#endif
+
+/* BE VERY CAREFUL IF YOU CHANGE THIS CODE!  */
+
+/* The strategy of this memcmp is:
+
+   1. Compare bytes until one of the block pointers is aligned.
+
+   2. Compare using memcmp_common_alignment or
+      memcmp_not_common_alignment, regarding the alignment of the other
+      block after the initial byte operations.  The maximum number of
+      full words (of type op_t) are compared in this way.
+
+   3. Compare the few remaining bytes.  */
+
+#ifndef WORDS_BIGENDIAN
+/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine.
+   A and B are known to be different.
+   This is needed only on little-endian machines.  */
+
+static int memcmp_bytes __P((op_t, op_t));
+
+# ifdef  __GNUC__
+__inline
+# endif
+static int
+memcmp_bytes (a, b)
+     op_t a, b;
+{
+  long int srcp1 = (long int) &a;
+  long int srcp2 = (long int) &b;
+  op_t a0, b0;
+
+  do
+    {
+      a0 = ((byte *) srcp1)[0];
+      b0 = ((byte *) srcp2)[0];
+      srcp1 += 1;
+      srcp2 += 1;
+    }
+  while (a0 == b0);
+  return a0 - b0;
+}
+#endif
+
+static int memcmp_common_alignment __P((long, long, size_t));
+
+/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
+   objects (not LEN bytes!).  Both SRCP1 and SRCP2 should be aligned for
+   memory operations on `op_t's.  */
+#ifdef __GNUC__
+__inline
+#endif
+static int
+memcmp_common_alignment (srcp1, srcp2, len)
+     long int srcp1;
+     long int srcp2;
+     size_t len;
+{
+  op_t a0, a1;
+  op_t b0, b1;
+
+  switch (len % 4)
+    {
+    default: /* Avoid warning about uninitialized local variables.  */
+    case 2:
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      srcp1 -= 2 * OPSIZ;
+      srcp2 -= 2 * OPSIZ;
+      len += 2;
+      goto do1;
+    case 3:
+      a1 = ((op_t *) srcp1)[0];
+      b1 = ((op_t *) srcp2)[0];
+      srcp1 -= OPSIZ;
+      srcp2 -= OPSIZ;
+      len += 1;
+      goto do2;
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+       return 0;
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      goto do3;
+    case 1:
+      a1 = ((op_t *) srcp1)[0];
+      b1 = ((op_t *) srcp2)[0];
+      srcp1 += OPSIZ;
+      srcp2 += OPSIZ;
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+       goto do0;
+      /* Fall through.  */
+    }
+
+  do
+    {
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      if (a1 != b1)
+       return CMP_LT_OR_GT (a1, b1);
+
+    do3:
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[1];
+      if (a0 != b0)
+       return CMP_LT_OR_GT (a0, b0);
+
+    do2:
+      a0 = ((op_t *) srcp1)[2];
+      b0 = ((op_t *) srcp2)[2];
+      if (a1 != b1)
+       return CMP_LT_OR_GT (a1, b1);
+
+    do1:
+      a1 = ((op_t *) srcp1)[3];
+      b1 = ((op_t *) srcp2)[3];
+      if (a0 != b0)
+       return CMP_LT_OR_GT (a0, b0);
+
+      srcp1 += 4 * OPSIZ;
+      srcp2 += 4 * OPSIZ;
+      len -= 4;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  if (a1 != b1)
+    return CMP_LT_OR_GT (a1, b1);
+  return 0;
+}
+
+static int memcmp_not_common_alignment __P((long, long, size_t));
+
+/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
+   `op_t' objects (not LEN bytes!).  SRCP2 should be aligned for memory
+   operations on `op_t', but SRCP1 *should be unaligned*.  */
+#ifdef __GNUC__
+__inline
+#endif
+static int
+memcmp_not_common_alignment (srcp1, srcp2, len)
+     long int srcp1;
+     long int srcp2;
+     size_t len;
+{
+  op_t a0, a1, a2, a3;
+  op_t b0, b1, b2, b3;
+  op_t x;
+  int shl, shr;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp1 to make it aligned for comparison.  */
+
+  shl = 8 * (srcp1 % OPSIZ);
+  shr = 8 * OPSIZ - shl;
+
+  /* Make SRCP1 aligned by rounding it down to the beginning of the `op_t'
+     it points in the middle of.  */
+  srcp1 &= -OPSIZ;
+
+  switch (len % 4)
+    {
+    default: /* Avoid warning about uninitialized local variables.  */
+    case 2:
+      a1 = ((op_t *) srcp1)[0];
+      a2 = ((op_t *) srcp1)[1];
+      b2 = ((op_t *) srcp2)[0];
+      srcp1 -= 1 * OPSIZ;
+      srcp2 -= 2 * OPSIZ;
+      len += 2;
+      goto do1;
+    case 3:
+      a0 = ((op_t *) srcp1)[0];
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[0];
+      srcp2 -= 1 * OPSIZ;
+      len += 1;
+      goto do2;
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+       return 0;
+      a3 = ((op_t *) srcp1)[0];
+      a0 = ((op_t *) srcp1)[1];
+      b0 = ((op_t *) srcp2)[0];
+      srcp1 += 1 * OPSIZ;
+      goto do3;
+    case 1:
+      a2 = ((op_t *) srcp1)[0];
+      a3 = ((op_t *) srcp1)[1];
+      b3 = ((op_t *) srcp2)[0];
+      srcp1 += 2 * OPSIZ;
+      srcp2 += 1 * OPSIZ;
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+       goto do0;
+      /* Fall through.  */
+    }
+
+  do
+    {
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      x = MERGE(a2, shl, a3, shr);
+      if (x != b3)
+       return CMP_LT_OR_GT (x, b3);
+
+    do3:
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[1];
+      x = MERGE(a3, shl, a0, shr);
+      if (x != b0)
+       return CMP_LT_OR_GT (x, b0);
+
+    do2:
+      a2 = ((op_t *) srcp1)[2];
+      b2 = ((op_t *) srcp2)[2];
+      x = MERGE(a0, shl, a1, shr);
+      if (x != b1)
+       return CMP_LT_OR_GT (x, b1);
+
+    do1:
+      a3 = ((op_t *) srcp1)[3];
+      b3 = ((op_t *) srcp2)[3];
+      x = MERGE(a1, shl, a2, shr);
+      if (x != b2)
+       return CMP_LT_OR_GT (x, b2);
+
+      srcp1 += 4 * OPSIZ;
+      srcp2 += 4 * OPSIZ;
+      len -= 4;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  x = MERGE(a2, shl, a3, shr);
+  if (x != b3)
+    return CMP_LT_OR_GT (x, b3);
+  return 0;
+}
+
+int
+rpl_memcmp (s1, s2, len)
+     const __ptr_t s1;
+     const __ptr_t s2;
+     size_t len;
+{
+  op_t a0;
+  op_t b0;
+  long int srcp1 = (long int) s1;
+  long int srcp2 = (long int) s2;
+  op_t res;
+
+  if (len >= OP_T_THRES)
+    {
+      /* There are at least some bytes to compare.  No need to test
+        for LEN == 0 in this alignment loop.  */
+      while (srcp2 % OPSIZ != 0)
+       {
+         a0 = ((byte *) srcp1)[0];
+         b0 = ((byte *) srcp2)[0];
+         srcp1 += 1;
+         srcp2 += 1;
+         res = a0 - b0;
+         if (res != 0)
+           return res;
+         len -= 1;
+       }
+
+      /* SRCP2 is now aligned for memory operations on `op_t'.
+        SRCP1 alignment determines if we can do a simple,
+        aligned compare or need to shuffle bits.  */
+
+      if (srcp1 % OPSIZ == 0)
+       res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
+      else
+       res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
+      if (res != 0)
+       return res;
+
+      /* Number of bytes remaining in the interval [0..OPSIZ-1].  */
+      srcp1 += len & -OPSIZ;
+      srcp2 += len & -OPSIZ;
+      len %= OPSIZ;
+    }
+
+  /* There are just a few bytes to compare.  Use byte memory operations.  */
+  while (len != 0)
+    {
+      a0 = ((byte *) srcp1)[0];
+      b0 = ((byte *) srcp2)[0];
+      srcp1 += 1;
+      srcp2 += 1;
+      res = a0 - b0;
+      if (res != 0)
+       return res;
+      len -= 1;
+    }
+
+  return 0;
+}
+
+#ifdef weak_alias
+# undef bcmp
+weak_alias (memcmp, bcmp)
+#endif
diff --git a/src/realloc.c b/src/realloc.c
new file mode 100644 (file)
index 0000000..4971b28
--- /dev/null
@@ -0,0 +1,44 @@
+/* Work around bug on some systems where realloc (NULL, 0) fails.
+   Copyright (C) 1997 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, Inc., Foundation,
+   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+/* written by Jim Meyering */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#undef realloc
+
+#include <sys/types.h>
+
+char *malloc ();
+char *realloc ();
+
+/* Change the size of an allocated block of memory P to N bytes,
+   with error checking.  If N is zero, change it to 1.  If P is NULL,
+   use malloc.  */
+
+char *
+rpl_realloc (p, n)
+     char *p;
+     size_t n;
+{
+  if (n == 0)
+    n = 1;
+  if (p == 0)
+    return malloc (n);
+  return realloc (p, n);
+}
diff --git a/src/splay_tree.c b/src/splay_tree.c
new file mode 100644 (file)
index 0000000..3a792e8
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+    splay_tree.c -- splay tree and linked list convenience
+    Copyright (C) 2004-2006 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "system.h"
+
+#include "splay_tree.h"
+#include "xalloc.h"
+
+/* Splay operation */
+
+static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *result) {
+       splay_node_t left = {0}, right = {0};
+       splay_node_t *leftbottom = &left, *rightbottom = &right, *child, *grandchild;
+       splay_node_t *root = tree->root;
+       int c;
+
+       if(!root) {
+               if(result)
+                       *result = 0;
+               return NULL;
+       }
+
+       while((c = tree->compare(data, root->data))) {
+               if(c < 0 && (child = root->left)) {
+                       c = tree->compare(data, child->data);
+
+                       if(c < 0 && (grandchild = child->left)) {
+                               rightbottom->left = child;
+                               child->parent = rightbottom;
+                               rightbottom = child;
+                               
+                               if((root->left = child->right))
+                                       child->right->parent = root;
+                               
+                               child->right = root;
+                               root->parent = child;
+
+                               child->left = NULL;
+                               grandchild->parent = NULL;
+
+                               root = grandchild;
+                       } else if (c > 0 && (grandchild = child->right)) {
+                               leftbottom->right = child;
+                               child->parent = leftbottom;
+                               leftbottom = child;
+
+                               child->right = NULL;
+                               grandchild->parent = NULL;
+
+                               rightbottom->left = root;
+                               root->parent = rightbottom;
+                               rightbottom = root;
+
+                               root->left = NULL;
+
+                               root = grandchild;
+                       } else {
+                               rightbottom->left = root;
+                               root->parent = rightbottom;
+                               rightbottom = root;
+                               
+                               root->left = NULL;
+                               child->parent = NULL;
+
+                               root = child;
+                               break;
+                       }
+               } else if(c > 0 && (child = root->right)) {
+                       c = tree->compare(data, child->data);
+
+                       if(c > 0 && (grandchild = child->right)) {
+                               leftbottom->right = child;
+                               child->parent = leftbottom;
+                               leftbottom = child;
+                               
+                               if((root->right = child->left))
+                                       child->left->parent = root;
+                               
+                               child->left = root;
+                               root->parent = child;
+
+                               child->right = NULL;
+                               grandchild->parent = NULL;
+
+                               root = grandchild;
+                       } else if (c < 0 && (grandchild = child->left)) {
+                               rightbottom->left = child;
+                               child->parent = rightbottom;
+                               rightbottom = child;
+
+                               child->left = NULL;
+                               grandchild->parent = NULL;
+
+                               leftbottom->right = root;
+                               root->parent = leftbottom;
+                               leftbottom = root;
+
+                               root->right = NULL;
+
+                               root = grandchild;
+                       } else {
+                               leftbottom->right = root;
+                               root->parent = leftbottom;
+                               leftbottom = root;
+
+                               root->right = NULL;
+                               child->parent = NULL;
+
+                               root = child;
+                               break;
+                       }
+               } else {
+                       break;
+               }
+       }
+
+       /* Merge trees */
+
+       if(left.right) {
+               if(root->left) {
+                       leftbottom->right = root->left;
+                       root->left->parent = leftbottom;
+               }
+               root->left = left.right;
+               left.right->parent = root;
+       }
+
+       if(right.left) {
+               if(root->right) {
+                       rightbottom->left = root->right;
+                       root->right->parent = rightbottom;
+               }
+               root->right = right.left;
+               right.left->parent = root;
+       }
+
+       /* Return result */
+
+       tree->root = root;
+       if(result)
+               *result = c;
+
+       return tree->root;
+}
+                       
+static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) {
+       splay_node_t *parent, *grandparent, *greatgrandparent;
+
+       while((parent = node->parent)) {
+               if(!(grandparent = parent->parent)) { /* zig */
+                       if(node == parent->left) {
+                               if((parent->left = node->right))                                
+                                       parent->left->parent = parent;
+                               node->right = parent;
+                       } else {
+                               if((parent->right = node->left))
+                                       parent->right->parent = parent;
+                               node->left = parent;
+                       }
+
+                       parent->parent = node;
+                       node->parent = NULL;
+               } else {
+                       greatgrandparent = grandparent->parent;
+
+                       if(node == parent->left && parent == grandparent->left) { /* left zig-zig */
+                               if((grandparent->left = parent->right))
+                                       grandparent->left->parent = grandparent;
+                               parent->right = grandparent;
+                               grandparent->parent = parent;
+
+                               if((parent->left = node->right))
+                                       parent->left->parent = parent;
+                               node->right = parent;
+                               parent->parent = node;
+                       } else if(node == parent->right && parent == grandparent->right) { /* right zig-zig */
+                               if((grandparent->right = parent->left))
+                                       grandparent->right->parent = grandparent;
+                               parent->left = grandparent;
+                               grandparent->parent = parent;
+
+                               if((parent->right = node->left))
+                                       parent->right->parent = parent;
+                               node->left = parent;
+                               parent->parent = node;
+                       } else if(node == parent->right && parent == grandparent->left) { /* left-right zig-zag */
+                               if((parent->right = node->left))
+                                       parent->right->parent = parent;
+                               node->left = parent;
+                               parent->parent = node;
+
+                               if((grandparent->left = node->right))
+                                       grandparent->left->parent = grandparent;
+                               node->right = grandparent;
+                               grandparent->parent = node;
+                       } else { /* right-left zig-zag */
+                               if((parent->left = node->right))
+                                       parent->left->parent = parent;
+                               node->right = parent;
+                               parent->parent = node;
+
+                               if((grandparent->right = node->left))
+                                       grandparent->right->parent = grandparent;
+                               node->left = grandparent;
+                               grandparent->parent = node;
+                       }
+
+                       if((node->parent = greatgrandparent)) {
+                               if(grandparent == greatgrandparent->left)
+                                       greatgrandparent->left = node;
+                               else
+                                       greatgrandparent->right = node;
+                       }
+               }
+       }
+
+       tree->root = node;
+}
+
+/* (De)constructors */
+
+splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) {
+       splay_tree_t *tree;
+
+       tree = xmalloc_and_zero(sizeof(splay_tree_t));
+       tree->compare = compare;
+       tree->delete = delete;
+
+       return tree;
+}
+
+void splay_free_tree(splay_tree_t *tree) {
+       free(tree);
+}
+
+splay_node_t *splay_alloc_node(void) {
+       return xmalloc_and_zero(sizeof(splay_node_t));
+}
+
+void splay_free_node(splay_tree_t *tree, splay_node_t *node) {
+       if(node->data && tree->delete)
+               tree->delete(node->data);
+
+       free(node);
+}
+
+/* Searching */
+
+void *splay_search(splay_tree_t *tree, const void *data) {
+       splay_node_t *node;
+
+       node = splay_search_node(tree, data);
+
+       return node ? node->data : NULL;
+}
+
+void *splay_search_closest(splay_tree_t *tree, const void *data, int *result) {
+       splay_node_t *node;
+
+       node = splay_search_closest_node(tree, data, result);
+
+       return node ? node->data : NULL;
+}
+
+void *splay_search_closest_smaller(splay_tree_t *tree, const void *data) {
+       splay_node_t *node;
+
+       node = splay_search_closest_smaller_node(tree, data);
+
+       return node ? node->data : NULL;
+}
+
+void *splay_search_closest_greater(splay_tree_t *tree, const void *data) {
+       splay_node_t *node;
+
+       node = splay_search_closest_greater_node(tree, data);
+
+       return node ? node->data : NULL;
+}
+
+splay_node_t *splay_search_node(splay_tree_t *tree, const void *data) {
+       splay_node_t *node;
+       int result;
+
+       node = splay_search_closest_node(tree, data, &result);
+
+       return result ? NULL : node;
+}
+
+splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const void *data, int *result) {
+       splay_node_t *node;
+       int c;
+
+       node = tree->root;
+
+       if(!node) {
+               if(result)
+                       *result = 0;
+               return NULL;
+       }
+
+       for(;;) {
+               c = tree->compare(data, node->data);
+
+               if(c < 0) {
+                       if(node->left)
+                               node = node->left;
+                       else
+                               break;
+               } else if(c > 0) {
+                       if(node->right)
+                               node = node->right;
+                       else 
+                               break;
+               } else {
+                       break;
+               }
+       }
+
+       if(result)
+               *result = c;
+       return node;
+}
+
+splay_node_t *splay_search_closest_node(splay_tree_t *tree, const void *data, int *result) {
+       return splay_top_down(tree, data, result);
+}
+
+splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void *data) {
+       splay_node_t *node;
+       int result;
+
+       node = splay_search_closest_node(tree, data, &result);
+
+       if(result < 0)
+               node = node->prev;
+
+       return node;
+}
+
+splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void *data) {
+       splay_node_t *node;
+       int result;
+
+       node = splay_search_closest_node(tree, data, &result);
+
+       if(result > 0)
+               node = node->next;
+
+       return node;
+}
+
+/* Insertion and deletion */
+
+splay_node_t *splay_insert(splay_tree_t *tree, void *data) {
+       splay_node_t *closest, *new;
+       int result;
+
+       if(!tree->root) {
+               new = splay_alloc_node();
+               new->data = data;
+               splay_insert_top(tree, new);
+       } else {
+               closest = splay_search_closest_node(tree, data, &result);
+
+               if(!result)
+                       return NULL;
+
+               new = splay_alloc_node();
+               new->data = data;
+               
+               if(result < 0)
+                       splay_insert_before(tree, closest, new);
+               else
+                       splay_insert_after(tree, closest, new);
+       }                       
+
+       return new;
+}
+
+splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) {
+       splay_node_t *closest;
+       int result;
+
+       if(!tree->root)
+               splay_insert_top(tree, node);
+       else {
+               closest = splay_search_closest_node(tree, node->data, &result);
+               
+               if(!result)
+                       return NULL;
+
+               if(result < 0)
+                       splay_insert_before(tree, closest, node);
+               else
+                       splay_insert_after(tree, closest, node);
+       }
+
+       return node;
+}
+
+void splay_insert_top(splay_tree_t *tree, splay_node_t *node) {
+       node->prev = node->next = node->left = node->right = node->parent = NULL;
+       tree->head = tree->tail = tree->root = node;
+}
+
+void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) {
+       if(!before) {
+               if(tree->tail)
+                       splay_insert_after(tree, tree->tail, node);
+               else
+                       splay_insert_top(tree, node);
+               return;
+       }
+
+       node->next = before;
+       if((node->prev = before->prev))
+               before->prev->next = node;
+       else
+               tree->head = node;
+       before->prev = node;
+
+       splay_bottom_up(tree, before);
+
+       node->right = before;
+       before->parent = node;
+       if((node->left = before->left))
+               before->left->parent = node;
+       before->left = NULL;
+
+       node->parent = NULL;
+       tree->root = node;
+}
+
+void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) {
+       if(!after) {
+               if(tree->head)
+                       splay_insert_before(tree, tree->head, node);
+               else
+                       splay_insert_top(tree, node);
+               return;
+       }
+
+       node->prev = after;
+       if((node->next = after->next))
+               after->next->prev = node;
+       else
+               tree->tail = node;
+       after->next = node;
+
+       splay_bottom_up(tree, after);
+
+       node->left = after;
+       after->parent = node;
+       if((node->right = after->right))
+               after->right->parent = node;
+       after->right = NULL;
+
+       node->parent = NULL;
+       tree->root = node;
+}
+
+splay_node_t *splay_unlink(splay_tree_t *tree, void *data) {
+       splay_node_t *node;
+
+       node = splay_search_node(tree, data);
+
+       if(node)
+               splay_unlink_node(tree, node);
+
+       return node;
+}
+
+void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) {
+       if(node->prev)
+               node->prev->next = node->next;
+       else
+               tree->head = node->next;
+
+       if(node->next)
+               node->next->prev = node->prev;
+       else
+               tree->tail = node->prev;
+
+       splay_bottom_up(tree, node);
+
+       if(node->prev) {
+               node->left->parent = NULL;
+               tree->root = node->left;
+               if((node->prev->right = node->right))
+                       node->right->parent = node->prev;
+       } else if(node->next) {
+               tree->root = node->right;
+               node->right->parent = NULL;
+       } else {
+               tree->root = NULL;
+       }
+}
+
+void splay_delete_node(splay_tree_t *tree, splay_node_t *node) {
+       splay_unlink_node(tree, node);
+       splay_free_node(tree, node);
+}
+
+void splay_delete(splay_tree_t *tree, void *data) {
+       splay_node_t *node;
+
+       node = splay_search_node(tree, data);
+
+       if(node)
+               splay_delete_node(tree, node);
+}
+
+/* Fast tree cleanup */
+
+void splay_delete_tree(splay_tree_t *tree) {
+       splay_node_t *node, *next;
+
+       for(node = tree->head; node; node = next) {
+               next = node->next;
+               splay_free_node(tree, node);
+       }
+
+       splay_free_tree(tree);
+}
+
+/* Tree walking */
+
+void splay_foreach(const splay_tree_t *tree, splay_action_t action) {
+       splay_node_t *node, *next;
+
+       for(node = tree->head; node; node = next) {
+               next = node->next;
+               action(node->data);
+       }
+}
+
+void splay_foreach_node(const splay_tree_t *tree, splay_action_t action) {
+       splay_node_t *node, *next;
+
+       for(node = tree->head; node; node = next) {
+               next = node->next;
+               action(node);
+       }
+}
diff --git a/src/splay_tree.h b/src/splay_tree.h
new file mode 100644 (file)
index 0000000..e4af0c4
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+    splay_tree.h -- header file for splay_tree.c
+    Copyright (C) 2004-2006 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+
+#ifndef __SPLAY_TREE_H__
+#define __SPLAY_TREE_H__
+
+typedef struct splay_node_t {
+
+       /* Linked list part */
+
+       struct splay_node_t *next;
+       struct splay_node_t *prev;
+
+       /* Tree part */
+
+       struct splay_node_t *parent;
+       struct splay_node_t *left;
+       struct splay_node_t *right;
+
+       /* Payload */
+
+       void *data;
+
+} splay_node_t;
+
+typedef int (*splay_compare_t)(const void *, const void *);
+typedef void (*splay_action_t)(const void *);
+typedef void (*splay_action_node_t)(const splay_node_t *);
+
+typedef struct splay_tree_t {
+
+       /* Linked list part */
+
+       splay_node_t *head;
+       splay_node_t *tail;
+
+       /* Tree part */
+
+       splay_node_t *root;
+
+       splay_compare_t compare;
+       splay_action_t delete;
+
+} splay_tree_t;
+
+/* (De)constructors */
+
+extern splay_tree_t *splay_alloc_tree(splay_compare_t, splay_action_t);
+extern void splay_free_tree(splay_tree_t *);
+
+extern splay_node_t *splay_alloc_node(void);
+extern void splay_free_node(splay_tree_t *tree, splay_node_t *);
+
+/* Insertion and deletion */
+
+extern splay_node_t *splay_insert(splay_tree_t *, void *);
+extern splay_node_t *splay_insert_node(splay_tree_t *, splay_node_t *);
+
+extern void splay_insert_top(splay_tree_t *, splay_node_t *);
+extern void splay_insert_before(splay_tree_t *, splay_node_t *, splay_node_t *);
+extern void splay_insert_after(splay_tree_t *, splay_node_t *, splay_node_t *);
+
+extern splay_node_t *splay_unlink(splay_tree_t *, void *);
+extern void splay_unlink_node(splay_tree_t *tree, splay_node_t *);
+extern void splay_delete(splay_tree_t *, void *);
+extern void splay_delete_node(splay_tree_t *, splay_node_t *);
+
+/* Fast tree cleanup */
+
+extern void splay_delete_tree(splay_tree_t *);
+
+/* Searching */
+
+extern void *splay_search(splay_tree_t *, const void *);
+extern void *splay_search_closest(splay_tree_t *, const void *, int *);
+extern void *splay_search_closest_smaller(splay_tree_t *, const void *);
+extern void *splay_search_closest_greater(splay_tree_t *, const void *);
+
+extern splay_node_t *splay_search_node(splay_tree_t *, const void *);
+extern splay_node_t *splay_search_closest_node(splay_tree_t *, const void *, int *);
+extern splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *, const void *, int *);
+extern splay_node_t *splay_search_closest_smaller_node(splay_tree_t *, const void *);
+extern splay_node_t *splay_search_closest_greater_node(splay_tree_t *, const void *);
+
+/* Tree walking */
+
+extern void splay_foreach(const splay_tree_t *, splay_action_t);
+extern void splay_foreach_node(const splay_tree_t *, splay_action_t);
+
+#endif
diff --git a/src/utils.c b/src/utils.c
new file mode 100644 (file)
index 0000000..dd7e4de
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+    utils.c -- gathering of some stupid small functions
+    Copyright (C) 1999-2005 Ivo Timmermans
+                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "system.h"
+
+#include "../src/logger.h"
+#include "utils.h"
+
+const char hexadecimals[] = "0123456789ABCDEF";
+
+int charhex2bin(char c) {
+       if(isdigit(c))
+               return c - '0';
+       else
+               return toupper(c) - 'A' + 10;
+}
+
+
+void hex2bin(char *src, char *dst, int length) {
+       int i;
+       for(i = 0; i < length; i++)
+               dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]);
+}
+
+void bin2hex(char *src, char *dst, int length) {
+       int i;
+       for(i = length - 1; i >= 0; i--) {
+               dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15];
+               dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4];
+       }
+}
+
+#if defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
+#ifdef HAVE_CYGWIN
+#include <w32api/windows.h>
+#endif
+
+const char *winerror(int err) {
+       static char buf[1024], *newline;
+
+       if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+               NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof(buf), NULL)) {
+               strncpy(buf, "(unable to format errormessage)", sizeof(buf));
+       };
+
+       if((newline = strchr(buf, '\r')))
+               *newline = '\0';
+
+       return buf;
+}
+#endif
+
+unsigned int bitfield_to_int(void *bitfield, size_t size) {
+       unsigned int value = 0;
+       if(size > sizeof value)
+               size = sizeof value;
+       memcpy(&value, bitfield, size);
+       return value;
+}
diff --git a/src/utils.h b/src/utils.h
new file mode 100644 (file)
index 0000000..fddb8a6
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    utils.h -- header file for utils.c
+    Copyright (C) 1999-2005 Ivo Timmermans
+                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __TINC_UTILS_H__
+#define __TINC_UTILS_H__
+
+extern void hex2bin(char *src, char *dst, int length);
+extern void bin2hex(char *src, char *dst, int length);
+
+#ifdef HAVE_MINGW
+extern const char *winerror(int);
+#define strerror(x) ((x)>0?strerror(x):winerror(GetLastError()))
+#define sockerrno WSAGetLastError()
+#define sockstrerror(x) winerror(x)
+#define sockwouldblock(x) ((x) == WSAEWOULDBLOCK || (x) == WSAEINTR)
+#define sockmsgsize(x) ((x) == WSAEMSGSIZE)
+#define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK)
+#define sockinuse(x) ((x) == WSAEADDRINUSE)
+#else
+#define sockerrno errno
+#define sockstrerror(x) strerror(x)
+#define sockwouldblock(x) ((x) == EWOULDBLOCK || (x) == EINTR)
+#define sockmsgsize(x) ((x) == EMSGSIZE)
+#define sockinprogress(x) ((x) == EINPROGRESS)
+#define sockinuse(x) ((x) == EADDRINUSE)
+#endif
+
+extern unsigned int bitfield_to_int(void *bitfield, size_t size);
+
+#endif                                                 /* __TINC_UTILS_H__ */
diff --git a/src/xalloc.h b/src/xalloc.h
new file mode 100644 (file)
index 0000000..51f99bd
--- /dev/null
@@ -0,0 +1,29 @@
+#include <sys/types.h>
+
+#ifndef PARAMS
+# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
+#  define PARAMS(Args) Args
+# else
+#  define PARAMS(Args) ()
+# endif
+#endif
+
+/* Exit value when the requested amount of memory is not available.
+   The caller may set it to some other value.  */
+extern int xalloc_exit_failure;
+
+/* FIXME: describe */
+extern char *const xalloc_msg_memory_exhausted;
+
+/* FIXME: describe */
+extern void (*xalloc_fail_func) ();
+
+void *xmalloc PARAMS ((size_t n)) __attribute__ ((__malloc__));
+void *xmalloc_and_zero PARAMS ((size_t n)) __attribute__ ((__malloc__));
+void *xcalloc PARAMS ((size_t n, size_t s));
+void *xrealloc PARAMS ((void *p, size_t n)) __attribute__ ((__malloc__));
+
+char *xstrdup PARAMS ((const char *s)) __attribute__ ((__malloc__));
+
+extern int xasprintf(char **strp, const char *fmt, ...);
+extern int xvasprintf(char **strp, const char *fmt, va_list ap);
diff --git a/src/xmalloc.c b/src/xmalloc.c
new file mode 100644 (file)
index 0000000..4e79aff
--- /dev/null
@@ -0,0 +1,160 @@
+/* xmalloc.c -- malloc with out of memory checking
+   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97 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, Inc., Foundation,
+   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#if STDC_HEADERS
+# include <stdlib.h>
+#else
+void *calloc ();
+void *malloc ();
+void *realloc ();
+void free ();
+#endif
+
+#include "dropin.h"
+#include "xalloc.h"
+
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+/* Prototypes for functions defined here.  */
+#if defined (__STDC__) && __STDC__
+void *xmalloc (size_t n);
+void *xcalloc (size_t n, size_t s);
+void *xrealloc (void *p, size_t n);
+#endif
+
+/* Exit value when the requested amount of memory is not available.
+   The caller may set it to some other value.  */
+int xalloc_exit_failure = EXIT_FAILURE;
+
+/* FIXME: describe */
+char *const xalloc_msg_memory_exhausted = "Memory exhausted";
+
+/* FIXME: describe */
+void (*xalloc_fail_func) (int) = 0;
+
+static void
+xalloc_fail (int size)
+{
+  if (xalloc_fail_func)
+    (*xalloc_fail_func) (size);
+  fprintf(stderr, "%s\n", xalloc_msg_memory_exhausted);
+  exit(xalloc_exit_failure);
+}
+
+/* Allocate N bytes of memory dynamically, with error checking.  */
+
+void *
+xmalloc (n)
+     size_t n;
+{
+  void *p;
+
+  p = malloc (n);
+  if (p == 0)
+    xalloc_fail ((int)n);
+  return p;
+}
+
+/* Allocate N bytes of memory dynamically, and set it all to zero. */
+
+void *
+xmalloc_and_zero (n)
+     size_t n;
+{
+  void *p;
+
+  p = malloc (n);
+  if (p == 0)
+    xalloc_fail ((int)n);
+  memset (p, '\0', n);
+  return p;
+}
+
+/* Change the size of an allocated block of memory P to N bytes,
+   with error checking.
+   If P is NULL, run xmalloc.  */
+
+void *
+xrealloc (p, n)
+     void *p;
+     size_t n;
+{
+  p = realloc (p, n);
+  if (p == 0)
+    xalloc_fail (n);
+  return p;
+}
+
+/* Duplicate a string */
+
+char *xstrdup(const char *s)
+{
+  char *p;
+  
+  p = strdup(s);
+  if(!p)
+    xalloc_fail ((int)strlen(s));
+  return p;
+}
+
+#ifdef NOT_USED
+
+/* Allocate memory for N elements of S bytes, with error checking.  */
+
+void *
+xcalloc (n, s)
+     size_t n, s;
+{
+  void *p;
+
+  p = calloc (n, s);
+  if (p == 0)
+    xalloc_fail ();
+  return p;
+}
+
+#endif /* NOT_USED */
+
+int xasprintf(char **strp, const char *fmt, ...) {
+       int result;
+       va_list ap;
+       va_start(ap, fmt);
+       result = xvasprintf(strp, fmt, ap);
+       va_end(ap);
+       return result;
+}
+
+int xvasprintf(char **strp, const char *fmt, va_list ap) {
+       int result = vasprintf(strp, fmt, ap);
+       if(result < 0) {
+               fprintf(stderr, "vasprintf() failed: %s\n", strerror(errno));
+               exit(xalloc_exit_failure);
+       }
+       return result;
+}
index dfb4c6d7c69ad49fd83765caecc4880c8a142ae0..5dc1dafcf006502ef3a5d926785803d056559be6 100644 (file)
--- a/system.h
+++ b/system.h
@@ -37,7 +37,7 @@ typedef int bool;
 
 /* Other functions */
 
-#include "dropin.h"
+#include "src/dropin.h"
 
 #ifndef HAVE_SOCKLEN_T
 typedef int socklen_t;