NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
getdomain.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <assert.h>
31 #include <netdb.h>
32 #include <string.h>
33 #include <sys/socket.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include "mutt/lib.h"
37 #include "conn/lib.h" // IWYU pragma: keep
38 
39 #ifdef HAVE_GETADDRINFO_A
40 
49 static struct addrinfo *mutt_getaddrinfo_a(const char *node, const struct addrinfo *hints)
50 {
51  assert(node);
52  assert(hints);
53  struct addrinfo *result = NULL;
54 
55  /* Allow 0.1 seconds to get the FQDN (fully-qualified domain name).
56  * If it takes longer, the system is mis-configured and the network is not
57  * working properly, so... */
58  struct timespec timeout = { 0, 100000000 };
59  struct gaicb *reqs[1];
60  reqs[0] = mutt_mem_calloc(1, sizeof(*reqs[0]));
61  reqs[0]->ar_name = node;
62  reqs[0]->ar_request = hints;
63  if (getaddrinfo_a(GAI_NOWAIT, reqs, 1, NULL) == 0)
64  {
65  gai_suspend((const struct gaicb *const *) reqs, 1, &timeout);
66  const int status = gai_error(reqs[0]);
67  if (status == 0)
68  result = reqs[0]->ar_result;
69  else if (status == EAI_INPROGRESS)
70  {
71  mutt_debug(LL_DEBUG1, "timeout\n");
72  /* request is not finished, cancel it to free it safely */
73  if (gai_cancel(reqs[0]) == EAI_NOTCANCELED)
74  {
75  while (gai_suspend((const struct gaicb *const *) reqs, 1, NULL) != 0)
76  continue;
77  }
78  }
79  else
80  mutt_debug(LL_DEBUG1, "fail: (%d) %s\n", status, gai_strerror(status));
81  }
82  FREE(&reqs[0]);
83  return result;
84 }
85 
86 #elif defined(HAVE_GETADDRINFO)
87 
96 static struct addrinfo *mutt_getaddrinfo(const char *node, const struct addrinfo *hints)
97 {
98  assert(node);
99  assert(hints);
100  struct addrinfo *result = NULL;
101  mutt_debug(LL_DEBUG3, "before getaddrinfo\n");
102  int rc = getaddrinfo(node, NULL, hints, &result);
103  mutt_debug(LL_DEBUG3, "after getaddrinfo\n");
104 
105  if (rc != 0)
106  result = NULL;
107 
108  return result;
109 }
110 #endif
111 
118 int getdnsdomainname(struct Buffer *result)
119 {
120  assert(result);
121  int rc = -1;
122 
123 #if defined(HAVE_GETADDRINFO) || defined(HAVE_GETADDRINFO_A)
124  char node[256];
125  if (gethostname(node, sizeof(node)) != 0)
126  return rc;
127 
128  struct addrinfo *lookup_result = NULL;
129  struct addrinfo hints;
130 
131  mutt_buffer_reset(result);
132  memset(&hints, 0, sizeof(struct addrinfo));
133  hints.ai_flags = AI_CANONNAME;
134  hints.ai_family = AF_UNSPEC;
135 
136 #ifdef HAVE_GETADDRINFO_A
137  lookup_result = mutt_getaddrinfo_a(node, &hints);
138 #else
139  lookup_result = mutt_getaddrinfo(node, &hints);
140 #endif
141 
142  char *hostname = NULL;
143  if (lookup_result && lookup_result->ai_canonname)
144  hostname = strchr(lookup_result->ai_canonname, '.');
145 
146  if (hostname)
147  {
148  mutt_buffer_strcpy(result, ++hostname);
149  rc = 0;
150  mutt_debug(LL_DEBUG1, "Hostname: %s\n", mutt_buffer_string(result));
151  }
152  freeaddrinfo(lookup_result);
153 #endif
154 
155  return rc;
156 }
mutt_mem_calloc
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
Buffer
String manipulation buffer.
Definition: buffer.h:33
LL_DEBUG3
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
FREE
#define FREE(x)
Definition: memory.h:40
getdnsdomainname
int getdnsdomainname(struct Buffer *result)
Lookup the host's name using DNS.
Definition: getdomain.c:118
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
lib.h
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
mutt_getaddrinfo
static struct addrinfo * mutt_getaddrinfo(const char *node, const struct addrinfo *hints)
Lookup the host's name using getaddrinfo()
Definition: getdomain.c:96
timespec
Time value with nanosecond precision.
Definition: file.h:49
lib.h
mutt_buffer_strcpy
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312