* configure.in: Check for gethostbyname_r, gethostbyaddr_r, getservbyname_r and
authorKen Raeburn <raeburn@mit.edu>
Fri, 12 Apr 2002 07:56:36 +0000 (07:56 +0000)
committerKen Raeburn <raeburn@mit.edu>
Fri, 12 Apr 2002 07:56:36 +0000 (07:56 +0000)
getservbyport_r.  Figure out the return type of gethostbyname_r.
* fake-addrinfo.h (GET_HOST_BY_NAME, GET_HOST_BY_ADDR): New macros.
(fai_add_hosts_by_name, fake_getnameinfo, getaddrinfo): Use them.
(fake_getaddrinfo): Use getservbyname_r if available.
(fake_getnameinfo): Never call inet_ntoa; in open-coded form, initialize local
pointer variable after label.  Use getservbyport_r if available.
(gaiptr, faiptr, gniptr): Pointer variables are now const.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14388 dc483132-0cff-0310-8789-dd5450dbe970

src/include/ChangeLog
src/include/configure.in
src/include/fake-addrinfo.h

index 4c4f6a60c93acafc7905aee594d313ac5678b195..ad3d83cdfc95cac62bccb3c07103fcabdd62aa65 100644 (file)
@@ -1,3 +1,17 @@
+2002-04-12  Ken Raeburn  <raeburn@mit.edu>
+
+       * configure.in: Check for gethostbyname_r, gethostbyaddr_r,
+       getservbyname_r and getservbyport_r.  Figure out the return type
+       of gethostbyname_r.
+       * fake-addrinfo.h (GET_HOST_BY_NAME, GET_HOST_BY_ADDR): New
+       macros.
+       (fai_add_hosts_by_name, fake_getnameinfo, getaddrinfo): Use them.
+       (fake_getaddrinfo): Use getservbyname_r if available.
+       (fake_getnameinfo): Never call inet_ntoa; in open-coded form,
+       initialize local pointer variable after label.  Use
+       getservbyport_r if available.
+       (gaiptr, faiptr, gniptr): Pointer variables are now const.
+
 2002-04-10  Danilo Almeida  <dalmeida@mit.edu>
 
        * port-sockets.h: Use Winsock 2 headers for Win32.
index 09f57589be86f7b7ee02dee8f3af873e4adba65b..6ddfdfe40da6b4875229806e53bdff56b29d7d59 100644 (file)
@@ -5,7 +5,37 @@ AC_PROG_INSTALL
 AC_PROG_AWK
 AC_PROG_LEX
 AC_C_CONST
-AC_CHECK_FUNCS(strdup labs setvbuf memmove bcopy inet_ntoa inet_aton)
+AC_CHECK_FUNCS(strdup labs setvbuf memmove bcopy inet_ntoa inet_aton gethostbyname_r gethostbyaddr_r getservbyname_r getservbyport_r)
+dnl
+dnl Check what the return type for gethostbyname_r is.
+dnl I don't think we need this for getservbyname_r at the moment, but
+dnl it does have similar issues.
+dnl
+if test "$ac_cv_func_gethostbyname_r" = yes; then
+  AC_MSG_CHECKING([if gethostbyname_r returns an int])
+  AC_CACHE_VAL(krb5_cv_gethostbyname_r_returns_int,
+  [AC_TRY_COMPILE([#include <netdb.h>
+  extern int gethostbyname_r ();], [1;],
+  krb5_cv_gethostbyname_r_returns_int=yes,
+  krb5_cv_gethostbyname_r_returns_int=no)])
+  AC_MSG_RESULT($krb5_cv_gethostbyname_r_returns_int)
+
+  AC_MSG_CHECKING([if gethostbyname_r returns a pointer])
+  AC_CACHE_VAL(krb5_cv_gethostbyname_r_returns_ptr,
+  [AC_TRY_COMPILE([#include <netdb.h>
+  extern struct hostent *gethostbyname_r ();], [1;],
+  krb5_cv_gethostbyname_r_returns_ptr=yes,
+  krb5_cv_gethostbyname_r_returns_ptr=no)])
+  AC_MSG_RESULT($krb5_cv_gethostbyname_r_returns_ptr)
+
+  if test "$krb5_cv_gethostbyname_r_returns_int" = "$krb5_cv_gethostbyname_r_returns_ptr"; then
+    AC_MSG_ERROR(cannot determine return type of gethostbyname_r)
+  fi
+  if test "$krb5_cv_gethostbyname_r_returns_int" = yes; then
+    AC_DEFINE(GETHOSTBYNAME_R_RETURNS_INT, 1, [Define if gethostbyname_r returns int rather than struct hostent * ])
+  fi
+fi
+dnl
 HAVE_YYLINENO
 CHECK_DIRENT
 AC_TYPE_UID_T
