NeoMutt  2024-04-25-92-gf10c0f
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
getdomain.c
Go to the documentation of this file.
1
32#include "config.h"
33#include <netdb.h>
34#include <string.h>
35#include <sys/socket.h>
36#include <time.h>
37#include <unistd.h>
38#include "mutt/lib.h"
39#include "lib.h"
40
41#ifdef HAVE_GETADDRINFO_A
51static struct addrinfo *mutt_getaddrinfo_a(const char *node, const struct addrinfo *hints)
52{
53 ASSERT(node);
54 ASSERT(hints);
55 struct addrinfo *result = NULL;
56
57 /* Allow 0.1 seconds to get the FQDN (fully-qualified domain name).
58 * If it takes longer, the system is mis-configured and the network is not
59 * working properly, so... */
60 struct timespec timeout = { 0, 100000000 };
61 struct gaicb req = { 0 };
62 req.ar_name = node;
63 req.ar_request = hints;
64 struct gaicb *reqs[1] = { &req };
65 if (getaddrinfo_a(GAI_NOWAIT, reqs, 1, NULL) == 0)
66 {
67 gai_suspend((const struct gaicb *const *) reqs, 1, &timeout);
68 const int status = gai_error(reqs[0]);
69 if (status == 0)
70 {
71 result = reqs[0]->ar_result;
72 }
73 else if (status == EAI_INPROGRESS)
74 {
75 mutt_debug(LL_DEBUG1, "timeout\n");
76 /* request is not finished, cancel it to free it safely */
77 if (gai_cancel(reqs[0]) == EAI_NOTCANCELED)
78 {
79 // try once more for half-a-second, then bail out
80 timeout.tv_nsec = 50000000;
81 gai_suspend((const struct gaicb *const *) reqs, 1, &timeout);
82 }
83 }
84 else
85 {
86 mutt_debug(LL_DEBUG1, "fail: (%d) %s\n", status, gai_strerror(status));
87 }
88 }
89 return result;
90}
91
92#elif defined(HAVE_GETADDRINFO)
102static struct addrinfo *mutt_getaddrinfo(const char *node, const struct addrinfo *hints)
103{
104 ASSERT(node);
105 ASSERT(hints);
106 struct addrinfo *result = NULL;
107 mutt_debug(LL_DEBUG3, "before getaddrinfo\n");
108 int rc = getaddrinfo(node, NULL, hints, &result);
109 mutt_debug(LL_DEBUG3, "after getaddrinfo\n");
110
111 if (rc != 0)
112 result = NULL;
113
114 return result;
115}
116#endif
117
124int getdnsdomainname(struct Buffer *result)
125{
126 ASSERT(result);
127 int rc = -1;
128
129#if defined(HAVE_GETADDRINFO) || defined(HAVE_GETADDRINFO_A)
130 char node[256] = { 0 };
131 if (gethostname(node, sizeof(node)) != 0)
132 return rc;
133
134 struct addrinfo *lookup_result = NULL;
135 struct addrinfo hints = { 0 };
136
137 buf_reset(result);
138 hints.ai_flags = AI_CANONNAME;
139 hints.ai_family = AF_UNSPEC;
140
141#ifdef HAVE_GETADDRINFO_A
142 lookup_result = mutt_getaddrinfo_a(node, &hints);
143#else
144 lookup_result = mutt_getaddrinfo(node, &hints);
145#endif
146
147 if (lookup_result && lookup_result->ai_canonname)
148 {
149 const char *hostname = strchr(lookup_result->ai_canonname, '.');
150 if (hostname && hostname[1] != '\0')
151 {
152 buf_strcpy(result, ++hostname);
153 rc = 0;
154 }
155 }
156
157 if (lookup_result)
158 freeaddrinfo(lookup_result);
159#endif
160
161 return rc;
162}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
int getdnsdomainname(struct Buffer *result)
Lookup the host's name using DNS.
Definition: getdomain.c:124
static struct addrinfo * mutt_getaddrinfo(const char *node, const struct addrinfo *hints)
Lookup the host's name using getaddrinfo()
Definition: getdomain.c:102
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
@ LL_DEBUG3
Log at debug level 3.
Definition: logging2.h:45
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
Convenience wrapper for the library headers.
#define ASSERT(COND)
Definition: signal2.h:58
Key value store.
String manipulation buffer.
Definition: buffer.h:36
Time value with nanosecond precision.
Definition: file.h:51
long tv_nsec
Number of nanosecond, on top.
Definition: file.h:53