changeset 605:eb2985b8de7e

Fixed hostnamestr() for hosts that can't find themselves using gethostbyname() (Benoit Dolez)
author mortenp
date Thu, 07 Dec 2006 00:33:24 +1100
parents 0e4cfa17a1f4
children 353118fefd6a
files ChangeLog src/strgen.c
diffstat 2 files changed, 45 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Dec 05 21:27:36 2006 +1100
+++ b/ChangeLog	Thu Dec 07 00:33:24 2006 +1100
@@ -1,3 +1,5 @@
+ o Fixed hostnamestr() for hosts that can't find themselves using
+   gethostbyname() (Benoit Dolez)
  o Add 'modnonsubposts' tunable that when set will moderate all posts
    from non subscribers
  o Fixed requeue for lists with noarchive enabled
--- a/src/strgen.c	Tue Dec 05 21:27:36 2006 +1100
+++ b/src/strgen.c	Thu Dec 07 00:33:24 2006 +1100
@@ -30,6 +30,7 @@
 #include <libgen.h>
 #include <time.h>
 #include <ctype.h>
+#include <errno.h>
 
 #include "strgen.h"
 #include "wrappers.h"
@@ -137,17 +138,51 @@
 char *hostnamestr()
 {
         struct hostent *hostlookup;
-        char hostname[1024];
+	char *hostname = NULL;
+	size_t len = 512;
+
+	for (;;) {
+		len *= 2;
+		free(hostname);
+
+		hostname = malloc(len);
+		hostname[len-1] = '\0';
 
-        /* TODO use dynamic allocation */
-        gethostname(hostname, sizeof(hostname) - 1);
-        /* gethostname() is allowed to return an unterminated string */
-        hostname[sizeof(hostname)-1] = '\0';
-        hostlookup = gethostbyname(hostname);
+		/* gethostname() is allowed to:
+		 * a) return -1 and undefined in hostname
+		 * b) return 0 and an unterminated string in hostname
+		 * c) return 0 and a NUL-terminated string in hostname
+		 *
+		 * We keep expanding the buffer until the hostname is
+		 * NUL-terminated (and pray that it is not truncated)
+		 * or an error occurs.
+		 */
+		if (gethostname(hostname, len - 1)) {
+			if (errno == ENAMETOOLONG) {
+				continue;
+			}
+			myfree(hostname);
+			return mystrdup("localhost");
+		}
 
+		if (hostname[len-1] == '\0') {
+			break;
+		}
+	}
+
+	if (strchr(hostname, '.')) {
+		/* hostname is FQDN */
+		return hostname;
+	}
+
+	if ((hostlookup = gethostbyname(hostname))) {
+		myfree(hostname);
         return mystrdup(hostlookup->h_name);
 }
 
+	return hostname;
+}
+
 char *mydirname(const char *path)
 {
 	char *mypath, *dname, *ret;