index 3225fbcd5d39661ca80c11a07f23fba71321e45c..bcfabcc6d8d97c0984b2616996d51e87d599426a 100644 (file)
@@ -80,6 +80,8 @@
      supporting IPv6 at all, they really should be doing getaddrinfo
      by now.
 
+   + inet_ntop, inet_pton
+
    + Upgrade host requirements to include working implementations of
      these functions, and throw all this away.  Pleeease?  :-)  */
 
 #define HAVE_GETNAMEINFO
 #endif
 
+
+/* Do we actually have *any* systems we care about that don't provide
+   either getaddrinfo or one of these two flavors of
+   gethostbyname_r?  */
+#ifndef HAVE_GETHOSTBYNAME_R
+#define GET_HOST_BY_NAME(NAME, HP, ERR) \
+    { (HP) = gethostbyname (NAME); (ERR) = h_errno; }
+#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
+    { (HP) = gethostbyaddr ((ADDR), (ADDRLEN), (FAMILY)); (ERR) = h_errno; }
+#else
+#ifdef GETHOSTBYNAME_R_RETURNS_INT
+#define GET_HOST_BY_NAME(NAME, HP, ERR) \
+    {                                                                  \
+       struct hostent my_h_ent, *my_hp;                                \
+       int my_h_err;                                                   \
+       char my_h_buf[8192];                                            \
+       (HP) = (gethostbyname_r((NAME), &my_h_ent,                      \
+                               my_h_buf, sizeof (my_h_buf), &my_hp,    \
+                               &my_h_err)                              \
+               ? &my_h_ent                                             \
+               : 0);                                                   \
+       (ERR) = my_h_err;                                               \
+    }
+#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
+    {                                                                  \
+       struct hostent my_h_ent;                                        \
+       int my_h_err;                                                   \
+       char my_h_buf[8192];                                            \
+       (HP) = (gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent, \
+                               my_h_buf, sizeof (my_h_buf), &my_hp,    \
+                               &my_h_err)                              \
+               ? &my_h_ent                                             \
+               : 0);                                                   \
+       (ERR) = my_h_err;                                               \
+    }
+#else
+#define GET_HOST_BY_NAME(NAME, HP, ERR) \
+    {                                                                  \
+       struct hostent my_h_ent;                                        \
+       int my_h_err;                                                   \
+       char my_h_buf[8192];                                            \
+       (HP) = gethostbyname_r((NAME), &my_h_ent,                       \
+                              my_h_buf, sizeof (my_h_buf), &my_h_err); \
+       (ERR) = my_h_err;                                               \
+    }
+#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
+    {                                                                  \
+       struct hostent my_h_ent;                                        \
+       int my_h_err;                                                   \
+       char my_h_buf[8192];                                            \
+       (HP) = gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent,  \
+                              my_h_buf, sizeof (my_h_buf), &my_h_err); \
+       (ERR) = my_h_err;                                               \
+    }
+#endif
+#endif
+
 #ifdef WRAP_GETADDRINFO
-static int (*gaiptr) (const char *, const char *, const struct addrinfo *,
-                     struct addrinfo **) = &getaddrinfo;
-static void (*faiptr) (struct addrinfo *) = &freeaddrinfo;
+static int (*const gaiptr) (const char *, const char *,
+                           const struct addrinfo *,
+                           struct addrinfo **) = &getaddrinfo;
+static void (*const faiptr) (struct addrinfo *) = &freeaddrinfo;
 #endif
 
 #ifdef WRAP_GETNAMEINFO
-static int (*gniptr) (const struct sockaddr *, socklen_t,
-                     char *, size_t, char *, size_t, int) = &getnameinfo;
+static int (*const gniptr) (const struct sockaddr *, socklen_t,
+                           char *, size_t, char *, size_t,
+                           int) = &getnameinfo;
 #endif
 
 #if !defined (HAVE_GETADDRINFO) || defined(WRAP_GETADDRINFO)
