summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2002-04-12 07:56:36 +0000
committerKen Raeburn <raeburn@mit.edu>2002-04-12 07:56:36 +0000
commitddf3e92511e504db5c90964db2741dbbe193d88c (patch)
tree347b17012225c81d858fd5e12b968121cc0afb4c /src/include
parentd378c230edc4c24ff95bea6da9e900f0c14d1b73 (diff)
downloadkrb5-ddf3e92511e504db5c90964db2741dbbe193d88c.tar.gz
krb5-ddf3e92511e504db5c90964db2741dbbe193d88c.tar.xz
krb5-ddf3e92511e504db5c90964db2741dbbe193d88c.zip
* 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. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14388 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/include')
-rw-r--r--src/include/ChangeLog14
-rw-r--r--src/include/configure.in32
-rw-r--r--src/include/fake-addrinfo.h126
3 files changed, 149 insertions, 23 deletions
diff --git a/src/include/ChangeLog b/src/include/ChangeLog
index 4c4f6a60c..ad3d83cdf 100644
--- a/src/include/ChangeLog
+++ b/src/include/ChangeLog
@@ -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.
diff --git a/src/include/configure.in b/src/include/configure.in
index 09f57589b..6ddfdfe40 100644
--- a/src/include/configure.in
+++ b/src/include/configure.in
@@ -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
diff --git a/src/include/fake-addrinfo.h b/src/include/fake-addrinfo.h
index 3225fbcd5..bcfabcc6d 100644
--- a/src/include/fake-addrinfo.h
+++ b/src/include/fake-addrinfo.h
@@ -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? :-) */
@@ -99,15 +101,74 @@
#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? */