Annotation of coherent/a/tmp/smail/resolve.ORIG, revision 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.