# 2.11BSD#431 - /usr/src/usr.sbin/sendmail.MX/src/domain.c

##### Functions

    getcanonname      X
    getmxrr           X

       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

- in /usr/src/usr.sbin/sendmail.MX/src/deliver.c line 391

#### Defined variables

hostbuf defined in line 34; used 3 times

- in line 79-80(2), 115

sccsid defined in line 20; never used

Last modified: 1988-10-15 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1091 |