Initial commit of `icmpmonitor-1.2` from http://www.crocodile.org/software.html
authorAaron Taylor <ataylor@subgeniuskitty.com>
Tue, 17 Sep 2019 00:57:00 +0000 (17:57 -0700)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Tue, 17 Sep 2019 00:57:00 +0000 (17:57 -0700)
16 files changed:
ChangeLog [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
cfg.c [new file with mode: 0644]
cfg.h [new file with mode: 0644]
configure [new file with mode: 0755]
configure.in [new file with mode: 0644]
icmpmonitor.c [new file with mode: 0644]
icmpmonitor.init [new file with mode: 0755]
icmpmonitor.man [new file with mode: 0644]
icmpmonitor.spec [new file with mode: 0644]
install-sh [new file with mode: 0755]
mkinstalldirs [new file with mode: 0755]
sample.cfg [new file with mode: 0644]

diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..3052f3c
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,130 @@
+2004-05-27  Vadim Zaliva  <lord@zembla.avistar.com>
+
+       * icmpmonitor.c: Per suggestion of Mats Peterson in bug
+       #933033 'ident' type changed to unsigned short.
+       (main): Applied patch from A.Mavrin which solves problems
+       with big PIDs causing ICMPmonitor not to recognize its own
+       pings if PID>0xFFFF.
+       * NEWS: Version 1.2
+
+2000-07-24  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.man: 
+       * icmpmonitor.c: Patch #100504 incorporated.
+
+       * Makefile.in (install): 
+       * icmpmonitor.spec (Source): fix for bug #107029 (install to sbin)
+
+1999-11-21  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.init: init script for redhat linux-6.1 added.
+
+       * icmpmonitor.man: Project moved to sourceforge.net. Now we have publicly accessible CVS and bug tracking system!
+
+       * icmpmonitor.c (init_hosts): ping delay is now calculated as GCD. Bug #100166
+
+1999-09-24  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c (start_daemon): few warnings to make Compaq compiler happy.
+
+       * cfg.c (cfg_new_entry): bug found by compaque compiler corrected.
+
+1999-09-17  Vadim Zaliva  <lord@crocodile.org>
+
+       * NEWS: Version 1.1
+
+1999-09-16  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c: new OLD_ICMPHEADER code from Bernhard Lutzmann <belu@gmx.at>
+       Event better Slacware 4 problem handling from Bernhard Lutzmann <belu@gmx.at>
+       Tested to compile on Solaris 7.
+
+1999-09-15  Vadim Zaliva  <lord@crocodile.org>
+
+       * cfg.c (readcfg): problem with very long tokens in cfg corrected.
+
+       * icmpmonitor.c: headers order corrected for FreeBSD-3.3RC compatibility.
+       (main): problem with -r option handling corrected.
+
+       * icmpmonitor.man (tabs): lots of typos corrected, thanks to Bernhard Lutzmann <belu@gmx.at>.
+
+1999-09-14  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c (main): new -r option added per Chris Montgomery <chris@trinsec.com> request.
+
+       * cfg.c: new implementation of cfg file handling.
+
+       * icmpmonitor.c: Added workaround for broken ip_icmp header on Slackware 4.0 from Bernhard Lutzmann <belu@gmx.at>
+
+1999-09-12  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c (read_hosts): applyed patch from Bernhard Lutzmann <belu@gmx.at> correcting error message when cfg format is incorrect.
+
+1999-08-17  Vadim Zaliva  <lord@crocodile.org>
+
+       * cfg.c (readcfg): small memory leak corrected
+
+1999-06-28  Vadim Zaliva  <lord@crocodile.org>
+
+       * cfg.c (cfgfind): bug fixed. find works fine now. (it is not used in current code anyway).
+
+1999-06-14  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.spec: spec file created, man page finished, 'install' goal added to makefile. This would be version 1.0
+
+1999-06-12  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c (read_icmp_data): completely done with zombies
+
+1999-05-12  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c (main): avoiding zombie processes.
+
+       * cfg.h (struct Cfg): memory structures changed.
+
+1999-05-05  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c: verbose command line option added. More consistent use of LOG_DEBUG and LOG_INFO.
+
+       * configure.in: checks for openlog, closelog, syslog.
+
+       * icmpmonitor.c (main): reading command line options,
+       (start_daemon): daemon mode.
+
+       * cfg.c (freecfg): small potenial bug corrected. 
+
+1999-05-04  Vadim Zaliva  <lord@crocodile.org>
+
+       * cfg.c (freecfg): bug corrected, thanks to FreeBSD malloc diagnostics.
+
+1999-05-04  Vadim Zaliva  <lord@freefall.freebsd.org>
+
+       * Made it compile under FreeBSD. Still coredumps. 
+
+1999-05-04  Vadim Zaliva  <lord@crocodile.org>
+
+       * configure.in: GNU autoconf used.
+
+       * icmpmonitor.c (pinger): up/down command execution.
+
+1999-05-01  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c (read_hosts): reading cfg file implemented.
+
+       * cfg.c: rewritten 
+
+1999-04-27  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c: works as basic ping.
+       (read_icmp_data): calculate round trip time.
+
+1999-04-26  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c (read_icmp_data): base reading code.
+
+1999-04-23  Vadim Zaliva  <lord@crocodile.org>
+
+       * icmpmonitor.c: Started keeping chnagelog.
+       BSD license inserted.
+       (pinger): basic sending code implemented.
+
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..291541e
--- /dev/null
@@ -0,0 +1,42 @@
+# $Id: Makefile.in,v 1.2 2000/07/25 01:10:25 lord Exp $
+
+CC=@CC@
+CFLAGS=@CFLAGS@ @DEFS@
+LIBS=@LIBS@
+top_srcdir=@top_srcdir@
+srcdir=@srcdir@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+mandir=@mandir@
+INSTALL = @INSTALL@
+
+OBJS=icmpmonitor.o cfg.o
+
+VERSION=1.0
+
+all: icmpmonitor
+
+icmpmonitor: $(OBJS) Makefile
+       $(CC) $(CFLAGS) $(OBJS) -o icmpmonitor $(LIBS)
+
+icmpmonitor.o: icmpmonitor.c cfg.h Makefile
+cfg.o: cfg.c cfg.h Makefile
+
+clean:
+       rm -f *.o icmpmonitor core
+
+distclean: clean
+       rm -f config.log config.cache config.status Makefile
+
+tar:   distclean
+       (cd ..; \
+       rm -f icmpmonitor*.tar icmpmonitor*.tar.gz; \
+       tar --exclude CVS -cvf icmpmonitor-$(VERSION).tar icmpmonitor; \
+       gzip -9 icmpmonitor-$(VERSION).tar)
+
+install: icmpmonitor icmpmonitor.man
+       $(top_srcdir)/mkinstalldirs $(sbindir)
+       $(INSTALL) icmpmonitor $(sbindir)
+       $(top_srcdir)/mkinstalldirs $(mandir)/man1
+       $(INSTALL) icmpmonitor.man $(mandir)/man1/icmpmonitor.1
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..7fd55fd
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,14 @@
+$Id: NEWS,v 1.2 2004/05/28 01:33:07 lord Exp $
+
+User-visible changes since version 1.1:
+
+. Mostly portability fixes for various platforms.
+  (see Changelog for details).
+
+User-visible changes since version 1.0:
+
+. Now compiles OK on Slackware 4.0
+. New -r option added
+. Better cfg file parsing
+. Many typos in man page and messages corrected
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..4bce2f5
--- /dev/null
+++ b/README
@@ -0,0 +1,14 @@
+It was reported to compile and work on following platfoms:
+
+BSDi 2.1
+BSDi 3.1
+FreeBSD 3.3-RC 
+Solaris 2.7 sparc 
+Solaris 2.6 sparc 
+Solaris 2.6 x86
+Solaris 2.5.1 sparc with GNU C 2.8.1
+RedHat Linux 6.0-9
+Slackware 6.0 (beta)
+Slackware 4.0
+MacOS 10.3.4
+
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..9f7daa9
--- /dev/null
+++ b/TODO
@@ -0,0 +1,5 @@
+$Id: TODO,v 1.2 1999/11/21 22:46:31 lord Exp $
+
+(this file may be obsolette.  Follow link to bug tracking system from
+home page to file/review bugs)
+
diff --git a/cfg.c b/cfg.c
new file mode 100644 (file)
index 0000000..72f30a1
--- /dev/null
+++ b/cfg.c
@@ -0,0 +1,373 @@
+/*
+ *  $Id: cfg.c,v 1.1.1.1 1999/11/21 08:16:12 lord Exp $
+ *
+ *  Vadim Zaliva <lord@crocodile.org>
+ *  http://www.crocodile.org/
+ *
+ *  Copyright (C) 1999 Vadim Zaliva
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "cfg.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#define MAXTOKENLEN 1024
+
+static int cfg_entry_cmp(const void *a,const void *b)
+{
+    return(strcmp((*((struct Dict **)a))->name, (*((struct Dict **)b))->name));
+}
+
+static int cfg_entry_match(const void *a,const void *b)
+{
+    return(strcmp((const char *)a, (*((struct Dict **)b))->name));
+}
+
+char *cfgfind(const char *name,struct Cfg *cfg, int offset)
+{
+    int j;
+    struct Dict **res;
+    
+    res=(struct Dict **)bsearch(name,
+                                cfg->dict,
+                                cfg->nelements,
+                                sizeof(struct Dict *),
+                                cfg_entry_match
+    );
+    
+    if(!res)
+        return NULL;
+    
+    if(offset>=(*res)->nvalues)
+        return NULL;
+    
+    return (*res)->value[offset];
+}
+
+int writecfg(const char *name,struct Cfg *cfg)
+{
+    FILE *f;
+    int  j;
+    int i;
+
+    if((f=fopen(name,"wb"))==NULL)
+        return -1;
+    
+    if(cfg)
+    {
+        for(i=0;i<cfg->nelements;i++)
+        {
+            if(!cfg->dict[i]->name)
+                continue;
+            fprintf(f,"%s\t",cfg->dict[i]->name);
+            for(j=0;j<cfg->dict[i]->nvalues;j++)
+                if(cfg->dict[i]->value[j])
+                    fprintf(f," %s",cfg->dict[i]->value[j]); //TODO: quote values with spaces.
+            fprintf(f,"\n");
+        }
+    }
+    fclose(f);
+    return 0;
+}
+
+void freecfg(struct Cfg *cfg)
+{
+    int i,j;
+    
+    if(!cfg)
+        return;
+    
+    for(i=0;i<cfg->nelements;i++)
+    {
+        if(cfg->dict[i]->value)
+        {
+            for(j=0;j<cfg->dict[i]->nvalues;j++)
+                if(cfg->dict[i]->value[j])
+                    free(cfg->dict[i]->value[j]);
+            free(cfg->dict[i]->value);
+        }
+        
+        if(cfg->dict[i]->name)
+            free(cfg->dict[i]->name);
+    }
+    
+    free(cfg->dict);
+    free(cfg);
+}
+
+struct Cfg *readcfg(const char *name)
+{
+    struct Cfg *cfg;
+    FILE       *f;
+    char        tmp[MAXTOKENLEN];
+    char       *s;
+    int         c;
+    
+    enum 
+    {
+        START,
+        NAME,
+        VALUE,
+        INQUOTE,
+        WHITESPACE,
+        COMMENT
+    } state=START;
+    
+    int n,i;
+    char *pname,*pvalue;
+    
+    if((f=fopen(name,"rb"))==NULL)
+        return NULL;
+
+    cfg=malloc(sizeof(struct Cfg));
+    cfg->nelements=0;
+    s=tmp;
+    
+    while((c=fgetc(f))!=EOF)
+    {
+        /* Order of 'case' statements is important here! */
+        switch(state)
+        {
+        case START:
+            if(c=='#')
+            {
+                state=COMMENT;
+                break;
+            }
+            else
+                if(!isspace(c))
+                {
+                    s=tmp;
+                    state=NAME;
+                } else
+                {
+                    break;
+                }
+            
+        case NAME:
+            if(isspace(c))
+            {
+                struct Dict *tmp1=malloc(sizeof(struct Dict));
+                *s='\0';
+                tmp1->nvalues = 0;
+                tmp1->value   = NULL;
+                tmp1->name    = strdup(tmp);
+                
+                cfg_add_entry(cfg, tmp1);
+                
+                state=WHITESPACE;
+            }
+            else
+            {
+                *s++=c;
+                if(s==(tmp+sizeof(tmp)))
+                {
+                    /* internal buffer overflow */
+                    freecfg(cfg);
+                    return NULL;
+                }
+            }
+            break;
+
+        case WHITESPACE:
+            if(c=='\n')
+            {
+                state=START;
+                break;
+            }
+            else
+            {
+                if(!isspace(c))
+                {
+                    s=tmp;
+                    state=VALUE;
+                } else
+                {
+                    break;
+                }
+            }
+            
+        case VALUE:
+            if(c=='"')
+                state=INQUOTE;
+            else
+                if(isspace(c))
+                {
+                    struct Dict *last=cfg->dict[cfg->nelements-1];
+                    char **tmp1;
+                    int  i;
+                    
+                    *s='\0';
+                    tmp1=last->value;
+                    last->value=malloc((last->nvalues+1)*sizeof(char *));
+                    if(tmp1)
+                    {
+                        for(i=0;i<last->nvalues;i++)
+                            last->value[i]=tmp1[i];
+                        free(tmp1);
+                    }
+                    last->value[last->nvalues]=strdup(tmp);
+                    last->nvalues++;
+                    if(c=='\n')
+                        state=START;
+                    else
+                        state=WHITESPACE;
+                } else
+                {
+                    *s++=c;
+                    if(s==(tmp+sizeof(tmp)))
+                    {
+                        /* internal buffer overflow */
+                        freecfg(cfg);
+                        return NULL;
+                    }
+                }
+            break;
+
+        case INQUOTE:
+            if(c=='"')
+            {
+                state=VALUE;
+            }
+            else
+            {
+                *s++=c;
+                if(s==(tmp+sizeof(tmp)))
+                {
+                    /* internal buffer overflow */
+                    freecfg(cfg);
+                    return NULL;
+                }
+            }
+            break;
+
+        case COMMENT:
+            if(c=='\n')
+                state=START;
+            break;
+        }
+    }
+
+    sortcfg(cfg);
+    return cfg;
+}
+
+/**
+ * Sorts cfg.
+ * Should be called after each modification
+ * before attempting to retrieve any data.
+ */
+void sortcfg (struct Cfg *cfg)
+{
+    qsort((void *) cfg->dict,
+          cfg->nelements,
+          sizeof(struct Dict *),
+          cfg_entry_cmp);
+    
+}
+
+/**
+ * Adds new cfg entry to the end of the dictionary.
+ * you need to call sortcfg() before it could be
+ * really used.
+ */
+void cfg_add_entry (struct Cfg *cfg, struct Dict *d)
+{
+    if(cfg->nelements)
+    {
+        struct Dict **last=cfg->dict;
+        cfg->dict=malloc(sizeof(struct Dict *)*(cfg->nelements+1));
+        memcpy(cfg->dict,last,sizeof(struct Dict *)*cfg->nelements);
+        cfg->dict[cfg->nelements]=d;
+        cfg->nelements++;
+        free(last);
+    }
+    else
+    {
+        cfg->dict      = malloc(sizeof(struct Dict *));
+        cfg->dict[0]   = d;
+        cfg->nelements = 1;
+    }
+}
+
+
+/**
+ * Adds entry with given name and list of values.
+ * list should be terminated with NULL and contain
+ * only const char pointers.
+ */
+void cfg_new_entry(struct Cfg *cfg, const char *name, ...)
+{
+    int n;
+    va_list ap;
+    struct Dict *tmp=malloc(sizeof(struct Dict));
+    
+    tmp->name    = strdup(name);
+    
+    va_start(ap,name);
+    n=0;
+    while(va_arg(ap, const char *)) n++;
+    va_end(ap);
+
+    tmp->nvalues = n;
+    if(n)
+    {
+        int i;
+        
+        va_start(ap,name);
+        tmp->value = malloc(n*sizeof(char *));
+        for(i=0;i<n;i++)
+            tmp->value[i] = strdup(va_arg(ap, const char *));
+        va_end(ap);
+    } else
+    {
+        tmp->value = NULL;
+    }
+    
+    cfg_add_entry(cfg, tmp);
+}
+
+void  cfg_new_ulong_entry (struct Cfg *cfg, const char *name, unsigned long v)
+{
+    char tmp[80];
+    sprintf(tmp,"%lu",v);
+    cfg_new_entry(cfg, name, tmp, NULL);    
+}
+
+/**
+ * add long extended to 'w' chars, with added trailing zeros.
+ *
+ * @param v - field value
+ * @param w - field width
+ */
+void  cfg_new_fmt_ulong_entry (struct Cfg *cfg, const char *name, unsigned long v, int w)
+{
+    char tmp[80];
+    sprintf(tmp,"%0*lu",w, v);
+    cfg_new_entry(cfg, name, tmp, NULL);    
+}
+
+struct Cfg *newcfg ()
+{
+    struct Cfg *res=malloc(sizeof(struct Cfg));
+    res->nelements  = 0;
+    return res;
+}
diff --git a/cfg.h b/cfg.h
new file mode 100644 (file)
index 0000000..3df5d9c
--- /dev/null
+++ b/cfg.h
@@ -0,0 +1,51 @@
+/*
+ *  $Id: cfg.h,v 1.1.1.1 1999/11/21 08:16:12 lord Exp $
+ *
+ *  Vadim Zaliva <lord@crocodile.org>
+ *  http://www.crocodile.org/
+ *
+ *  Copyright (C) 1999 Vadim Zaliva
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+struct Dict
+{
+    char  *name;
+    char **value;
+    int    nvalues;
+};
+
+struct Cfg
+{
+    struct Dict **dict;
+    int    nelements ;
+};
+
+struct Cfg *readcfg   (const char *filename);
+int         writecfg  (const char * filename, struct Cfg *);
+char       *cfgfind   (const char *,struct Cfg *, int offset);
+void        freecfg   (struct Cfg *);
+struct Cfg *newcfg    ();
+void        sortcfg   (struct Cfg *);
+void        cfg_add_entry (struct Cfg *, struct Dict *);
+
+/* convinience functions */
+void        cfg_new_entry (struct Cfg *cfg, const char *name, ...);
+void        cfg_new_ulong_entry (struct Cfg *cfg, const char *name, unsigned long v);
+void        cfg_new_fmt_ulong_entry (struct Cfg *cfg, const char *name, unsigned long v, int w);
+
+
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..bd8dc32
--- /dev/null
+++ b/configure
@@ -0,0 +1,1758 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=icmpmonitor.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:529: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:559: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:610: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:642: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 653 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:684: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:689: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:698: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:717: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:779: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:833: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 841 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lnsl $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for socketpair in -lsocket""... $ac_c" 1>&6
+echo "configure:880: checking for socketpair in -lsocket" >&5
+ac_lib_var=`echo socket'_'socketpair | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsocket  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 888 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char socketpair();
+
+int main() {
+socketpair()
+; return 0; }
+EOF
+if { (eval echo configure:899: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lsocket $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:928: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 943 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:949: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 960 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:966: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 977 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:983: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1008: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1013 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1021: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1038 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1056 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1077 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in sys/time.h syslog.h unistd.h sys/fcntl.h fcntl.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1115: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1120 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1125: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1153: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1158 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1207: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1228: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1233 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_size_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+  cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1261: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1266 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1275: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_time=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+  cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:1297: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1302 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:1319: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_type_signal=void
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&6
+echo "configure:1338: checking for vprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1343 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char vprintf(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char vprintf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_vprintf=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
+echo "configure:1390: checking for _doprnt" >&5
+if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1395 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char _doprnt();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1418: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func__doprnt=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+for ac_func in openlog closelog syslog gettimeofday select socket strdup vsnprintf vsprintf
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1445: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1450 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1473: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[    `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@CPP@%$CPP%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..eb30a99
--- /dev/null
@@ -0,0 +1,26 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(icmpmonitor.c)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+
+dnl Checks for libraries.
+AC_CHECK_LIB(nsl, gethostbyname)
+AC_CHECK_LIB(socket, socketpair)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(sys/time.h syslog.h unistd.h sys/fcntl.h fcntl.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(openlog closelog syslog gettimeofday select socket strdup vsnprintf vsprintf)
+
+AC_OUTPUT(Makefile)
diff --git a/icmpmonitor.c b/icmpmonitor.c
new file mode 100644 (file)
index 0000000..89535fd
--- /dev/null
@@ -0,0 +1,764 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Muuss.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ *                     ICMPMONITOR.C
+ *
+ * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
+ * monitor several hosts, and notify admin if some of them are down.
+ *
+ * Author -
+ *      Vadim Zaliva <lord@crocodile.org>
+ *
+ * Status -
+ *     Public Domain.  Distribution Unlimited.
+ */
+
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n"
+"All rights reserved.\n";
+
+char rcsid[] = "$Id: icmpmonitor.c,v 1.8 2004/05/28 01:33:07 lord Exp $";
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_SYSLOG_H
+# include <syslog.h>
+#endif
+#include <stdarg.h>
+#include <signal.h>
+#include <string.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/socket.h>
+#include <sys/types.h>
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+
+/* Workaround for broken ICMP header on Slackware 4.x */
+#ifdef _LINUX_ICMP_H
+# warning "Broken Slackware 4.x 'netinet/ip_icmp.h' header detected. Using replacement 'struct icmp' definition."
+# define ICMP_MINLEN    8
+struct icmp
+{
+    u_int8_t  icmp_type;
+    u_int8_t  icmp_code;
+    u_int16_t icmp_cksum;
+    union
+    {
+        struct ih_idseq
+        { 
+            u_int16_t icd_id;
+            u_int16_t icd_seq;
+        } ih_idseq;
+    } icmp_hun;
+    
+# define icmp_id         icmp_hun.ih_idseq.icd_id
+# define icmp_seq        icmp_hun.ih_idseq.icd_seq
+    
+    union {
+        u_int8_t    id_data[1];
+    } icmp_dun;
+    
+# define icmp_data       icmp_dun.id_data
+    
+};
+#endif /* _LINUX_ICMP_H */
+
+#include <stddef.h>
+#include <errno.h>
+
+#include "cfg.h"
+
+/* defines */
+
+/* #define DEBUG */
+
+#ifndef nil
+# define nil NULL
+#endif
+
+/* return codes */
+#define RET_OK         0
+#define RET_NO_HOSTS   1
+#define RET_INIT_ERROR 2
+#define RET_BAD_CFG    3
+#define RET_BAD_OPT    4
+
+#define        MAXPACKET       (65536 - 60 - 8) /* max packet size     */
+#define        DEFDATALEN      (64 - 8)         /* default data length */
+
+#define VERSION "ICMPmonitor v1.2 by lord@crocodile.org"
+#define MAX_LOG_MSG_SIZE 4096
+
+# define icmphdr                       icmp
+
+/* typedefs */
+typedef struct monitor_host
+{
+    /* following are coming from cfg */
+    char  *name;
+    int    ping_interval;
+    int    max_delay;
+    char  *upcmd;
+    char  *downcmd;
+
+    /* following values are calculated */
+    int    socket;
+    struct timeval last_ping_received;
+    struct timeval last_ping_sent;
+    int    up;
+    int    down;
+    struct sockaddr_in dest;
+
+    unsigned int sentpackets ;
+    unsigned int recvdpackets;
+    
+    /* linked list */
+    struct monitor_host *next;
+} monitor_host_t;
+
+/* protos */
+static void logopen(void);
+static void logclose(void);
+static void log(int type, char *format, ...);
+static int  gethostaddr(const char *name);
+static void read_hosts(const char *cfg_file_name);
+static void init_hosts(void);
+static void get_response(void);
+static void pinger(int);
+static int  in_cksum(u_short *addr, int len);
+static void read_icmp_data(monitor_host_t *p);
+static void tvsub(struct timeval *out, struct timeval *in);
+static void done(int code);
+static void start_daemon(void);
+static int gcd(int x, int y);
+
+/* globals */
+
+static monitor_host_t **hosts      = nil;
+static int             isDaemon    = 0; 
+static int             isVerbose   = 0;
+static int             keepBanging = 0;
+static unsigned short  ident;
+static int             send_delay  = 1;
+
+int main(int ac, char **av)
+{
+    extern char* optarg;
+    extern int   optind;
+    char         *cfgfile=nil;
+    int          param;
+    
+    logopen();
+    log(LOG_INFO, VERSION " is starting.");
+
+    while((param = getopt(ac, av, "rvdf:")) != -1)
+       switch(param)
+        { 
+       case 'v':
+            isVerbose = 1;
+           break; 
+       case 'd':
+            isDaemon = 1;
+           break; 
+       case 'r':
+            keepBanging = 1;
+           break; 
+       case 'f':  
+           cfgfile=strdup(optarg);  
+           break;  
+       default: 
+           fprintf(stderr,"Usage: icmpmonitor [-d] [-v] [-r] [-f cfgfile]\n");
+            done(RET_BAD_OPT);
+       } 
+    
+    if(!cfgfile)
+    {
+        log(LOG_WARNING,"No cfg file specified. Assuming 'icmpmonitor.cfg'");
+       cfgfile="icmpmonitor.cfg";
+    }
+
+    read_hosts(cfgfile); /* we do this before becoming daemon,
+                            to be able process relative path */
+
+    if(isDaemon)
+        start_daemon();
+    
+    init_hosts();
+    
+    ident=getpid() & 0xFFFF;
+    
+    (void)signal(SIGALRM, pinger);
+    alarm(send_delay); 
+
+    get_response();
+    
+    done(RET_OK);
+}
+
+
+/*
+ * in_cksum --
+ *     Checksum routine for Internet Protocol family headers (C Version)
+ */
+static int
+in_cksum(u_short *addr, int len)
+{
+    register int nleft = len;
+    register u_short *w = addr;
+    register int sum = 0;
+    u_short answer = 0;
+    
+    /*
+     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+     * sequential 16 bit words to it, and at the end, fold back all the
+     * carry bits from the top 16 bits into the lower 16 bits.
+     */
+    while (nleft > 1)  {
+        sum += *w++;
+        nleft -= 2;
+    }
+    
+    /* mop up an odd byte, if necessary */
+    if (nleft == 1) {
+        *(u_char *)(&answer) = *(u_char *)w ;
+        sum += answer;
+    }
+    
+    /* add back carry outs from top 16 bits to low 16 bits */
+    sum = (sum >> 16) + (sum & 0xffff);        /* add hi 16 to low 16 */
+    sum += (sum >> 16);                        /* add carry */
+    answer = ~sum;                     /* truncate to 16 bits */
+    return(answer);
+}
+
+/*
+ * pinger --
+ *     Compose and transmit an ICMP ECHO REQUEST packet.  The IP packet
+ * will be added on by the kernel.  The ID field is our UNIX process ID,
+ * and the sequence number is an ascending integer.  The first 8 bytes
+ * of the data portion are used to hold a UNIX "timeval" struct in VAX
+ * byte-order, to compute the round-trip time.
+ */
+static void pinger(int ignore)
+{
+    register struct icmphdr *icp;
+    register int             cc;
+    int                      i;
+    monitor_host_t           *p;
+    u_char outpack[MAXPACKET];
+
+    p=hosts[0];
+    while(p)
+    {
+        if(p->socket!=-1)
+        {
+            struct timeval now;
+            
+            (void)gettimeofday(&now,(struct timezone *)NULL);
+            tvsub(&now, &p->last_ping_received);
+
+            if(now.tv_sec > (p->max_delay+p->ping_interval))
+            {            
+                p->up=0;
+                if((!p->down) || keepBanging)
+                {
+                   p->down = 1;
+                    
+                    if(isVerbose)
+                        log(LOG_INFO,"Host %s in down. Executing DOWN command",p->name);
+                    if(!fork())
+                    {
+                        system(p->downcmd);
+                        exit(0);
+                    } else
+                    {
+                        wait(nil);
+                    }
+                }
+            }
+            
+            (void)gettimeofday(&now,(struct timezone *)NULL);
+            tvsub(&now, &p->last_ping_sent);
+            
+            if(now.tv_sec > p->ping_interval)
+            {
+                /* Time to send ping */
+                
+                icp = (struct icmphdr *)outpack;
+                icp->icmp_type  = ICMP_ECHO;
+                icp->icmp_code  = 0;
+                icp->icmp_cksum = 0;
+                icp->icmp_seq   = p->socket;
+                icp->icmp_id    = ident;                       
+
+                if(isVerbose)
+                    log(LOG_INFO,"Sending ICMP packet to %s.",p->name);
+                
+                (void)gettimeofday((struct timeval *)&outpack[8],
+                                   (struct timezone *)NULL);
+                
+                cc = DEFDATALEN + 8;  /* skips ICMP portion */
+                
+                /* compute ICMP checksum here */
+                icp->icmp_cksum = in_cksum((u_short *)icp, cc);
+                
+                i = sendto(p->socket, (char *)outpack, cc, 0, (const struct sockaddr *)(&p->dest),
+                           sizeof(struct sockaddr));
+                
+                (void)gettimeofday(&p->last_ping_sent,
+                                   (struct timezone *)NULL);
+                
+                if(i<0 || i!=cc)
+                {
+                    if(i<0)
+                        log(LOG_WARNING,"Sending ICMP packet to %s failed.",p->name);
+                }
+                p->sentpackets++;
+            }
+        }
+        p=p->next;
+        
+    }
+    
+    (void)signal(SIGALRM, pinger); /* restore handler */
+    alarm(send_delay);
+}
+
+static void get_response(void)
+{
+    fd_set rfds;
+    int    retval;
+    monitor_host_t *p;
+    int    maxd=-1;
+    
+    while(1)
+    {
+        p=hosts[0];
+        FD_ZERO(&rfds);
+        while(p)
+        {
+            if(p->socket != -1)
+            {
+                if(p->socket > maxd)
+                    maxd=p->socket;
+                FD_SET(p->socket, &rfds);
+            }
+            p=p->next;
+        }
+
+        retval = select(maxd+1, &rfds, nil, nil, nil);
+        if(retval<0)
+        {
+            /* we get her in case we are interrupted by signal.
+               it's ok. */
+        }
+        else
+        {
+            if(retval>0)
+            {
+                /* log(LOG_DEBUG,"ICMP data is available now."); */
+                p=hosts[0];
+                while(p)
+                {
+                    if(p->socket!=-1 && FD_ISSET(p->socket, &rfds))
+                    {
+                        /* Read data */
+                        read_icmp_data(p);
+                    }
+                    p=p->next;
+                }
+            } else
+            {
+                log(LOG_DEBUG,"select returns 0."); /* TODO */
+            }
+        }
+    }
+}
+
+static void read_icmp_data(monitor_host_t *p)
+{
+    socklen_t fromlen       ;
+    struct sockaddr_in from ;
+    int cc                  ;
+    struct ip   *ip         ;
+    struct icmp *icmp       ;
+    int    iphdrlen         ;
+    int    delay            ;
+    struct timeval tv       ;
+    unsigned char buf[MAXPACKET]; /* read buffer */
+
+    (void)gettimeofday(&tv, (struct timezone *)NULL);
+    
+    fromlen = sizeof(from);
+    if((cc = recvfrom(p->socket, buf, sizeof(buf), 0,
+                      (struct sockaddr *)&from, &fromlen)) < 0)
+    {
+        if(errno != EINTR)
+            log(LOG_WARNING,"Error reading ICMP data from %s.",p->name);
+        return;
+    } 
+
+    /* log(LOG_DEBUG,"Got %d bytes of ICMP data from %s.",cc, p->name); */
+
+    /* check IP header actual len */ 
+    ip       = (struct ip *)buf               ; 
+    iphdrlen = ip->ip_hl<<2                   ; 
+    icmp     = (struct icmp *) (buf+iphdrlen) ;
+    
+    if(cc < iphdrlen+ICMP_MINLEN)
+    {
+        log(LOG_WARNING,"Received short packet from %s.",p->name);
+        return;
+    }
+    
+    if(icmp->icmp_type == ICMP_ECHOREPLY &&
+       icmp->icmp_id   == ident          &&
+       icmp->icmp_seq  == p->socket)
+    {
+        p->recvdpackets++;
+
+        memcpy(&p->last_ping_received, &tv, sizeof(tv));
+        
+        tvsub(&tv, (struct timeval *) &icmp->icmp_data[0]);
+        delay=tv.tv_sec*1000+(tv.tv_usec/1000);
+        
+        if(isVerbose)
+            log(LOG_INFO,"Got ICMP reply from %s in %d ms.",p->name,delay);
+       p->down=0;
+        if(!p->up)
+        {
+            p->up=1;
+            if(isVerbose)
+                log(LOG_INFO,"Host %s in now up. Executing UP command",p->name);
+            if(!fork())
+            {
+                system(p->upcmd);
+                exit(0);
+            } else
+            {
+                wait(nil);
+            }
+        }
+    } else
+    {
+        /*
+          log(LOG_DEBUG,"ICMP packet of type %d from %s. Ident=%d",icmp->icmp_type,
+          p->name,
+          icmp->icmp_id
+          );
+        */
+    }
+}
+
+static void read_hosts(const char *cfg_file_name)
+{
+    int    i,n=0;
+    struct Cfg *cfg;
+    
+    if((cfg=readcfg(cfg_file_name))==NULL)
+    {
+        log(LOG_ERR,"Error reading cfg. Exiting.");
+        done(RET_BAD_CFG);
+    }
+    
+    if(cfg->nelements)
+    {
+        hosts=malloc(sizeof(monitor_host_t *)*cfg->nelements);
+        for(i=0;i<cfg->nelements;i++)
+        {
+            if(cfg->dict[i]->nvalues<4)
+            {
+                log(LOG_ERR,"Not enough fields in record %d of cfg file. Got %d.",n, cfg->dict[i]->nvalues+1);
+                done(RET_BAD_CFG);
+            } else if(cfg->dict[i]->nvalues>5)
+            {
+                log(LOG_ERR,"Too many fields in record %d of cfg file. Got %d.",n, cfg->dict[i]->nvalues+1);
+                done(RET_BAD_CFG);
+            }
+            
+            hosts[n]=malloc(sizeof(monitor_host_t));
+            hosts[n]->name          = strdup(cfg->dict[i]->name);
+            hosts[n]->ping_interval = atoi  (cfg->dict[i]->value[0]);
+            hosts[n]->max_delay     = atoi  (cfg->dict[i]->value[1]);
+            hosts[n]->upcmd         = strdup(cfg->dict[i]->value[2]);
+            hosts[n]->downcmd       = strdup(cfg->dict[i]->value[3]);
+            
+           if(cfg->dict[i]->nvalues==4)
+           {
+               hosts[n]->down = 0;
+               hosts[n]->up   = 1;
+           } else if(strcmp(cfg->dict[i]->value[4], "up")==0)
+           {
+               hosts[n]->down = 0;
+               hosts[n]->up   = 1;
+           } else if(strcmp(cfg->dict[i]->value[4], "down")==0)
+           {
+               hosts[n]->down = 1;
+               hosts[n]->up   = 0;
+           } else if(strcmp(cfg->dict[i]->value[4], "auto")==0)
+           {
+               hosts[n]->down = 1;
+               hosts[n]->up   = 1;
+           } else if(strcmp(cfg->dict[i]->value[4], "none")==0)
+           {
+               hosts[n]->down = 0;
+               hosts[n]->up   = 0;
+           } else
+           {
+               log(LOG_ERR,"Illegal value %s in record %n for startup condition.", cfg->dict[i]->value[4], n);
+               done(RET_BAD_CFG);
+           }
+            hosts[n]->sentpackets   = 0;
+            hosts[n]->recvdpackets  = 0;
+
+            hosts[n]->socket           = -1;
+            hosts[n]->next             = nil;
+            if(n>0)
+                hosts[n-1]->next=hosts[n];
+            (void)gettimeofday(&(hosts[n]->last_ping_received), (struct timezone *)NULL);
+
+            n++;
+        } 
+    }
+
+    freecfg(cfg);
+
+    if(n<=0)
+    {
+        log(LOG_ERR,"No hosts defined in cfg file, exiting.");
+        done(RET_NO_HOSTS);
+    }
+    else
+        log(LOG_DEBUG,"%d host(s) found in cfg file,", n);
+    
+}
+
+static int gethostaddr(const char *name)
+{
+    static  int  res;
+    struct hostent *he;
+    
+    if((res=inet_addr(name))<0)
+    {
+       he=gethostbyname(name);
+        if(!he)
+            return -1;
+       memcpy( &res , he->h_addr , he->h_length );
+    } 
+    return(res);
+}
+
+static void init_hosts(void)
+{
+    monitor_host_t *p=hosts[0];
+    struct protoent   *proto;
+    int ok=0;
+
+    if((proto=getprotobyname("icmp"))==nil)
+    {
+        log(LOG_ERR,"Unknown protocol: icmp. Exiting.");
+        done(RET_INIT_ERROR);
+    }
+    
+    while(p)
+    {
+        log(LOG_DEBUG,"resolving host %s", p->name);
+        
+        bzero(&p->dest,sizeof(p->dest));
+        p->dest.sin_family=AF_INET;
+        if((p->dest.sin_addr.s_addr=gethostaddr(p->name))<=0)
+        {
+            log(LOG_ERR,"Can't resolve host. Skipping client %s.",p->name);
+            p->socket=-1;
+        } else
+        {
+            if((p->socket=socket(AF_INET,SOCK_RAW,proto->p_proto))<0)
+            {
+                log(LOG_ERR,"Can't create socket. Skipping client %s.",p->name);
+                p->socket=-1;
+            } else
+            {
+                if(ok==0)
+                    send_delay = p->ping_interval;
+                else
+                    send_delay = gcd(send_delay, p->ping_interval);
+                ok++;
+            }
+        }
+        p=p->next;
+    }
+
+    if(!ok)
+    {
+        log(LOG_ERR,"No hosts left to process, exiting.");
+        done(RET_NO_HOSTS);
+    }
+}
+
+/*
+ * tvsub --
+ *     Subtract 2 timeval structs:  out = out - in.  Out is assumed to
+ * be >= in.
+ */
+static void
+tvsub(register struct timeval *out, register struct timeval *in)
+{
+       if ((out->tv_usec -= in->tv_usec) < 0) {
+               --out->tv_sec;
+               out->tv_usec += 1000000;
+       }
+       out->tv_sec -= in->tv_sec;
+}
+
+void done(int code)
+{
+    logclose();
+    exit(code);
+}
+
+void start_daemon(void)
+{
+    if(fork())
+       exit(0);
+    
+    chdir("/");
+    umask(0);
+    (void) close(0);
+    (void) close(1);
+    (void) close(2);
+    (void) open("/", O_RDONLY);
+    (void) dup2(0, 1);
+    (void) dup2(0, 2);
+    setsid();
+}
+
+static void logopen(void)
+{
+#if HAVE_OPENLOG
+    if(isDaemon)
+        openlog("icmpmonitor", LOG_PID| LOG_CONS|LOG_NOWAIT, LOG_USER);
+#else
+    log(LOG_WARNING,"Compiled without syslog. Syslog can't be used.");
+#endif
+}
+
+static void logclose(void)
+{
+#if HAVE_CLOSELOG
+    if(isDaemon)
+        closelog();
+#endif
+}
+
+/**
+ * This function should be used as central logging facility.
+ * 'type' argument should be one of following:
+ *
+ *  LOG_EMERG  system is unusable 
+ *  LOG_ALERT  action must be taken immediately 
+ *  LOG_CRIT   critical conditions 
+ *  LOG_ERR    error conditions 
+ *  LOG_WARNING        warning conditions 
+ *  LOG_NOTICE normal but significant condition 
+ *  LOG_INFO   informational 
+ *  LOG_DEBUG  debug-level messages 
+ */
+static void log(int type, char *format, ...)
+{
+    va_list ap;
+
+#ifndef DEBUG
+    if(type==LOG_DEBUG)
+        return;
+#endif
+    
+    va_start(ap, format);
+
+    if(isDaemon)
+    {
+        char buffer[MAX_LOG_MSG_SIZE];
+            
+#if HAVE_VSNPRINTF    
+        (void)vsnprintf(buffer, MAX_LOG_MSG_SIZE, format, ap);
+#else
+# if HAVE_VSPRINTF
+#  warning "Using VSPRINTF. Buffer overflow could happen!"
+        (void)vsprintf(buffer, format, ap);
+# else
+#  error "Your standard libabry have neither vsnprintf nor vsprintf defined. One of them is reqired!"
+# endif
+#endif
+#if HAVE_SYSLOG            
+        syslog(type,buffer);
+#endif
+    } else
+    {
+        (void)  fprintf(stderr, "icmpmonitor[%d]:", (int)getpid());
+        (void) vfprintf(stderr, format, ap);
+        (void)  fprintf(stderr, "\n");
+    }
+    va_end(ap);
+}
+
+static int gcd(int x, int y)
+{
+    while(x!=y)
+    {
+        if(x<y)
+            y-=x;
+        else 
+            x-=y;
+    }
+    return x;
+}
diff --git a/icmpmonitor.init b/icmpmonitor.init
new file mode 100755 (executable)
index 0000000..4df8065
--- /dev/null
@@ -0,0 +1,54 @@
+#! /bin/sh
+#
+# chkconfig: - 60 20
+# description: check is some hosts are alive
+# processname: icmpmonitor
+
+# Get config.
+. /etc/sysconfig/network
+
+# Get functions
+. /etc/rc.d/init.d/functions
+
+# Check that networking is up.
+if [ ${NETWORKING} = "no" ] ; then
+       exit 0
+fi
+
+[ -f /usr/local/sbin/icmpmonitor ] || exit 0
+[ -f /usr/local/etc/icmpmonitor.cfg ] || exit 0
+
+RETVAL=0
+
+# See how we were called.
+case "$1" in
+  start)
+       echo -n "Starting icmpmonitor: "
+       daemon /usr/local/sbin/icmpmonitor -d -f /usr/local/etc/icmpmonitor.cfg
+       RETVAL=$?
+       echo
+       [ $RETVAL -eq 0 ] && touch /var/lock/subsys/icmpmonitor
+       ;;
+  stop)
+       echo -n "Stopping icmpmonitor: "
+       killproc icmpmonitor
+       RETVAL=$?
+       echo
+       [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/icmpmonitor
+       ;;
+  status)
+       status icmpmonitor
+       RETVAL=$?
+       ;;
+  restart)
+       $0 stop
+       $0 start
+       RETVAL=$?
+       ;;
+  *)
+       echo "Usage: $0 {start|stop|status|restart}"
+       exit 1
+       ;;
+esac
+
+exit $RETVAL
diff --git a/icmpmonitor.man b/icmpmonitor.man
new file mode 100644 (file)
index 0000000..e6d0570
--- /dev/null
@@ -0,0 +1,105 @@
+.TH icmpmonitor 1 "Version 1.2"
+.ds ]W September 1999
+.SH NAME
+icmpmonitor \- multiple host monitoring tool
+.SH SYNOPSIS
+.ta 6n
+\fBicmpmonitor\fP 
+[-f \fIcfg file\fP]
+[-d]
+[-v]
+[-r]
+.br
+.SH DESCRIPTION
+The 
+.I icmpmonitor 
+Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 
+monitors several hosts, and notify admin if some of them are down.
+
+.SH OPTIONS
+.PP
+.I icmpmonitor\fP accepts following options:
+.TP 8
+.B \-d 
+if specified, the program will detach itself from control terminal and work in 'daemon' mode. All error messages will go to syslog.
+.TP 8
+.B \-f \fP<\fIconfiguration file\fP>
+Name of configuration file.
+.TP 8
+.B \-v
+if specified, the program will produce more log messages describing its activity.
+.TP 8
+.B \-r
+Execute DOWN command repeatedly until host will be up again. If it is not specified, the command is excuted only once.
+
+.SH CONFIGURATION FILE FORMAT
+.PP
+You need to create the configuration file. You can find a sample one in the distribution named 'sample.cfg'. The file consists of one or more lines. Lines starting with "#" are
+comments and are ignored. Each line must contain following fields, separeated by spaces or
+tabs:
+
+.TP 8
+.B Hostname          \fP
+Name of the host which will be monitored.
+.TP 8
+.B Ping Interval            \fP
+Interval (in seconds) on which ICMP packets will be sent to the host to check it's status.
+.TP 8
+.B Max. Delay             \fP
+Maximum delay (in seconds) after which host considered to be "down" if no response was received.
+.TP 8
+.B "Up" Command        \fP
+Command which will be executed when host became accessible. 
+This command is executed
+using "sh -c" and may contain shell syntax. If command contain spaces or tabs
+it should be quoted. 
+If the command is executing some lenghy operation it is recommended to start
+it as detached process (for example using '&'), because icmpmonitor will not resume monitoring of this
+and other hosts until command is finished.
+.TP 8
+.B "Down" Command       \fP
+Command which will be executed when host became not accessible.
+This command will be executed
+using "sh -c" and may contain shell syntax. If command contain spaces or tabs
+it should be quoted.
+If the command is executing some lenghy operation it is recommended to start
+it as detached process (for example using '&'), because icmpmonitor will not resume monitoring of this
+and other hosts until command is finished.
+.TP 8
+.B Startup Condition (optional) \fp
+Condition of the host that should be assumed on startup.
+Possible values are "auto", "down", "none" and "up".
+The parameter is optional with "up" being the default value.
+The main purpose is controlling which up/down commands will be launched on startup.
+"auto" detects the state of the host silently on startup and doesn't launch any command first.
+"down" assumes the host is down and executes the up command on the first ping recieved. Similar to "up".
+"none" starts either up or down command on startup.
+
+.SH BUGS
+It was reported that some systems (e.g. Solaris 2.5) do not have function 
+vsnprintf. In such case icmpmonitor will use vsprintf instead, but this could 
+cause buffer overflow problem. 
+
+If you find any other bugs, please follow link to bug tracking system
+from ICMPmonitor project home page to file them.
+.TP 8
+
+.PP
+.SH SEE ALSO
+.PP
+\fBhttp://www.crocodile.org/software.html\fP
+.SH AUTHOR
+.PP
+Vadim Zaliva <lord@crocodile.org>
+.SH CONTRIBUTORS
+.PP
+I would like to thank following people for help in developement of this software:
+Alexandr S. Dubovicov <shurik@te.net.ua>,
+Andrey Arhipov <andy@paco.net>,
+Bernhard Lutzmann <belu@gmx.at>,
+Ingo Saitz <Salz@users.sourceforge.net> 
+
+
+
+
diff --git a/icmpmonitor.spec b/icmpmonitor.spec
new file mode 100644 (file)
index 0000000..02cbefa
--- /dev/null
@@ -0,0 +1,31 @@
+Name: icmpmonitor
+Summary: multiple host monitoring tool
+Packager: Vadim Zaliva <lord@crocodile.org>
+Url: http://www.crocodile.org/software.html
+Version: 1.2
+Release: 1
+Copyright: BSD
+Group: Networking/Daemons
+Source: ftp://ftp.crocodile.org/pub/icmpmonitor-%{version}.tar.gz
+
+%description
+Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 
+monitors several hosts, and notify admin if some of them are down.
+
+%prep
+%setup -n icmpmonitor-%{version}
+
+%build
+./configure --prefix=/usr
+make
+
+%install
+make install
+
+%files
+%defattr(-,root,root)
+/usr/sbin/icmpmonitor
+/usr/man/man1/icmpmonitor.1
+%doc README ChangeLog TODO sample.cfg NEWS
+
+
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..ebc6691
--- /dev/null
@@ -0,0 +1,250 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755 (executable)
index 0000000..271e571
--- /dev/null
@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.1.1.1 1999/11/21 08:16:17 lord Exp $
+
+errstatus=0
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+
+        mkdir "$pathcomp" || lasterr=$?
+
+        if test ! -d "$pathcomp"; then
+         errstatus=$lasterr
+        fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/sample.cfg b/sample.cfg
new file mode 100644 (file)
index 0000000..32a5128
--- /dev/null
@@ -0,0 +1,16 @@
+# $Id: sample.cfg,v 1.2 2000/07/25 01:57:01 lord Exp $
+#
+#Name,  ping_interval, max_delay, upcmd, downcmd, startup condition
+
+# Monitor these hosts when they go down
+r90                1  5  "echo r90  up| mail lord" "echo r90  down| mail lord"
+noir.crocodile.org 60 10 "echo noir up| mail lord" "echo noir down| mail lord"
+crocodile.org      60 10 "echo home up| mail lord" "echo home down| mail lord"
+lizard             1  5  "echo lizard  up| mail lord" "echo lizard  down| mail lord"
+
+# Monitor this host when it is started
+windoze                   60 10 "echo warning windoze is running| mail lord" "echo internet clean again| mail lord" down
+
+# If and only if the fast gateway goes down switch to another, slower one.
+# Assume no valid configuration on startup.
+gate.ether         1  5  "ifup -s ether" "ifup -s phone" none