]> Pileus Git - ~andy/fetchmail/blobdiff - mxget.c
Minor bug fixes for socket.c
[~andy/fetchmail] / mxget.c
diff --git a/mxget.c b/mxget.c
index 081c20f6efe8cf9f69637702d29cd86890f4f7ab..4529c223bea99e1abc838837d7dc88f8907df295 100644 (file)
--- a/mxget.c
+++ b/mxget.c
@@ -1,51 +1,93 @@
 /*
  * mxget.c -- fetch MX records for given DNS name
  *
- * Copyright 1996 by Eric S. Raymond
- * All rights reserved.
+ * Copyright (C) 1996, 1997, 1998, 2000, 2002 by Eric S. Raymond
+ * Copyright (C) 2005, 2006, 2007 by Matthias Andree
  * For license terms, see the file COPYING in this directory.
  */
 
-#include <config.h>
-#ifdef HAVE_GETHOSTBYNAME
+#include "config.h"
+#include "fetchmail.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_RES_SEARCH
+#ifdef HAVE_NET_SOCKET_H
+#include <net/socket.h>
+#endif
 #include <netdb.h>
 #include <sys/types.h>
 #include <netinet/in.h>
+
+#ifdef __BEOS__
+#include "beos/beos_nameser.h"
+#endif
+
+#ifdef HAVE_ARPA_NAMESER_H
 #include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
 #include <resolv.h>
+#endif
+
 #include "mx.h"
 
 /*
  * This ought to be in the bind library.  It's adapted from sendmail.
  */
 
-int getmxrecords(name, nmx, pmx)
+/*
+ * These are defined in RFC833. Some bind interface headers don't declare them.
+ * Ghod help us if they're ever actually incompatible with what's in 
+ * the arpa/nameser.h header.
+ */
+#ifndef PACKETSZ
+#define PACKETSZ       512             /* maximum packet size */
+#endif
+#ifndef HFIXEDSZ
+#define        HFIXEDSZ        12              /* #/bytes of fixed data in header */
+#endif
+#ifndef INT32SZ
+#define        INT32SZ         4               /* for systems without 32-bit ints */
+#endif
+#ifndef INT16SZ
+#define        INT16SZ         2               /* for systems without 16-bit ints */
+#endif
+
+/* minimum possible size of MX record in packet */
+#define MIN_MX_SIZE    8       /* corresp to "a.com 0" w/ terminating space */
+
+struct mxentry *getmxrecords(const char *name)
 /* get MX records for given host */
-char *name;
-int nmx;
-struct mxentry *pmx;
 {
-    unsigned char answer[PACKETSZ], MXHostBuf[PACKETSZ], *eom, *cp, *bp;
+    char answer[PACKETSZ], *eom, *cp, *bp;
     int n, ancount, qdcount, buflen, type, pref, ind;
+    static struct mxentry pmx[(PACKETSZ - HFIXEDSZ) / MIN_MX_SIZE];
+    static char MXHostBuf[PACKETSZ - HFIXEDSZ]; 
     HEADER *hp;
 
-    n = res_search(name,C_IN,T_MX,(unsigned char*)&answer, sizeof(answer));
+    pmx->name = (char *)NULL;
+    pmx->pref = -1;
+    n = res_search(name, C_IN,T_MX, (unsigned char *)&answer, sizeof(answer));
     if (n == -1)
-       return(-1);
+       return((struct mxentry *)NULL);
+    if ((size_t)n > sizeof(answer))
+       n = sizeof(answer);     
 
     hp = (HEADER *)&answer;
     cp = answer + HFIXEDSZ;
     eom = answer + n;
+    h_errno = 0;
     for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
-       if ((n = dn_skipname(cp, eom)) < 0)
-           return(-1);
+      if ((n = dn_skipname((unsigned char *)cp, (unsigned char *)eom)) < 0)
+           return((struct mxentry *)NULL);
     buflen = sizeof(MXHostBuf) - 1;
     bp = MXHostBuf;
     ind = 0;
     ancount = ntohs(hp->ancount);
     while (--ancount >= 0 && cp < eom)
     {
-       if ((n = dn_expand(answer, eom, cp, bp, buflen)) < 0)
+       if ((n = dn_expand((unsigned char *)answer, (unsigned char *)eom,
+                          (unsigned char *)cp, bp, buflen)) < 0)
            break;
        cp += n;
        GETSHORT(type, cp);
@@ -57,25 +99,57 @@ struct mxentry *pmx;
            continue;
        }
        GETSHORT(pref, cp);
-       if ((n = dn_expand(answer, eom, cp, bp, buflen)) < 0)
+       if ((n = dn_expand((unsigned char *)answer, (unsigned char *)eom,
+                          (unsigned char *)cp, bp, buflen)) < 0)
            break;
        cp += n;
 
        pmx[ind].name = bp;
        pmx[ind].pref = pref;
-       if (++ind > nmx)
-           break;
+       ++ind;
 
-       n = strlen(bp);
+       n = strlen((const char *)bp);
        bp += n;
        *bp++ = '\0';
 
-
        buflen -= n + 1;
     }
 
-    return(ind);
+    pmx[ind].name = (char *)NULL;
+    pmx[ind].pref = -1;
+    return(pmx);
+}
+#endif /* HAVE_RES_SEARCH */
+
+#ifdef STANDALONE
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+#ifdef HAVE_RES_SEARCH
+    struct mxentry *responses;
+#endif
+
+    if (argc != 2 || 0 == strcmp(argv[1], "-h")) {
+       fprintf(stderr, "Usage: %s domain\n", argv[0]);
+       exit(1);
+    }
+
+#ifdef HAVE_RES_SEARCH
+    responses = getmxrecords(argv[1]);
+    if (responses == (struct mxentry *)NULL) {
+       puts("No MX records found");
+    } else {
+       do {
+           printf("%s %d\n", responses->name, responses->pref);
+       } while ((++responses)->name);
+    }
+#else
+    puts("This program was compiled without HAS_RES_SEARCH and does nothing.");
+#endif
+
+    return 0;
 }
-#endif /* HAVE_GETHOSTBYNAME */
+#endif /* TESTMAIN */
 
 /* mxget.c ends here */