From c5de9e278c4df31cbe34b4197d3dd9bfd1b98e73 Mon Sep 17 00:00:00 2001 From: Aaron Taylor Date: Mon, 16 Sep 2019 17:57:00 -0700 Subject: [PATCH] Initial commit of `icmpmonitor-1.2` from http://www.crocodile.org/software.html --- ChangeLog | 130 ++++ Makefile.in | 42 ++ NEWS | 14 + README | 14 + TODO | 5 + cfg.c | 373 ++++++++++ cfg.h | 51 ++ configure | 1758 ++++++++++++++++++++++++++++++++++++++++++++++ configure.in | 26 + icmpmonitor.c | 764 ++++++++++++++++++++ icmpmonitor.init | 54 ++ icmpmonitor.man | 105 +++ icmpmonitor.spec | 31 + install-sh | 250 +++++++ mkinstalldirs | 40 ++ sample.cfg | 16 + 16 files changed, 3673 insertions(+) create mode 100644 ChangeLog create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 cfg.c create mode 100644 cfg.h create mode 100755 configure create mode 100644 configure.in create mode 100644 icmpmonitor.c create mode 100755 icmpmonitor.init create mode 100644 icmpmonitor.man create mode 100644 icmpmonitor.spec create mode 100755 install-sh create mode 100755 mkinstalldirs create mode 100644 sample.cfg diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..3052f3c --- /dev/null +++ b/ChangeLog @@ -0,0 +1,130 @@ +2004-05-27 Vadim Zaliva + + * 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 + + * 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 + + * 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 + + * 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 + + * NEWS: Version 1.1 + +1999-09-16 Vadim Zaliva + + * icmpmonitor.c: new OLD_ICMPHEADER code from Bernhard Lutzmann + Event better Slacware 4 problem handling from Bernhard Lutzmann + Tested to compile on Solaris 7. + +1999-09-15 Vadim Zaliva + + * 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 . + +1999-09-14 Vadim Zaliva + + * icmpmonitor.c (main): new -r option added per Chris Montgomery 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 + +1999-09-12 Vadim Zaliva + + * icmpmonitor.c (read_hosts): applyed patch from Bernhard Lutzmann correcting error message when cfg format is incorrect. + +1999-08-17 Vadim Zaliva + + * cfg.c (readcfg): small memory leak corrected + +1999-06-28 Vadim Zaliva + + * cfg.c (cfgfind): bug fixed. find works fine now. (it is not used in current code anyway). + +1999-06-14 Vadim Zaliva + + * icmpmonitor.spec: spec file created, man page finished, 'install' goal added to makefile. This would be version 1.0 + +1999-06-12 Vadim Zaliva + + * icmpmonitor.c (read_icmp_data): completely done with zombies + +1999-05-12 Vadim Zaliva + + * icmpmonitor.c (main): avoiding zombie processes. + + * cfg.h (struct Cfg): memory structures changed. + +1999-05-05 Vadim Zaliva + + * 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 + + * cfg.c (freecfg): bug corrected, thanks to FreeBSD malloc diagnostics. + +1999-05-04 Vadim Zaliva + + * Made it compile under FreeBSD. Still coredumps. + +1999-05-04 Vadim Zaliva + + * configure.in: GNU autoconf used. + + * icmpmonitor.c (pinger): up/down command execution. + +1999-05-01 Vadim Zaliva + + * icmpmonitor.c (read_hosts): reading cfg file implemented. + + * cfg.c: rewritten + +1999-04-27 Vadim Zaliva + + * icmpmonitor.c: works as basic ping. + (read_icmp_data): calculate round trip time. + +1999-04-26 Vadim Zaliva + + * icmpmonitor.c (read_icmp_data): base reading code. + +1999-04-23 Vadim Zaliva + + * 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 index 0000000..291541e --- /dev/null +++ b/Makefile.in @@ -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 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 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 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 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 + * 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 +#include +#include +#include +#include + +#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;inelements;i++) + { + if(!cfg->dict[i]->name) + continue; + fprintf(f,"%s\t",cfg->dict[i]->name); + for(j=0;jdict[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;inelements;i++) + { + if(cfg->dict[i]->value) + { + for(j=0;jdict[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;invalues;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;ivalue[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 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 + * 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 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 <&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 <&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 <&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 <&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 <&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 < +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 < +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 < +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 < +#include +#include +#include +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 +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 +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 < +#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 +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 <&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 <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 < +#if STDC_HEADERS +#include +#include +#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 < +#include +#include +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 < +#include +#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 <&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 < +/* 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 < +/* 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 < +/* 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 <&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 </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 < 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 <> $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 <> $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 index 0000000..eb30a99 --- /dev/null +++ b/configure.in @@ -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 index 0000000..89535fd --- /dev/null +++ b/icmpmonitor.c @@ -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 + * + * 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 +#include +#include +#ifdef HAVE_SYSLOG_H +# include +#endif +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +# include +#endif +#include +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_SYS_FCNTL_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +/* 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 +#include + +#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;inelements;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 +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 +.SH CONTRIBUTORS +.PP +I would like to thank following people for help in developement of this software: +Alexandr S. Dubovicov , +Andrey Arhipov , +Bernhard Lutzmann , +Ingo Saitz + + + + diff --git a/icmpmonitor.spec b/icmpmonitor.spec new file mode 100644 index 0000000..02cbefa --- /dev/null +++ b/icmpmonitor.spec @@ -0,0 +1,31 @@ +Name: icmpmonitor +Summary: multiple host monitoring tool +Packager: Vadim Zaliva +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 index 0000000..ebc6691 --- /dev/null +++ b/install-sh @@ -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 index 0000000..271e571 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# 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 index 0000000..32a5128 --- /dev/null +++ b/sample.cfg @@ -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 -- 2.20.1