r25543: Merge libreplace support for inet_pton, inet_ntop, getaddrinfo, getnameinfo
authorJelmer Vernooij <jelmer@samba.org>
Fri, 5 Oct 2007 23:54:12 +0000 (23:54 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 20:07:51 +0000 (15:07 -0500)
(and friends) from SAMBA_3_2, with some minor tweaks:

- avoid including network headers in replace.h unless absolutely required
- autoconf tests for getaddrinfo() in lib/replace

The heimdal-specific code also no longer looks for these functions anymore.
(This used to be commit b6d3fd84a5d7d814035e60d6fa22f19bed9f77da)

12 files changed:
source4/auth/kerberos/config.mk
source4/heimdal_build/config.m4
source4/heimdal_build/config.mk
source4/lib/replace/getaddrinfo.c [new file with mode: 0644]
source4/lib/replace/getaddrinfo.h [new file with mode: 0644]
source4/lib/replace/inet_ntop.c [new file with mode: 0644]
source4/lib/replace/inet_ntop.m4 [new file with mode: 0644]
source4/lib/replace/inet_pton.c [new file with mode: 0644]
source4/lib/replace/inet_pton.m4 [new file with mode: 0644]
source4/lib/replace/libreplace.m4
source4/lib/replace/replace.h
source4/lib/replace/system/network.h

index f75fd993230fa2a7e9b7a83025ccc2206f8f987d..87c62fb6edfad91f5ac4b6dc40e59a3231a64243 100644 (file)
@@ -10,6 +10,6 @@ OBJ_FILES = kerberos.o \
                        gssapi_parse.o \
                        krb5_init_context.o
 PUBLIC_DEPENDENCIES = HEIMDAL_KRB5 NDR_KRB5PAC samba-socket LIBCLI_RESOLVE
-PRIVATE_DEPENDENCIES = ASN1_UTIL HEIMDAL_ROKEN_ADDRINFO auth_sam CREDENTIALS_KRB5
+PRIVATE_DEPENDENCIES = ASN1_UTIL auth_sam CREDENTIALS_KRB5
 # End SUBSYSTEM KERBEROS
 #################################
index 01a620c1c5a8d859d02a8e7f1a6fcc8b7b017d0a..8c0959550bebeba3853c8ffa911719fb52e14b11 100644 (file)
@@ -71,8 +71,6 @@ AC_CHECK_FUNCS([                              \
        cgetent                                 \
        getprogname                             \
        inet_aton                               \
-       inet_ntop                               \
-       inet_pton                               \
        gethostname                             \
        getnameinfo                             \
        iruserok                                \
@@ -100,8 +98,6 @@ AC_CHECK_FUNCS([                             \
        errx                                    \
        warnx                                   \
        flock                                   \
-       getaddrinfo                             \
-       freeaddrinfo                            \
        getipnodebyname                         \
        getipnodebyaddr                         \
        freehostent                             \
@@ -229,49 +225,6 @@ SMB_ENABLE(KERBEROS_LIB, YES)
 SMB_ENABLE(asn1_compile, YES)
 SMB_ENABLE(compile_et, YES)
 
-# only add getaddrinfo and related functions if needed
-SMB_ENABLE(HEIMDAL_ROKEN_ADDRINFO, NO)
-if test t$ac_cv_func_getaddrinfo != tyes; then
-       SMB_ENABLE(HEIMDAL_ROKEN_ADDRINFO, YES)
-fi
-
-SMB_ENABLE(HEIMDAL_ROKEN_GETNAMEINFO, NO)
-if test t$ac_cv_func_getnameinfo != tyes; then
-       SMB_ENABLE(HEIMDAL_ROKEN_GETNAMEINFO, YES)
-fi
-
-# only add inet_aton if needed
-SMB_ENABLE(HEIMDAL_ROKEN_INET_ATON, NO)
-if test t$ac_cv_func_inet_aton != tyes; then
-       SMB_ENABLE(HEIMDAL_ROKEN_INET_ATON, YES)
-fi
-
-SMB_ENABLE(HEIMDAL_ROKEN_INET_NTOP, NO)
-if test x"$ac_cv_func_inet_ntop" = x"no"; then
-    AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, inet_ntop)
-    AC_CHECK_LIB_EXT(nsl, NSL_LIBS, inet_ntop)
-    if test x"$ac_cv_lib_ext_nsl_s_inet_ntop" != x"yes" &&
-       test x"$ac_cv_lib_ext_nsl_inet_ntop" != x"yes"; then
-       SMB_ENABLE(HEIMDAL_ROKEN_INET_NTOP, YES)
-    else
-       SMB_ENABLE(NSL,YES)
-    fi
-fi
-
-SMB_ENABLE(HEIMDAL_ROKEN_INET_PTON, NO)
-if test x"$ac_cv_func_inet_pton" = x"no"; then
-    AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, inet_pton)
-    AC_CHECK_LIB_EXT(nsl, NSL_LIBS, inet_pton)
-    if test x"$ac_cv_lib_ext_nsl_s_inet_pton" != x"yes" &&
-       test x"$ac_cv_lib_ext_nsl_inet_pton" != x"yes"; then
-       SMB_ENABLE(HEIMDAL_ROKEN_INET_PTON, YES)
-    else
-       SMB_ENABLE(NSL,YES)
-    fi
-fi
-
-SMB_EXT_LIB(NSL,[${NSL_LIBS}],[],[],[])
-
 # only add closefrom if needed
 SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM, NO)
 if test t$ac_cv_func_closefrom != tyes; then
@@ -285,29 +238,3 @@ if test t$ac_cv_func_getprogname != tyes; then
        SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME, YES)
        SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME_H, YES)
 fi
