On Wed, 15 Mar 2017 09:57:26 -0600, "Todd C. Miller" wrote:

> There's no need to realloc() a chunk of memory when you don't care
> about the old contents, we don't want have to memcpy() the old
> contents to the new chunk only to throw it away.
> While here, use asprintf() to simplify things.

Updated diff that frees the server string if it is allocated.  We
are headed for exit() anyway but if there are multiple things being
looked up it is probably best to clean up before going on to the
next one.

 - todd

Index: usr.bin/whois/whois.c
===================================================================
RCS file: /cvs/src/usr.bin/whois/whois.c,v
retrieving revision 1.53
diff -u -p -u -r1.53 whois.c
--- usr.bin/whois/whois.c       9 Dec 2015 19:29:49 -0000       1.53
+++ usr.bin/whois/whois.c       15 Mar 2017 16:21:20 -0000
@@ -79,7 +79,7 @@ int
 main(int argc, char *argv[])
 {
        int ch, flags, rval;
-       char *host, *name, *country;
+       char *host, *name, *country, *server;
 
        country = host = NULL;
        flags = rval = 0;
@@ -147,10 +147,13 @@ main(int argc, char *argv[])
 
        if (host == NULL && country == NULL && !(flags & WHOIS_QUICK))
                flags |= WHOIS_RECURSE;
-       for (name = *argv; (name = *argv) != NULL; argv++)
-               rval += whois(name, host ? host : choose_server(name, country),
-                   port_whois, flags);
-       exit(rval);
+       for (name = *argv; (name = *argv) != NULL; argv++) {
+               server = host ? host : choose_server(name, country);
+               rval += whois(name, server, port_whois, flags);
+               if (host == NULL)
+                   free(server);
+       }
+       return (rval);
 }
 
 int
@@ -279,11 +282,9 @@ whois(const char *query, const char *ser
 char *
 choose_server(const char *name, const char *country)
 {
-       static char *server;
+       char *server;
        const char *qhead;
-       char *nserver;
        char *ep;
-       size_t len;
        struct addrinfo hints, *res;
 
        memset(&hints, 0, sizeof(hints));
@@ -307,16 +308,13 @@ choose_server(const char *name, const ch
                        return (NICHOST);
        } else if (isdigit((unsigned char)*(++qhead)))
                return (ANICHOST);
-       len = strlen(qhead) + sizeof(QNICHOST_TAIL);
-       if ((nserver = realloc(server, len)) == NULL)
-               err(1, "realloc");
-       server = nserver;
 
        /*
         * Post-2003 ("new") gTLDs are all supposed to have "whois.nic.domain"
         * (per registry agreement), some older gTLDs also support this...
         */
-       snprintf(server, len, "whois.nic.%s", qhead);
+       if (asprintf(&server, "whois.nic.%s", qhead) == -1)
+               err(1, NULL);
 
        /* most ccTLDs don't do this, but QNICHOST/whois-servers mostly works */
        if ((strlen(qhead) == 2 ||
@@ -333,8 +331,9 @@ choose_server(const char *name, const ch
            strcasecmp(qhead, "museum") == 0 ||
             /* for others, if whois.nic.TLD doesn't exist, try whois-servers */
            getaddrinfo(server, NULL, &hints, &res) != 0)) {
-               strlcpy(server, qhead, len);
-               strlcat(server, QNICHOST_TAIL, len);
+               free(server);
+               if (asprintf(&server, "%s%s", qhead, QNICHOST_TAIL) == -1)
+                       err(1, NULL);
        }
 
        return (server);

Reply via email to