mxget.c
上传用户:xxcykj
上传日期:2007-01-04
资源大小:727k
文件大小:3k
源码类别:

Email客户端

开发平台:

Unix_Linux

  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. #include "config.h"
  8. #ifdef HAVE_RES_SEARCH
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <netdb.h>
  12. #include <sys/types.h>
  13. #include <netinet/in.h>
  14. #include <arpa/nameser.h>
  15. #include <resolv.h>
  16. #include "mx.h"
  17. /*
  18.  * This ought to be in the bind library.  It's adapted from sendmail.
  19.  */
  20. /*
  21.  * These are defined in RFC833. Some bind interface headers don't declare them.
  22.  * Ghod help us if they're ever actually incompatible with what's in 
  23.  * the arpa/nameser.h header.
  24.  */
  25. #ifndef PACKETSZ
  26. #define PACKETSZ 512 /* maximum packet size */
  27. #endif
  28. #ifndef HFIXEDSZ
  29. #define HFIXEDSZ 12 /* #/bytes of fixed data in header */
  30. #endif
  31. #ifndef INT32SZ
  32. #define INT32SZ 4 /* for systems without 32-bit ints */
  33. #endif
  34. #ifndef INT16SZ
  35. #define INT16SZ 2 /* for systems without 16-bit ints */
  36. #endif
  37. /* minimum possible size of MX record in packet */
  38. #define MIN_MX_SIZE 8 /* corresp to "a.com 0" w/ terminating space */
  39. struct mxentry *getmxrecords(const char *name)
  40. /* get MX records for given host */
  41. {
  42.     char answer[PACKETSZ], *eom, *cp, *bp;
  43.     int n, ancount, qdcount, buflen, type, pref, ind;
  44.     static struct mxentry pmx[(PACKETSZ - HFIXEDSZ) / MIN_MX_SIZE];
  45.     static char MXHostBuf[PACKETSZ - HFIXEDSZ]; 
  46.     HEADER *hp;
  47.     pmx->name = (char *)NULL;
  48.     pmx->pref = -1;
  49.     n = res_search(name, C_IN,T_MX, (unsigned char *)&answer, sizeof(answer));
  50.     if (n == -1)
  51. return((struct mxentry *)NULL);
  52.     hp = (HEADER *)&answer;
  53.     cp = answer + HFIXEDSZ;
  54.     eom = answer + n;
  55.     h_errno = 0;
  56.     for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
  57. if ((n = dn_skipname(cp, eom)) < 0)
  58.     return((struct mxentry *)NULL);
  59.     buflen = sizeof(MXHostBuf) - 1;
  60.     bp = MXHostBuf;
  61.     ind = 0;
  62.     ancount = ntohs(hp->ancount);
  63.     while (--ancount >= 0 && cp < eom)
  64.     {
  65. if ((n = dn_expand(answer, eom, cp, bp, buflen)) < 0)
  66.     break;
  67. cp += n;
  68. GETSHORT(type, cp);
  69. cp += INT16SZ + INT32SZ;
  70. GETSHORT(n, cp);
  71. if (type != T_MX)
  72. {
  73.     cp += n;
  74.     continue;
  75. }
  76. GETSHORT(pref, cp);
  77. if ((n = dn_expand(answer, eom, cp, bp, buflen)) < 0)
  78.     break;
  79. cp += n;
  80. pmx[ind].name = bp;
  81. pmx[ind].pref = pref;
  82. ++ind;
  83. n = strlen((const char *)bp);
  84. bp += n;
  85. *bp++ = '';
  86. buflen -= n + 1;
  87.     }
  88.     pmx[ind].name = (char *)NULL;
  89.     pmx[ind].pref = -1;
  90.     return(pmx);
  91. }
  92. #endif /* HAVE_RES_SEARCH */
  93. #ifdef TESTMAIN
  94. main(int argc, char *argv[])
  95. {
  96.     int count, i;
  97.     struct mxentry *responses;
  98.     responses = getmxrecords(argv[1]);
  99.     if (responses == (struct mxentry *)NULL)
  100. puts("No MX records found");
  101.     else
  102. do {
  103.     printf("%s %dn", responses->name, responses->pref);
  104. } while
  105.     ((++responses)->name);
  106. }
  107. #endif /* TESTMAIN */
  108. /* mxget.c ends here */