-
-# only add gai_strerror if needed
-SMB_ENABLE(HEIMDAL_ROKEN_GAI_STRERROR, NO)
-AC_CHECK_FUNC(gai_strerror)
-
-if test t$ac_cv_func_gai_strerror != tyes; then
-    AC_CHECK_LIB_EXT(nsl, GAI_LIBS, gai_strerror)
-    AC_CHECK_LIB_EXT(socket, GAI_LIBS, gai_strerror)
-    AC_CHECK_LIB_EXT(xnet, GAI_LIBS, gai_strerror)
-
-    dnl We can't just call AC_CHECK_FUNCS(gai_strerror) here, because the value
-    dnl has been cached.
-    if test x"$ac_cv_lib_ext_nsl_gai_strerror" = x"yes" ||
-       test x"$ac_cv_lib_ext_socket_gai_strerror" = x"yes" ||
-       test x"$ac_cv_lib_ext_xnet_gai_strerror" = x"yes"; then
-        AC_DEFINE(HAVE_GAI_STRERROR,1,[Whether the system has gai_strerror()])
-       SMB_ENABLE(GAI, YES)
-    else
-       SMB_ENABLE(HEIMDAL_ROKEN_GAI_STRERROR, YES)
-    fi
-
-else
-    AC_DEFINE(HAVE_GAI_STRERROR,1,[Whether gai_strerror() is available])
-fi
-
-SMB_EXT_LIB(GAI,[${GAI_LIBS}],[${GAI_CFLAGS}],[${GAI_CPPFLAGS}],[${GAI_LDFLAGS}])
index 940d9cdb9ce6b958cab916669cb2f90f3c92a7bc..ce5fa6e98ea233ec02fb162c3be8f5a75b267bc2 100644 (file)
@@ -369,24 +369,6 @@ OBJ_FILES = \
 # End SUBSYSTEM HEIMDAL_HX509
 #######################
 
-#######################
-# Start SUBSYSTEM HEIMDAL_ROKEN_GAI_STRERROR
-[SUBSYSTEM::HEIMDAL_ROKEN_GAI_STRERROR]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
-OBJ_FILES = ../heimdal/lib/roken/gai_strerror.o
-
-[SUBSYSTEM::HEIMDAL_ROKEN_INET_ATON]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
-OBJ_FILES = ../heimdal/lib/roken/inet_aton.o
-
-[SUBSYSTEM::HEIMDAL_ROKEN_INET_NTOP]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
-OBJ_FILES = ../heimdal/lib/roken/inet_ntop.o
-
-[SUBSYSTEM::HEIMDAL_ROKEN_INET_PTON]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
-OBJ_FILES = ../heimdal/lib/roken/inet_pton.o
-
 [SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME]
 CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/roken/getprogname.o
@@ -399,24 +381,6 @@ OBJ_FILES = ../heimdal/lib/roken/closefrom.o
 CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/roken/getprogname.ho
 
-[SUBSYSTEM::HEIMDAL_ROKEN_GETNAMEINFO]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
-OBJ_FILES = ../heimdal/lib/roken/getnameinfo.o
-
-#######################
-# Start SUBSYSTEM HEIMDAL_ROKEN_ADDRINFO
-[SUBSYSTEM::HEIMDAL_ROKEN_ADDRINFO]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken
-OBJ_FILES = \
-       ../heimdal/lib/roken/getaddrinfo.o \
-       ../heimdal/lib/roken/freeaddrinfo.o \
-       ../heimdal/lib/roken/getipnodebyaddr.o \
-       ../heimdal/lib/roken/getipnodebyname.o \
-       ../heimdal/lib/roken/freehostent.o \
-       ../heimdal/lib/roken/copyhostent.o \
-       ../heimdal/lib/roken/hostent_find_fqdn.o
-PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN_INET_PTON EXT_SOCKET
-
 #######################
 # Start SUBSYSTEM HEIMDAL_ROKEN
 [SUBSYSTEM::HEIMDAL_ROKEN]
@@ -453,16 +417,8 @@ OBJ_FILES = \
        ../heimdal/lib/roken/rtbl.o \
        replace.o
 PUBLIC_DEPENDENCIES = \
-                       HEIMDAL_ROKEN_ADDRINFO \
-                       HEIMDAL_ROKEN_GAI_STRERROR \
-                       HEIMDAL_ROKEN_INET_ATON \
-                       HEIMDAL_ROKEN_INET_NTOP \
-                       HEIMDAL_ROKEN_INET_PTON \
                        HEIMDAL_ROKEN_GETPROGNAME \
                        HEIMDAL_ROKEN_CLOSEFROM \
-                       HEIMDAL_ROKEN_GETNAMEINFO \
-                       GAI \
-                       NSL \
                        RESOLV \
                        EXT_SOCKET
 # End SUBSYSTEM HEIMDAL_ROKEN
