Use const sockaddr pointer in interface.
authorKen Raeburn <raeburn@mit.edu>
Wed, 6 Dec 2000 11:46:04 +0000 (11:46 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 6 Dec 2000 11:46:04 +0000 (11:46 +0000)
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
src/util/pty/configure.in
src/util/pty/libpty.h
src/util/pty/sane_hostname.c

index a7db011b063ec8de9507cadc8b4766d562868e47..903e7bb30d575b0121947b48be48cf4959556349 100644 (file)
@@ -1,9 +1,14 @@
 2000-12-06  Ken Raeburn  <raeburn@mit.edu>
 
        * 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  <epeisach@mit.edu>
 
        * configure.in: Quote macro use inside AC_CHECK_LIB. Change
index a77083aeebc1b78b9c372b9be6e34320c4ac19d2..52ccca73b0e3e8880b342c40e647e3ac645ac249 100644 (file)
@@ -170,6 +170,7 @@ fi
 dnl
 dnl
 ADD_DEF(-DKERBEROS)
+KRB5_AC_INET6
 AC_C_CONST
 KRB5_BUILD_LIBRARY_WITH_DEPS
 KRB5_BUILD_LIBOBJS
index 5e1200bf527f5b19365faf5c246a92653944ede7..0274c98cdd9d1a9a25f233b79467bf9c4735217a 100644 (file)
@@ -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();
index 23955c06da7eff4a2454fefe9af75f9eea232385..692e6e81a107b1e9dab2dc7ee8bf449004765100 100644 (file)
  */
 #include <com_err.h>
 #include "pty-int.h"
+#include <sys/socket.h>
 #include "libpty.h"
 #include <arpa/inet.h>
 
+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);