Tcl Source Code

Artifact [3723755838]
Login

Artifact 37237558385e28562cf10476477e0acb2187a2b7:

Attachment "tcl86-gethostbyaddr.patch" to ticket [9146698599] added by gustafn2 2016-07-26 10:04:14. (unpublished)
Index: unix/tclUnixSock.c
==================================================================
--- unix/tclUnixSock.c
+++ unix/tclUnixSock.c
@@ -184,10 +184,95 @@
 		    NI_NUMERICHOST|NI_NUMERICSERV);
 	fprintf(stderr,"%s: %s:%s\n", prefix, host, port);
     }
 }
 #endif
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetHostByName --
+ *
+ * 	Obtain for a given domain name or IPv4/IPv6 address the cononical 
+ *      name of a host. This function contains the only calls to 
+ *      TclpGetHostByName() which could be phased out on the longer range.
+ *
+ * Results:
+ *	Boolean success code. On success, the result is copied to the 
+ *      provided buffer.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+GetHostByName(
+    const char* name,
+    char *buffer,
+    size_t bufferSize)
+{
+    int success = 0;
+#ifdef HAVE_GETADDRINFO
+    int rc;
+    struct addrinfo hints, *res;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family   = AF_UNSPEC;
+    hints.ai_flags    = AI_CANONNAME;
+    hints.ai_socktype = SOCK_STREAM;
+
+    rc = getaddrinfo(name, NULL, &hints, &res);
+    if (rc == 0 && res != NULL) {
+        size_t len = strlen(res->ai_canonname);
+
+        /* 
+         * Safety belt. In theory, the buffer (as determined by NI_MAXHOST)
+         * should always be sufficiently large of the returned value, so this
+         * check is strictly speaking not necessary.
+         */
+        if (len > bufferSize-1) {
+            len = bufferSize-1;
+        }
+        
+        memcpy(buffer,  (char *)res->ai_canonname, len);
+        buffer[len] = '\0';
+        success = 1;
+        freeaddrinfo(res);
+    }
+#else
+    struct hostent *hp;
+
+    hp = TclpGetHostByName(node);
+    if (hp != NULL) {
+        memcpy(buffer,  hp->h_name, sizeof(hp->h_name));
+        success = 1;
+    } else {
+        /*
+         * Sometimes the nodename is fully qualified, but gets truncated
+         * as it exceeds SYS_NMLN. See if we can just get the immediate
+         * nodename and get a proper answer that way.
+         */
+        
+        char *dot = strchr(u.nodename, '.');
+        
+        if (dot != NULL) {
+            char *node = ckalloc(dot - u.nodename + 1);
+
+            memcpy(node, u.nodename, (size_t) (dot - u.nodename));
+            node[dot - u.nodename] = '\0';
+            hp = TclpGetHostByName(node);
+            if (hp != NULL) {
+                memcpy(buffer,  hp->h_name, sizeof(hp->h_name));
+                success = 1;
+            }
+            ckfree(node);
+        }
+    }
+#endif
+    return success;
+}
+
+
 /*
  *----------------------------------------------------------------------
  *
  * InitializeHostName --
  *
@@ -208,38 +293,21 @@
 {
     const char *native = NULL;
 
 #ifndef NO_UNAME
     struct utsname u;
-    struct hostent *hp;
-
+    int    success = 0;
+    char   buf[NI_MAXHOST];    
+    
     memset(&u, (int) 0, sizeof(struct utsname));
-    if (uname(&u) > -1) {				/* INTL: Native. */
-        hp = TclpGetHostByName(u.nodename);		/* INTL: Native. */
-	if (hp == NULL) {
-	    /*
-	     * Sometimes the nodename is fully qualified, but gets truncated
-	     * as it exceeds SYS_NMLN. See if we can just get the immediate
-	     * nodename and get a proper answer that way.
-	     */
-
-	    char *dot = strchr(u.nodename, '.');
-
-	    if (dot != NULL) {
-		char *node = ckalloc(dot - u.nodename + 1);
-
-		memcpy(node, u.nodename, (size_t) (dot - u.nodename));
-		node[dot - u.nodename] = '\0';
-		hp = TclpGetHostByName(node);
-		ckfree(node);
-	    }
-	}
-        if (hp != NULL) {
-	    native = hp->h_name;
-        } else {
-	    native = u.nodename;
-        }
+    if (uname(&u) > -1) {			           	/* INTL: Native. */
+        success = GetHostByName(u.nodename, buf, sizeof(buf));  /* INTL: Native. */
+    }
+    if (success) {
+        native = buf;
+    } else {
+        native = u.nodename;
     }
     if (native == NULL) {
 	native = tclEmptyStringRep;
     }
 #else /* !NO_UNAME */