diff --git a/source4/lib/replace/getaddrinfo.c b/source4/lib/replace/getaddrinfo.c
new file mode 100644 (file)
index 0000000..519c300
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this paragraph
+and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
+EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS
+TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+*/
+
+/*-------------------------------------------------------------------------
+ *
+ * getaddrinfo.c
+ *       Support getaddrinfo() on platforms that don't have it.
+ *
+ * We also supply getnameinfo() here, assuming that the platform will have
+ * it if and only if it has getaddrinfo().     If this proves false on some
+ * platform, we'll need to split this file and provide a separate configure
+ * test for getnameinfo().
+ *
+ * Copyright (c) 2003-2007, PostgreSQL Global Development Group
+ *
+ * Copyright (C) 2007 Jeremy Allison.
+ * Modified to return multiple IPv4 addresses for Samba.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+#ifndef SMB_MALLOC
+#define SMB_MALLOC(s) malloc(s)
+#endif
+
+#ifndef SMB_STRDUP
+#define SMB_STRDUP(s) strdup(s)
+#endif
+
+static int check_hostent_err(struct hostent *hp)
+{
+       if (!hp) {
+               switch (h_errno) {
+                       case HOST_NOT_FOUND:
+                       case NO_DATA:
+                               return EAI_NONAME;
+                       case TRY_AGAIN:
+                               return EAI_AGAIN;
+                       case NO_RECOVERY:
+                       default:
+                               return EAI_FAIL;
+               }
+       }
+       if (!hp->h_name || hp->h_addrtype != AF_INET) {
+               return EAI_FAIL;
+       }
+       return 0;
+}
+
+static char *canon_name_from_hostent(struct hostent *hp,
+                               int *perr)
+{
+       char *ret = NULL;
+
+       *perr = check_hostent_err(hp);
+       if (*perr) {
+               return NULL;
+       }
+       ret = SMB_STRDUP(hp->h_name);
+       if (!ret) {
+               *perr = EAI_MEMORY;
+       }
+       return ret;
+}
+
+static char *get_my_canon_name(int *perr)
+{
+       char name[HOST_NAME_MAX+1];
+
+       if (gethostname(name, HOST_NAME_MAX) == -1) {
+               *perr = EAI_FAIL;
+               return NULL;
+       }
+       /* Ensure null termination. */
+       name[HOST_NAME_MAX] = '\0';
+       return canon_name_from_hostent(gethostbyname(name), perr);
+}
+
+static char *get_canon_name_from_addr(struct in_addr ip,
+                               int *perr)
+{
+       return canon_name_from_hostent(
+                       gethostbyaddr(&ip, sizeof(ip), AF_INET),
+                       perr);
+}
+
+static struct addrinfo *alloc_entry(const struct addrinfo *hints,
+                               struct in_addr ip,
+                               unsigned short port)
+{
+       struct sockaddr_in *psin = NULL;
+       struct addrinfo *ai = SMB_MALLOC(sizeof(*ai));
+
+       if (!ai) {
+               return NULL;
+       }
+       memset(ai, '\0', sizeof(*ai));
+
+       psin = SMB_MALLOC(sizeof(*psin));
+       if (!psin) {
+               free(ai);
+               return NULL;
+       }
+
+       memset(psin, '\0', sizeof(*psin));
+
+       psin->sin_family = AF_INET;
+       psin->sin_port = htons(port);
+       psin->sin_addr = ip;
+
+       ai->ai_flags = 0;
+       ai->ai_family = AF_INET;
+       ai->ai_socktype = hints->ai_socktype;
+       ai->ai_protocol = hints->ai_protocol;
+       ai->ai_addrlen = sizeof(*psin);
+       ai->ai_addr = (struct sockaddr *) psin;
+       ai->ai_canonname = NULL;
+       ai->ai_next = NULL;
+
+       return ai;
+}
+
+/*
+ * get address info for a single ipv4 address.
+ *
+ *     Bugs:   - servname can only be a number, not text.
+ */
+
+static int getaddr_info_single_addr(const char *service,
+                               uint32_t addr,
+                               const struct addrinfo *hints,
+                               struct addrinfo **res)
+{
+
+       struct addrinfo *ai = NULL;
+       struct in_addr ip;
+       unsigned short port = 0;
+
+       if (service) {
+               port = (unsigned short)atoi(service);
+       }
+       ip.s_addr = htonl(addr);
+
+       ai = alloc_entry(hints, ip, port);
+       if (!ai) {
+               return EAI_MEMORY;
+       }
+
+       /* If we're asked for the canonical name,
+        * make sure it returns correctly. */
+       if (!(hints->ai_flags & AI_NUMERICSERV) &&
+                       hints->ai_flags & AI_CANONNAME) {
+               int err;
+               if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) {
+                       ai->ai_canonname = get_my_canon_name(&err);
+               } else {
+                       ai->ai_canonname =
+                       get_canon_name_from_addr(ip,&err);
+               }
+               if (ai->ai_canonname == NULL) {
+                       freeaddrinfo(ai);
+                       return err;
+               }
+       }
+
+       *res = ai;
+       return 0;
+}
+
+/*
+ * get address info for multiple ipv4 addresses.
+ *
+ *     Bugs:   - servname can only be a number, not text.
+ */
+
+static int getaddr_info_name(const char *node,
+                               const char *service,
+                               const struct addrinfo *hints,
+                               struct addrinfo **res)
+{
+       struct addrinfo *listp = NULL, *prevp = NULL;
+       char **pptr = NULL;
+       int err;
+       struct hostent *hp = NULL;
+       unsigned short port = 0;
+
+       if (service) {
+               port = (unsigned short)atoi(service);
+       }
+
+       hp = gethostbyname(node);
+       err = check_hostent_err(hp);
+       if (err) {
+               return err;
+       }
+
+       for(pptr = hp->h_addr_list; *pptr; pptr++) {
+               struct in_addr ip = *(struct in_addr *)pptr;
+               struct addrinfo *ai = alloc_entry(hints, ip, port);
+
+               if (!ai) {
+                       freeaddrinfo(listp);
+                       return EAI_MEMORY;
+               }
+
+               if (!listp) {
+                       listp = ai;
+                       prevp = ai;
+                       ai->ai_canonname = SMB_STRDUP(hp->h_name);
+                       if (!ai->ai_canonname) {
+                               freeaddrinfo(listp);
+                               return EAI_MEMORY;
+                       }
+               } else {
+                       prevp->ai_next = ai;
+                       prevp = ai;
+               }
+       }
+       *res = listp;
+       return 0;
+}
+
+/*
+ * get address info for ipv4 sockets.
+ *
+ *     Bugs:   - servname can only be a number, not text.
+ */
+
+int getaddrinfo(const char *node,
+               const char *service,
+               const struct addrinfo * hintp,
+               struct addrinfo ** res)
+{
+       struct addrinfo hints;
+
+       /* Setup the hints struct. */
+       if (hintp == NULL) {
+               memset(&hints, 0, sizeof(hints));
+               hints.ai_family = AF_INET;
+               hints.ai_socktype = SOCK_STREAM;
+       } else {
+               memcpy(&hints, hintp, sizeof(hints));
+       }
+
+       if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) {
+               return EAI_FAMILY;
+       }
+
+       if (hints.ai_socktype == 0) {
+               hints.ai_socktype = SOCK_STREAM;
+       }
+
+       if (!node && !service) {
+               return EAI_NONAME;
+       }
+
+       if (node) {
+               if (node[0] == '\0') {
+                       return getaddr_info_single_addr(service,
+                                       INADDR_ANY,
+                                       &hints,
+                                       res);
+               } else if (hints.ai_flags & AI_NUMERICHOST) {
+                       struct in_addr ip;
+                       if (!inet_aton(node, &ip)) {
+                               return EAI_FAIL;
+                       }
+                       return getaddr_info_single_addr(service,
+                                       ntohl(ip.s_addr),
+                                       &hints,
+                                       res);
+               } else {
+                       return getaddr_info_name(node,
+                                               service,
+                                               &hints,
+                                               res);
+               }
+       } else if (hints.ai_flags & AI_PASSIVE) {
+               return getaddr_info_single_addr(service,
+                                       INADDR_ANY,
+                                       &hints,
+                                       res);
+       }
+       return getaddr_info_single_addr(service,
+                                       INADDR_LOOPBACK,
+                                       &hints,
+                                       res);
+}
+
+
+void freeaddrinfo(struct addrinfo *res)
+{
+       struct addrinfo *next = NULL;
+
+       for (;res; res = next) {
+               next = res->ai_next;
+               if (res->ai_canonname) {
+                       free(res->ai_canonname);
+               }
+               if (res->ai_addr) {
+                       free(res->ai_addr);
+               }
+               free(res);
+       }
+}
+
+
+const char *gai_strerror(int errcode)
+{
+#ifdef HAVE_HSTRERROR
+       int                     hcode;
+
+       switch (errcode)
+       {
+               case EAI_NONAME:
+                       hcode = HOST_NOT_FOUND;
+                       break;
+               case EAI_AGAIN:
+                       hcode = TRY_AGAIN;
+                       break;
+               case EAI_FAIL:
+               default:
+                       hcode = NO_RECOVERY;
+                       break;
+       }
+
+       return hstrerror(hcode);
+#else                                                  /* !HAVE_HSTRERROR */
+
+       switch (errcode)
+       {
+               case EAI_NONAME:
+                       return "Unknown host";
+               case EAI_AGAIN:
+                       return "Host name lookup failure";
+#ifdef EAI_BADFLAGS
+               case EAI_BADFLAGS:
+                       return "Invalid argument";
+#endif
+#ifdef EAI_FAMILY
+               case EAI_FAMILY:
+                       return "Address family not supported";
+#endif
+#ifdef EAI_MEMORY
+               case EAI_MEMORY:
+                       return "Not enough memory";
+#endif
+#ifdef EAI_NODATA
+               case EAI_NODATA:
+                       return "No host data of that type was found";
+#endif
+#ifdef EAI_SERVICE
+               case EAI_SERVICE:
+                       return "Class type not found";
+#endif
+#ifdef EAI_SOCKTYPE
+               case EAI_SOCKTYPE:
+                       return "Socket type not supported";
+#endif
+               default:
+                       return "Unknown server error";
+       }
+#endif   /* HAVE_HSTRERROR */
+}
+
+static int gethostnameinfo(const struct sockaddr *sa,
+                       char *node,
+                       size_t nodelen,
+                       int flags)
+{
+       int ret = -1;
+       char *p = NULL;
+
+       if (!(flags & NI_NUMERICHOST)) {
+               struct hostent *hp = gethostbyaddr(
+                               &((struct sockaddr_in *)sa)->sin_addr,
+                               sizeof(struct in_addr),
+                               sa->sa_family);
+               ret = check_hostent_err(hp);
+               if (ret == 0) {
+                       /* Name looked up successfully. */
+                       ret = snprintf(node, nodelen, "%s", hp->h_name);
+                       if (ret == -1 || ret > nodelen) {
+                               return EAI_MEMORY;
+                       }
+                       if (flags & NI_NOFQDN) {
+                               p = strchr(node,'.');
+                               if (p) {
+                                       *p = '\0';
+                               }
+                       }
+                       return 0;
+               }
+
+               if (flags & NI_NAMEREQD) {
+                       /* If we require a name and didn't get one,
+                        * automatically fail. */
+                       return ret;
+               }
+               /* Otherwise just fall into the numeric host code... */
+       }
+       p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
+       ret = snprintf(node, nodelen, "%s", p);
+       if (ret == -1 || ret > nodelen) {
+               return EAI_MEMORY;
+       }
+       return 0;
+}
+
+static int getservicenameinfo(const struct sockaddr *sa,
+                       char *service,
+                       size_t servicelen,
+                       int flags)
+{
+       int ret = -1;
+       int port = ntohs(((struct sockaddr_in *)sa)->sin_port);
+
+       if (!(flags & NI_NUMERICSERV)) {
+               struct servent *se = getservbyport(
+                               port,
+                               (flags & NI_DGRAM) ? "udp" : "tcp");
+               if (se && se->s_name) {
+                       /* Service name looked up successfully. */
+                       ret = snprintf(service, servicelen, "%s", se->s_name);
+                       if (ret == -1 || ret > servicelen) {
+                               return EAI_MEMORY;
+                       }
+                       return 0;
+               }
+               /* Otherwise just fall into the numeric service code... */
+       }
+       ret = snprintf(service, servicelen, "%d", port);
+       if (ret == -1 || ret > servicelen) {
+               return EAI_MEMORY;
+       }
+       return 0;
+}
+
+/*
+ * Convert an ipv4 address to a hostname.
+ *
+ * Bugs:       - No IPv6 support.
+ */
+int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+                       char *node, size_t nodelen,
+                       char *service, size_t servicelen, int flags)
+{
+
+       /* Invalid arguments. */
+       if (sa == NULL || (node == NULL && service == NULL)) {
+               return EAI_FAIL;
+       }
+
+       if (sa->sa_family != AF_INET) {
+               return EAI_FAIL;
+       }
+
+       if (salen < sizeof(struct sockaddr_in)) {
+               return EAI_FAIL;
+       }
+
+       /* We don't support those. */
+       if ((node && !(flags & NI_NUMERICHOST))
+               || (service && !(flags & NI_NUMERICSERV)))
+               return EAI_FAIL;
+
+       if (node) {
+               return gethostnameinfo(sa, node, nodelen, flags);
+       }
+
+       if (service) {
+               return getservicenameinfo(sa, service, servicelen, flags);
+       }
+       return 0;
+}
diff --git a/source4/lib/replace/getaddrinfo.h b/source4/lib/replace/getaddrinfo.h
new file mode 100644 (file)
index 0000000..ed678bd
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this paragraph
+and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
+EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS
+TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+*/
+
+/*-------------------------------------------------------------------------
+ *
+ * getaddrinfo.h
+ *       Support getaddrinfo() on platforms that don't have it.
+ *
+ * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO,
+ * whether or not the library routine getaddrinfo() can be found.  This
+ * policy is needed because on some platforms a manually installed libbind.a
+ * may provide getaddrinfo(), yet the system headers may not provide the
+ * struct definitions needed to call it.  To avoid conflict with the libbind
+ * definition in such cases, we rename our routines to pg_xxx() via macros.
+ *
+ * This code will also work on platforms where struct addrinfo is defined
+ * in the system headers but no getaddrinfo() can be located.
+ *
+ * Copyright (c) 2003-2007, PostgreSQL Global Development Group
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GETADDRINFO_H
+#define GETADDRINFO_H
+
+
+/* Various macros that ought to be in <netdb.h>, but might not be */
+
+#ifndef EAI_FAIL
+#define EAI_BADFLAGS   (-1)
+#define EAI_NONAME             (-2)
+#define EAI_AGAIN              (-3)
+#define EAI_FAIL               (-4)
+#define EAI_FAMILY             (-6)
+#define EAI_SOCKTYPE   (-7)
+#define EAI_SERVICE            (-8)
+#define EAI_MEMORY             (-10)
+#define EAI_SYSTEM             (-11)
+#endif   /* !EAI_FAIL */
+
+#ifndef AI_PASSIVE
+#define AI_PASSIVE             0x0001
+#endif
+
+#ifndef AI_NUMERICHOST
+/*
+ * some platforms don't support AI_NUMERICHOST; define as zero if using
+ * the system version of getaddrinfo...
+ */
+#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
+#define AI_NUMERICHOST 0
+#else
+#define AI_NUMERICHOST 0x0004
+#endif
+#endif
+
+#ifndef NI_NUMERICHOST
+#define NI_NUMERICHOST 1
+#endif
+
+#ifndef NI_NUMERICSERV
+#define NI_NUMERICSERV 2
+#endif
+
+#ifndef NI_NOFQDN
+#define NI_NOFQDN      4
+#endif
+
+#ifndef NI_NAMEREQD
+#define NI_NAMEREQD    8
+#endif
+
+#ifndef NI_DGRAM
+#define NI_DGRAM       16
+#endif
+
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST     1025
+#endif
+
+#ifndef NI_MAXSERV
+#define NI_MAXSERV     32
+#endif
+
+#ifndef HAVE_STRUCT_ADDRINFO
+
+struct addrinfo
+{
+       int                     ai_flags;
+       int                     ai_family;
+       int                     ai_socktype;
+       int                     ai_protocol;
+       size_t          ai_addrlen;
+       struct sockaddr *ai_addr;
+       char       *ai_canonname;
+       struct addrinfo *ai_next;
+};
+#endif   /* HAVE_STRUCT_ADDRINFO */
+
+
+#ifndef HAVE_GETADDRINFO
+
+/* Rename private copies per comments above */
+#ifdef getaddrinfo
+#undef getaddrinfo
+#endif
+#define getaddrinfo pg_getaddrinfo
+
+#ifdef freeaddrinfo
+#undef freeaddrinfo
+#endif
+#define freeaddrinfo pg_freeaddrinfo
+
+#ifdef gai_strerror
+#undef gai_strerror
+#endif
+#define gai_strerror pg_gai_strerror
+
+#ifdef getnameinfo
+#undef getnameinfo
+#endif
+#define getnameinfo pg_getnameinfo
+
+extern int getaddrinfo(const char *node, const char *service,
+                       const struct addrinfo * hints, struct addrinfo ** res);
+extern void freeaddrinfo(struct addrinfo * res);
+extern const char *gai_strerror(int errcode);
+extern int getnameinfo(const struct sockaddr * sa, socklen_t salen,
+                       char *node, size_t nodelen,
+                       char *service, size_t servicelen, int flags);
+#endif   /* HAVE_GETADDRINFO */
+
+#endif   /* GETADDRINFO_H */
diff --git a/source4/lib/replace/inet_ntop.c b/source4/lib/replace/inet_ntop.c
new file mode 100644 (file)
index 0000000..fb3d8e9
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 1996-2001  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include "replace.h"
+#include "system/network.h"
+
+#define NS_INT16SZ      2
+#define NS_IN6ADDRSZ   16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const unsigned char *src, char *dst,
+                             socklen_t size);
+
+#ifdef AF_INET6
+static const char *inet_ntop6(const unsigned char *src, char *dst,
+                             socklen_t size);
+#endif
+
+/* char *
+ * isc_net_ntop(af, src, dst, size)
+ *     convert a network format address to presentation format.
+ * return:
+ *     pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ *     Paul Vixie, 1996.
+ */
+const char *
+rep_inet_ntop(int af, const void *src, char *dst, socklen_t size)
+{
+       switch (af) {
+       case AF_INET:
+               return (inet_ntop4(src, dst, size));
+#ifdef AF_INET6
+       case AF_INET6:
+               return (inet_ntop6(src, dst, size));
+#endif
+       default:
+               errno = EAFNOSUPPORT;
+               return (NULL);
+       }
+       /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ *     format an IPv4 address
+ * return:
+ *     `dst' (as a const)
+ * notes:
+ *     (1) uses no statics
+ *     (2) takes a unsigned char* not an in_addr as input
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const unsigned char *src, char *dst, socklen_t size)
+{
+       static const char *fmt = "%u.%u.%u.%u";
+       char tmp[sizeof "255.255.255.255"];
+       size_t len;
+
+       len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]);
+       if (len >= size) {
+               errno = ENOSPC;
+               return (NULL);
+       }
+       memcpy(dst, tmp, len + 1);
+
+       return (dst);
+}
+
+/* const char *
+ * isc_inet_ntop6(src, dst, size)
+ *     convert IPv6 binary address into presentation (printable) format
+ * author:
+ *     Paul Vixie, 1996.
+ */
+#ifdef AF_INET6
+static const char *
+inet_ntop6(const unsigned char *src, char *dst, socklen_t size)
+{
+       /*
+        * Note that int32_t and int16_t need only be "at least" large enough
+        * to contain a value of the specified size.  On some systems, like
+        * Crays, there is no such thing as an integer variable with 16 bits.
+        * Keep this in mind if you think this function should have been coded
+        * to use pointer overlays.  All the world's not a VAX.
+        */
+       char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+       struct { int base, len; } best, cur;
+       unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
+       int i, inc;
+
+       /*
+        * Preprocess:
+        *      Copy the input (bytewise) array into a wordwise array.
+        *      Find the longest run of 0x00's in src[] for :: shorthanding.
+        */
+       memset(words, '\0', sizeof words);
+       for (i = 0; i < NS_IN6ADDRSZ; i++)
+               words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+       best.base = -1;
+       best.len = 0;
+       cur.base = -1;
+       cur.len = 0;
+       for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+               if (words[i] == 0) {
+                       if (cur.base == -1)
+                               cur.base = i, cur.len = 1;
+                       else
+                               cur.len++;
+               } else {
+                       if (cur.base != -1) {
+                               if (best.base == -1 || cur.len > best.len)
+                                       best = cur;
+                               cur.base = -1;
+                       }
+               }
+       }
+       if (cur.base != -1) {
+               if (best.base == -1 || cur.len > best.len)
+                       best = cur;
+       }
+       if (best.base != -1 && best.len < 2)
+               best.base = -1;
+
+       /*
+        * Format the result.
+        */
+       tp = tmp;
+       for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+               /* Are we inside the best run of 0x00's? */
+               if (best.base != -1 && i >= best.base &&
+                   i < (best.base + best.len)) {
+                       if (i == best.base)
+                               *tp++ = ':';
+                       continue;
+               }
+               /* Are we following an initial run of 0x00s or any real hex? */
+               if (i != 0)
+                       *tp++ = ':';
+               /* Is this address an encapsulated IPv4? */
+               if (i == 6 && best.base == 0 &&
+                   (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+                       if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+                               return (NULL);
+                       tp += strlen(tp);
+                       break;
+               }
+               inc = snprintf(tp, 5, "%x", words[i]);
+               if (inc >= 5) {
+                       abort();
+               }
+               tp += inc;
+       }
+       /* Was it a trailing run of 0x00's? */
+       if (best.base != -1 && (best.base + best.len) ==
+           (NS_IN6ADDRSZ / NS_INT16SZ))
+               *tp++ = ':';
+       *tp++ = '\0';
+
+       /*
+        * Check for overflow, copy, and we're done.
+        */
+       if ((size_t)(tp - tmp) > size) {
+               errno = ENOSPC;
+               return (NULL);
+       }
+       memcpy(dst, tmp, tp - tmp);
+       return (dst);
+}
+#endif /* AF_INET6 */
diff --git a/source4/lib/replace/inet_ntop.m4 b/source4/lib/replace/inet_ntop.m4
new file mode 100644 (file)
index 0000000..6f39056
--- /dev/null
@@ -0,0 +1 @@
+AC_CHECK_FUNCS(inet_ntop,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_ntop.o"])
diff --git a/source4/lib/replace/inet_pton.c b/source4/lib/replace/inet_pton.c
new file mode 100644 (file)
index 0000000..80e4865
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 1996-2001  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+#define NS_INT16SZ      2
+#define NS_INADDRSZ     4
+#define NS_IN6ADDRSZ   16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4(const char *src, unsigned char *dst);
+#ifdef AF_INET6
+static int inet_pton6(const char *src, unsigned char *dst);
+#endif
+
+/* int
+ * inet_pton(af, src, dst)
+ *     convert from presentation format (which usually means ASCII printable)
+ *     to network format (which is usually some kind of binary format).
+ * return:
+ *     1 if the address was valid for the specified address family
+ *     0 if the address wasn't valid (`dst' is untouched in this case)
+ *     -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *     Paul Vixie, 1996.
+ */
+int
+rep_inet_pton(int af,
+         const char *src,
+         void *dst)
+{
+       switch (af) {
+       case AF_INET:
+               return (inet_pton4(src, dst));
+#ifdef AF_INET6
+       case AF_INET6:
+               return (inet_pton6(src, dst));
+#endif
+       default:
+               errno = EAFNOSUPPORT;
+               return (-1);
+       }
+       /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *     like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *     1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *     does not touch `dst' unless it's returning 1.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+       const char *src;
+       unsigned char *dst;
+{
+       static const char digits[] = "0123456789";
+       int saw_digit, octets, ch;
+       unsigned char tmp[NS_INADDRSZ], *tp;
+
+       saw_digit = 0;
+       octets = 0;
+       *(tp = tmp) = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr(digits, ch)) != NULL) {
+                       unsigned int new = *tp * 10 + (pch - digits);
+
+                       if (new > 255)
+                               return (0);
+                       *tp = new;
+                       if (! saw_digit) {
+                               if (++octets > 4)
+                                       return (0);
+                               saw_digit = 1;
+                       }
+               } else if (ch == '.' && saw_digit) {
+                       if (octets == 4)
+                               return (0);
+                       *++tp = 0;
+                       saw_digit = 0;
+               } else
+                       return (0);
+       }
+       if (octets < 4)
+               return (0);
+       memcpy(dst, tmp, NS_INADDRSZ);
+       return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *     convert presentation level address to network order binary form.
+ * return:
+ *     1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *     (1) does not touch `dst' unless it's returning 1.
+ *     (2) :: in a full address is silently ignored.
+ * credit:
+ *     inspired by Mark Andrews.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+#ifdef AF_INET6
+static int
+inet_pton6(src, dst)
+       const char *src;
+       unsigned char *dst;
+{
+       static const char xdigits_l[] = "0123456789abcdef",
+                         xdigits_u[] = "0123456789ABCDEF";
+       unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+       const char *xdigits, *curtok;
+       int ch, saw_xdigit;
+       unsigned int val;
+
+       memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+       endp = tp + NS_IN6ADDRSZ;
+       colonp = NULL;
+       /* Leading :: requires some special handling. */
+       if (*src == ':')
+               if (*++src != ':')
+                       return (0);
+       curtok = src;
+       saw_xdigit = 0;
+       val = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+                       pch = strchr((xdigits = xdigits_u), ch);
+               if (pch != NULL) {
+                       val <<= 4;
+                       val |= (pch - xdigits);
+                       if (val > 0xffff)
+                               return (0);
+                       saw_xdigit = 1;
+                       continue;
+               }
+               if (ch == ':') {
+                       curtok = src;
+                       if (!saw_xdigit) {
+                               if (colonp)
+                                       return (0);
+                               colonp = tp;
+                               continue;
+                       }
+                       if (tp + NS_INT16SZ > endp)
+                               return (0);
+                       *tp++ = (unsigned char) (val >> 8) & 0xff;
+                       *tp++ = (unsigned char) val & 0xff;
+                       saw_xdigit = 0;
+                       val = 0;
+                       continue;
+               }
+               if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+                   inet_pton4(curtok, tp) > 0) {
+                       tp += NS_INADDRSZ;
+                       saw_xdigit = 0;
+                       break;  /* '\0' was seen by inet_pton4(). */
+               }
+               return (0);
+       }
+       if (saw_xdigit) {
+               if (tp + NS_INT16SZ > endp)
+                       return (0);
+               *tp++ = (unsigned char) (val >> 8) & 0xff;
+               *tp++ = (unsigned char) val & 0xff;
+       }
+       if (colonp != NULL) {
+               /*
+                * Since some memmove()'s erroneously fail to handle
+                * overlapping regions, we'll do the shift by hand.
+                */
+               const int n = tp - colonp;
+               int i;
+
+               for (i = 1; i <= n; i++) {
+                       endp[- i] = colonp[n - i];
+                       colonp[n - i] = 0;
+               }
+               tp = endp;
+       }
+       if (tp != endp)
+               return (0);
+       memcpy(dst, tmp, NS_IN6ADDRSZ);
+       return (1);
+}
+#endif
diff --git a/source4/lib/replace/inet_pton.m4 b/source4/lib/replace/inet_pton.m4
new file mode 100644 (file)
index 0000000..51de927
--- /dev/null
@@ -0,0 +1 @@
+AC_CHECK_FUNCS(inet_pton,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_pton.o"])
index a6b1c4f5e68e609a463dd935260cfa6184ad37a4..29ec2acdabbeb0c286b84ce0e753a2877aac159d 100644 (file)
@@ -137,6 +137,45 @@ if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then
     AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced])
 fi
 
