NeoMutt  2020-09-25
Teaching an old dog new tricks
DOXYGEN
getdomain.c File Reference

DNS lookups. More...

#include "config.h"
#include <netdb.h>
#include <string.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "conn/lib.h"
+ Include dependency graph for getdomain.c:

Go to the source code of this file.

Functions

int getdnsdomainname (struct Buffer *domain)
 Lookup the host's name using DNS. More...
 

Detailed Description

DNS lookups.

Authors
  • Derek Martin

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file getdomain.c.

Function Documentation

◆ getdnsdomainname()

int getdnsdomainname ( struct Buffer domain)

Lookup the host's name using DNS.

Parameters
domainBuffer for the result
Return values
0Success
-1Error

Definition at line 44 of file getdomain.c.

45 {
46  int rc = -1;
47 
48 #if defined(HAVE_GETADDRINFO) || defined(HAVE_GETADDRINFO_A)
49  char node[256];
50  if (gethostname(node, sizeof(node)) != 0)
51  return rc;
52 
53  struct addrinfo hints;
54  struct addrinfo *h = NULL;
55 
56  mutt_buffer_reset(domain);
57  memset(&hints, 0, sizeof(struct addrinfo));
58  hints.ai_flags = AI_CANONNAME;
59  hints.ai_family = AF_UNSPEC;
60 
61 #ifdef HAVE_GETADDRINFO_A
62  /* Allow 0.1 seconds to get the FQDN (fully-qualified domain name).
63  * If it takes longer, the system is mis-configured and the network is not
64  * working properly, so... */
65  struct timespec timeout = { 0, 100000000 };
66  struct gaicb *reqs[1];
67  reqs[0] = mutt_mem_calloc(1, sizeof(*reqs[0]));
68  reqs[0]->ar_name = node;
69  reqs[0]->ar_request = &hints;
70  if (getaddrinfo_a(GAI_NOWAIT, reqs, 1, NULL) == 0)
71  {
72  gai_suspend((const struct gaicb *const *) reqs, 1, &timeout);
73  const int status = gai_error(reqs[0]);
74  if (status == 0)
75  h = reqs[0]->ar_result;
76  else if (status == EAI_INPROGRESS)
77  {
78  mutt_debug(LL_DEBUG1, "timeout\n");
79  /* request is not finish, cancel it to free it safely */
80  if (gai_cancel(reqs[0]) == EAI_NOTCANCELED)
81  {
82  while (gai_suspend((const struct gaicb *const *) reqs, 1, NULL) != 0)
83  continue;
84  }
85  }
86  else
87  mutt_debug(LL_DEBUG1, "fail: (%d) %s\n", status, gai_strerror(status));
88  }
89  FREE(&reqs[0]);
90 #else /* !HAVE_GETADDRINFO_A */
91  mutt_debug(LL_DEBUG3, "before getaddrinfo\n");
92  getaddrinfo(node, NULL, &hints, &h);
93  mutt_debug(LL_DEBUG3, "after getaddrinfo\n");
94 #endif
95 
96  char *p = NULL;
97  if (h && h->ai_canonname && (p = strchr(h->ai_canonname, '.')))
98  {
99  mutt_buffer_strcpy(domain, ++p);
100  rc = 0;
101  mutt_debug(LL_DEBUG1, "Hostname: %s\n", mutt_b2s(domain));
102  freeaddrinfo(h);
103  }
104 #endif /* HAVE_GETADDRINFO || defined HAVE_GETADDRINFO_A */
105 
106  return rc;
107 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
Log at debug level 1.
Definition: logging.h:40
#define FREE(x)
Definition: memory.h:40
Time value with nanosecond precision.
Definition: file.h:46
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function: