Annotation of 43BSDTahoe/usr.lib/sendmail/src/domain.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1986 Eric P. Allman
                      3:  * Copyright (c) 1988 Regents of the University of California.
                      4:  * All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms are permitted
                      7:  * provided that the above copyright notice and this paragraph are
                      8:  * duplicated in all such forms and that any documentation,
                      9:  * advertising materials, and other materials related to such
                     10:  * distribution and use acknowledge that the software was developed
                     11:  * by the University of California, Berkeley.  The name of the
                     12:  * University may not be used to endorse or promote products derived
                     13:  * from this software without specific prior written permission.
                     14:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     15:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     16:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     17:  */
                     18: 
                     19: #ifndef lint
                     20: static char sccsid[] = "@(#)domain.c   5.15 (Berkeley) 6/30/88";
                     21: #endif /* not lint */
                     22: 
                     23: #include <sendmail.h>
                     24: #include <sys/param.h>
                     25: #include <arpa/nameser.h>
                     26: #include <resolv.h>
                     27: #include <netdb.h>
                     28: 
                     29: typedef union {
                     30:        HEADER qb1;
                     31:        char qb2[PACKETSZ];
                     32: } querybuf;
                     33: 
                     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: 
                    151: getcanonname(host, hbsize)
                    152:        char *host;
                    153:        int hbsize;
                    154: {
                    155:        register u_char *eom, *cp;
                    156:        register int n; 
                    157:        HEADER *hp;
                    158:        querybuf answer;
                    159:        u_short type;
                    160:        int first, ancount, qdcount, loopcnt;
                    161:        char nbuf[PACKETSZ];
                    162: 
                    163:        loopcnt = 0;
                    164: loop:
                    165:        n = res_search(host, C_IN, T_CNAME, (char *)&answer, sizeof(answer));
                    166:        if (n < 0) {
                    167: #ifdef DEBUG
                    168:                if (tTd(8, 1))
                    169:                        printf("getcanonname:  res_search failed (errno=%d, h_errno=%d)\n",
                    170:                            errno, h_errno);
                    171: #endif
                    172:                return;
                    173:        }
                    174: 
                    175:        /* find first satisfactory answer */
                    176:        hp = (HEADER *)&answer;
                    177:        ancount = ntohs(hp->ancount);
                    178: 
                    179:        /* we don't care about errors here, only if we got an answer */
                    180:        if (ancount == 0) {
                    181: #ifdef DEBUG
                    182:                if (tTd(8, 1))
                    183:                        printf("rcode = %d, ancount=%d\n", hp->rcode, ancount);
                    184: #endif
                    185:                return;
                    186:        }
                    187:        cp = (u_char *)&answer + sizeof(HEADER);
                    188:        eom = (u_char *)&answer + n;
                    189:        for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
                    190:                if ((n = dn_skipname(cp, eom)) < 0)
                    191:                        return;
                    192: 
                    193:        /*
                    194:         * just in case someone puts a CNAME record after another record,
                    195:         * check all records for CNAME; otherwise, just take the first
                    196:         * name found.
                    197:         */
                    198:        for (first = 1; --ancount >= 0 && cp < eom; cp += n) {
                    199:                if ((n = dn_expand((char *)&answer, eom, cp, nbuf,
                    200:                    sizeof(nbuf))) < 0)
                    201:                        break;
                    202:                if (first) {                    /* XXX */
                    203:                        (void)strncpy(host, nbuf, hbsize);
                    204:                        host[hbsize - 1] = '\0';
                    205:                        first = 0;
                    206:                }
                    207:                cp += n;
                    208:                GETSHORT(type, cp);
                    209:                cp += sizeof(u_short) + sizeof(u_long);
                    210:                GETSHORT(n, cp);
                    211:                if (type == T_CNAME)  {
                    212:                        /*
                    213:                         * assume that only one cname will be found.  More
                    214:                         * than one is undefined.  Copy so that if dn_expand
                    215:                         * fails, `host' is still okay.
                    216:                         */
                    217:                        if ((n = dn_expand((char *)&answer, eom, cp, nbuf,
                    218:                            sizeof(nbuf))) < 0)
                    219:                                break;
                    220:                        (void)strncpy(host, nbuf, hbsize); /* XXX */
                    221:                        host[hbsize - 1] = '\0';
                    222:                        if (++loopcnt > 8)      /* never be more than 1 */
                    223:                                return;
                    224:                        goto loop;
                    225:                }
                    226:        }
                    227: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.