Changed rprintf() calls that included strerror() to use rsyserr().
[rsync/rsync.git] / clientname.c
index 02846b3..b54e745 100644 (file)
@@ -55,8 +55,7 @@ char *client_addr(int fd)
 
        initialised = 1;
 
-       if (am_server) {
-               /* daemon over --rsh mode */
+       if (am_server) {        /* daemon over --rsh mode */
                strcpy(addr_buf, "0.0.0.0");
                if ((ssh_client = getenv("SSH_CLIENT")) != NULL) {
                        /* truncate SSH_CLIENT to just IP address */
@@ -101,11 +100,7 @@ char *client_name(int fd)
        static char name_buf[100];
        static char port_buf[100];
        static int initialised;
-       struct sockaddr_storage ss, *ssp;
-       struct sockaddr_in sin;
-#ifdef INET6
-       struct sockaddr_in6 sin6;
-#endif
+       struct sockaddr_storage ss;
        socklen_t ss_len;
 
        if (initialised)
@@ -114,43 +109,47 @@ char *client_name(int fd)
        strcpy(name_buf, default_name);
        initialised = 1;
 
+       memset(&ss, 0, sizeof ss);
+
        if (am_server) {        /* daemon over --rsh mode */
                char *addr = client_addr(fd);
-#ifdef INET6
-               int dots = 0;
-               char *p;
+               struct addrinfo hint, *answer;
+               int err;
 
-               for (p = addr; *p && (dots <= 3); p++) {
-                       if (*p == '.')
-                               dots++;
-               }
-               if (dots > 3) {
-                       /* more than 4 parts to IP address, must be ipv6 */
-                       ssp = (struct sockaddr_storage *) &sin6;
-                       ss_len = sizeof sin6;
-                       memset(ssp, 0, ss_len);
-                       inet_pton(AF_INET6, addr, &sin6.sin6_addr);
-                       sin6.sin6_family = AF_INET6;
-               } else
+               memset(&hint, 0, sizeof hint);
+
+#ifdef AI_NUMERICHOST
+               hint.ai_flags = AI_NUMERICHOST;
 #endif
-               {
-                       ssp = (struct sockaddr_storage *) &sin;
-                       ss_len = sizeof sin;
-                       memset(ssp, 0, ss_len);
-                       inet_pton(AF_INET, addr, &sin.sin_addr);
-                       sin.sin_family = AF_INET;
+               hint.ai_socktype = SOCK_STREAM;
+
+               if ((err = getaddrinfo(addr, NULL, &hint, &answer)) != 0) {
+                       rprintf(FERROR, RSYNC_NAME ": malformed address %s: %s\n",
+                               addr, gai_strerror(err));
+                       return name_buf;
                }
 
+               switch (answer->ai_family) {
+               case AF_INET:
+                       ss_len = sizeof (struct sockaddr_in);
+                       memcpy(&ss, answer->ai_addr, ss_len);
+                       break;
+#ifdef INET6
+               case AF_INET6:
+                       ss_len = sizeof (struct sockaddr_in6);
+                       memcpy(&ss, answer->ai_addr, ss_len);
+                       break;
+#endif
+               }
+               freeaddrinfo(answer);
        } else {
                ss_len = sizeof ss;
-               ssp = &ss;
-
                client_sockaddr(fd, &ss, &ss_len);
        }
 
-       if (!lookup_name(fd, ssp, ss_len, name_buf, sizeof name_buf,
+       if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf,
                        port_buf, sizeof port_buf))
-               check_name(fd, ssp, name_buf);
+               check_name(fd, &ss, name_buf);
 
        return name_buf;
 }
@@ -171,8 +170,7 @@ void client_sockaddr(int fd,
 
        if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
                /* FIXME: Can we really not continue? */
-               rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
-                       fd, strerror(errno));
+               rsyserr(FERROR, errno, "getpeername on fd%d failed", fd);
                exit_cleanup(RERR_SOCKETIO);
        }