Annotation of coherent/a/tmp/smail/resolve.ORIG, revision 1.1.1.1

1.1       root        1: /*
                      2: **
                      3: **  Resolve.c
                      4: **
                      5: **  Routes then resolves addresses into UUCP or LOCAL.
                      6: **
                      7: */
                      8: #ifndef lint
                      9: static char    *sccsid="@(#)resolve.c  2.5 (smail) 9/15/87";
                     10: #endif
                     11: 
                     12: #include       <ctype.h>
                     13: #include       <stdio.h>
                     14: #include       "defs.h"
                     15: 
                     16: extern int exitstat;           /* set if address doesn't resolve       */
                     17: extern enum ehandle handle;    /* what mail we can handle              */
                     18: extern enum edebug debug;      /* verbose and debug modes              */
                     19: extern enum erouting routing;  /* when to route addresses              */
                     20: extern char hostdomain[];      /* */
                     21: extern char hostname[];                /* */
                     22: extern char *pathfile;         /* location of path database            */
                     23: extern int getcost;            /* get path cost even if not routing    */
                     24: 
                     25: char *sform();
                     26: 
                     27: /*
                     28: **
                     29: **  rsvp(): how to resolve addresses.
                     30: **
                     31: **  After parsing an address into <form>, the resolved form will be
                     32: **  rsvp( form ).  If == ROUTE, we route the parsed address and parse again.
                     33: **
                     34: */
                     35: 
                     36: # define rsvp(a) table[(int)a][(int)handle]
                     37: 
                     38: enum eform table[5][3] = {
                     39: /*     all             justuucp        none */
                     40: {      ERROR,          ERROR,          ERROR },        /* error */
                     41: {      LOCAL,          LOCAL,          LOCAL },        /* local */
                     42: {      ROUTE,          LOCAL,          LOCAL },        /* domain */
                     43: {      UUCP,           UUCP,           LOCAL },        /* uucp */
                     44: {      ERROR,          ERROR,          ERROR }};       /* route */
                     45: 
                     46: /*
                     47: **
                     48: **  resolve(): resolve addresses to <host, user, form>.
                     49: **
                     50: **  This is a gnarly piece of code, but it does it all.  Each section 
                     51: **  is documented.
                     52: **
                     53: */
                     54: 
                     55: enum eform
                     56: resolve( address, domain, user , cost)
                     57: char *address;                         /* the input address    */
                     58: char *domain;                          /* the returned domain  */
                     59: char *user;                            /* the returned user    */
                     60: int *cost;                             /* the returned cost    */
                     61: {
                     62:        enum eform form;                /* the returned form    */ 
                     63:        enum eform parse();             /* to crack addresses   */
                     64:        int parts;                      /* to ssplit addresses  */
                     65:        char *partv[MAXPATH];           /* "  "      "          */
                     66:        char temp[SMLBUF];              /* "  "      "          */
                     67:        int i;
                     68:                
                     69: 
                     70: /*
                     71: **  If we set REROUTE and are prepared to deliver UUCP mail, we split the 
                     72: **  address apart at !'s and try to resolve successively larger righthand 
                     73: **  substrings until we succeed.  Otherwise, we just resolve the whole thing 
                     74: **  once.
                     75: */
                     76:        if ((routing == REROUTE) && (rsvp( UUCP ) == UUCP)) {
                     77:                parts = ssplit( address, '!', partv );
                     78:        } else {
                     79:                parts = 1;
                     80:                partv[0] = address;
                     81:        }
                     82: /*
                     83: **  This for(i) loop selects successively larger
                     84: **  righthand substrings of the address.
                     85: */
                     86:        for( i = parts - 1; i >= 0; i-- ) {
                     87: /*
                     88: **  Parse the address.
                     89: */
                     90:                (void) strcpy( temp, partv[i] );
                     91:                form = parse( temp, domain, user );
                     92: 
                     93: DEBUG("resolve: parse address '%s' = '%s' @ '%s' (%s)\n",
                     94:        temp,user,domain,sform(form));
                     95: 
                     96: /*
                     97: **  If we are looking at a substring (that's not the entire string)
                     98: **  which parses to a LOCAL address, we skip to the next larger substring.
                     99: */
                    100:                if((i != 0) && (form == LOCAL))
                    101:                        continue;
                    102: /*
                    103: **  Routing, when required, is the next step.
                    104: **  We route the address if we have a ROUTE form
                    105: **  or if we have a UUCP form and we are told to
                    106: **  route ALWAYS or REROUTE (i.e., routing != JUSTDOMAIN)
                    107: */
                    108:                if((rsvp( form ) == ROUTE)
                    109:                 ||((rsvp( form ) == UUCP) && (routing != JUSTDOMAIN ))) {
                    110: 
                    111:                        int look_smart = 0;
                    112: 
                    113:                        if((routing == REROUTE) && (i == 0)) {
                    114:                                look_smart = 1; /* last chance */
                    115:                        }
                    116: 
                    117:                        /* route() puts the new route in 'temp' */
                    118:                        if(route(domain,user,look_smart,temp,cost) != EX_OK) {
                    119:                                continue;       /* If routing fails, try
                    120:                                                /* next larger substring.
                    121:                                                /* */
                    122:                        }
                    123: /*
                    124: **  After routing, reparse the new route into domain and user. 
                    125: */
                    126:                        form = parse( temp, domain, user );
                    127: 
                    128: DEBUG("resolve: parse route '%s' = '%s' @ '%s' (%s)\n",
                    129:        temp,user,domain,sform(form));
                    130: 
                    131:                } else if((getcost) && (rsvp(form) == UUCP)) {
                    132:                        /* get the cost of the route
                    133:                        ** even if we're not going route the mail.
                    134:                        ** this allows smart decisions about using
                    135:                        ** the -r flag to uux when we're not routing.
                    136:                        */
                    137:                        char junk[SMLBUF];
                    138:                        if(route(domain,user,0,junk,cost) != EX_OK) {
                    139:                                continue;       /* If routing fails, try
                    140:                                                /* next larger substring.
                    141:                                                /* */
                    142:                        }
                    143:                }
                    144:                break;  /* route is resolved */
                    145:        }
                    146: /*
                    147: **  For LOCAL mail in non-local format, we rewrite the full address into 
                    148: **  <user> and leave <domain> blank.
                    149: */
                    150:        if ((rsvp( form ) == LOCAL) && (form != LOCAL )) {
                    151:                build( domain, user, form, temp );
                    152:                (void) strcpy( user, temp );
                    153:                (void) strcpy( domain, "" );
                    154:                form = LOCAL;
                    155:        }
                    156: /*
                    157: **  If we were supposed to route an address but failed (form == ERROR), 
                    158: **  or after routing we are left with an address that still needs to
                    159: **  be routed (rsvp( form ) == ROUTE), complain.
                    160: */
                    161:        if ((form == ERROR) || (rsvp( form ) == ROUTE )) {
                    162:                exitstat = EX_NOHOST;
                    163:                ADVISE("resolve failed '%s' = '%s' @ '%s' (%s)\n",
                    164:                        address, user, domain, sform(form));
                    165:                form = ERROR;
                    166:        } else {
                    167:                ADVISE("resolve '%s' = '%s' @ '%s' (%s)\n",
                    168:                        address, user, domain, sform(form));
                    169:        }
                    170:        return ( form );
                    171: }
                    172: 
                    173: /*
                    174: **
                    175: **  route(): route domain, plug in user.
                    176: **
                    177: **  Less complicated than it looks.  Each section is documented.
                    178: **
                    179: */
                    180: 
                    181: route(domain, user, look_smart, result, cost)
                    182: char *domain;                  /* domain or host name  */
                    183: char *user;                    /* user name            */
                    184: int look_smart;                        /* do we try to route through a smarter host? */
                    185: char *result;                  /* output route         */
                    186: int *cost;                     /* cost of output route */
                    187: {
                    188:        int     uucpdom = 0;
                    189:        int     domains, step;                  /* to split domain      */
                    190:        char    *domainv[MAXDOMS];              /* "  "     "           */
                    191:        char    temp[SMLBUF], path[SMLBUF];
                    192: 
                    193: /*
                    194: **  Fully qualify the domain, and then strip the last (top level domain) 
                    195: **  component off, so that we look it up separately.
                    196: */
                    197:        temp[0] = '.';
                    198:        (void) strcpy(temp+1, domain );
                    199: 
                    200:        domains = ssplit( temp+1, '.', domainv );
                    201: 
                    202: /*
                    203: ** check target domain for the local host name and host domain.
                    204: ** if it matches, then skip the lookup in the database.
                    205: ** this prevents mail loops for cases where SMARTHOST is defined
                    206: ** in the routing table, but the local host is not.  It also is
                    207: ** a little faster when the local host is the target domain.
                    208: */
                    209:        if((strcmpic(domain, hostname) == 0)
                    210:        || (strcmpic(domain, hostdomain) == 0)) {
                    211:                step = 0;
                    212:                *cost = 0;
                    213:                (void) strcpy(path, "%s");
                    214: DEBUG("route: '%s' is local\n", domain);
                    215:                goto route_complete;
                    216:        }
                    217: 
                    218:        /* If the domain ends in .UUCP, trim that off. */
                    219:        if((domains > 0) && isuucp(domainv[domains-1])) {
                    220:                domains--;
                    221:                domainv[domains][-1] = '\0';
                    222:                uucpdom = 1;
                    223:        }
                    224: /*
                    225: **  Try to get the path for successive components of the domain.  
                    226: **  Example for osgd.cb.att.uucp:
                    227: **     osgd.cb.att
                    228: **     cb.att
                    229: **     att
                    230: **     uucp ( remember stripping top level? )
                    231: **     SMARTHOST
                    232: **  Returns with error if we find no path.
                    233: */
                    234:        for(step = 0; (step < domains); step++) {
                    235:                if((getpath(domainv[step]-1, path, cost) == EX_OK) /* w/ dot */
                    236:                || (getpath(domainv[step]  , path, cost) == EX_OK))/* no dot */
                    237:                        break;
                    238:        }
                    239: 
                    240:        if(step == domains) {
                    241:        /*
                    242:        ** we've looked at each component of the domain without success
                    243:        */
                    244:                /*
                    245:                ** If domain is a UUCP address, look for a UUCP gateway.
                    246:                */
                    247:                if((uucpdom == 0) || (getpath(".UUCP", path, cost) != EX_OK)) {
                    248:                        /*
                    249:                        ** The domain not is a UUCP address, or we can't
                    250:                        ** find a UUCP gateway.  If this is our last chance,
                    251:                        ** look for a smarter host to deliver the mail.
                    252:                        */
                    253:                        if((look_smart == 0)
                    254:                        || (getpath(SMARTHOST, path, cost) != EX_OK)) {
                    255:                                /*
                    256:                                ** All our efforts have been in vain.
                    257:                                ** Tell them the bad news.
                    258:                                */
                    259:                                DEBUG("route '%s' failed\n", domain);
                    260:                                return( EX_NOHOST );
                    261:                        }
                    262:                }
                    263:        }
                    264: 
                    265: route_complete:
                    266: 
                    267: DEBUG("route:  '%s' (%s) = '%s' (%d)\n", domain, domainv[step]?domainv[step]:"NULL", path, *cost);
                    268: 
                    269: /*
                    270: **  If we matched on the entire domain name, this address is fully resolved, 
                    271: **  and we plug <user> into it.  If we matched on only part of the domain 
                    272: **  name, we plug <domain>!<user> in.  
                    273: */
                    274:        build(domain, user, (step == 0) ? LOCAL : UUCP, temp);
                    275:        (void) sprintf(result, path, temp);
                    276:        return( EX_OK );
                    277: }

unix.superglobalmegacorp.com

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