Annotation of coherent/a/tmp/smail/resolve.c, 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: DEBUG("route(dom: '%s', user: '%s', smart: %d ...)\n",
        !           118:        domain, user, look_smart);
        !           119:                        /* route() puts the new route in 'temp' */
        !           120:                        if(route(domain,user,look_smart,temp,cost) != EX_OK) {
        !           121:                                continue;       /* If routing fails, try
        !           122:                                                /* next larger substring.
        !           123:                                                /* */
        !           124:                        }
        !           125: /*
        !           126: **  After routing, reparse the new route into domain and user. 
        !           127: */
        !           128:                        form = parse( temp, domain, user );
        !           129: 
        !           130: DEBUG("resolve: parse route '%s' = '%s' @ '%s' (%s)\n",
        !           131:        temp,user,domain,sform(form));
        !           132: 
        !           133:                } else if((getcost) && (rsvp(form) == UUCP)) {
        !           134:                        /* get the cost of the route
        !           135:                        ** even if we're not going route the mail.
        !           136:                        ** this allows smart decisions about using
        !           137:                        ** the -r flag to uux when we're not routing.
        !           138:                        */
        !           139:                        char junk[SMLBUF];
        !           140:                        if(route(domain,user,0,junk,cost) != EX_OK) {
        !           141:                                continue;       /* If routing fails, try
        !           142:                                                /* next larger substring.
        !           143:                                                /* */
        !           144:                        }
        !           145:                }
        !           146:                break;  /* route is resolved */
        !           147:        }
        !           148: /*
        !           149: **  For LOCAL mail in non-local format, we rewrite the full address into 
        !           150: **  <user> and leave <domain> blank.
        !           151: */
        !           152:        if ((rsvp( form ) == LOCAL) && (form != LOCAL )) {
        !           153:                build( domain, user, form, temp );
        !           154:                (void) strcpy( user, temp );
        !           155:                (void) strcpy( domain, "" );
        !           156:                form = LOCAL;
        !           157:        }
        !           158: /*
        !           159: **  If we were supposed to route an address but failed (form == ERROR), 
        !           160: **  or after routing we are left with an address that still needs to
        !           161: **  be routed (rsvp( form ) == ROUTE), complain.
        !           162: */
        !           163:        if ((form == ERROR) || (rsvp( form ) == ROUTE )) {
        !           164:                exitstat = EX_NOHOST;
        !           165:                ADVISE("resolve failed '%s' = '%s' @ '%s' (%s)\n",
        !           166:                        address, user, domain, sform(form));
        !           167:                form = ERROR;
        !           168:        } else {
        !           169:                ADVISE("resolve '%s' = '%s' @ '%s' (%s)\n",
        !           170:                        address, user, domain, sform(form));
        !           171:        }
        !           172:        return ( form );
        !           173: }
        !           174: 
        !           175: /*
        !           176: **
        !           177: **  route(): route domain, plug in user.
        !           178: **
        !           179: **  Less complicated than it looks.  Each section is documented.
        !           180: **
        !           181: */
        !           182: 
        !           183: route(domain, user, look_smart, result, cost)
        !           184: char *domain;                  /* domain or host name  */
        !           185: char *user;                    /* user name            */
        !           186: int look_smart;                        /* do we try to route through a smarter host? */
        !           187: char *result;                  /* output route         */
        !           188: int *cost;                     /* cost of output route */
        !           189: {
        !           190:        int     uucpdom = 0;
        !           191:        int     domains, step;                  /* to split domain      */
        !           192:        char    *domainv[MAXDOMS];              /* "  "     "           */
        !           193:        char    temp[SMLBUF], path[SMLBUF];
        !           194:        char    *tdom;
        !           195: 
        !           196: /*
        !           197: **  Fully qualify the domain, and then strip the last (top level domain) 
        !           198: **  component off, so that we look it up separately.
        !           199: */
        !           200:        temp[0] = '.';
        !           201:        (void) strcpy(temp+1, domain );
        !           202: 
        !           203:        domains = ssplit( temp+1, '.', domainv );
        !           204: 
        !           205: /*
        !           206: ** check target domain for the local host name and host domain.
        !           207: ** if it matches, then skip the lookup in the database.
        !           208: ** this prevents mail loops for cases where SMARTHOST is defined
        !           209: ** in the routing table, but the local host is not.  It also is
        !           210: ** a little faster when the local host is the target domain.
        !           211: */
        !           212:        if((strcmpic(domain, hostname) == 0)
        !           213:        || (strcmpic(domain, hostdomain) == 0)) {
        !           214:                step = 0;
        !           215:                *cost = 0;
        !           216:                (void) strcpy(path, "%s");
        !           217: DEBUG("route: '%s' is local\n", domain);
        !           218:                goto route_complete;
        !           219:        }
        !           220: 
        !           221:        /* If the domain ends in .UUCP, trim that off. */
        !           222:        if((domains > 0) && isuucp(domainv[domains-1])) {
        !           223:                domains--;
        !           224:                domainv[domains][-1] = '\0';
        !           225:                uucpdom = 1;
        !           226:        }
        !           227: /*
        !           228: **  Try to get the path for successive components of the domain.  
        !           229: **  Example for osgd.cb.att.uucp:
        !           230: **     osgd.cb.att
        !           231: **     cb.att
        !           232: **     att
        !           233: **     uucp ( remember stripping top level? )
        !           234: **     SMARTHOST
        !           235: **  Returns with error if we find no path.
        !           236: */
        !           237:        for(step = 0; (step < domains); step++) {
        !           238:                if((getpath(domainv[step]-1, path, cost) == EX_OK) /* w/ dot */
        !           239:                || (getpath(domainv[step]  , path, cost) == EX_OK))/* no dot */
        !           240:                        break;
        !           241:        }
        !           242: 
        !           243:        if(step == domains) {
        !           244:        /*
        !           245:        ** we've looked at each component of the domain without success
        !           246:        */
        !           247:                /*
        !           248:                ** If domain is a UUCP address, look for a UUCP gateway.
        !           249:                */
        !           250:                if((uucpdom == 0) || (getpath(".UUCP", path, cost) != EX_OK)) {
        !           251:                        /*
        !           252:                        ** The domain not is a UUCP address, or we can't
        !           253:                        ** find a UUCP gateway.  If this is our last chance,
        !           254:                        ** look for a smarter host to deliver the mail.
        !           255:                        */
        !           256:                        if((look_smart == 0)
        !           257:                        || (getpath(SMARTHOST, path, cost) != EX_OK)) {
        !           258:                                /*
        !           259:                                ** All our efforts have been in vain.
        !           260:                                ** Tell them the bad news.
        !           261:                                */
        !           262:                                DEBUG("route '%s' failed\n", domain);
        !           263:                                return( EX_NOHOST );
        !           264:                        }
        !           265:                }
        !           266:        }
        !           267: 
        !           268: route_complete:
        !           269: 
        !           270: DEBUG("route:  '%s' (%s) = '%s' (%d)\n", domain, domainv[step]?domainv[step]:"NULL", path, *cost);
        !           271: 
        !           272: /*
        !           273: **  If we matched on the entire domain name, this address is fully resolved, 
        !           274: **  and we plug <user> into it.  If we matched on only part of the domain 
        !           275: **  name, we plug <domain>!<user> in.  
        !           276: */
        !           277:         if ((strcmp(path,"%s")) == 0 && (step != 0))
        !           278:         {
        !           279:            /*
        !           280:            ** part of the right-hand side of the entire domain name has
        !           281:            ** been matched. This portion needs to be stripped out, and
        !           282:            ** the remainder of the left-hand side needs to be used in
        !           283:            ** building up the address to which the mail will be delivered.
        !           284:            **
        !           285:            ** The right-hand portion to be stripped off is contained in
        !           286:            ** domainv[step]-1.
        !           287:            */
        !           288:            for (tdom = domain; strcmp(tdom,domainv[step]-1) != 0; tdom++);
        !           289: 
        !           290:             *tdom = '\0';
        !           291: 
        !           292:        }
        !           293:        build(domain, user, (step == 0) ? LOCAL : UUCP, temp);
        !           294:        (void) sprintf(result, path, temp);
        !           295:        return( EX_OK );
        !           296: }

unix.superglobalmegacorp.com

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