From bc8dc4e1c0ddaae0f83bdf16b8c0ae72160f15ab Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Wed, 6 Dec 2000 11:46:04 +0000 Subject: [PATCH] Use const sockaddr pointer in interface. Use get{name,addr}info if available, to pick up IPv6 support. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12884 dc483132-0cff-0310-8789-dd5450dbe970 --- src/util/pty/ChangeLog | 7 ++- src/util/pty/configure.in | 1 + src/util/pty/libpty.h | 4 +- src/util/pty/sane_hostname.c | 92 ++++++++++++++++++++++++++++++------ 4 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/util/pty/ChangeLog b/src/util/pty/ChangeLog index a7db011b0..903e7bb30 100644 --- a/src/util/pty/ChangeLog +++ b/src/util/pty/ChangeLog @@ -1,9 +1,14 @@ 2000-12-06 Ken Raeburn * sane_hostname.c (pty_make_sane_hostname, do_ntoa): Pass address - as sockaddr pointer. + as const sockaddr pointer. * libpty.h (pty_make_sane_hostname): Update prototype. + * sane_hostname.c (sockaddrlen, downcase): New function. + (do_ntoa, pty_make_sane_hostname): Reimplement using getnameinfo + and getaddrinfo if available. + * configure.in: Check for IPv6 support. + 2000-11-01 Ezra Peisach * configure.in: Quote macro use inside AC_CHECK_LIB. Change diff --git a/src/util/pty/configure.in b/src/util/pty/configure.in index a77083aee..52ccca73b 100644 --- a/src/util/pty/configure.in +++ b/src/util/pty/configure.in @@ -170,6 +170,7 @@ fi dnl dnl ADD_DEF(-DKERBEROS) +KRB5_AC_INET6 AC_C_CONST KRB5_BUILD_LIBRARY_WITH_DEPS KRB5_BUILD_LIBOBJS diff --git a/src/util/pty/libpty.h b/src/util/pty/libpty.h index 5e1200bf5..0274c98cd 100644 --- a/src/util/pty/libpty.h +++ b/src/util/pty/libpty.h @@ -46,10 +46,10 @@ long pty_logwtmp (char *tty, char * user, char *host); long pty_cleanup(char *slave, int pid, int update_utmp); #ifndef SOCK_DGRAM -struct sockaddr_in; +struct sockaddr; #endif -long pty_make_sane_hostname(struct sockaddr *, int, int, int, char **); +long pty_make_sane_hostname(const struct sockaddr *, int, int, int, char **); #else /*__STDC__*/ long pty_init(); long pty_getpty(); diff --git a/src/util/pty/sane_hostname.c b/src/util/pty/sane_hostname.c index 23955c06d..692e6e81a 100644 --- a/src/util/pty/sane_hostname.c +++ b/src/util/pty/sane_hostname.c @@ -21,31 +21,65 @@ */ #include #include "pty-int.h" +#include #include "libpty.h" #include +static size_t +sockaddrlen (const struct sockaddr *addr) +{ +#ifdef HAVE_SA_LEN + return addr->sa_len; +#else + if (addr->sa_family == AF_INET) + return sizeof (struct sockaddr_in); +#ifdef AF_INET6 + if (addr->sa_family == AF_INET6) + return sizeof (struct sockaddr_in6); +#endif + /* unknown address family */ + return 0; +#endif +} + +static void +downcase (char *s) +{ + for (; *s != '\0'; s++) + *s = tolower (*s); +} + static long -do_ntoa(struct sockaddr *addr, - size_t hostlen, - char **out) +do_ntoa(const struct sockaddr *addr, size_t hostlen, char **out) { +#ifdef HAVE_GETNAMEINFO + char addrbuf[NI_MAXHOST]; + if (getnameinfo (addr, sockaddrlen (addr), addrbuf, sizeof (addrbuf), + (char *)0, 0, NI_NUMERICHOST) == 0) + strncpy(*out, addrbuf, hostlen); + else + strncpy(*out, "??", hostlen); +#else if (addr->sa_family == AF_INET) - strncpy(*out, inet_ntoa(((struct sockaddr_in *)addr)->sin_addr), + strncpy(*out, inet_ntoa(((const struct sockaddr_in *)addr)->sin_addr), hostlen); else strncpy(*out, "??", hostlen); +#endif (*out)[hostlen - 1] = '\0'; return 0; } long -pty_make_sane_hostname(struct sockaddr *addr, - int maxlen, - int strip_ldomain, - int always_ipaddr, - char **out) +pty_make_sane_hostname(const struct sockaddr *addr, int maxlen, + int strip_ldomain, int always_ipaddr, char **out) { +#ifdef HAVE_GETNAMEINFO + struct addrinfo *ai; + char addrbuf[NI_MAXHOST]; +#else struct hostent *hp; +#endif #ifndef NO_UT_HOST struct utmp ut; #else @@ -70,9 +104,40 @@ pty_make_sane_hostname(struct sockaddr *addr, if (*out == NULL) return ENOMEM; - if (always_ipaddr) { + if (always_ipaddr) + use_ipaddr: return do_ntoa(addr, ut_host_len, out); + +#ifdef HAVE_GETNAMEINFO + /* If we didn't want to chop off the local domain, this would be + much simpler -- just a single getnameinfo call and a strncpy. */ + if (getnameinfo(addr, sockaddrlen (addr), addrbuf, sizeof (addrbuf), + (char *) NULL, 0, NI_NAMEREQD) != 0) + goto use_ipaddr; + downcase (addrbuf); + if (strip_ldomain) { + struct addrinfo hints; + (void) gethostname(lhost, sizeof (lhost)); + memset (&hints, 0, sizeof (hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_flags = AI_CANONNAME; + if (getaddrinfo(lhost, (char *)NULL, &hints, &ai) == 0 + && ai != NULL) { + if (ai->ai_canonname != NULL) { + downcase (ai->ai_canonname); + domain = strchr (ai->ai_canonname, '.'); + if (domain != NULL) { + cp = strstr (addrbuf, domain); + if (cp != NULL) + *cp = '\0'; + } + } + freeaddrinfo (ai); + } } + strncpy(*out, addrbuf, ut_host_len); + (*out)[ut_host_len - 1] = '\0'; +#else /* old gethostbyaddr interface; how quaint :-) */ if (addr->sa_family == AF_INET) hp = gethostbyaddr((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof (struct in_addr), addr->sa_family); @@ -83,8 +148,7 @@ pty_make_sane_hostname(struct sockaddr *addr, } strncpy(*out, hp->h_name, ut_host_len); (*out)[ut_host_len - 1] = '\0'; - for (cp = *out; *cp != '\0'; cp++) - *cp = tolower(*cp); + downcase (*out); if (strip_ldomain) { (void) gethostname(lhost, sizeof (lhost)); @@ -93,14 +157,14 @@ pty_make_sane_hostname(struct sockaddr *addr, strncpy(lhost, hp->h_name, sizeof (lhost)); domain = strchr(lhost, '.'); if (domain != NULL) { - for (cp = domain; *cp != '\0'; cp++) - *cp = tolower(*cp); + downcase (domain); cp = strstr(*out, domain); if (cp != NULL) *cp = '\0'; } } } +#endif if (strlen(*out) >= maxlen) { return do_ntoa(addr, ut_host_len, out); -- 2.26.2