@@ -299,13 +360,14 @@ static inline int fai_add_hosts_by_name (const char *name, int af,
 {
     struct hostent *hp;
     int i, r;
+    int herr;
 
     if (af != AF_INET)
        /* For now, real ipv6 support needs real getaddrinfo.  */
        return EAI_FAMILY;
-    hp = gethostbyname (name);
+    GET_HOST_BY_NAME (name, hp, herr);
     if (hp == 0)
-       return translate_h_errno (h_errno);
+       return translate_h_errno (herr);
     for (i = 0; hp->h_addr_list[i]; i++) {
        r = fai_add_entry (result, hp->h_addr_list[i], portnum, template);
        if (r)
@@ -367,7 +429,17 @@ fake_getaddrinfo (const char *name, const char *serv,
                socktype = SOCK_STREAM;
            }
        try_service_lookup:
+#ifdef HAVE_GETSERVBYNAME_R
+           {
+               char my_s_buf[1024];
+               struct servent my_s_ent;
+               sp = getservbyname_r(serv,
+                                    socktype == SOCK_STREAM ? "tcp" : "udp",
+                                    &my_s_ent, my_s_buf, sizeof(my_s_buf));
+           }
+#else
            sp = getservbyname (serv, socktype == SOCK_STREAM ? "tcp" : "udp");
+#endif
            if (sp == 0) {
                if (try_dgram_too) {
                    socktype = SOCK_DGRAM;
@@ -440,14 +512,15 @@ fake_getnameinfo (const struct sockaddr *sa, socklen_t len,
 
     if (host) {
        if (flags & NI_NUMERICHOST) {
-#if defined(__GNUC__) && defined(__mips__)
-           /* The inet_ntoa call, passing a struct, fails on Irix 6.5
+#if (defined(__GNUC__) && defined(__mips__)) || 1 /* thread-safe version */
+           /* The inet_ntoa call, passing a struct, fails on IRIX 6.5
               using gcc 2.95; we get back "0.0.0.0".  Since this in a
               configuration still important at Athena, here's the
               workaround....  */
-           const unsigned char *uc = (const unsigned char *) &sinp->sin_addr;
+           const unsigned char *uc;
            char tmpbuf[20];
        numeric_host:
+           uc = (const unsigned char *) &sinp->sin_addr;
            sprintf(tmpbuf, "%d.%d.%d.%d", uc[0], uc[1], uc[2], uc[3]);
            strncpy(host, tmpbuf, hostlen);
 #else
@@ -457,13 +530,13 @@ fake_getnameinfo (const struct sockaddr *sa, socklen_t len,
            strncpy (host, p, hostlen);
 #endif
        } else {
-           hp = gethostbyaddr ((const char *) &sinp->sin_addr,
-                               sizeof (struct in_addr),
-                               sa->sa_family);
+           int herr;
+           GET_HOST_BY_ADDR(&sinp->sin_addr, sizeof (struct in_addr),
+                            sa->sa_family, hp, herr);
            if (hp == 0) {
-               if (h_errno == NO_ADDRESS && !(flags & NI_NAMEREQD)) /* ??? */
+               if (herr == NO_ADDRESS && !(flags & NI_NAMEREQD)) /* ??? */
                    goto numeric_host;
-               return translate_h_errno (h_errno);
+               return translate_h_errno (herr);
            }
            /* According to the Open Group spec, getnameinfo can
               silently truncate, but must still return a
@@ -484,8 +557,16 @@ fake_getnameinfo (const struct sockaddr *sa, socklen_t len,
            sprintf (numbuf, "%d", port);
            strncpy (service, numbuf, servicelen);
        } else {
+#ifdef HAVE_GETSERVBYPORT_R
+           char my_s_buf[1024];
+           struct servent my_s_ent;
+           sp = getservbyport_r(sinp->sin_port,
+                                (flags & NI_DGRAM) ? "udp" : "tcp",
+                                &my_s_ent, my_s_buf, sizeof(my_s_buf));
+#else
            sp = getservbyport (sinp->sin_port,
                                (flags & NI_DGRAM) ? "udp" : "tcp");
+#endif
            if (sp == 0)
                goto numeric_service;
            strncpy (service, sp->s_name, servicelen);
@@ -576,12 +657,13 @@ int getnameinfo (const struct sockaddr *sa, socklen_t len,
    have to be initialized at the end, because the way we initialize
    them (for UNIX) is #undef and a reference to the C library symbol
    name.  */
-static int (*gaiptr) (const char *, const char *, const struct addrinfo *,
-                     struct addrinfo **);
-static void (*faiptr) (struct addrinfo *);
+static int (*const gaiptr) (const char *, const char *,
+                           const struct addrinfo *,
+                           struct addrinfo **);
+static void (*const faiptr) (struct addrinfo *);
 #ifdef WRAP_GETNAMEINFO
-static int (*gniptr) (const struct sockaddr *, socklen_t,
-                     char *, size_t, char *, size_t, int);
+static int (*const gniptr) (const struct sockaddr *, socklen_t,
+                           char *, size_t, char *, size_t, int);
 #endif
 
 #ifdef WRAP_GETADDRINFO
@@ -633,9 +715,9 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
     if (name && hint && (hint->ai_flags & AI_CANONNAME)) {
        struct hostent *hp;
        const char *name2 = 0;
-       int i;
+       int i, herr;
 
-       hp = gethostbyname(name);
+       GET_HOST_BY_NAME (name, hp, herr);
        if (hp == 0) {
            if ((*result)->ai_canonname != 0)
                /* XXX Indicate success with the existing name?  */