From 7ceff0d5a95f5c5f34235ef6682595f169864d2f Mon Sep 17 00:00:00 2001 From: "Jeremy T. Bouse" Date: Fri, 7 Mar 2003 22:11:25 +0000 Subject: Added getaddrinfo.[ch] & gethostbyname.[ch] to provide RFC2553 functions if missing in system libs and lwres not present Moved all references to netdb.h and sys/socket.h into common.h.in Modified automake call in tools/setup to include adding missing files so config.sub and config.guess will be available git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@376 f882894a-f735-0410-b71e-b25c423dba1c diff --git a/configure.in b/configure.in index ef0d06b..7fccb98 100644 --- a/configure.in +++ b/configure.in @@ -11,6 +11,7 @@ PACKAGE_RELEASE="${REL}" AC_SUBST(PACKAGE_RELEASE) AM_INIT_AUTOMAKE(nagios-plugins,${PACKAGE_VERSION}) AM_CONFIG_HEADER(plugins/config.h plugins/common.h plugins/version.h plugins/netutils.h plugins/utils.h plugins/popen.h) +AC_CANONICAL_HOST AC_PREFIX_DEFAULT(/usr/local/nagios) @@ -52,18 +53,38 @@ SUPPORT="Send email to nagios-users@lists.sourceforge.net if you have questions\ AC_SUBST(SUPPORT) dnl CGIURL has changed for Nagios with 1.0 beta -AC_ARG_WITH(cgiurl,--with-cgiurl= sets URL for cgi programs,cgiurl=$withval,cgiurl=/nagios/cgi-bin) +dnl AC_ARG_WITH(cgiurl,--with-cgiurl= sets URL for cgi programs,cgiurl=$withval,cgiurl=/nagios/cgi-bin) +AC_ARG_WITH(cgiurl, + ACX_HELP_STRING([--with-cgiurl=DIR], + [sets URL for cgi programs]), + cgiurl=$withval, + cgiurl=/nagios/cgi-bin) CGIURL="$cgiurl" AC_DEFINE_UNQUOTED(CGIURL,"$CGIURL",[URL of CGI programs]) -AC_ARG_WITH(nagios_user,--with-nagios-user= sets user name to run nagios,nagios_usr=$withval,nagios_usr=nagios) -AC_ARG_WITH(nagios_group,--with-nagios-group= sets group name to run nagios,nagios_grp=$withval,nagios_grp=nagios) +dnl AC_ARG_WITH(nagios_user,--with-nagios-user= sets user name to run nagios,nagios_usr=$withval,nagios_usr=nagios) +AC_ARG_WITH(nagios_user, + ACX_HELP_STRING([--with-nagios-user=USER], + [set user name to run nagios]), + nagios_usr=$withval, + nagios_usr=nagios) +dnl AC_ARG_WITH(nagios_group,--with-nagios-group= sets group name to run nagios,nagios_grp=$withval,nagios_grp=nagios) +AC_ARG_WITH(nagios_group, + ACX_HELP_STRING([--with-nagios-group=GROUP], + [set group name to run nagios]), + nagios_grp=$withval, + nagios_grp=nagios) AC_SUBST(nagios_usr) AC_SUBST(nagios_grp) INSTALL_OPTS="-o $nagios_usr -g $nagios_grp" AC_SUBST(INSTALL_OPTS) -AC_ARG_WITH(trusted_path,--with-trusted-path=/bin:/sbin:/usr/bin:/usr/sbin sets trusted path for executables called by scripts,trusted_path=$withval,trusted_path=/bin:/sbin:/usr/bin:/usr/sbin) +dnl AC_ARG_WITH(trusted_path,--with-trusted-path=/bin:/sbin:/usr/bin:/usr/sbin sets trusted path for executables called by scripts,trusted_path=$withval,trusted_path=/bin:/sbin:/usr/bin:/usr/sbin) +AC_ARG_WITH(trusted_path, + ACX_HELP_STRING([--with-trusted-path=PATH], + [sets trusted path for executables called by scripts (default=/bin:/sbin:/usr/bin:/usr/sbin)]), + trusted_path=$withval, + trusted_path=/bin:/sbin:/usr/bin:/usr/sbin) AC_SUBST(trusted_path) EXTRAS= @@ -84,6 +105,18 @@ AC_PATH_PROG(SH,sh) AC_PATH_PROG(HOSTNAME,hostname) AC_PATH_PROG(BASENAME,basename) +dnl +dnl Check for miscellaneous stuff +dnl + +case $host_vender-$host_os in +sun*) + AC_DEFINE(__EXTENSIONS__,1,[Sun's netdb.h needs this for getaddrinfo]) + ;; +osf*) + AC_DEFINE(_OSF_SOURCE,1,[OSF needs this for getaddrinfo]) + ;; +esac dnl dnl Checks for libraries. @@ -98,7 +131,11 @@ AC_SUBST(SOCKETLIBS) dnl Check for PostgreSQL libraries _SAVEDLIBS="$LIBS" _SAVEDCPPFLAGS="$CPPFLAGS" -AC_ARG_WITH(pgsql,--with-pgsql= sets path to pgsql installation,[PGSQL=$withval]) +dnl AC_ARG_WITH(pgsql,--with-pgsql= sets path to pgsql installation,[PGSQL=$withval]) +AC_ARG_WITH(pgsql, + ACX_HELP_STRING([--with-pgsql=DIR], + [sets path to pgsql installation]), + PGSQL=$withval,) AC_CHECK_LIB(crypt,main) if test "$ac_cv_lib_crypt_main" = "yes"; then if test -n "$PGSQL"; then @@ -175,7 +212,11 @@ LIBS="$_SAVEDLIBS" dnl Check for mysql libraries _SAVEDLIBS="$LIBS" _SAVEDCPPFLAGS="$CPPFLAGS" -AC_ARG_WITH(mysql,--with-mysql= sets path to mysql installation (assumes lib/mysql and include subdirs),[MYSQL=$withval]) +dnl AC_ARG_WITH(mysql,--with-mysql= sets path to mysql installation (assumes lib/mysql and include subdirs),[MYSQL=$withval]) +AC_ARG_WITH(mysql, + ACX_HELP_STRING([--with-mysql=DIR], + [sets path to mysql installation (assumes lib/mysql and include subdirs]), + MYSQL=$withval,) if test -n "$MYSQL"; then MYSQLLIBDIR=$MYSQL/lib/mysql CPPFLAGS="-I$MYSQL/include" @@ -229,7 +270,11 @@ elif test "$OPENSSL" = "/usr/local/bin/openssl"; then elif test "$OPENSSL" = "/usr/local/ssl/bin/openssl"; then OPENSSL=/usr/local/ssl fi -AC_ARG_WITH(openssl,--with-openssl= sets path to openssl installation,[OPENSSL=$withval]) +dnl AC_ARG_WITH(openssl,--with-openssl= sets path to openssl installation,[OPENSSL=$withval]) +AC_ARG_WITH(openssl, + ACX_HELP_STRING([--with-openssl=DIR], + [sets path to openssl installation]), + OPENSSL=$withval,) dnl ######################################################################### dnl Check if Posix getaddrinfo() is available. It is also possible to use @@ -785,7 +830,11 @@ else echo "** Unable to find usable ps syntax" fi -AC_ARG_WITH(df_command,--with-df-command= sets syntax for df,DF_COMMAND=$withval) +dnl AC_ARG_WITH(df_command,--with-df-command=,sets syntax for df,DF_COMMAND=$withval) +AC_ARG_WITH(df_command, + ACX_HELP_STRING([--with-df-command=SYNTAX], + [sets syntax for df]), + DF_COMMAND=$withval,) if test -n "$DF_COMMAND" then AC_DEFINE_UNQUOTED(DF_COMMAND,"$DF_COMMAND",[path and args for df command]) @@ -815,7 +864,11 @@ fi AC_PATH_PROG(PATH_TO_PING,ping) -AC_ARG_WITH(ping_command,--with-ping-command= sets syntax for ping,PING_COMMAND=$withval) +dnl AC_ARG_WITH(ping_command,--with-ping-command= sets syntax for ping,PING_COMMAND=$withval) +AC_ARG_WITH(ping_command, + ACX_HELP_STRING([--with-ping-command=SYNTAX], + [sets syntax for ping]), + PING_COMMAND=$withval,) if test -n "$PING_COMMAND" then echo " ping syntax... (command-line) $PING_COMMAND" diff --git a/lib/Makefile.am b/lib/Makefile.am index d82f138..7826a28 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,9 +2,10 @@ noinst_LIBRARIES = libnagiosplug.a -noinst_HEADERS = getopt.h +noinst_HEADERS = getopt.h getaddrinfo.h gethostbyname.h libnagiosplug_a_SOURCES = getopt.c getopt1.c getloadavg.c INCLUDES = -I$(srcdir) +EXTRA_DIST = getaddrinfo.c gethostbyname.c diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c new file mode 100644 index 0000000..c958da6 --- /dev/null +++ b/lib/getaddrinfo.c @@ -0,0 +1,312 @@ +/* + * This file is part of libESMTP, a library for submission of RFC 2822 + * formatted electronic mail messages using the SMTP protocol described + * in RFC 2821. + * + * Copyright (C) 2001,2002 Brian Stafford + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* An emulation of the RFC 2553 / Posix getaddrinfo resolver interface. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/* Need to turn off Posix features in glibc to build this */ +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "gethostbyname.h" +#include "getaddrinfo.h" + +static struct addrinfo * +dup_addrinfo (struct addrinfo *info, void *addr, size_t addrlen) +{ + struct addrinfo *ret; + + ret = malloc (sizeof (struct addrinfo)); + if (ret == NULL) + return NULL; + memcpy (ret, info, sizeof (struct addrinfo)); + ret->ai_addr = malloc (addrlen); + if (ret->ai_addr == NULL) + { + free (ret); + return NULL; + } + memcpy (ret->ai_addr, addr, addrlen); + ret->ai_addrlen = addrlen; + return ret; +} + +int +getaddrinfo (const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct hostent *hp; + struct servent *servent; + const char *socktype; + int port; + struct addrinfo hint, result; + struct addrinfo *ai, *sai, *eai; + struct ghbnctx ghbnctx; + char **addrs; + int code; + + memset (&result, 0, sizeof result); + + /* default for hints */ + if (hints == NULL) + { + memset (&hint, 0, sizeof hint); + hint.ai_family = PF_UNSPEC; + hints = &hint; + } + + /* servname must not be NULL in this implementation */ + if (servname == NULL) + return EAI_NONAME; + + /* check for tcp or udp sockets only */ + if (hints->ai_socktype == SOCK_STREAM) + socktype = "tcp"; + else if (hints->ai_socktype == SOCK_DGRAM) + socktype = "udp"; + else + return EAI_SERVICE; + result.ai_socktype = hints->ai_socktype; + + /* Note: maintain port in host byte order to make debugging easier */ + if (isdigit (*servname)) + port = strtol (servname, NULL, 10); + else if ((servent = getservbyname (servname, socktype)) != NULL) + port = ntohs (servent->s_port); + else + return EAI_NONAME; + + /* if nodename == NULL refer to the local host for a client or any + for a server */ + if (nodename == NULL) + { + struct sockaddr_in sin; + + /* check protocol family is PF_UNSPEC or PF_INET - could try harder + for IPv6 but that's more code than I'm prepared to write */ + if (hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET) + result.ai_family = AF_INET; + else + return EAI_FAMILY; + + sin.sin_family = result.ai_family; + sin.sin_port = htons (port); + if (hints->ai_flags & AI_PASSIVE) + sin.sin_addr.s_addr = htonl (INADDR_ANY); + else + sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + /* Duplicate result and addr and return */ + *res = dup_addrinfo (&result, &sin, sizeof sin); + return (*res == NULL) ? EAI_MEMORY : 0; + } + + /* If AI_NUMERIC is specified, use inet_addr to translate numbers and + dots notation. */ + if (hints->ai_flags & AI_NUMERICHOST) + { + struct sockaddr_in sin; + + /* check protocol family is PF_UNSPEC or PF_INET */ + if (hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET) + result.ai_family = AF_INET; + else + return EAI_FAMILY; + + sin.sin_family = result.ai_family; + sin.sin_port = htons (port); + sin.sin_addr.s_addr = inet_addr (nodename); + /* Duplicate result and addr and return */ + *res = dup_addrinfo (&result, &sin, sizeof sin); + return (*res == NULL) ? EAI_MEMORY : 0; + } + + errno = 0; + hp = gethostbyname_ctx (nodename, &ghbnctx); + if (hp == NULL) + { + if (errno != 0) + { + free_ghbnctx (&ghbnctx); + return EAI_SYSTEM; + } + code = h_error_ctx (&ghbnctx); + switch (code) + { + case HOST_NOT_FOUND: code = EAI_NODATA; break; + case NO_DATA: code = EAI_NODATA; break; +#if defined(NO_ADDRESS) && NO_ADDRESS != NO_DATA + case NO_ADDRESS: code = EAI_NODATA; break; +#endif + case NO_RECOVERY: code = EAI_FAIL; break; + case TRY_AGAIN: code = EAI_AGAIN; break; + default: code = EAI_FAIL; break; + } + free_ghbnctx (&ghbnctx); + return code; + } + + /* Check that the address family is acceptable. + */ + switch (hp->h_addrtype) + { + case AF_INET: + if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET)) + goto eai_family; + break; +#ifdef USE_IPV6 + case AF_INET6: + if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET6)) + goto eai_family; + break; +#endif + default: + eai_family: + free_ghbnctx (&ghbnctx); + return EAI_FAMILY; + } + + /* For each element pointed to by hp, create an element in the + result linked list. */ + sai = eai = NULL; + for (addrs = hp->h_addr_list; *addrs != NULL; addrs++) + { + struct sockaddr sa; + size_t addrlen; + + sa.sa_family = hp->h_addrtype; + switch (hp->h_addrtype) + { + case AF_INET: + ((struct sockaddr_in *) &sa)->sin_port = htons (port); + memcpy (&((struct sockaddr_in *) &sa)->sin_addr, + *addrs, hp->h_length); + addrlen = sizeof (struct sockaddr_in); + break; +#ifdef USE_IPV6 + case AF_INET6: +# if SIN6_LEN + ((struct sockaddr_in6 *) &sa)->sin6_len = hp->h_length; +# endif + ((struct sockaddr_in6 *) &sa)->sin6_port = htons (port); + memcpy (&((struct sockaddr_in6 *) &sa)->sin6_addr, + *addrs, hp->h_length); + addrlen = sizeof (struct sockaddr_in6); + break; +#endif + default: + continue; + } + + result.ai_family = hp->h_addrtype; + ai = dup_addrinfo (&result, &sa, addrlen); + if (ai == NULL) + { + free_ghbnctx (&ghbnctx); + freeaddrinfo (sai); + return EAI_MEMORY; + } + if (sai == NULL) + sai = ai; + else + eai->ai_next = ai; + eai = ai; + } + + if (sai == NULL) + { + free_ghbnctx (&ghbnctx); + return EAI_NODATA; + } + + if (hints->ai_flags & AI_CANONNAME) + { + sai->ai_canonname = malloc (strlen (hp->h_name) + 1); + if (sai->ai_canonname == NULL) + { + free_ghbnctx (&ghbnctx); + freeaddrinfo (sai); + return EAI_MEMORY; + } + strcpy (sai->ai_canonname, hp->h_name); + } + + free_ghbnctx (&ghbnctx); + *res = sai; + return 0; +} + +void +freeaddrinfo (struct addrinfo *ai) +{ + struct addrinfo *next; + + while (ai != NULL) + { + next = ai->ai_next; + if (ai->ai_canonname != NULL) + free (ai->ai_canonname); + if (ai->ai_addr != NULL) + free (ai->ai_addr); + free (ai); + ai = next; + } +} + +const char * +gai_strerror (int ecode) +{ + static const char *eai_descr[] = + { + "no error", + "address family for nodename not supported", /* EAI_ADDRFAMILY */ + "temporary failure in name resolution", /* EAI_AGAIN */ + "invalid value for ai_flags", /* EAI_BADFLAGS */ + "non-recoverable failure in name resolution", /* EAI_FAIL */ + "ai_family not supported", /* EAI_FAMILY */ + "memory allocation failure", /* EAI_MEMORY */ + "no address associated with nodename", /* EAI_NODATA */ + "nodename nor servname provided, or not known", /* EAI_NONAME */ + "servname not supported for ai_socktype", /* EAI_SERVICE */ + "ai_socktype not supported", /* EAI_SOCKTYPE */ + "system error returned in errno", /* EAI_SYSTEM */ + }; + + if (ecode < 0 || ecode > (int) (sizeof eai_descr/ sizeof eai_descr[0])) + return "unknown error"; + return eai_descr[ecode]; +} + diff --git a/lib/getaddrinfo.h b/lib/getaddrinfo.h new file mode 100644 index 0000000..c474d3b --- /dev/null +++ b/lib/getaddrinfo.h @@ -0,0 +1,67 @@ +#ifndef _getaddrinfo_h +#define _getaddrinfo_h +/* + * This file is part of libESMTP, a library for submission of RFC 2822 + * formatted electronic mail messages using the SMTP protocol described + * in RFC 2821. + * + * Copyright (C) 2001,2002 Brian Stafford + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* Structure and prototypes aken from RFC 2553 */ + +struct addrinfo + { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for nodename */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ + }; + +/* Supposed to be defined in */ +#define AI_PASSIVE 1 /* Socket address is intended for `bind'. */ +#define AI_CANONNAME 2 /* Request for canonical name. */ +#define AI_NUMERICHOST 4 /* Don't use name resolution. */ + +/* Supposed to be defined in */ +#define EAI_ADDRFAMILY 1 /* address family for nodename not supported */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#define EAI_NODATA 7 /* no address associated with nodename */ +#define EAI_NONAME 8 /* nodename nor servname provided, or not known */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ + +/* RFC 2553 / Posix resolver */ +int getaddrinfo (const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); + +/* Free addrinfo structure and associated storage */ +void freeaddrinfo (struct addrinfo *ai); + +/* Convert error return from getaddrinfo() to string */ +const char *gai_strerror (int code); + +#endif diff --git a/lib/gethostbyname.c b/lib/gethostbyname.c new file mode 100644 index 0000000..d151606 --- /dev/null +++ b/lib/gethostbyname.c @@ -0,0 +1,228 @@ +/* + * This file is a ghastly hack because nobody can agree on + * gethostbyname_r()'s prototype. + * + * Copyright (C) 2001,2002 Brian Stafford + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _SVID_SOURCE 1 /* Need this to get gethostbyname_r() */ + +#include + +#include +#include +#include +#include + +#include "gethostbyname.h" + +#if HAVE_GETIPNODEBYNAME + +void +free_ghbnctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + if (ctx->hostent != NULL) + freehostent (ctx->hostent); +} + +struct hostent * +gethostbyname_ctx (const char *host, struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + memset (ctx, 0, sizeof (struct ghbnctx)); + ctx->hostent = getipnodebyname (host, AF_UNSPEC, AI_ADDRCONFIG, &ctx->h_err); + return ctx->hostent; +} + +int +h_error_ctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + return ctx->h_err; +} + +#elif HAVE_GETHOSTBYNAME_R == 6 + +void +free_ghbnctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + if (ctx->hostbuf != NULL) + free (ctx->hostbuf); +} + +struct hostent * +gethostbyname_ctx (const char *host, struct ghbnctx *ctx) +{ + struct hostent *hp; + char *tmp; + int err; + + assert (ctx != NULL); + + memset (ctx, 0, sizeof (struct ghbnctx)); + ctx->hostbuf_len = 2048; + if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL) + { + errno = ENOMEM; + return NULL; + } + while ((err = gethostbyname_r (host, + &ctx->hostent, ctx->hostbuf, ctx->hostbuf_len, + &hp, &ctx->h_err)) == ERANGE) + { + ctx->hostbuf_len += 1024; + if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL) + { + errno = ENOMEM; + return NULL; + } + ctx->hostbuf = tmp; + } + if (err != 0) + { + errno = err; + return NULL; + } + return hp; +} + +int +h_error_ctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + return ctx->h_err; +} + +#elif HAVE_GETHOSTBYNAME_R == 5 + +void +free_ghbnctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + if (ctx->hostbuf != NULL) + free (ctx->hostbuf); +} + +struct hostent * +gethostbyname_ctx (const char *host, struct ghbnctx *ctx) +{ + struct hostent *hp; + char *tmp; + + assert (ctx != NULL); + + memset (ctx, 0, sizeof (struct ghbnctx)); + ctx->hostbuf_len = 2048; + if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL) + { + errno = ENOMEM; + return NULL; + } + while ((hp = gethostbyname_r (host, &ctx->hostent, + ctx->hostbuf, ctx->hostbuf_len, + &ctx->h_err)) == NULL && errno == ERANGE) + { + ctx->hostbuf_len += 1024; + if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL) + { + errno = ENOMEM; + return NULL; + } + ctx->hostbuf = tmp; + } + return hp; +} + +int +h_error_ctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + return ctx->h_err; +} + +#elif HAVE_GETHOSTBYNAME_R == 3 + +void +free_ghbnctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + /* FIXME: does this need to do anything? */ +} + +struct hostent * +gethostbyname_ctx (const char *host, struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + if (!gethostbyname_r (host, &ctx->hostent, &ctx->hostent_data)) + { + ctx->h_err = h_errno; /* FIXME: is this correct? */ + return NULL; + } + return &ctx->hostent; +} + +int +h_error_ctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + return ctx->h_err; +} + +#else + +void +free_ghbnctx (struct ghbnctx *ctx __attribute__ ((unused))) +{ + assert (ctx != NULL); +} + +struct hostent * +gethostbyname_ctx (const char *host, struct ghbnctx *ctx) +{ + struct hostent *hp; + + hp = gethostbyname (host); + if (hp == NULL) + ctx->h_err = h_errno; + return hp; +} + +int +h_error_ctx (struct ghbnctx *ctx) +{ + assert (ctx != NULL); + + return ctx->h_err; +} + +#endif diff --git a/lib/gethostbyname.h b/lib/gethostbyname.h new file mode 100644 index 0000000..2b96399 --- /dev/null +++ b/lib/gethostbyname.h @@ -0,0 +1,103 @@ +/* + * This file is a ghastly hack because nobody can agree on + * gethostbyname_r()'s prototype. + * + * Copyright (C) 2001,2002 Brian Stafford + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/************************************************************************* + Usage: + + #include + #include "gethostbyname.h" + + f () + { + struct ghbnctx ctx; + + errno = 0; + hp = gethostbyname_ctx (host, &ctx); + if (hp == NULL) + { + if (errno != 0) + handle_value_of_errno (errno); + else + handle_value_of_h_errno (h_error_ctx (&ctx)); + } + else + { + ... + } + free_ghbnctx (&ctx); + } + *************************************************************************/ + +#ifndef _gethostbyname_h +#define _gethostbyname_h + +#if HAVE_GETIPNODEBYNAME + +struct ghbnctx + { + int h_err; + struct hostent *hostent; + }; + +#elif HAVE_GETHOSTBYNAME_R == 6 + +struct ghbnctx + { + int h_err; + struct hostent hostent; + char *hostbuf; + size_t hostbuf_len; + }; + +#elif HAVE_GETHOSTBYNAME_R == 5 + +struct ghbnctx + { + int h_err; + struct hostent hostent; + char *hostbuf; + int hostbuf_len; + }; + +#elif HAVE_GETHOSTBYNAME_R == 3 + +struct ghbnctx + { + int h_err; + struct hostent_data hostent_data; + struct hostent hostent; + }; + +#else + +struct ghbnctx + { + int h_err; + }; + +#endif + +struct hostent *gethostbyname_ctx (const char *host, struct ghbnctx *ctx); +int h_error_ctx (struct ghbnctx *ctx); +void free_ghbnctx (struct ghbnctx *ctx); + +#endif + diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c index f8419dc..2033b8c 100644 --- a/plugins/check_pgsql.c +++ b/plugins/check_pgsql.c @@ -79,7 +79,6 @@ enum { #include "config.h" #include "common.h" #include "utils.h" -#include #include int process_arguments (int, char **); diff --git a/plugins/common.h.in b/plugins/common.h.in index 48e7f6f..09df00d 100644 --- a/plugins/common.h.in +++ b/plugins/common.h.in @@ -72,6 +72,13 @@ #include +#if HAVE_LWRES_NETDB_H +#include +#elif !HAVE_GETADDRINFO +#include "getaddrinfo.h" +#else +#include +#endif /* * diff --git a/plugins/netutils.c b/plugins/netutils.c index e5d3528..fc85a24 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c @@ -31,10 +31,8 @@ #include "config.h" #include "common.h" -#include #include #include -#include extern int socket_timeout; RETSIGTYPE socket_timeout_alarm_handler (int); diff --git a/plugins/netutils.h.in b/plugins/netutils.h.in index be4ae24..1907ab7 100644 --- a/plugins/netutils.h.in +++ b/plugins/netutils.h.in @@ -34,10 +34,9 @@ #undef HAVE_STRINGS_H #undef HAVE_STRING_H -#include +#include "common.h" #include #include -#include void socket_timeout_alarm_handler (int); diff --git a/tools/setup b/tools/setup index 18281a3..b825a6b 100755 --- a/tools/setup +++ b/tools/setup @@ -3,7 +3,7 @@ aclocal -I lib autoconf autoheader -automake +automake --add-missing --copy if [ -f debian/rules ] ; then chmod +x debian/rules -- cgit v0.10-9-g596f