]> granicus.if.org Git - neomutt/commitdiff
use gethostname() to determine the system host name
authorMichael Elkins <me@sigpipe.org>
Wed, 10 Apr 2013 23:40:18 +0000 (23:40 +0000)
committerMichael Elkins <me@sigpipe.org>
Wed, 10 Apr 2013 23:40:18 +0000 (23:40 +0000)
use getaddrinfo() to look up canonical DNS name, and fall back to hinting from /etc/resolv.conf

see #3298

getdomain.c
init.c

index 71636279cf7b86b532aa06fd50aa404b1ae7a792..13c4fa25746152c5671151fde7a576dff1b3482f 100644 (file)
@@ -6,6 +6,10 @@
 #include <ctype.h>
 #include <string.h>
 
+/* for getaddrinfo() */
+#include <sys/types.h>
+#include <netdb.h>
+
 #include "mutt.h"
 
 #ifndef STDC_HEADERS
@@ -29,40 +33,63 @@ static void strip_trailing_dot (char *q)
 
 int getdnsdomainname (char *s, size_t l)
 {
+#ifdef DOMAIN
+  /* specified at compile time */
+  snprintf(s, l, "%s.%s", Hostname, DOMAIN);
+#else
   FILE *f;
   char tmp[1024];
   char *p = NULL;
   char *q;
+  struct addrinfo hints;
+  struct addrinfo *res;
 
-  if ((f = fopen ("/etc/resolv.conf", "r")) == NULL) return (-1);
+  /* Try a DNS lookup on the hostname to find the canonical name. */
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_flags = AI_CANONNAME;
+  if (getaddrinfo(Hostname, NULL, &hints, &res) == 0)
+  {
+    snprintf(s, l, "%s", res->ai_canonname);
+    freeaddrinfo(res);
+  }
+  else
+  {
+    /* Otherwise inspect /etc/resolve.conf for a hint. */
 
-  tmp[sizeof (tmp) - 1] = 0;
+    if ((f = fopen ("/etc/resolv.conf", "r")) == NULL) return (-1);
 
-  l--; /* save room for the terminal \0 */
+    tmp[sizeof (tmp) - 1] = 0;
 
-  while (fgets (tmp, sizeof (tmp) - 1, f) != NULL)
-  {
-    p = tmp;
-    while (ISSPACE (*p)) p++;
-    if (mutt_strncmp ("domain", p, 6) == 0 || mutt_strncmp ("search", p, 6) == 0)
-    {
-      p += 6;
-      
-      for (q = strtok (p, " \t\n"); q; q = strtok (NULL, " \t\n"))
-       if (strcmp (q, "."))
-         break;
+    l--; /* save room for the terminal \0 */
 
-      if (q)
+    while (fgets (tmp, sizeof (tmp) - 1, f) != NULL)
+    {
+      p = tmp;
+      while (ISSPACE (*p)) p++;
+      if (mutt_strncmp ("domain", p, 6) == 0 || mutt_strncmp ("search", p, 6) == 0)
       {
-       strip_trailing_dot (q);
-       strfcpy (s, q, l);
-       safe_fclose (&f);
-       return 0;
+       p += 6;
+
+       for (q = strtok (p, " \t\n"); q; q = strtok (NULL, " \t\n"))
+         if (strcmp (q, "."))
+           break;
+
+       if (q)
+       {
+         strip_trailing_dot (q);
+         snprintf (s, l, "%s.%s", Hostname, q);
+         safe_fclose (&f);
+         return 0;
+       }
+
       }
-      
     }
-  }
 
-  safe_fclose (&f);
-  return (-1);
+    safe_fclose (&f);
+
+    /* fall back to using just the bare hostname */
+    snprintf(s, l, "%s", Hostname);
+  }
+#endif
+  return 0;
 }
diff --git a/init.c b/init.c
index 0cc362b75d37cca0eb5eed1ca0de04e48e07cb50..9fcd53f280c71572888bba8a085a244524392829 100644 (file)
--- a/init.c
+++ b/init.c
@@ -2887,7 +2887,6 @@ static void mutt_srandom (void)
 void mutt_init (int skip_sys_rc, LIST *commands)
 {
   struct passwd *pw;
-  struct utsname utsname;
   char *p, buffer[STRING];
   int i, default_rc = 0, need_pause = 0;
   BUFFER err;
@@ -2953,30 +2952,21 @@ void mutt_init (int skip_sys_rc, LIST *commands)
 #endif
 
   /* And about the host... */
-  uname (&utsname);
-  /* some systems report the FQDN instead of just the hostname */
-  if ((p = strchr (utsname.nodename, '.')))
   {
-    Hostname = mutt_substrdup (utsname.nodename, p);
-    p++;
-    strfcpy (buffer, p, sizeof (buffer)); /* save the domain for below */
+    size_t namelen = sysconf(_SC_HOST_NAME_MAX);
+    char *name = safe_malloc(namelen + 1);
+    if (gethostname(name, namelen) == -1)
+    {
+      fputs (_("unable to determine hostname"), stderr);
+      exit (1);
+    }
+    Hostname = safe_strdup(name);
+    FREE (&name);
   }
-  else
-    Hostname = safe_strdup (utsname.nodename);
 
-#ifndef DOMAIN
-#define DOMAIN buffer
-  if (!p && getdnsdomainname (buffer, sizeof (buffer)) == -1)
-    Fqdn = safe_strdup ("@");
-  else
-#endif /* DOMAIN */
-    if (*DOMAIN != '@')
-  {
-    Fqdn = safe_malloc (mutt_strlen (DOMAIN) + mutt_strlen (Hostname) + 2);
-    sprintf (Fqdn, "%s.%s", NONULL(Hostname), DOMAIN); /* __SPRINTF_CHECKED__ */
-  }
-  else
-    Fqdn = safe_strdup(NONULL(Hostname));
+  /* determine the DNS domain name */
+  getdnsdomainname (buffer, sizeof (buffer));
+  Fqdn = safe_strdup(buffer);
 
   if ((p = getenv ("MAIL")))
     Spoolfile = safe_strdup (p);