Browse Source

Initial import into CVS

Ethan Galstad 25 years ago
parent
commit
c861650004
15 changed files with 4394 additions and 0 deletions
  1. 104 0
      Changelog
  2. 32 0
      Makefile.in
  3. 151 0
      README
  4. 62 0
      common/common.h
  5. 144 0
      common/config.h.in
  6. 1969 0
      configure
  7. 52 0
      configure.in
  8. 250 0
      install-sh
  9. 70 0
      nrpe.cfg
  10. 35 0
      src/Makefile.in
  11. 259 0
      src/check_nrpe.c
  12. 319 0
      src/netutils.c
  13. 48 0
      src/netutils.h
  14. 863 0
      src/nrpe.c
  15. 36 0
      src/nrpe.h

+ 104 - 0
Changelog

@@ -0,0 +1,104 @@
+**************
+NRPE Changelog
+**************
+
+1.3 - 06/23/2001
+----------------
+- Name change
+- Version number change
+
+
+1.2.3 - 12/21/2000
+------------------
+- A bit more documentation on configuring command definitions for the plugin
+
+
+1.2.2 - 06/05/2000
+------------------
+- Fixed error in docs for running under inetd using TCP wrappers
+- Replaced old email address in src/netutils.h with new one
+
+
+1.2.1 - 05/07/2000
+------------------
+- Removed trapping of SIGCHLD
+- Changed wait4() to waitpid() to allow compilation on HP-UX and AIX
+
+
+1.2.0 - 04/18/2000
+------------------
+- Server forks twice after accepting a client connection, so as to prevent the
+  creation of zombies
+
+
+1.1.5 - 04/07/2000
+------------------
+- Fixed a small bug where one debug message was not getting logged properly
+
+
+1.1.4 - 03/30/2000
+------------------
+- Added option to disable/enable debug messages using the debug option in the
+  config file
+
+
+1.1.3 - 03/11/2000
+------------------
+- Changed config file to use an absolute path
+- Changed all debug output to use syslog (Rene Klootwijk)
+- No convert all data to network order before sending it and convert it back to
+  host order when receiving it. This makes it possible to mix Solaris and Linux,  
+  e.g. running check_nrpe on Linux and nrpe on Solaris. (Rene Klootwijk)
+
+
+1.1.2 - 03/07/2000
+------------------
+- Removed unnecessary code in signal handler routine
+- Unused signals are no longer trapper
+
+
+1.1.1 - 02/28/2000 - RKL
+---------------------------
+- Modified syslog code to include string describing the error code.
+- Changed hardcoded number in signal handler to its name. This prevented nrpe
+  to run on Solaris.
+- Fixed race condition in accept loop. The result of accept should also be
+  checked for EINTR.
+- Modified recv and send function calls to compile without warnings on Solaris.
+- Modified configure.in,configure and Makefile.in to include nsl and socket libs
+  for Solaris.
+- Modified the signal handler to reestablish itself after being called.
+
+
+
+1.1 - 02/24/2000 - Rene Klootwijk <rene@klootwijk.org>
+-----------------
+- Added ability to bind nrpe to a specific interface by specifying the address
+  of this interface in the nrpe.cfg file (e.g. server_address=192.168.2.3)
+
+
+1.0   - 02/16/2000
+------------------
+- Added ability to run as a service under inetd
+
+
+1.0b6 - 02/01/2000
+------------------
+- Added configure script
+- Netutils functions from the plugins is now used
+- Reset SIGCHLD to default behavior before calling popen() to
+  prevent race condition with pclose() (Reported by Rene Klootwijk)
+- Cleaned up code
+
+
+1.0b5 - 01/10/2000
+------------------
+- Added init script contributed by Jacob L
+- Incorporated syslog code and other patches contributed by Jacob L
+
+
+1.0b4 - 11/04/1999
+------------------
+- Changed 'allowed_ip' option in configuration file to
+  'allowed_hosts' and added support for multiple hosts
+- Minor buffer overflow protection fixes

+ 32 - 0
Makefile.in

@@ -0,0 +1,32 @@
+###############################
+# Makefile for NRPE
+#
+# Last Modified: 01/21/2000
+###############################
+
+
+# Source code directories
+SRC_BASE=./src/
+SRC_COMMON=./common/
+
+all:	nrpe check_nrpe	
+
+nrpe:
+	cd $(SRC_BASE); $(MAKE) ; cd ..
+
+check_nrpe:
+	cd $(SRC_BASE); $(MAKE) ; cd ..
+
+
+clean:
+	cd $(SRC_BASE); $(MAKE) $@ ; cd ..
+	rm -f core
+
+distclean: clean
+	cd $(SRC_BASE); $(MAKE) $@ ; cd ..
+	rm -f config.log config.status config.cache Makefile \
+	$(SRC_COMMON)/config.h \
+
+devclean: distclean
+	rm -f *~ */*~
+

+ 151 - 0
README

@@ -0,0 +1,151 @@
+***********
+NRPE README
+***********
+
+
+Purpose
+-------
+The purpose of this addon is to allow you to execute Nagios
+plugins on a remote host in as transparent a manner as possible.
+
+
+Contents
+--------
+
+There are two pieces to this addon:
+
+  1) NRPE       - This program runs as a background process on the 
+                  remote host and processes command execution requests
+	          from the check_nrpe plugin on the Nagios host.
+		  Upon receiving a plugin request from an authorized
+                  host, it will execute the command line associated
+                  with the command name it received and send the
+                  program output and return code back to the 
+                  check_nrpe plugin
+
+  2) check_nrpe - This is a plugin that is run on the Nagios host
+                  and is used to contact the NRPE process on remote
+	          hosts.  The plugin requests that a plugin be
+                  executed on the remote host and wait for the NRPE
+                  process to execute the plugin and return the result.
+                  The plugin then uses the output and return code
+                  from the plugin execution on the remote host for
+                  its own output and return code.
+
+
+Compiling
+---------
+
+The code is very basic and may not work on your particular
+system without some tweaking.  I just haven't put a lot of effort
+into this addond.  Most Linux users should be able to compile
+NRPE and the check_nrpe plugin with the following commands...
+
+./configure
+make all
+
+The binaries will be located in the src/ directory after you
+run 'make all' and will have to be installed manually somewhere
+on your system.
+
+
+NOTE: Since the check_nrpe plugin and nrpe daemon run on different
+      machines (the plugin runs on the Nagios host and the daemon
+      runs on the remote host), you will have to compile the nrpe
+      daemon on the target machine.
+
+
+
+Installing
+----------
+
+The check_nrpe plugin should be placed on the Nagios host along
+with your other plugins.  In most cases, this will be in the
+/usr/local/nagios/libexec directory.
+
+The nrpe program and the configuration file (nrpe.cfg) should
+be placed somewhere on the remote host.  Note that you will also
+have to install some plugins on the remote host if you want to
+make much use of this addon.
+
+
+
+Running Under INETD
+-------------------
+
+If you plan on running nrpe under inetd and making use of TCP
+wrappers, you need to do two things:
+
+1) Add a line to your /etc/services file as follows (modify the port
+   number as you see fit)
+
+	nrpe            5666/tcp	# NRPE
+
+2) Add an entry to /etc/inetd.conf as follows
+
+	nrpe 	stream 	tcp 	nowait 	<user> /usr/sbin/tcpd <nrpebin> -i <nrpecfg>
+
+   - Replace <user> with the name of the user that nrpe should run as
+	Example: nagios
+   - Replace <nrpebin> with the path to the nrpe binary on your system.
+	Example: /usr/local/nagios/nrpe
+   - Replace <nrpecfg> with the path to the nrpe config file on your system.
+	Example: /usr/local/nagios/nrpe.cfg
+
+3) Restart inetd will the following command
+
+	/etc/rc.d/init.d/inet restart
+
+4) Add entries to your /etc/hosts.allow and /etc/hosts.deny
+   file to enable TCP wrapper protection for the nrpe service.
+   This is optional, although highly recommended.
+
+
+Note: If you run nrpe under inetd, the server_port and 
+      allowed_hosts variables in the nrpe.cfg configuration 
+      file are ignored.
+
+
+
+Configuring Things On The Nagios Host
+---------------------------------------
+
+Examples for configuring the nrpe daemon are found in the sample
+nrpe.cfg file included in this distribution.  That config file
+resides on the remote host(s) along with the nrpe daemon.  The
+check_nrpe plugin gets installed on the Nagios host.  In order
+to use the check_nrpe plugin from within Nagios, you'll have
+to define a few things in the host config file.  An example
+command definition for the check_nrpe plugin would look like this:
+
+command[check_nrpe]=/usr/local/nagios/libexec/check_nrpe $HOSTADDRESS$ -c $ARG1$
+
+In any service definitions that use the nrpe plugin/daemon to
+get their results, you would set the service check command portion
+of the definition to something like this:
+
+check_nrpe!yourcommand
+
+where "yourcommand" is a name of a command that you define in 
+your nrpe.cfg file on the remote host (see the docs in the 
+sample nrpe.cfg file for more information).
+
+
+
+
+Questions?
+----------
+
+If you have questions about this addon, or problems getting things
+working, first try searching the nagios-users mailing list archives.
+Details on searching the list archives can be found at 
+http://www.nagios.org
+
+If all else fails, you can email me and I'll try and respond as
+soon as I get a chance.
+
+	-- Ethan Galstad (nagios@nagios.org)
+
+
+
+

+ 62 - 0
common/common.h

@@ -0,0 +1,62 @@
+/************************************************************************
+ *
+ * COMMON.H - NRPE Common Include File
+ * Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
+ * Last Modified: 06-23-2001
+ *
+ * License:
+ *
+ * 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.
+ ************************************************************************/
+
+
+#define OK		0
+#define ERROR		-1
+
+#define TRUE		1
+#define FALSE		0
+
+#define	STATE_CRITICAL 	2	/* service state return codes */
+#define STATE_WARNING 	1
+#define STATE_OK       	0
+#define STATE_UNKNOWN  	-1
+
+
+#define DEFAULT_SOCKET_TIMEOUT	10	/* timeout after 10 seconds */
+#define DEFAULT_SERVER_PORT	5666	/* default port to use */
+
+#define MAX_INPUT_BUFFER	2048	/* max size of most buffers we use */
+
+#define MAX_HOST_ADDRESS_LENGTH	256	/* max size of a host address */
+
+#define NRPE_HELLO_COMMAND      "_NRPE_CHECK"
+
+
+/**************** PACKET STRUCTURE DEFINITION **********/
+
+#define QUERY_PACKET		1		/* id code for a packet containing a query */
+#define	RESPONSE_PACKET		2		/* id code for a packet containing a response */
+
+#define NRPE_PACKET_VERSION_1	1		/* packet version identifier (in case packet type changes in future versions) */
+
+#define MAX_PACKETBUFFER_LENGTH	1024		/* max amount of data we'll send in one query/response */
+
+typedef struct packet_struct{
+	int packet_type;
+	int packet_version;
+	int result_code;
+	int buffer_length;
+	char buffer[MAX_PACKETBUFFER_LENGTH];
+        }packet;

