1: /*
   2:  * Copyright (c) 1988 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms are permitted
   6:  * provided that this notice is preserved and that due credit is given
   7:  * to the University of California at Berkeley. The name of the University
   8:  * may not be used to endorse or promote products derived from this
   9:  * software without specific prior written permission. This software
  10:  * is provided ``as is'' without express or implied warranty.
  11:  *
  12:  *  Sendmail
  13:  *  Copyright (c) 1986  Eric P. Allman
  14:  *  Berkeley, California
  15:  */
  16: 
  17: #include <sendmail.h>
  18: 
  19: #if !defined(lint) && !defined(NOSCCS)
  20: static char sccsid[] = "@(#)domain.c	5.14 (Berkeley) 5/3/88";
  21: #endif /* not lint */
  22: 
  23: #include <sys/param.h>
  24: #include <arpa/nameser.h>
  25: #include <resolv.h>
  26: #include <netdb.h>
  27: 
  28: typedef union {
  29:     HEADER qb1;
  30:     char qb2[PACKETSZ];
  31: } querybuf;
  32: 
  33: #ifdef  MXDOMAIN
  34: static char hostbuf[MAXMXHOSTS*PACKETSZ];
  35: 
  36: getmxrr(host, mxhosts, localhost, rcode)
  37:     char *host, **mxhosts, *localhost;
  38:     int *rcode;
  39: {
  40:     extern int h_errno;
  41:     register u_char *eom, *cp;
  42:     register int i, j, n, nmx;
  43:     register char *bp;
  44:     HEADER *hp;
  45:     querybuf answer;
  46:     int ancount, qdcount, buflen, seenlocal;
  47:     u_short pref, localpref, type, prefer[MAXMXHOSTS];
  48: 
  49:     n = res_search(host, C_IN, T_MX, (char *)&answer, sizeof(answer));
  50:     if (n < 0) {
  51: #ifdef DEBUG
  52:         if (tTd(8, 1))
  53:             printf("getmxrr: res_search failed (errno=%d, h_errno=%d)\n",
  54:                 errno, h_errno);
  55: #endif
  56:         switch(h_errno) {
  57:         case NO_DATA:
  58:         case NO_RECOVERY:
  59:             goto punt;
  60:         case HOST_NOT_FOUND:
  61:             *rcode = EX_NOHOST;
  62:             break;
  63:         case TRY_AGAIN:
  64:             *rcode = EX_TEMPFAIL;
  65:             break;
  66:         }
  67:         return(-1);
  68:     }
  69: 
  70:     /* find first satisfactory answer */
  71:     hp = (HEADER *)&answer;
  72:     cp = (u_char *)&answer + sizeof(HEADER);
  73:     eom = (u_char *)&answer + n;
  74:     for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
  75:         if ((n = dn_skipname(cp, eom)) < 0)
  76:             goto punt;
  77:     nmx = 0;
  78:     seenlocal = 0;
  79:     buflen = sizeof(hostbuf);
  80:     bp = hostbuf;
  81:     ancount = ntohs(hp->ancount);
  82:     while (--ancount >= 0 && cp < eom && nmx < MAXMXHOSTS) {
  83:         if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0)
  84:             break;
  85:         cp += n;
  86:         GETSHORT(type, cp);
  87:         cp += sizeof(u_short) + sizeof(u_long);
  88:         GETSHORT(n, cp);
  89:         if (type != T_MX)  {
  90: #ifdef DEBUG
  91:             if (tTd(8, 1) || _res.options & RES_DEBUG)
  92:                 printf("unexpected answer type %d, size %d\n",
  93:                     type, n);
  94: #endif
  95:             cp += n;
  96:             continue;
  97:         }
  98:         GETSHORT(pref, cp);
  99:         if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0)
 100:             break;
 101:         cp += n;
 102:         if (!strcasecmp(bp, localhost)) {
 103:             if (seenlocal == 0 || pref < localpref)
 104:                 localpref = pref;
 105:             seenlocal = 1;
 106:             continue;
 107:         }
 108:         prefer[nmx] = pref;
 109:         mxhosts[nmx++] = bp;
 110:         n = strlen(bp) + 1;
 111:         bp += n;
 112:         buflen -= n;
 113:     }
 114:     if (nmx == 0) {
 115: punt:       mxhosts[0] = strcpy(hostbuf, host);
 116:         return(1);
 117:     }
 118: 
 119:     /* sort the records */
 120:     for (i = 0; i < nmx; i++) {
 121:         for (j = i + 1; j < nmx; j++) {
 122:             if (prefer[i] > prefer[j]) {
 123:                 register int temp;
 124:                 register char *temp1;
 125: 
 126:                 temp = prefer[i];
 127:                 prefer[i] = prefer[j];
 128:                 prefer[j] = temp;
 129:                 temp1 = mxhosts[i];
 130:                 mxhosts[i] = mxhosts[j];
 131:                 mxhosts[j] = temp1;
 132:             }
 133:         }
 134:         if (seenlocal && prefer[i] >= localpref) {
 135:             /*
 136: 			 * truncate higher pref part of list; if we're
 137: 			 * the best choice left, we should have realized
 138: 			 * awhile ago that this was a local delivery.
 139: 			 */
 140:             if (i == 0) {
 141:                 *rcode = EX_CONFIG;
 142:                 return(-1);
 143:             }
 144:             nmx = i;
 145:             break;
 146:         }
 147:     }
 148:     return(nmx);
 149: }
 150: #endif MXDOMAIN
 151: 
 152: getcanonname(host, hbsize)
 153:     char *host;
 154:     int hbsize;
 155: {
 156:     register u_char *eom, *cp;
 157:     register int n;
 158:     HEADER *hp;
 159:     querybuf answer;
 160:     u_short type;
 161:     int first, ancount, qdcount, loopcnt;
 162:     extern int h_errno;
 163:     char nbuf[PACKETSZ];
 164: 
 165:     loopcnt = 0;
 166: loop:
 167:     n = res_search(host, C_IN, T_ANY, (char *)&answer, sizeof(answer));
 168:     if (n < 0) {
 169: #ifdef DEBUG
 170:         if (tTd(8, 1))
 171:             printf("getcanonname:  res_search failed (errno=%d, h_errno=%d)\n",
 172:                 errno, h_errno);
 173: #endif
 174:         return;
 175:     }
 176: 
 177:     /* find first satisfactory answer */
 178:     hp = (HEADER *)&answer;
 179:     ancount = ntohs(hp->ancount);
 180: 
 181:     /* we don't care about errors here, only if we got an answer */
 182:     if (ancount == 0) {
 183: #ifdef DEBUG
 184:         if (tTd(8, 1))
 185:             printf("rcode = %d, ancount=%d\n", hp->rcode, ancount);
 186: #endif
 187:         return;
 188:     }
 189:     cp = (u_char *)&answer + sizeof(HEADER);
 190:     eom = (u_char *)&answer + n;
 191:     for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
 192:         if ((n = dn_skipname(cp, eom)) < 0)
 193:             return;
 194: 
 195:     /*
 196: 	 * just in case someone puts a CNAME record after another record,
 197: 	 * check all records for CNAME; otherwise, just take the first
 198: 	 * name found.
 199: 	 */
 200:     for (first = 1; --ancount >= 0 && cp < eom; cp += n) {
 201:         if ((n = dn_expand((char *)&answer, eom, cp, nbuf,
 202:             sizeof(nbuf))) < 0)
 203:             break;
 204:         if (first) {            /* XXX */
 205:             (void)strncpy(host, nbuf, hbsize);
 206:             host[hbsize - 1] = '\0';
 207:             first = 0;
 208:         }
 209:         cp += n;
 210:         GETSHORT(type, cp);
 211:         cp += sizeof(u_short) + sizeof(u_long);
 212:         GETSHORT(n, cp);
 213:         if (type == T_CNAME)  {
 214:             /*
 215: 			 * assume that only one cname will be found.  More
 216: 			 * than one is undefined.  Copy so that if dn_expand
 217: 			 * fails, `host' is still okay.
 218: 			 */
 219:             if ((n = dn_expand((char *)&answer, eom, cp, nbuf,
 220:                 sizeof(nbuf))) < 0)
 221:                 break;
 222:             (void)strncpy(host, nbuf, hbsize); /* XXX */
 223:             host[hbsize - 1] = '\0';
 224:             if (++loopcnt > 8)  /* never be more than 1 */
 225:                 return;
 226:             goto loop;
 227:         }
 228:     }
 229: }

Defined functions

getcanonname defined in line 152; never used
getmxrr defined in line 36; used 1 times

Defined variables

hostbuf defined in line 34; used 3 times
sccsid defined in line 20; never used
Last modified: 1988-10-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2916
Valid CSS Valid XHTML 1.0 Strict