r25505: Add a replacement (IPv4 only) implementation of getaddrinfo/freeaddrinfo
authorJeremy Allison <jra@samba.org>
Thu, 4 Oct 2007 17:20:49 +0000 (17:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:31:10 +0000 (12:31 -0500)
under the 2 clause *BSD license for future use in IPv6 code. Original
code was from PostgreSQL and I've maintained their license even though
I've rewritten large parts of it (I probably should donate this back
to them).
Jeremy.
(This used to be commit 760d993340a966269d71acfb7a6b5e4d3776ac5d)

source3/configure.in
source3/lib/replace/getaddrinfo.c [new file with mode: 0644]
source3/lib/replace/replace.h
source3/lib/replace/system/getaddrinfo.h [new file with mode: 0644]
source3/lib/replace/system/network.h
source3/lib/system.c
source3/lib/util.c

index 1a74583b3bb352639df9858b1fa7bec8b7f521fe..dd9d296f640e9c6f8b97f7453f6fe6d76fdd9271 100644 (file)
@@ -1370,7 +1370,7 @@ AC_CHECK_FUNCS(syslog vsyslog timegm)
 AC_CHECK_FUNCS(setlocale nl_langinfo)
 AC_CHECK_FUNCS(nanosleep)
 AC_CHECK_FUNCS(mlock munlock mlockall munlockall)
-AC_CHECK_FUNCS(memalign posix_memalign)
+AC_CHECK_FUNCS(memalign posix_memalign hstrerror)
 AC_CHECK_HEADERS(sys/mman.h)
 # setbuffer, shmget, shm_open are needed for smbtorture
 AC_CHECK_FUNCS(setbuffer shmget shm_open)
@@ -3195,18 +3195,55 @@ if test x"$samba_cv_HAVE_IPV6" = x"yes"; then
 fi
 
 dnl test for struct sockaddr_storage
-AC_CACHE_CHECK([for ipv6 support],samba_cv_HAVE_SOCKADDR_STORAGE,[
+AC_CACHE_CHECK([for ipv6 support],samba_cv_HAVE_STRUCT_SOCKADDR_STORAGE,[
 AC_TRY_COMPILE([
 #include <sys/socket.h>
 #include <sys/types.h>],
 [
 struct sockaddr_storage sa_store;
 ],
-samba_cv_HAVE_SOCKADDR_STORAGE=yes,samba_cv_HAVE_SOCKADDR_STORAGE=no)])
-if test x"$samba_cv_HAVE_SOCKADDR_STORAGE" = x"yes"; then
-    AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,[Whether the system has struct sockaddr_storage])
+samba_cv_HAVE_STRUCT_SOCKADDR_STORAGE=yes,samba_cv_HAVE_STRUCT_SOCKADDR_STORAGE=no)])
+if test x"$samba_cv_HAVE_STRUCT_SOCKADDR_STORAGE" = x"yes"; then
+    AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE,1,[Whether the system has struct sockaddr_storage])
 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
 
 ################################################
 # look for a method of setting the effective uid
diff --git a/source3/lib/replace/getaddrinfo.c b/source3/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;
+}
index 27265e35c4ff7c41c4eee14f9f9d955ddc5ea8ad..ca4becaa7087323c30ddec8d31f47ee498a9d520 100644 (file)
@@ -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,9 +330,7 @@ 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
 
-#if !defined(HAVE_INET_PTON) || !defined(HAVE_INET_NTOP)
 #include "system/network.h"
-#endif
 
 #ifndef HAVE_INET_PTON
 int rep_inet_pton(int af, const char *src, void *dst);
@@ -344,6 +342,10 @@ const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size);
 #define inet_ntop rep_inet_ntop
 #endif
 
+#if !defined(HAVE_GETADDRINFO)
+#include "system/getaddrinfo.h"
+#endif
+
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
diff --git a/source3/lib/replace/system/getaddrinfo.h b/source3/lib/replace/system/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 */
index d5d2be068e5aa64aead40b43ef20b8661795a7fe..a09d3bb01b7595bbf408a20d7ec344c92922af36 100644 (file)
@@ -126,9 +126,13 @@ typedef int socklen_t;
 typedef unsigned short int sa_family_t;
 #endif
 
-#ifndef HAVE_SOCKADDR_STORAGE
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
 #define sockaddr_storage sockaddr_in
 #define ss_family sin_family
 #endif
 
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 256
+#endif
+
 #endif
index ab5c06d5f675cd1a01b420b99b0843afab09ed18..bc7de847675c70975a6ce21a7f1a80289e0b2313 100644 (file)
@@ -683,7 +683,7 @@ int sys_chroot(const char *dname)
 }
 
 /**************************************************************************
-A wrapper for gethostbyname() that tries avoids looking up hostnames 
+A wrapper for gethostbyname() that tries avoids looking up hostnames
 in the root domain, which can cause dial-on-demand links to come up for no
 apparent reason.
 ****************************************************************************/
@@ -691,7 +691,7 @@ apparent reason.
 struct hostent *sys_gethostbyname(const char *name)
 {
 #ifdef REDUCE_ROOT_DNS_LOOKUPS
-       char query[256], hostname[256];
+       char query[HOST_NAME_MAX], hostname[HOST_NAME_MAX];
        char *domain;
 
        /* Does this name have any dots in it? If so, make no change */
@@ -699,9 +699,9 @@ struct hostent *sys_gethostbyname(const char *name)
        if (strchr_m(name, '.'))
                return(gethostbyname(name));
 
-       /* Get my hostname, which should have domain name 
+       /* Get my hostname, which should have domain name
                attached. If not, just do the gethostname on the
-               original string. 
+               original string.
        */
 
        gethostname(hostname, sizeof(hostname) - 1);
index 6c86376e57c12e0493497a866036669f00e787f0..b98441ea53d0eb531deaeaa3548105bdb044c719 100644 (file)
@@ -1203,7 +1203,7 @@ void safe_free(void *p)
 
 BOOL get_myname(char *my_name)
 {
-       pstring hostname;
+       fstring hostname;
 
        *hostname = 0;
 
@@ -1211,7 +1211,7 @@ BOOL get_myname(char *my_name)
        if (gethostname(hostname, sizeof(hostname)) == -1) {
                DEBUG(0,("gethostname failed\n"));
                return False;
-       } 
+       }
 
        /* Ensure null termination. */
        hostname[sizeof(hostname)-1] = '\0';
@@ -1222,10 +1222,10 @@ BOOL get_myname(char *my_name)
 
                if (p)
                        *p = 0;
-               
+
                fstrcpy(my_name,hostname);
        }
-       
+
        return(True);
 }