summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Elkins <me@sigpipe.org>2013-04-10 23:40:18 +0000
committerMichael Elkins <me@sigpipe.org>2013-04-10 23:40:18 +0000
commit001bc020604322d38414291400d6d978001c1f06 (patch)
tree1b6e0c977a50f4c0b13bc97f3105225bd7d5eec4
parent564787560c432d02dfc311ec3489f227d2a56abb (diff)
use gethostname() to determine the system host name
use getaddrinfo() to look up canonical DNS name, and fall back to hinting from /etc/resolv.conf see #3298
-rw-r--r--getdomain.c73
-rw-r--r--init.c34
2 files changed, 62 insertions, 45 deletions
diff --git a/getdomain.c b/getdomain.c
index 71636279..13c4fa25 100644
--- a/getdomain.c
+++ b/getdomain.c
@@ -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 0cc362b7..9fcd53f2 100644
--- 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);