]> Pileus Git - ~andy/fetchmail/blob - mxget.c
Fix compiler warning in 'make check'.
[~andy/fetchmail] / mxget.c
1 /*
2  * mxget.c -- fetch MX records for given DNS name
3  *
4  * Copyright 1997 by Eric S. Raymond
5  * For license terms, see the file COPYING in this directory.
6  */
7
8 #include "config.h"
9 #ifdef HAVE_RES_SEARCH
10 #include <stdio.h>
11 #include <string.h>
12 #ifdef HAVE_NET_SOCKET_H
13 #include <net/socket.h>
14 #endif
15 #include <netdb.h>
16 #include <sys/types.h>
17 #include <netinet/in.h>
18
19 #ifdef __BEOS__
20 #include "beos/beos_nameser.h"
21 #endif
22
23 #ifdef HAVE_ARPA_NAMESER_H
24 #include <arpa/nameser.h>
25 #endif
26 #ifdef HAVE_RESOLV_H
27 #include <resolv.h>
28 #endif
29
30 #include "mx.h"
31
32 /*
33  * This ought to be in the bind library.  It's adapted from sendmail.
34  */
35
36 /*
37  * These are defined in RFC833. Some bind interface headers don't declare them.
38  * Ghod help us if they're ever actually incompatible with what's in 
39  * the arpa/nameser.h header.
40  */
41 #ifndef PACKETSZ
42 #define PACKETSZ        512             /* maximum packet size */
43 #endif
44 #ifndef HFIXEDSZ
45 #define HFIXEDSZ        12              /* #/bytes of fixed data in header */
46 #endif
47 #ifndef INT32SZ
48 #define INT32SZ         4               /* for systems without 32-bit ints */
49 #endif
50 #ifndef INT16SZ
51 #define INT16SZ         2               /* for systems without 16-bit ints */
52 #endif
53
54 /* minimum possible size of MX record in packet */
55 #define MIN_MX_SIZE     8       /* corresp to "a.com 0" w/ terminating space */
56
57 struct mxentry *getmxrecords(const char *name)
58 /* get MX records for given host */
59 {
60     char answer[PACKETSZ], *eom, *cp, *bp;
61     int n, ancount, qdcount, buflen, type, pref, ind;
62     static struct mxentry pmx[(PACKETSZ - HFIXEDSZ) / MIN_MX_SIZE];
63     static char MXHostBuf[PACKETSZ - HFIXEDSZ]; 
64     HEADER *hp;
65
66     pmx->name = (char *)NULL;
67     pmx->pref = -1;
68     n = res_search(name, C_IN,T_MX, (unsigned char *)&answer, sizeof(answer));
69     if (n == -1)
70         return((struct mxentry *)NULL);
71     if (n > sizeof(answer))
72         n = sizeof(answer);     
73
74     hp = (HEADER *)&answer;
75     cp = answer + HFIXEDSZ;
76     eom = answer + n;
77     h_errno = 0;
78     for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
79         if ((n = dn_skipname(cp, eom)) < 0)
80             return((struct mxentry *)NULL);
81     buflen = sizeof(MXHostBuf) - 1;
82     bp = MXHostBuf;
83     ind = 0;
84     ancount = ntohs(hp->ancount);
85     while (--ancount >= 0 && cp < eom)
86     {
87         if ((n = dn_expand(answer, eom, cp, bp, buflen)) < 0)
88             break;
89         cp += n;
90         GETSHORT(type, cp);
91         cp += INT16SZ + INT32SZ;
92         GETSHORT(n, cp);
93         if (type != T_MX)
94         {
95             cp += n;
96             continue;
97         }
98         GETSHORT(pref, cp);
99         if ((n = dn_expand(answer, eom, cp, bp, buflen)) < 0)
100             break;
101         cp += n;
102
103         pmx[ind].name = bp;
104         pmx[ind].pref = pref;
105         ++ind;
106
107         n = strlen((const char *)bp);
108         bp += n;
109         *bp++ = '\0';
110
111         buflen -= n + 1;
112     }
113
114     pmx[ind].name = (char *)NULL;
115     pmx[ind].pref = -1;
116     return(pmx);
117 }
118 #endif /* HAVE_RES_SEARCH */
119
120 #ifdef STANDALONE
121 #include <stdlib.h>
122
123 int main(int argc, char *argv[])
124 {
125     int count, i;
126     struct mxentry *responses;
127
128     if (argc != 2 || 0 == strcmp(argv[1], "-h")) {
129         fprintf(stderr, "Usage: %s domain\n", argv[0]);
130         exit(1);
131     }
132
133     responses = getmxrecords(argv[1]);
134     if (responses == (struct mxentry *)NULL)
135         puts("No MX records found");
136     else
137         do {
138             printf("%s %d\n", responses->name, responses->pref);
139         } while
140             ((++responses)->name);
141
142     return 0;
143 }
144 #endif /* TESTMAIN */
145
146 /* mxget.c ends here */