+ 144 - 0
common/config.h.in

@@ -0,0 +1,144 @@
+/************************************************************************
+ *
+ * NRPE Common Header File
+ * Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
+ * Last Modified: 06-23-2001
+ *
+ * License:
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+
+
+#undef STDC_HEADERS
+#undef HAVE_SYSLOG_H
+#undef HAVE_STRDUP
+#undef HAVE_STRSTR
+#undef HAVE_STRTOUL 
+#undef HAVE_LIMITS_H
+#undef HAVE_SYS_RESOURCE_H
+
+
+#define SOCKET_SIZE_TYPE ""
+#define GETGROUPS_T ""
+#define RETSIGTYPE ""
+
+#undef HAVE_STRINGS_H
+#undef HAVE_STRING_H
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#include <string.h>
+#endif
+
+#undef HAVE_UNISTD_H
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+
+#undef HAVE_SIGNAL_H
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#undef HAVE_SYSLOG_H
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+#undef HAVE_SYS_STAT_H
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#undef HAVE_FCNTL_H
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#undef HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#undef HAVE_SYS_WAIT_H
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+#undef HAVE_ERRNO_H
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+/* needed for the time_t structures we use later... */
+#undef TIME_WITH_SYS_TIME
+#undef HAVE_SYS_TIME_H
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+
+#undef HAVE_SYS_SOCKET_H
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#undef HAVE_SOCKET
+#ifdef HAVE_SOCKET_H
+#include <socket.h>
+#endif
+
+#undef HAVE_NETINET_IN_H
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#undef HAVE_ARPA_INET_H
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#undef HAVE_NETDB_H
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#undef HAVE_CTYPE_H
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+
+

+ 1969 - 0
configure

@@ -0,0 +1,1969 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12 
+# 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:
+ac_default_prefix=/usr/local/netsaint
+
+# 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=
+# 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.12"
+    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=src/nrpe.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 $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+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
+
+
+
+
+
+
+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
+# 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:557: 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="${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.
+      for ac_prog in ginstall installbsd 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.
+	    # OSF/1 installbsd also uses dspmsg, but is usable.
+	    :
+	  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_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+
+# 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:611: 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="${IFS}:"
+  for ac_dir in $PATH; 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:640: 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="${IFS}:"
+  ac_prog_rejected=no
+  for ac_dir in $PATH; 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
+
+  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:688: 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 $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 698 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; 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*
+
+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:722: 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:727: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:736: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+  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:751: 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
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-O2"
+  fi
+else
+  GCC=
+  test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:779: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+	@echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:807: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 822 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:828: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 839 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:845: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+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*
+  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:868: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 873 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:881: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 898 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 916 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 937 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:948: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./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
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:972: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 977 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:986: \"$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 for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:1007: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1012 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:1028: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_sys_wait_h=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+for ac_hdr in ctype.h errno.h fcntl.h netdb.h signal.h strings.h string.h syslog.h unistd.h arpa/inet.h netinet/in.h sys/types.h sys/time.h sys/resource.h sys/wait.h sys/socket.h sys/stat.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1052: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1057 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1062: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1090: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1095 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1144: \"$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 whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:1165: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1170 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:1178: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_struct_tm=time.h
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+  cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking for mode_t""... $ac_c" 1>&6
+echo "configure:1199: checking for mode_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1204 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_mode_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_mode_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_mode_t" 1>&6
+if test $ac_cv_type_mode_t = no; then
+  cat >> confdefs.h <<\EOF
+#define mode_t int
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:1232: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1237 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_pid_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+  cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1265: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1270 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "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 return type of signal handlers""... $ac_c" 1>&6
+echo "configure:1298: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1303 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:1320: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_type_signal=void
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:1339: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1344 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uid_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_uid_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+  cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
+echo "configure:1373: checking type of array argument to getgroups" >&5
+if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_type_getgroups=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1381 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Rendell for this test.  */
+#include <sys/types.h>
+#define NGID 256
+#undef MAX
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+main()
+{
+  gid_t gidset[NGID];
+  int i, n;
+  union { gid_t gval; long lval; }  val;
+
+  val.lval = -1;
+  for (i = 0; i < NGID; i++)
+    gidset[i] = val.gval;
+  n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
+                 gidset);
+  /* Exit non-zero if getgroups seems to require an array of ints.  This
+     happens when gid_t is short but getgroups modifies an array of ints.  */
+  exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
+}
+
+EOF
+if { (eval echo configure:1406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+    ac_cv_type_getgroups=gid_t
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_type_getgroups=int
+fi
+rm -fr conftest*
+fi
+
+if test $ac_cv_type_getgroups = cross; then
+        cat > conftest.$ac_ext <<EOF
+#line 1420 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_getgroups=gid_t
+else
+  rm -rf conftest*
+  ac_cv_type_getgroups=int
+fi
+rm -f conftest*
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_type_getgroups" 1>&6
+cat >> confdefs.h <<EOF
+#define GETGROUPS_T $ac_cv_type_getgroups
+EOF
+
+
+
+echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
+echo "configure:1445: checking for main in -lnsl" >&5
+ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1453 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:1460: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; 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
+  SOCKETLIBS="$SOCKETLIBS -lnsl"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
+echo "configure:1481: checking for socket in -lsocket" >&5
+ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsocket  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1489 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:1500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; 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
+  SOCKETLIBS="$SOCKETLIBS -lsocket"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+for ac_func in strdup strstr strtoul
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1524: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1529 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1552: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for type of socket size""... $ac_c" 1>&6
+echo "configure:1578: checking for type of socket size" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1580 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int main() {
+int a = send(1, (const void *) buffer, (size_t *) 0, (int *) 0);
+; return 0; }
+EOF
+if { (eval echo configure:1590: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cat >> confdefs.h <<\EOF
+#define SOCKET_SIZE_TYPE size_t
+EOF
+ echo "$ac_t""size_t" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cat >> confdefs.h <<\EOF
+#define SOCKET_SIZE_TYPE int
+EOF
+ echo "$ac_t""int" 1>&6
+fi
+rm -f conftest*
+
+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) 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
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.12"
+    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 src/Makefile common/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%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%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@INSTALL@%$INSTALL%g
+s%@CC@%$CC%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CPP@%$CPP%g
+s%@SOCKETLIBS@%$SOCKETLIBS%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile src/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="common/config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; 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
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # 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"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+
+
+
+
+
+

+ 52 - 0
configure.in

@@ -0,0 +1,52 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(src/nrpe.c)
+AC_CONFIG_HEADER(common/config.h)
+AC_PREFIX_DEFAULT(/usr/local/nnagios)
+
+dnl Figure out how to invoke "install" and what install options to use.
+
+AC_PROG_INSTALL
+AC_SUBST(INSTALL)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_MAKE_SET
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_TIME
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(ctype.h errno.h fcntl.h netdb.h signal.h strings.h string.h syslog.h unistd.h arpa/inet.h netinet/in.h sys/types.h sys/time.h sys/resource.h sys/wait.h sys/socket.h sys/stat.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_STRUCT_TM
+AC_TYPE_MODE_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_SIGNAL
+AC_TYPE_GETGROUPS
+
+dnl Checks for library functions.
+AC_CHECK_LIB(nsl,main,SOCKETLIBS="$SOCKETLIBS -lnsl")
+AC_CHECK_LIB(socket,socket,SOCKETLIBS="$SOCKETLIBS -lsocket")
+AC_SUBST(SOCKETLIBS)
+AC_CHECK_FUNCS(strdup strstr strtoul)
+
+AC_MSG_CHECKING(for type of socket size)
+AC_TRY_COMPILE([#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+],
+[int a = send(1, (const void *)0, (size_t *) 0, (int *) 0);],
+[AC_DEFINE(SOCKET_SIZE_TYPE, size_t) AC_MSG_RESULT(size_t)],
+[AC_DEFINE(SOCKET_SIZE_TYPE, int) AC_MSG_RESULT(int)])
+
+AC_OUTPUT(Makefile src/Makefile)
+
+
+
+
+
+
+

+ 250 - 0
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

+ 70 - 0
nrpe.cfg

@@ -0,0 +1,70 @@
+####################################################
+# Sample NRPE Config File 
+# Written by: Ethan Galstad (nagios@nagios.org)
+# 
+# Last Modified: 06/23/2001
+####################################################
+
+
+
+# PORT NUMBER
+# Port number we should wait for connections on.
+# This must be a non-priveledged port (i.e. > 1024).
+
+server_port=5666
+
+
+
+# SERVER ADDRESS
+# Address that nrpe has to bind to in case there are
+# more as one interface and we do not want nrpe to bind
+# (thus listen) on all interfaces.
+
+#server_address=192.168.1.1
+
+
+
+# ALLOWED HOST ADDRESSES
+# This is a comma-delimited list of IP address of hosts that are allowed
+# to talk to the NRPE daemon.
+#
+# Note: The daemon only does rudimentary checking of the client's IP
+# address.  I would highly recommend adding entries in your /etc/hosts.allow
+# file to allow only the specified host to connect to the port
+# you are running this daemon on.
+
+allowed_hosts=127.0.0.1,192.168.0.2
+
+
+
+# DEBUGGING OPTION
+# This option determines whether or not debugging
+# messages are logged to the syslog facility. 0=off, 1=on
+
+debug=0
+
+
+
+# COMMAND DEFINITIONS
+# Command definitions that this daemon will run.  Definitions
+# are in the following format:
+#
+# command[<command_name>]=<command_line>
+#
+# When the daemon receives a request to return the results of <command_name>
+# it will execute the command specified by the <command_line> argument.
+#
+# Unlike Nagios, the command line cannot contain macros - it must be
+# typed exactly as it should be executed.
+#
+# Note: Any plugins that are used in the command lines must reside
+# on the machine that this daemon is running on!  The examples below
+# assume that you have plugins installed in a /usr/local/nagios/libexec
+# directory.
+
+command[check_users]=/usr/local/nagios/libexec/check_users 5 10
+command[check_load]=/usr/local/nagios/libexec/check_load 5 10 15 20 25 30
+command[check_disk1]=/usr/local/nagios/libexec/check_disk 80 95 /dev/hda1
+command[check_disk2]=/usr/local/nagios/libexec/check_disk 80 95 /dev/hdb1
+command[check_zombie_procs]=/usr/local/nagios/libexec/check_procs 5 10 Z
+command[check_total_procs]=/usr/local/nagios/libexec/check_procs 150 200 

+ 35 - 0
src/Makefile.in

@@ -0,0 +1,35 @@
+###############################
+# Makefile for NRPE
+#
+# Last Modified: 06/23/2001
+###############################
+
+
+# Source code directories
+SRC_COMMON=../common
+
+CC=@CC@
+CFLAGS=@CFLAGS@ @DEFS@
+LDFLAGS=@LDFLAGS@ @LIBS@
+SOCKETLIBS=@SOCKETLIBS@
+
+CP=@CP@
+
+
+all: nrpe check_nrpe
+
+nrpe: nrpe.c nrpe.h netutils.c netutils.h $(SRC_COMMON)/common.h $(SRC_COMMON)/config.h
+	$(CC) $(CFLAGS) $(LDFLAGS) $(SOCKETLIBS) nrpe.c netutils.c -o $@
+
+check_nrpe: check_nrpe.c netutils.c netutils.h $(SRC_COMMON)/common.h $(SRC_COMMON)/config.h
+	$(CC) $(CFLAGS) $(LDFLAGS) $(SOCKETLIBS) check_nrpe.c netutils.c -o $@
+
+clean:
+	rm -f core \
+	nrpe check_nrpe
+
+distclean: clean
+	rm -f Makefile
+
+devclean: distclean
+	rm -f *~ */*~

+ 259 - 0
src/check_nrpe.c

@@ -0,0 +1,259 @@
+/********************************************************************************************
+ *
+ * CHECK_NRPE.C
+ *
+ * Program: NRPE plugin for Nagios
+ * License: GPL
+ * Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
+ *
+ * Version: 1.3
+ * Last Modified: 06-23-2001
+ *
+ * Command line: CHECK_NRPE <host_address> [-p port] [-c command] [-wt warn_time] \
+ *                          [-ct crit_time] [-to to_sec]
+ *
+ * Description:
+ *
+ * This plugin will attempt to connect to the Nagios remote plugin executor daemon on the
+ * specified server and port.  The daemon will attempt to run the command defined as
+ * [command].  Program output and return code are sent back from the daemon and displayed
+ * as this plugin's own output and return code.
+ *
+ ********************************************************************************************/
+
+#include "../common/common.h"
+#include "../common/config.h"
+#include "netutils.h"
+
+
+#define PROGRAM_VERSION "1.3"
+#define MODIFICATION_DATE "06-23-2001"
+
+#define DEFAULT_NRPE_COMMAND	"_NRPE_CHECK"  /* check version of NRPE daemon */
+
+time_t start_time,end_time;
+
+int server_port=DEFAULT_SERVER_PORT;
+char server_name[MAX_HOST_ADDRESS_LENGTH];
+
+char query_string[MAX_PACKETBUFFER_LENGTH]=DEFAULT_NRPE_COMMAND;;
+int socket_timeout=DEFAULT_SOCKET_TIMEOUT;
+
+int warning_time=0;
+int check_warning_time=FALSE;
+int critical_time=0;
+int check_critical_time=FALSE;
+
+
+int process_arguments(int,char **);
+void alarm_handler(int);
+
+
+
+
+int main(int argc, char **argv){
+	int sd;
+	int rc;
+	int result;
+	packet send_packet;
+	packet receive_packet;
+
+	result=process_arguments(argc,argv);
+
+	if(result!=OK){
+
+		printf("Incorrect command line arguments supplied\n");
+		printf("\n");
+		printf("NRPE Plugin for Nagios\n");
+		printf("Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)\n");
+		printf("Version: %s\n",PROGRAM_VERSION);
+		printf("Last Modified: %s\n",MODIFICATION_DATE);
+		printf("License: GPL\n");
+		printf("\n");
+		printf("Usage: %s <host_address> [-p port] [-c command] [-wt warn_time]\n",argv[0]);
+		printf("          [-ct crit_time] [-to to_sec]\n");
+		printf("\n");
+		printf("Options:\n");
+		printf(" <host_address> = The IP address of the host running the NRPE daemon\n");
+		printf(" [port]         = The port on which the daemon is running - default is %d\n",DEFAULT_SERVER_PORT);
+		printf(" [command]      = The name of the command that the remote daemon should run\n");
+		printf(" [warn_time]    = Response time in seconds necessary to result in a warning\n");
+		printf("                  status\n");
+		printf(" [crit_time]    = Response time in seconds necessary to result in a critical\n");
+		printf("                  status\n");
+		printf(" [to_sec]       = Number of seconds before connection attempt times out.\n");
+		printf("                  Default timeout is %d seconds\n",DEFAULT_SOCKET_TIMEOUT);
+		printf("\n");
+		printf("Note:\n");
+		printf("This plugin requires that you have the NRPE daemon running on the remote host.\n");
+		printf("You must also have configured the daemon to associate a specific plugin command\n");
+		printf("with the [command] option you are specifying here.  Upon receipt of the\n");
+		printf("[command] argument, the NRPE daemon will run the appropriate plugin command and\n");
+		printf("send the plugin output and return code back to *this* plugin.  This allows you\n");
+		printf("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n");
+		printf("the plugin is being run locally.\n");
+		printf("\n");
+
+		return STATE_UNKNOWN;
+	        }
+
+	/* initialize alarm signal handling */
+	signal(SIGALRM,alarm_handler);
+
+	/* set socket timeout */
+	alarm(socket_timeout);
+
+	time(&start_time);
+
+	/* try to connect to the host at the given port number */
+	result=my_tcp_connect(server_name,server_port,&sd);
+
+	/* we connected, so close connection before exiting */
+	if(result==STATE_OK){
+
+		/* send the query packet */
+		bzero(&send_packet,sizeof(send_packet));
+		send_packet.packet_type=htonl(QUERY_PACKET);
+		send_packet.packet_version=htonl(NRPE_PACKET_VERSION_1);
+		send_packet.buffer_length=htonl(strlen(query_string));
+		strcpy(&send_packet.buffer[0],query_string);
+
+		rc=send(sd,(void *)&send_packet,sizeof(send_packet),0);
+
+		if(rc==-1){
+			printf("CHECK_NRPE: Error sending query to host\n");
+			close(sd);
+			return STATE_UNKNOWN;
+		        }
+
+		/* wait for the response packet */
+		bzero(&receive_packet,sizeof(receive_packet));
+		rc=recv(sd,(void *)&receive_packet,sizeof(receive_packet),0);
+
+		if(rc==-1){
+			printf("CHECK_NRPE: Error receiving data from host\n");
+			close(sd);
+			return STATE_UNKNOWN;
+		        }
+
+		else if(rc==0){
+			printf("CHECK_NRPE: Received 0 bytes. Is this host authorized to connect with nrpe daemon?\n");
+			close(sd);
+			return STATE_UNKNOWN;
+		        }
+
+		else if(rc<sizeof(receive_packet)){
+			printf("CHECK_NRPE: Receive underflow.  Only %d bytes received (%d expected).\n",rc,sizeof(receive_packet));
+			close(sd);
+			return STATE_UNKNOWN;
+		        }
+
+		time(&end_time);
+
+		result=STATE_OK;
+
+		if(check_critical_time==TRUE && (end_time-start_time)>critical_time)
+			result=STATE_CRITICAL;
+		else if(check_warning_time==TRUE && (end_time-start_time)>warning_time)
+			result=STATE_WARNING;
+
+		if(result!=STATE_OK)
+			printf("CHECK_NRPE problem - %d second response time: ",(int)(end_time-start_time));
+
+		/* get the return code from the remote plugin */
+		result=ntohl(receive_packet.result_code);
+
+		/* make sure there is something in the plugin output buffer */
+		if(!strcmp(receive_packet.buffer,""))
+			printf("CHECK_NRPE: No output returned from NRPE daemon.\n");
+		else
+			printf("%s\n",receive_packet.buffer);
+
+		/* close the connection */
+		close(sd);
+	        }
+
+	/* reset the alarm */
+	alarm(0);
+
+	return result;
+        }
+
+
+
+/* process command line arguments */
+int process_arguments(int argc, char **argv){
+	int x;
+
+
+	/* no options were supplied */
+	if(argc<2)
+		return ERROR;
+
+	/* first option is always the server name/address */
+	strncpy(server_name,argv[1],sizeof(server_name)-1);
+	server_name[sizeof(server_name)-1]='\x0';
+
+	/* process all remaining arguments */
+	for(x=3;x<=argc;x++){
+
+		if(!strcmp(argv[x-1],"-c")){
+			if(x<argc){
+				strncpy(query_string,argv[x],sizeof(query_string)-1);
+				query_string[sizeof(query_string)-1]='\x0';
+				x++;
+			        }
+			else
+				return ERROR;
+		        }
+		else if(!strcmp(argv[x-1],"-p")){
+			if(x<argc){
+				server_port=atoi(argv[x]);
+				x++;
+			        }
+			else
+				return ERROR;
+		        }
+		else if(!strcmp(argv[x-1],"-to")){
+			if(x<argc){
+				socket_timeout=atoi(argv[x]);
+				if(socket_timeout<=0)
+					return ERROR;
+				x++;
+			        }
+			else
+				return ERROR;
+		        }
+		else if(!strcmp(argv[x-1],"-wt")){
+			if(x<argc){
+				warning_time=atoi(argv[x]);
+				check_warning_time=TRUE;
+				x++;
+			        }
+			else
+				return ERROR;
+		        }
+		else if(!strcmp(argv[x-1],"-ct")){
+			if(x<argc){
+				critical_time=atoi(argv[x]);
+				check_critical_time=TRUE;
+				x++;
+			        }
+			else
+				return ERROR;
+		        }
+		else
+			return ERROR;
+	        }
+
+	return OK;
+        }
+
+
+
+void alarm_handler(int sig){
+
+	printf("CHECK_NRPE: Socket timeout after %d seconds\n",socket_timeout);
+
+	exit(STATE_CRITICAL);
+        }

+ 319 - 0
src/netutils.c

@@ -0,0 +1,319 @@
+/****************************************************************************
+ *
+ * NETUTILS.C - NRPE Network Utilities
+ * Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
+ * License: GPL
+ * Last Modified: 06-23-2001
+ *
+ * Description:
+ *
+ * This file contains common network functions used in nrpe and check_nrpe.
+ *
+ * License Information:
+ *
+ * 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 "../common/common.h"
+#include "netutils.h"
+
+extern int socket_timeout;    /* this doesn't have to be used, but it is nice to know how many seconds we timed out after */
+
+extern int errno;
+
+
+/* handles socket timeouts */
+void socket_timeout_alarm_handler(int sig){
+
+	printf("Socket timeout after %d seconds\n",socket_timeout);
+
+	exit(STATE_CRITICAL);
+        }
+
+
+/* connects to a host on a specified TCP port, sends a string, and gets a response */
+int process_tcp_request(char *server_address, int server_port, char *send_buffer, char *recv_buffer, int recv_size){
+	int result;
+
+	result=process_request(server_address,server_port,"tcp",send_buffer,recv_buffer,recv_size);
+
+	return result;
+        }
+
+
+/* connects to a host on a specified UDP port, sends a string, and gets a response */
+int process_udp_request(char *server_address, int server_port, char *send_buffer, char *recv_buffer, int recv_size){
+	int result;
+
+	result=process_request(server_address,server_port,"udp",send_buffer,recv_buffer,recv_size);
+
+	return result;
+        }
+
+
+/* connects to a host on a specified port, sends a string, and gets a response */
+int process_request(char *server_address, int server_port, char *proto, char *send_buffer, char *recv_buffer, int recv_size){
+	int result;
+	int send_result;
+	int recv_result;
+	int sd;
+	struct timeval tv;
+	fd_set readfds;
+
+	result=STATE_OK;
+
+	result=my_connect(server_address,server_port,&sd,proto);
+	if(result!=STATE_OK)
+		return STATE_CRITICAL;
+
+	send_result=send(sd,send_buffer,strlen(send_buffer),0);
+	if(send_result!=strlen(send_buffer)){
+		printf("send() failed\n");
+		result=STATE_WARNING;
+	        }
+
+	/* wait up to the number of seconds for socket timeout minus one for data from the host */
+	tv.tv_sec=socket_timeout-1;
+	tv.tv_usec=0;
+	FD_ZERO(&readfds);
+	FD_SET(sd,&readfds);
+	select(sd+1,&readfds,NULL,NULL,&tv);
+
+	/* make sure some data has arrived */
+	if(!FD_ISSET(sd,&readfds)){
+		strcpy(recv_buffer,"");
+		printf("No data was recieved from host!\n");
+		result=STATE_WARNING;
+	        }
+
+	else{
+		recv_result=recv(sd,recv_buffer,recv_size-1,0);
+		if(recv_result==-1){
+			strcpy(recv_buffer,"");
+			if(!strcmp(proto,"tcp"))
+				printf("recv() failed\n");
+			result=STATE_WARNING;
+	                }
+		else
+			recv_buffer[recv_result]='\x0';
+
+		/* terminate returned string */
+		recv_buffer[recv_size-1]='\x0';
+	        }
+
+	close(sd);
+
+	return result;
+        }
+
+
+/* opens a connection to a remote host/tcp port */
+int my_tcp_connect(char *host_name,int port,int *sd){
+	int result;
+
+	result=my_connect(host_name,port,sd,"tcp");
+
+	return result;
+        }
+
+
+/* opens a connection to a remote host/udp port */
+int my_udp_connect(char *host_name,int port,int *sd){
+	int result;
+
+	result=my_connect(host_name,port,sd,"udp");
+
+	return result;
+        }
+
+
+/* opens a tcp or udp connection to a remote host */
+int my_connect(char *host_name,int port,int *sd,char *proto){
+	struct sockaddr_in servaddr;
+	struct hostent *hp;
+	struct protoent *ptrp;
+	int result;
+
+	bzero((char *)&servaddr,sizeof(servaddr));
+	servaddr.sin_family=AF_INET;
+	servaddr.sin_port=htons(port);
+
+	/* try to bypass using a DNS lookup if this is just an IP address */
+	if(!my_inet_aton(host_name,&servaddr.sin_addr)){
+
+		/* else do a DNS lookup */
+		hp=gethostbyname((const char *)host_name);
+		if(hp==NULL){
+			printf("Invalid host name '%s'\n",host_name);
+			return STATE_UNKNOWN;
+		        }
+
+		memcpy(&servaddr.sin_addr,hp->h_addr,hp->h_length);
+	        }
+
+	/* map transport protocol name to protocol number */
+	if(((int)(ptrp=getprotobyname(proto)))==(int)0){
+		printf("Cannot map \"%s\" to protocol number\n",proto);
+		return STATE_UNKNOWN;
+	        }
+
+	/* create a socket */
+	*sd=socket(PF_INET,(!strcmp(proto,"udp"))?SOCK_DGRAM:SOCK_STREAM,ptrp->p_proto);
+	if(*sd<0){
+		printf("Socket creation failed\n");
+		return STATE_UNKNOWN;
+	        }
+
+	/* open a connection */
+	result=connect(*sd,(struct sockaddr *)&servaddr,sizeof(servaddr));
+	if(result<0){
+		switch(errno){  
+		case ECONNREFUSED:
+			printf("Connection refused by host\n");
+			break;
+		case ETIMEDOUT:
+			printf("Timeout while attempting connection\n");
+			break;
+		case ENETUNREACH:
+			printf("Network is unreachable\n");
+			break;
+		default:
+			printf("Connection refused or timed out\n");
+		        }
+
+		return STATE_CRITICAL;
+	        }
+
+	return STATE_OK;
+        }
+
+
+
+/* This code was taken from Fyodor's nmap utility, which was originally taken from
+   the GLIBC 2.0.6 libraries because Solaris doesn't contain the inet_aton() funtion. */
+int my_inet_aton(register const char *cp, struct in_addr *addr){
+	register unsigned int val;	/* changed from u_long --david */
+	register int base, n;
+	register char c;
+	u_int parts[4];
+	register u_int *pp = parts;
+
+	c=*cp;
+
+	for(;;){
+
+		/*
+		 * Collect number up to ``.''.
+		 * Values are specified as for C:
+		 * 0x=hex, 0=octal, isdigit=decimal.
+		 */
+		if (!isdigit((int)c))
+			return (0);
+		val=0;
+		base=10;
+
+		if(c=='0'){
+			c=*++cp;
+			if(c=='x'||c=='X')
+				base=16,c=*++cp;
+			else
+				base=8;
+		        }
+
+		for(;;){
+			if(isascii((int)c) && isdigit((int)c)){
+				val=(val*base)+(c -'0');
+				c=*++cp;
+			        } 
+			else if(base==16 && isascii((int)c) && isxdigit((int)c)){
+				val=(val<<4) | (c+10-(islower((int)c)?'a':'A'));
+				c = *++cp;
+			        } 
+			else
+				break;
+		        }
+
+		if(c=='.'){
+
+			/*
+			 * Internet format:
+			 *	a.b.c.d
+			 *	a.b.c	(with c treated as 16 bits)
+			 *	a.b	(with b treated as 24 bits)
+			 */
+			if(pp>=parts+3)
+				return (0);
+			*pp++=val;
+			c=*++cp;
+		        } 
+		else
+			break;
+	        }
+
+	/* Check for trailing characters */
+	if(c!='\0' && (!isascii((int)c) || !isspace((int)c)))
+		return (0);
+
+	/* Concoct the address according to the number of parts specified */
+	n=pp-parts+1;
+	switch(n){
+
+	case 0:
+		return (0);		/* initial nondigit */
+
+	case 1:				/* a -- 32 bits */
+		break;
+
+	case 2:				/* a.b -- 8.24 bits */
+		if(val>0xffffff)
+			return (0);
+		val|=parts[0]<<24;
+		break;
+
+	case 3:				/* a.b.c -- 8.8.16 bits */
+		if(val>0xffff)
+			return (0);
+		val|=(parts[0]<< 24) | (parts[1]<<16);
+		break;
+
+	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
+		if(val>0xff)
+			return (0);
+		val|=(parts[0]<<24) | (parts[1]<<16) | (parts[2]<<8);
+		break;
+	        }
+
+	if(addr)
+		addr->s_addr=htonl(val);
+
+	return (1);
+        }
+
+
+void strip(char *buffer){
+	int x;
+	int index;
+
+	for(x=strlen(buffer);x>=1;x--){
+		index=x-1;
+		if(buffer[index]==' ' || buffer[index]=='\r' || buffer[index]=='\n' || buffer[index]=='\t')
+			buffer[index]='\x0';
+		else
+			break;
+	        }
+
+	return;
+        }

+ 48 - 0
src/netutils.h

@@ -0,0 +1,48 @@
+/************************************************************************************************
+ *
+ * NETUTILS.H - NRPE Network Function Header File
+ * Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
+ * Last Modified: 06-23-2001
+ *
+ * Description:
+ *
+ * This file contains common include files and function definitions used in many of the plugins.
+ *
+ * License Information:
+ *
+ * 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 "../common/config.h"
+
+void socket_timeout_alarm_handler(int);
+
+int process_tcp_request(char *address,int port,char *sbuffer,char *rbuffer,int rsize);
+int process_udp_request(char *address,int port,char *sbuffer,char *rbuffer,int rsize);
+int process_request(char *address,int port,char *proto,char *sbuffer,char *rbuffer,int rsize);
+
+int my_tcp_connect(char *address,int port,int *sd);
+int my_udp_connect(char *address,int port,int *sd);
+int my_connect(char *address,int port,int *sd,char *proto);
+
+int my_inet_aton(register const char *cp, struct in_addr *addr);
+
+void strip(char *);
+
+
+
+
+

+ 863 - 0
src/nrpe.c

@@ -0,0 +1,863 @@
+/*******************************************************************************
+ *
+ * NRPE.C - Nagios Remote Plugin Executor
+ * Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
+ * Version: 1.3
+ * License: GPL
+ *
+ * Last Modified: 06-23-2001
+ *
+ * Command line: nrpe [-i | -d] <config_file>
+ *
+ * Description:
+ *
+ * This program is designed to run as a background process and
+ * handle incoming requests (from the host running Nagios) for
+ * plugin execution.  It is useful for running "local" plugins
+ * such as check_users, check_load, check_disk, etc. without
+ * having to use rsh or ssh.
+ * 
+ * Modifications:
+ * 
+ * Vers 1.0b4-2   2000-01-03 jaclu@grm.se
+ * 
+ * main() returned STATE_UNKNOWN on successfull launch, changed to STATE_OK
+ * I also added syslog support
+ * 
+ ******************************************************************************/
+
+#include "../common/common.h"
+#include "../common/config.h"
+#include "nrpe.h"
+#include "netutils.h"
+
+
+#define PROGRAM_VERSION "1.3"
+#define MODIFICATION_DATE "06-23-2001"
+
+#define COMMAND_TIMEOUT		60			/* timeout for execution of plugins */
+
+char allowed_hosts[MAX_INPUT_BUFFER];
+int server_port=DEFAULT_SERVER_PORT;
+char server_address[16]="0.0.0.0";
+int socket_timeout=DEFAULT_SOCKET_TIMEOUT;
+command *command_list=NULL;
+
+void wait_for_connections(void);
+void handle_connection(int);
+int read_config_file(char *);
+int add_command(char *,char *);
+command *find_command(char *);
+void sighandler(int);
+void free_memory(void);
+int is_an_allowed_host(char *);
+
+int my_system(char *,int,int *,char *,int);            	/* executes a command via popen(), but also protects against timeouts */
+void my_system_sighandler(int);				/* handles timeouts when executing commands via my_system() */
+
+int use_inetd=TRUE;
+int debug=FALSE;
+
+
+
+int main(int argc, char **argv){
+	int error=FALSE;
+	int result;
+	char config_file[MAX_INPUT_BUFFER];
+	char buffer[MAX_INPUT_BUFFER];
+
+	/* check command line arguments */
+	if(argc!=3)
+		error=TRUE;
+	else{
+		if(!strcmp(argv[1],"-d"))
+			use_inetd=FALSE;
+		else if(!strcmp(argv[1],"-i"))
+			use_inetd=TRUE;
+		else
+			error=TRUE;
+	        }
+
+	if(error==TRUE){
+
+		printf("\n");
+		printf("NRPE - Nagios Remote Plugin Executor\n");
+		printf("Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)\n");
+		printf("Version: %s\n",PROGRAM_VERSION);
+		printf("Last Modified: %s\n",MODIFICATION_DATE);
+		printf("License: GPL\n");
+		printf("\n");
+		printf("Usage: %s <-i | -d> <config_file>\n",argv[0]);
+		printf("\n");
+		printf("Options:\n");
+		printf("  -i      Run as a service under inetd\n");
+		printf("  -d      Run as a standalone daemon without inetd\n");
+		printf("\n");
+		printf("Notes:\n");
+		printf("This program is designed to process requests from the check_nrpe\n");
+		printf("plugin on the host(s) running Nagios.  It can run as a service\n");
+		printf("under inetd (read the docs for info on this), or as a standalone\n");
+		printf("daemon if you wish. Once a request is received from an authorized\n");
+		printf("host, NRPE will execute the command/plugin (as defined in the\n");
+		printf("config file) and return the plugin output and return code to the\n");
+		printf("check_nrpe plugin.\n");
+		printf("\n");
+
+		exit(STATE_UNKNOWN);
+		}
+
+	/* open a connection to the syslog facility */
+        openlog("nrpe",LOG_PID,LOG_DAEMON); 
+
+	/* grab the config file */
+	strncpy(config_file,argv[2],sizeof(config_file)-1);
+	config_file[sizeof(config_file)-1]='\x0';
+
+	/* make sure the config file uses an absolute path */
+	if(config_file[0]!='/'){
+
+		/* save the name of the config file */
+		strncpy(buffer,config_file,sizeof(buffer));
+		buffer[sizeof(buffer)-1]='\x0';
+
+		/* get absolute path of current working directory */
+		strcpy(config_file,"");
+		getcwd(config_file,sizeof(config_file));
+
+		/* append a forward slash */
+		strncat(config_file,"/",sizeof(config_file)-2);
+		config_file[sizeof(config_file)-1]='\x0';
+
+		/* append the config file to the path */
+		strncat(config_file,buffer,sizeof(config_file)-strlen(config_file)-1);
+		config_file[sizeof(config_file)-1]='\x0';
+	        }
+
+	/* read the config file */
+	result=read_config_file(config_file);	
+
+	/* exit if there are errors... */
+	if(result==ERROR){
+		syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
+		return STATE_CRITICAL;
+		}
+
+	/* if we're running under inetd... */
+	if(use_inetd==TRUE)
+		handle_connection(0);
+
+	/* else daemonize and start listening for requests... */
+	else if(fork()==0){
+
+		/* wait for connections */
+		wait_for_connections();
+	        }
+
+	/* We are now running in daemon mode, or the connection handed over by inetd has
+	   been completed, so the parent process exits */
+        return STATE_OK;
+	}
+
+
+
+
+/* read in the configuration file */
+int read_config_file(char *filename){
+	FILE *fp;
+	char input_buffer[MAX_INPUT_BUFFER];
+	char *temp_buffer;
+	char *varname;
+	char *varvalue;
+	int line;
+
+
+	/* open the config file for reading */
+	fp=fopen(filename,"r");
+
+	/* exit if we couldn't open the config file */
+	if(fp==NULL)
+		return ERROR;
+
+	line=0;
+	while(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){
+
+		line++;
+
+		/* skip comments and blank lines */
+		if(input_buffer[0]=='#')
+			continue;
+		if(input_buffer[0]=='\x0')
+			continue;
+		if(input_buffer[0]=='\n')
+			continue;
+
+		/* get the variable name */
+		varname=strtok(input_buffer,"=");
+		if(varname==NULL){
+			syslog(LOG_ERR,"No variable name specified in config file '%s' - Line %d\n",filename,line);
+			return ERROR;
+		        }
+
+		/* get the variable value */
+		varvalue=strtok(NULL,"\n");
+		if(varvalue==NULL){
+			syslog(LOG_ERR,"No variable value specified in config file '%s' - Line %d\n",filename,line);
+			return ERROR;
+		        }
+
+		if(!strcmp(varname,"server_port")){
+			server_port=atoi(varvalue);
+			if(server_port<1024){
+				syslog(LOG_ERR,"Invalid port number specified in config file '%s' - Line %d\n",filename,line);
+				return ERROR;
+			        }
+		        }
+
+                else if(!strcmp(varname,"server_address")){
+                        strncpy(server_address,varvalue,sizeof(server_address) - 1);
+                        server_address[sizeof(server_address) - 1] = '\0';
+                        }
+
+		else if(!strcmp(varname,"allowed_hosts")){
+			if(strlen(input_buffer)>sizeof(allowed_hosts)){
+				syslog(LOG_ERR,"Allowed hosts list too long in config file '%s' - Line %d\n",filename,line);
+				return ERROR;
+			        }
+			strncpy(allowed_hosts,varvalue,sizeof(allowed_hosts));
+			allowed_hosts[sizeof(allowed_hosts)-1]='\x0';
+		        }
+
+		else if(strstr(input_buffer,"command[")){
+			temp_buffer=strtok(varname,"[");
+			temp_buffer=strtok(NULL,"]");
+			if(temp_buffer==NULL){
+				syslog(LOG_ERR,"Invalid command specified in config file '%s' - Line %d\n",filename,line);
+				return ERROR;
+			        }
+			add_command(temp_buffer,varvalue);
+		        }
+
+		else if(strstr(input_buffer,"debug")){
+			debug=atoi(varvalue);
+			if(debug>0)
+				debug=TRUE;
+			else 
+				debug=FALSE;
+		        }
+
+		else{
+			syslog(LOG_ERR,"Unknown option specified in config file '%s' - Line %d\n",filename,line);
+
+			return ERROR;
+		        }
+
+	        }
+
+
+	/* close the config file */
+	fclose(fp);
+
+	return OK;
+	}
+
+
+
+/* adds a new command definition from the config file to the list in memory */
+int add_command(char *command_name, char *command_line){
+	command *new_command;
+
+	/* allocate memory for the new command */
+	new_command=(command *)malloc(sizeof(command));
+	if(new_command==NULL)
+		return ERROR;
+
+	strcpy(new_command->command_name,command_name);
+	strcpy(new_command->command_line,command_line);
+
+	/* add new command to head of list in memory */
+	new_command->next=command_list;
+	command_list=new_command;
+
+	if(debug==TRUE)
+		syslog(LOG_DEBUG,"Added command[%s]=%s\n",command_name,command_line);
+
+	return OK;
+        }
+
+
+
+/* given a command name, find the structure in memory */
+command *find_command(char *command_name){
+	command *temp_command;
+
+	for(temp_command=command_list;temp_command!=NULL;temp_command=temp_command->next)
+		if(!strcmp(command_name,temp_command->command_name))
+			return temp_command;
+
+	return NULL;
+        }
+
+
+
+/* wait for incoming connection requests */
+void wait_for_connections(void){
+	struct sockaddr_in myname;
+	struct sockaddr_in *nptr;
+	struct sockaddr addr;
+	int rc;
+	int sock, new_sd, addrlen;
+	char connecting_host[16];
+	pid_t pid;
+	int flag=1;
+
+	/* create a socket for listening */
+	sock=socket(AF_INET,SOCK_STREAM,0);
+
+	/* exit if we couldn't create the socket */
+	if(sock<0){
+	        syslog(LOG_ERR,"Network server socket failure (%d: %s)",errno,strerror(errno));
+	        exit (STATE_CRITICAL);
+		}
+
+        /* set the reuse address flag so we don't get errors when restarting */
+        flag=1;
+        if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){
+		syslog(LOG_ERR,"Could not set reuse address option on socket!\n");
+		exit(STATE_UNKNOWN);
+	        }
+
+	myname.sin_family=AF_INET;
+	myname.sin_port=htons(server_port);
+ 	bzero(&myname.sin_zero,8);
+
+	/* what address should we bind to? */
+        if(!strlen(server_address))
+		myname.sin_addr.s_addr=INADDR_ANY;
+
+	else if(!my_inet_aton(server_address,&myname.sin_addr)){
+		syslog(LOG_ERR,"Server address is not a valid IP address\n");
+		exit (STATE_CRITICAL);
+                }
+
+
+	/* bind the address to the Internet socket */
+	if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){
+		syslog(LOG_ERR,"Network server bind failure (%d: %s)\n",errno,strerror(errno));
+	        exit (STATE_CRITICAL);
+	        }
+
+	/* open the socket for listening */
+	if(listen(sock,5)<0){
+	    	syslog(LOG_ERR,"Network server listen failure (%d: %s)\n",errno,strerror(errno));
+	        exit (STATE_CRITICAL);
+		}
+
+	/* log info to syslog facility */
+        syslog(LOG_NOTICE,"Starting up daemon");
+
+	/* Trap signals */
+	signal(SIGQUIT,sighandler);
+	signal(SIGTERM,sighandler);
+
+	if(debug==TRUE){
+		syslog(LOG_DEBUG,"Listening for connections on port %d\n",htons(myname.sin_port));
+		syslog(LOG_DEBUG,"Allowing connections from: %s\n",allowed_hosts);
+	        }
+
+	/* listen for connection requests - fork() if we get one */
+	while(1){
+
+		/* wait for a connection request */
+	        while(1){
+			new_sd=accept(sock,0,0);
+			if(new_sd>=0 || (errno!=EWOULDBLOCK && errno!=EINTR))
+				break;
+			sleep(1);
+		        }
+
+		/* hey, there was an error... */
+		if(new_sd<0){
+
+			/* log error to syslog facility */
+			syslog(LOG_ERR,"Network server accept failure (%d: %s)",errno,strerror(errno));
+
+			/* close socket prioer to exiting */
+			close(sock);
+
+			return;
+			}
+
+		/* child process should handle the connection */
+    		pid=fork();
+    		if(pid==0){
+
+			/* fork again so we don't create zombies */
+			pid=fork();
+			if(pid==0){
+
+				/* grandchild does not need to listen for connections, so close the socket */
+				close(sock);  
+
+				/* find out who just connected... */
+				addrlen=sizeof(addr);
+				rc=getpeername(new_sd,&addr,&addrlen);
+
+				if(rc<0){
+
+				        /* log error to syslog facility */
+					syslog(LOG_ERR,"Error: Network server getpeername() failure (%d: %s)",errno,strerror(errno));
+
+				        /* close socket prior to exiting */
+					close(new_sd);
+
+					return;
+		                        }
+
+				nptr=(struct sockaddr_in *)&addr;
+
+				/* log info to syslog facility */
+				if(debug==TRUE)
+					syslog(LOG_DEBUG,"Connection from %s port %d",inet_ntoa(nptr->sin_addr),nptr->sin_port);
+
+				/* is this is a blessed machine? */
+				snprintf(connecting_host,sizeof(connecting_host),"%s",inet_ntoa(nptr->sin_addr));
+				connecting_host[sizeof(connecting_host)-1]='\x0';
+
+				if(!is_an_allowed_host(connecting_host)){
+
+				        /* log error to syslog facility */
+					syslog(LOG_ERR,"Host %s is not allowed to talk to us!",connecting_host);
+			                }
+				else{
+
+				        /* log info to syslog facility */
+					if(debug==TRUE)
+						syslog(LOG_DEBUG,"Host address checks out ok");
+
+				        /* handle the client connection */
+					handle_connection(new_sd);
+			                }
+
+				/* log info to syslog facility */
+				if(debug==TRUE)
+					syslog(LOG_DEBUG,"Connection from %s closed.",connecting_host);
+
+				/* close socket prior to exiting */
+				close(new_sd);
+
+				return;
+    			        }
+
+			/* first child returns immediately, grandchild is inherited by INIT process -> no zombies... */
+			else
+				exit(STATE_OK);
+		        }
+		
+		/* parent ... */
+		else{
+			/* parent doesn't need the new connection */
+			close(new_sd);
+
+			/* parent waits for first child to exit */
+			waitpid(pid,NULL,0);
+		        }
+  		}
+
+	/* we shouldn't ever get here... */
+	syslog(LOG_NOTICE,"Terminating");
+
+	return;
+	}
+
+
+
+/* handles a client connection */
+void handle_connection(int sock){
+	command *temp_command;
+	packet receive_packet;
+	packet send_packet;
+	char buffer[MAX_INPUT_BUFFER];
+	int result=STATE_OK;
+	int early_timeout=FALSE;
+	int rc;
+	time_t current_time;
+	time_t start_time;
+
+
+	/* log info to syslog facility */
+	if(debug==TRUE)
+		syslog(LOG_DEBUG,"Handling the connection...");
+
+	/* socket should be non-blocking */
+	fcntl(sock,F_SETFL,O_NONBLOCK);
+
+	/* clear the request packet buffer */
+	bzero(&receive_packet,sizeof(receive_packet));
+
+	/* get the current time */
+	time(&start_time);
+
+	/* wait for the data from the client */
+	while(1){
+
+		/* read the packet */
+		rc=recv(sock,(void *)&receive_packet,sizeof(receive_packet),0);
+
+		/* we haven't received data, hang around for a bit more */
+		if(rc==-1 && errno==EAGAIN){
+			time(&current_time);
+			if(current_time-start_time>DEFAULT_SOCKET_TIMEOUT){
+				return;
+			        }
+			sleep(1);
+			continue;
+		        }
+
+		/* the client connection was closed */
+		else if(rc==0)
+			return;
+
+		/* there was an error receiving data... */
+		else if(rc==-1){
+
+			/* log error to syslog facility */
+			syslog(LOG_ERR,"Could not read request from client, bailing out...");
+
+			return;
+	                }
+
+		/* we couldn't read the correct amount of data, so bail out */
+		else if(rc!=sizeof(receive_packet)){
+
+			/* log error to syslog facility */
+			syslog(LOG_ERR,"Data packet from client was too short, bailing out...");
+
+			return;
+		        }
+
+		/* the packet looks good so far... */
+		else
+			break;
+	        }
+
+	/* make sure this is the right type of packet */
+	if(ntohl(receive_packet.packet_type)!=QUERY_PACKET || ntohl(receive_packet.packet_version)!=NRPE_PACKET_VERSION_1){
+
+		/* log error to syslog facility */
+		syslog(LOG_ERR,"Received invalid packet from client, bailing out...");
+
+		return;
+	        }
+
+	/* log info to syslog facility */
+	if(debug==TRUE)
+		syslog(LOG_DEBUG,"Host is asking for command '%s' to be run...",receive_packet.buffer);
+
+	/* if this is the version check command, just spew it out */
+	if(!strcmp(&receive_packet.buffer[0],NRPE_HELLO_COMMAND)){
+
+		snprintf(buffer,sizeof(buffer),"NRPE v%s",PROGRAM_VERSION);
+		buffer[sizeof(buffer)-1]='\x0';
+
+		/* log info to syslog facility */
+		if(debug==TRUE)
+			syslog(LOG_DEBUG,"Response: %s",buffer);
+
+		result=STATE_OK;
+	        }
+
+	/* find the command we're supposed to run */
+	else{
+		temp_command=find_command(receive_packet.buffer);
+		if(temp_command==NULL){
+
+			snprintf(buffer,sizeof(buffer),"NRPE: Command '%s' not defined",receive_packet.buffer);
+			buffer[sizeof(buffer)-1]='\x0';
+
+			/* log error to syslog facility */
+			if(debug==TRUE)
+				syslog(LOG_DEBUG,"%s",buffer);
+
+			result=STATE_CRITICAL;
+	                }
+
+		else{
+
+			/* log info to syslog facility */
+			if(debug==TRUE)
+				syslog(LOG_DEBUG,"Running command: %s",temp_command->command_line);
+
+			/* run the command */
+			strcpy(buffer,"");
+			result=my_system(temp_command->command_line,COMMAND_TIMEOUT,&early_timeout,buffer,sizeof(buffer));
+
+			/* see if the command timed out */
+			if(early_timeout==TRUE)
+				snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",COMMAND_TIMEOUT);
+			else if(!strcmp(buffer,""))
+				snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n");
+
+			buffer[sizeof(buffer)-1]='\x0';
+
+			/* check return code bounds */
+			if((result<-1) || (result>2)){
+
+				/* log error to syslog facility */
+				syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result);
+
+				result=STATE_UNKNOWN;
+			        }
+		        }
+	        }
+
+	/* strip newline character from end of output buffer */
+	if(buffer[strlen(buffer)-1]=='\n')
+		buffer[strlen(buffer)-1]='\x0';
+
+	/* clear the response packet buffer */
+	bzero(&send_packet,sizeof(send_packet));
+
+	/* fill the response packet with data */
+	send_packet.packet_type=htonl(RESPONSE_PACKET);
+	send_packet.packet_version=htonl(NRPE_PACKET_VERSION_1);
+	send_packet.result_code=htonl(result);
+	send_packet.buffer_length=htonl(strlen(buffer));
+	strncpy(&send_packet.buffer[0],buffer,sizeof(send_packet.buffer));
+	send_packet.buffer[sizeof(send_packet.buffer)-1]='\x0';
+	
+	/* send the response back to the client */
+	send(sock,(void *)&send_packet,sizeof(send_packet),0);
+
+	/* log info to syslog facility */
+	if(debug==TRUE)
+		syslog(LOG_DEBUG,"Return Code: %d, Output: %s",result,buffer);
+
+	return;
+        }
+
+
+
+/* checks to see if a given host is allowed to talk to us */
+int is_an_allowed_host(char *connecting_host){
+	char temp_buffer[MAX_INPUT_BUFFER];
+	char *temp_ptr;
+
+	strncpy(temp_buffer,allowed_hosts,sizeof(temp_buffer));
+	temp_buffer[sizeof(temp_buffer)-1]='\x0';
+
+	for(temp_ptr=strtok(temp_buffer,",");temp_ptr!=NULL;temp_ptr=strtok(NULL,",")){
+		if(!strcmp(connecting_host,temp_ptr))
+			return 1;
+	        }
+
+	return 0;
+        }
+
+
+
+/* handle signals */
+void sighandler(int sig){
+
+	/* free all memory we allocated */
+	free_memory();
+	
+	/* terminate... */
+	exit(0);
+
+	/* so the compiler doesn't complain.. */
+	return;
+        }
+
+
+
+/* free all allocated memory */
+void free_memory(void){
+	command *this_command;
+	command *next_command;
+	
+	/* free memory for the command list */
+	this_command=command_list;
+	while(this_command!=NULL){
+		next_command=this_command->next;
+		free(this_command);
+		this_command=next_command;
+	        }
+
+	return;
+        }
+
+
+
+
+/* executes a system command via popen(), but protects against timeouts */
+int my_system(char *command,int timeout,int *early_timeout,char *output,int output_length){
+        pid_t pid;
+	int status;
+	int result;
+	extern int errno;
+	char buffer[MAX_INPUT_BUFFER];
+	int fd[2];
+	FILE *fp;
+	int bytes_read=0;
+	time_t start_time,end_time;
+
+	/* initialize return variables */
+	if(output!=NULL)
+		strcpy(output,"");
+	*early_timeout=FALSE;
+
+	/* if no command was passed, return with no error */
+	if(command==NULL)
+	        return STATE_OK;
+
+	/* create a pipe */
+	pipe(fd);
+
+	/* make the pipe non-blocking */
+	fcntl(fd[0],F_SETFL,O_NONBLOCK);
+	fcntl(fd[1],F_SETFL,O_NONBLOCK);
+
+	/* get the command start time */
+	time(&start_time);
+
+	/* fork */
+	pid=fork();
+
+	/* return an error if we couldn't fork */
+	if(pid==-1){
+
+		snprintf(buffer,sizeof(buffer)-1,"NRPE: Call to fork() failed\n");
+		buffer[sizeof(buffer)-1]='\x0';
+
+		if(output!=NULL){
+			strncpy(output,buffer,output_length-1);
+			output[output_length-1]='\x0';
+		        }
+
+		/* close both ends of the pipe */
+		close(fd[0]);
+		close(fd[1]);
+		
+	        return STATE_UNKNOWN;  
+	        }
+
+	/* execute the command in the child process */
+        if(pid==0){
+
+		/* close pipe for reading */
+		close(fd[0]);
+
+		/* become process group leader */
+		setpgid(0,0);
+
+		/* trap commands that timeout */
+		signal(SIGALRM,my_system_sighandler);
+		alarm(timeout);
+
+		/* run the command */
+		fp=popen(command,"r");
+		
+		/* report an error if we couldn't run the command */
+		if(fp==NULL){
+
+			strncpy(buffer,"NRPE: Call to popen() failed\n",sizeof(buffer)-1);
+			buffer[sizeof(buffer)-1]='\x0';
+
+			/* write the error back to the parent process */
+			write(fd[1],buffer,strlen(buffer)+1);
+
+			result=STATE_CRITICAL;
+		        }
+		else{
+
+			/* read in the first line of output from the command */
+			fgets(buffer,sizeof(buffer)-1,fp);
+
+			/* close the command and get termination status */
+			status=pclose(fp);
+
+			/* report an error if we couldn't close the command */
+			if(status==-1)
+				result=STATE_CRITICAL;
+			else
+				result=WEXITSTATUS(status);
+
+			/* write the output back to the parent process */
+			write(fd[1],buffer,strlen(buffer)+1);
+		        }
+
+		/* close pipe for writing */
+		close(fd[1]);
+
+		/* reset the alarm */
+		alarm(0);
+
+		exit(result);
+	        }
+
+	/* parent waits for child to finish executing command */
+	else{
+		
+		/* close pipe for writing */
+		close(fd[1]);
+
+		/* wait for child to exit */
+		waitpid(pid,&status,0);
+
+		/* get the end time for running the command */
+		time(&end_time);
+
+		/* get the exit code returned from the program */
+		result=WEXITSTATUS(status);
+
+		/* because of my idiotic idea of having UNKNOWN states be equivalent to -1, I must hack things a bit... */
+		if(result==255)
+			result=STATE_UNKNOWN;
+
+		/* check bounds on the return value */
+		if(result<-1 || result>2)
+			result=STATE_UNKNOWN;
+
+		/* try and read the results from the command output (retry if we encountered a signal) */
+		if(output!=NULL){
+			do{
+				bytes_read=read(fd[0],output,output_length-1);
+		                }while(bytes_read==-1 && errno==EINTR);
+		        }
+
+		if(bytes_read==-1 && output!=NULL)
+			strcpy(output,"");
+
+		/* if there was a critical return code and no output AND the command time exceeded the timeout thresholds, assume a timeout */
+		if(result==STATE_CRITICAL && bytes_read==-1 && (end_time-start_time)>=timeout){
+			*early_timeout=TRUE;
+
+			/* send termination signal to child process group */
+			kill((pid_t)(-pid),SIGTERM);
+			kill((pid_t)(-pid),SIGKILL);
+		        }
+
+		/* close the pipe for reading */
+		close(fd[0]);
+	        }
+
+#ifdef DEBUG
+	printf("my_system() end\n");
+#endif
+
+	return result;
+        }
+
+
+
+/* handle timeouts when executing commands via my_system() */
+void my_system_sighandler(int sig){
+
+	/* force the child process to exit... */
+	exit(STATE_CRITICAL);
+        }
+
+
+
+
+

+ 36 - 0
src/nrpe.h

@@ -0,0 +1,36 @@
+/************************************************************************
+ *
+ * NRPE.H - NRPE Include File
+ * Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
+ * Last Modified: 06-23-2001
+ *
+ * License:
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+/**************** COMMAND STRUCTURE DEFINITION **********/
+
+#define MAX_COMMANDNAME_LENGTH	32		/* maximum short name of a command */
+#define MAX_COMMANDLINE_LENGTH	1024		/* maximum command line length */
+
+typedef struct command_struct{
+	char command_name[MAX_COMMANDNAME_LENGTH];
+	char command_line[MAX_COMMANDLINE_LENGTH];
+	struct command_struct *next;
+        }command;
+