diff -r -u -N --exclude='*.orig' fetchmail-6.3.11.orig/mxget.c fetchmail-6.3.11/mxget.c --- fetchmail-6.3.11.orig/mxget.c 2009-05-25 02:54:58.000000000 -0700 +++ fetchmail-6.3.11/mxget.c 2009-09-25 12:30:02.000000000 -0700 @@ -4,8 +4,12 @@ * 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. + * + * 28 July 2006 + * Converted to use dns API for MacOS X - majka */ + #include "config.h" #include "fetchmail.h" #include <stdio.h> @@ -17,107 +21,48 @@ #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 <nameser.h> +#include <dns.h> +#include <dns_util.h> -#include "mx.h" - -/* - * This ought to be in the bind library. It's adapted from sendmail. - */ -/* - * 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 +#include "mx.h" -/* minimum possible size of MX record in packet */ -#define MIN_MX_SIZE 8 /* corresp to "a.com 0" w/ terminating space */ +#define MX_MAX 255 -struct mxentry *getmxrecords(const char *name) /* get MX records for given host */ +struct mxentry * +getmxrecords(const char *name) { - 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; - - pmx->name = (char *)NULL; - pmx->pref = -1; - n = res_search(name, C_IN,T_MX, (unsigned char *)&answer, sizeof(answer)); - if (n == -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((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((unsigned char *)answer, (unsigned char *)eom, - (unsigned char *)cp, bp, buflen)) < 0) - break; - cp += n; - GETSHORT(type, cp); - cp += INT16SZ + INT32SZ; - GETSHORT(n, cp); - if (type != T_MX) + static struct mxentry pmx[MX_MAX + 1]; + int i, j; + dns_handle_t dns; + dns_reply_t *reply; + + dns = dns_open(NULL); + if (dns == NULL) return NULL; + + reply = dns_lookup(dns, name, ns_c_in, ns_t_mx); + dns_free(dns); + + if (reply == NULL) return NULL; + + j = 0; + for (i = 0; (i < reply->header->ancount) && (j < MX_MAX); i++) { - cp += n; - continue; + if (reply->answer[i]->dnstype != ns_t_mx) continue; + pmx[j].pref = reply->answer[i]->data.MX->preference; + pmx[j].name = strdup(reply->answer[i]->data.MX->name); + j++; } - GETSHORT(pref, cp); - 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; - ++ind; - - n = strlen((const char *)bp); - bp += n; - *bp++ = '\0'; - - buflen -= n + 1; - } - - pmx[ind].name = (char *)NULL; - pmx[ind].pref = -1; - return(pmx); + + if (j == 0) return NULL; + + pmx[i].name = NULL; + pmx[i].pref = -1; + + return(pmx); } #endif /* HAVE_RES_SEARCH */ @@ -129,6 +74,7 @@ #ifdef HAVE_RES_SEARCH struct mxentry *responses; #endif + int i; if (argc != 2 || 0 == strcmp(argv[1], "-h")) { fprintf(stderr, "Usage: %s domain\n", argv[0]); @@ -137,12 +83,16 @@ #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); + if (responses == (struct mxentry *)NULL) + { + puts("No MX records found"); + } + else + { + for (i = 0; responses[i].name != NULL; i++) + { + printf("%s %d\n", responses[i].name, responses[i].pref); + } } #else puts("This program was compiled without HAS_RES_SEARCH and does nothing.");