+dnl test for struct addrinfo
+AC_CACHE_CHECK([for struct addrinfo],samba_cv_HAVE_STRUCT_ADDRINFO,[
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>],
+[
+struct addrinfo ai;
+],
+samba_cv_HAVE_STRUCT_ADDRINFO=yes,samba_cv_HAVE_STRUCT_ADDRINFO=no)])
+if test x"$samba_cv_HAVE_STRUCT_ADDRINFO" = x"yes"; then
+    AC_DEFINE(HAVE_STRUCT_ADDRINFO,1,[Whether the system has struct addrinfo])
+fi
+
+dnl test for getaddrinfo/getnameinfo
+AC_CACHE_CHECK([for getaddrinfo],samba_cv_HAVE_GETADDRINFO,[
+AC_TRY_COMPILE([
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netdb.h>],
+[
+struct sockaddr sa;
+struct addrinfo *ai = NULL;
+int ret = getaddrinfo(NULL, NULL, NULL, &ai);
+if (ret != 0) {
+       const char *es = gai_strerror(ret);
+}
+freeaddrinfo(ai);
+ret = getnameinfo(&sa, sizeof(sa),
+               NULL, 0,
+               NULL, 0, 0);
+
+],
+samba_cv_HAVE_GETADDRINFO=yes,samba_cv_HAVE_GETADDRINFO=no)])
+if test x"$samba_cv_HAVE_GETADDRINFO" = x"yes"; then
+    AC_DEFINE(HAVE_GETADDRINFO,1,[Whether the system has getaddrinfo and getnameinfo])
+fi
+
+
 dnl Provided by replace.c:
 AC_TRY_COMPILE([
 #include <sys/types.h>
@@ -304,7 +343,7 @@ AC_TRY_COMPILE([
 samba_cv_HAVE_OPEN_O_DIRECT=yes,samba_cv_HAVE_OPEN_O_DIRECT=no)])
 if test x"$samba_cv_HAVE_OPEN_O_DIRECT" = x"yes"; then
     AC_DEFINE(HAVE_OPEN_O_DIRECT,1,[Whether the open(2) accepts O_DIRECT])
-fi 
+fi
 
 
 dnl Check if the C compiler understands volatile (it should, being ANSI).
@@ -322,6 +361,8 @@ m4_include(getpass.m4)
 m4_include(strptime.m4)
 m4_include(win32.m4)
 m4_include(timegm.m4)
+m4_include(inet_ntop.m4)
+m4_include(inet_pton.m4)
 m4_include(repdir.m4)
 
 AC_CHECK_FUNCS([syslog memset memcpy],,[AC_MSG_ERROR([Required function not found])])
index af05516e8ceea7c1a738ef61596c93644d61b22b..26e39ac603dc6974212158a93361724581ebbf61 100644 (file)
@@ -1,15 +1,16 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
 
    macros to go along with the lib/replace/ portability layer code
 
    Copyright (C) Andrew Tridgell 2005
    Copyright (C) Jelmer Vernooij 2006
+   Copyright (C) Jeremy Allison 2007.
 
      ** NOTE! The following LGPL license applies to the replace
      ** library. This does NOT imply that all of Samba is released
      ** under the LGPL
-   
+
    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
@@ -71,7 +72,6 @@
 #include <stddef.h>
 #endif
 
-
 #ifndef HAVE_STRERROR
 extern char *sys_errlist[];
 #define strerror(i) sys_errlist[i]
@@ -139,7 +139,7 @@ int setenv(const char *name, const char *value, int overwrite);
 
 #ifndef HAVE_UNSETENV
 #define unsetenv rep_unsetenv
-int rep_unsetenv(const char *name); 
+int rep_unsetenv(const char *name);
 #endif
 
 #ifndef HAVE_SETEUID
@@ -163,7 +163,7 @@ char *rep_strcasestr(const char *haystack, const char *needle);
 #endif
 
 #ifndef HAVE_STRTOK_R
-#define strtok_r rep_strtok_r 
+#define strtok_r rep_strtok_r
 char *rep_strtok_r(char *s, const char *delim, char **save_ptr);
 #endif
 
@@ -330,6 +330,17 @@ ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset);
 ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset);
 #endif
 
+#ifndef HAVE_INET_PTON
+int rep_inet_pton(int af, const char *src, void *dst);
+#define inet_pton rep_inet_pton
+#endif
+
+#ifndef HAVE_INET_NTOP
+#include "system/network.h"
+const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size);
+#define inet_ntop rep_inet_ntop
+#endif
+
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
index 7469040b283fe3633b52e39b46c2e83d70a95782..877f5f25e61bcbcbd6a2a4626cb6db347a1aa77a 100644 (file)
 #include <netinet/tcp.h>
 #endif
 
+#if !defined(HAVE_GETADDRINFO)
+#include "getaddrinfo.h"
+#endif
+
 /*
  * The next three defines are needed to access the IPTOS_* options
  * on some systems.