Attachment "tcl86-gethostbyaddr.patch" to
ticket [9146698599]
added by
gustafn2
2016-07-26 10:04:14.
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 */