Skip to content

Instantly share code, notes, and snippets.

@flatcap
Created October 17, 2017 16:20
Show Gist options
  • Save flatcap/fa4308849f68d9883ddfef7887fe289d to your computer and use it in GitHub Desktop.
Save flatcap/fa4308849f68d9883ddfef7887fe289d to your computer and use it in GitHub Desktop.
// gcc -Wall -o test-dns test-dns.c
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>
char *strfcpy(char *dest, const char *src, size_t dlen)
{
char *dest0 = dest;
while ((--dlen > 0) && (*src != '\0'))
*dest++ = *src++;
*dest = '\0';
return dest0;
}
char *mutt_substrdup(const char *begin, const char *end)
{
size_t len;
char *p = NULL;
if (!begin)
{
return NULL;
}
if (end)
{
if (begin > end)
return NULL;
len = end - begin;
}
else
{
len = strlen(begin);
}
p = malloc(len + 1);
memcpy(p, begin, len);
p[len] = '\0';
return p;
}
int getdnsdomainname(char *d, size_t len)
{
int ret = -1;
char node[256];
if (gethostname(node, sizeof(node)))
return ret;
struct addrinfo hints;
struct addrinfo *h = NULL;
*d = '\0';
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC;
getaddrinfo(node, NULL, &hints, &h);
char *p = NULL;
if (h != NULL && h->ai_canonname && (p = strchr(h->ai_canonname, '.')))
{
strfcpy(d, ++p, len);
ret = 0;
freeaddrinfo(h);
}
return ret;
}
int main()
{
char *Hostname = NULL;
char *ShortHostname = NULL;
struct utsname utsname;
char *p, buffer[256];
if ((uname(&utsname)) == -1)
return 1;
/* some systems report the FQDN instead of just the hostname */
p = strchr(utsname.nodename, '.');
if (p)
ShortHostname = mutt_substrdup(utsname.nodename, p);
else
ShortHostname = strdup(utsname.nodename);
/* now get FQDN. Use configured domain first, DNS next, then uname */
if (!(getdnsdomainname(buffer, sizeof(buffer))))
{
Hostname = malloc(strlen(buffer) + strlen(ShortHostname) + 2);
sprintf(Hostname, "%s.%s", ShortHostname, buffer);
}
else
{
/*
* DNS failed, use the nodename. Whether or not the nodename had a '.' in
* it, we can use the nodename as the FQDN. On hosts where DNS is not
* being used, e.g. small network that relies on hosts files, a short host
* name is all that is required for SMTP to work correctly. It could be
* wrong, but we've done the best we can, at this point the onus is on the
* user to provide the correct hostname if the nodename won't work in their
* network.
*/
Hostname = strdup(utsname.nodename);
}
printf("short : %s\n", ShortHostname);
printf("hostname : %s\n", Hostname);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment