home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / comm / mail / smail / src / rcs / resolve.c,v < prev    next >
Text File  |  1993-12-21  |  10KB  |  381 lines

  1. head    1.2;
  2. access;
  3. symbols
  4.     C_1:1.2;
  5. locks; strict;
  6. comment    @ * @;
  7.  
  8.  
  9. 1.2
  10. date    93.10.26.23.05.24;    author Aussem;    state Exp;
  11. branches;
  12. next    1.1;
  13.  
  14. 1.1
  15. date    93.10.24.00.20.08;    author Aussem;    state Exp;
  16. branches;
  17. next    ;
  18.  
  19.  
  20. desc
  21. @resolving the UUCP address
  22. (the earlier versions are lost :-(
  23. @
  24.  
  25.  
  26. 1.2
  27. log
  28. @smail -OA torfhh!test!root now reports really
  29. torfhh!test!root
  30. @
  31. text
  32. @/*
  33.  *  resolve.c
  34.  *
  35.  *  Routines to resolve mail address
  36.  *
  37.  * This program is free software; you can redistribute it and/or
  38.  * modify it under the terms of the GNU General Public License as
  39.  * published by the Free Software Foundation; either version 2 of
  40.  * the License, or (at your option) any later version.
  41.  *
  42.  * This program is distributed in the hope that it will be useful,
  43.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  44.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  45.  * General Public License for more details.
  46.  *
  47.  * You should have received a copy of the GNU General Public License
  48.  * along with this program; if not, write to the Free Software
  49.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  50.  *
  51.  * $Log: resolve.c,v $
  52.  * Revision 1.1  1993/10/24  00:20:08  Aussem
  53.  * Initial revision
  54.  *
  55.  *
  56.  */
  57.  
  58. static char     *rcsid="$Id: resolve.c,v 1.1 1993/10/24 00:20:08 Aussem Exp Aussem $";
  59.  
  60. #include    <ctype.h>
  61. #include    <stdio.h>
  62. #include    "defs.h"
  63.  
  64. extern int exitstat;        /* set if address doesn't resolve     */
  65. extern enum ehandle handle;    /* what mail we can handle        */
  66. extern enum edebug debug;    /* verbose and debug modes        */
  67. extern enum erouting routing;    /* when to route addresses        */
  68. extern char hostdomain[];    /* */
  69. extern char hostname[];        /* */
  70. extern char *pathfile;        /* location of path database        */
  71. extern int getcost;        /* get path cost even if not routing    */
  72. extern char smarthost[];
  73.  
  74. char *sform();
  75.  
  76. /*
  77. **
  78. **  rsvp(): how to resolve addresses.
  79. **
  80. **  After parsing an address into <form>, the resolved form will be
  81. **  rsvp( form ).  If == ROUTE, we route the parsed address and parse again.
  82. **
  83. */
  84.  
  85. # define rsvp(a) table[(int)a][(int)handle]
  86.  
  87. enum eform table[5][3] = {
  88. /*    all        justuucp    none */
  89. {    ERROR,         ERROR,         ERROR },     /* error */
  90. {    LOCAL,         LOCAL,         LOCAL },     /* local */
  91. {    ROUTE,         LOCAL,         LOCAL },     /* domain */
  92. {    UUCP,         UUCP,         LOCAL },     /* uucp */
  93. {    ERROR,         ERROR,         ERROR }};    /* route */
  94.  
  95. /*
  96. **
  97. **  resolve(): resolve addresses to <host, user, form>.
  98. **
  99. **  This is a gnarly piece of code, but it does it all.  Each section 
  100. **  is documented.
  101. **
  102. */
  103.  
  104. enum eform
  105. resolve( address, domain, user , cost)
  106. char *address;                /* the input address     */
  107. char *domain;                /* the returned domain     */
  108. char *user;                /* the returned user     */
  109. int *cost;                /* the returned cost     */
  110. {
  111.     enum eform form;        /* the returned form    */ 
  112.     enum eform parse();        /* to crack addresses    */
  113.     int parts;            /* to ssplit addresses    */
  114.     char *partv[MAXPATH];        /* "  "      "        */
  115.     char temp[SMLBUF];        /* "  "      "        */
  116.     int i;
  117.         
  118.  
  119. /*
  120. **  If we set REROUTE and are prepared to deliver UUCP mail, we split the 
  121. **  address apart at !'s and try to resolve successively larger righthand 
  122. **  substrings until we succeed.  Otherwise, we just resolve the whole thing 
  123. **  once.
  124. */
  125.     if ((routing == REROUTE) && (rsvp( UUCP ) == UUCP)) {
  126.         parts = ssplit( address, '!', partv );
  127.     } else {
  128.         parts = 1;
  129.         partv[0] = address;
  130.     }
  131. /*
  132. **  This for(i) loop selects successively larger
  133. **  righthand substrings of the address.
  134. */
  135.     for( i = parts - 1; i >= 0; i-- ) {
  136. /*
  137. **  Parse the address.
  138. */
  139.         (void) strcpy( temp, partv[i] );
  140.         form = parse( temp, domain, user );
  141.  
  142. DEBUG("resolve: parse address '%s' = '%s' @@ '%s' (%s)\n",
  143.     temp,user,domain,sform(form));
  144.  
  145. /*
  146. **  If we are looking at a substring (that's not the entire string)
  147. **  which parses to a LOCAL address, we skip to the next larger substring.
  148. */
  149.         if((i != 0) && (form == LOCAL))
  150.             continue;
  151. /*
  152. **  Routing, when required, is the next step.
  153. **  We route the address if we have a ROUTE form
  154. **  or if we have a UUCP form and we are told to
  155. **  route ALWAYS or REROUTE (i.e., routing != JUSTDOMAIN)
  156. */
  157.         if((rsvp( form ) == ROUTE)
  158.          ||((rsvp( form ) == UUCP) && (routing != JUSTDOMAIN ))) {
  159.  
  160.             int look_smart = 0;
  161. /*
  162. **       if the host is not found the mail cannot be delivered
  163. **            if((routing == REROUTE) && (i == 0)) {
  164. **
  165. **       Now the mail will be delivered to smarthost anyway
  166. */
  167.             if(i == 0) {
  168.                 look_smart = 1; /* last chance */
  169.             }
  170.  
  171.             /* route() puts the new route in 'temp' */
  172.             if(route(domain,user,look_smart,temp,cost) != EX_OK) {
  173.                 continue;    /* If routing fails, try
  174.                         /* next larger substring.
  175.                         /* */
  176.             }
  177. /*
  178. **  After routing, reparse the new route into domain and user. 
  179. */
  180.             form = parse( temp, domain, user );
  181.  
  182. DEBUG("resolve: parse route '%s' = '%s' @@ '%s' (%s)\n",
  183.     temp,user,domain,sform(form));
  184.  
  185. if(debug==NO)
  186.     printf("Ok, mail sent to %s via %s\n",  user, domain);
  187.  
  188.         } else if((getcost) && (rsvp(form) == UUCP)) {
  189.             /* get the cost of the route
  190.             ** even if we're not going route the mail.
  191.             ** this allows smart decisions about using
  192.             ** the -r flag to uux when we're not routing.
  193.             */
  194.             char junk[SMLBUF];
  195.             if(route(domain,user,0,junk,cost) != EX_OK) {
  196.                 continue;    /* If routing fails, try
  197.                         /* next larger substring.
  198.                         /* */
  199.             }
  200.         }
  201.         break;    /* route is resolved */
  202.     }
  203. /*
  204. **  For LOCAL mail in non-local format, we rewrite the full address into 
  205. **  <user> and leave <domain> blank.
  206. */
  207.     if ((rsvp( form ) == LOCAL) && (form != LOCAL )) {
  208.         build( domain, user, form, temp );
  209.         (void) strcpy( user, temp );
  210.         (void) strcpy( domain, "" );
  211.         form = LOCAL;
  212.     }
  213. /*
  214. **  If we were supposed to route an address but failed (form == ERROR), 
  215. **  or after routing we are left with an address that still needs to
  216. **  be routed (rsvp( form ) == ROUTE), complain.
  217. */
  218.     if ((form == ERROR) || (rsvp( form ) == ROUTE )) {
  219.         exitstat = EX_NOHOST;
  220.         ADVISE("resolve failed '%s' = '%s' @@ '%s' (%s)\n",
  221.             address, user, domain, sform(form));
  222.         form = ERROR;
  223.     } else {
  224.         ADVISE("resolve '%s' = '%s' @@ '%s' (%s)\n",
  225.             address, user, domain, sform(form));
  226.     }
  227.     return ( form );
  228. }
  229.  
  230. /*
  231. **
  232. **  route(): route domain, plug in user.
  233. **
  234. **  Less complicated than it looks.  Each section is documented.
  235. **
  236. */
  237.  
  238. route(domain, user, look_smart, result, cost)
  239. char *domain;            /* domain or host name     */
  240. char *user;            /* user name         */
  241. int look_smart;            /* do we try to route through a smarter host? */
  242. char *result;            /* output route     */
  243. int *cost;            /* cost of output route */
  244. {
  245.     int    uucpdom = 0;
  246.     int    domains, step;            /* to split domain    */
  247.     char    *domainv[MAXDOMS];        /* "  "     "        */
  248.     char    temp[SMLBUF], path[SMLBUF];
  249.     char *p_tmp;
  250.  
  251. /*
  252. **  Fully qualify the domain, and then strip the last (top level domain)
  253. **  component off, so that we look it up separately.
  254. */
  255.     temp[0] = '.';
  256.     (void) strcpy(temp+1, domain );
  257.  
  258.     domains = ssplit( temp+1, '.', domainv );
  259.  
  260. /*
  261. ** check target domain for the local host name and host domain.
  262. ** if it matches, then skip the lookup in the database.
  263. ** this prevents mail loops for cases where SMARTHOST is defined
  264. ** in the routing table, but the local host is not.  It also is
  265. ** a little faster when the local host is the target domain.
  266. */
  267.     if((strcmpic(domain, hostname) == 0)
  268.     || (strcmpic(domain, hostdomain) == 0)) {
  269.         step = 0;
  270.         *cost = 0;
  271.         (void) strcpy(path, "%s");
  272. DEBUG("route: '%s' is local\n", domain);
  273.         goto route_complete;
  274.     }
  275.  
  276.     /* If the domain ends in .UUCP, trim that off. */
  277.     if((domains > 0) && isuucp(domainv[domains-1])) {
  278.         domains--;
  279.         domainv[domains][-1] = '\0';
  280.         uucpdom = 1;
  281.     }
  282. /*
  283. **  Try to get the path for successive components of the domain.
  284. **  Example for osgd.cb.att.uucp:
  285. **    osgd.cb.att
  286. **    cb.att
  287. **    att
  288. **    uucp ( remember stripping top level? )
  289. **    SMARTHOST
  290. **  Returns with error if we find no path.
  291. */
  292.     for(step = 0; (step < domains); step++) {
  293.         if((getpath(domainv[step]-1, path, cost) == EX_OK) /* w/ dot */
  294.         || (getpath(domainv[step]  , path, cost) == EX_OK))/* no dot */
  295.             break;
  296.     }
  297.  
  298.  
  299.     if(step == domains) {
  300.     /*
  301.     ** we've looked at each component of the domain without success
  302.     */
  303.         /*
  304.         ** if we don't look up for smarthost return (RTA)
  305.         */
  306.         if(look_smart==0)
  307.             return( EX_NOHOST );
  308.  
  309.         /*
  310.         ** If domain is a UUCP address, look for a UUCP gateway.
  311.         */
  312.         if((uucpdom == 0) || (getpath(".UUCP", path, cost) != EX_OK)) {
  313.             /*
  314.             ** The domain not is a UUCP address, or we can't
  315.             ** find a UUCP gateway.  If this is our last chance,
  316.             ** look for a smarter host to deliver the mail.
  317.             */
  318.             if(getpath(smarthost, path, cost) != EX_OK) {
  319.                 /*
  320.                 ** All our efforts have been in vain.
  321.                 ** Tell them the bad news.
  322.                 */
  323. #ifdef SMARTMAIL
  324.                 DEBUG("route '%s' failed, sending it to smarthost '%s'\n", domain,smarthost);
  325.                 /* only use the last component of smarthost */
  326.                 p_tmp=index(smarthost,'.');
  327.                 if(p_tmp)
  328.                *p_tmp='\0';
  329.                 p_tmp=index(smarthost,'!');
  330.                 if(p_tmp)
  331.                *p_tmp='\0';
  332.             step=0;sprintf(path,"%s!%s!%%s",smarthost,domain);
  333.             *cost=0;
  334. #else
  335.                 DEBUG("route '%s' failed\n", domain);
  336.                 return( EX_NOHOST );
  337. #endif
  338.             }
  339.         }
  340.     }
  341.  
  342. route_complete:
  343.  
  344. DEBUG("route:  '%s' (%s) = '%s' (%d)\n", domain, domainv[step]?domainv[step]:"NULL", path, *cost);
  345.  
  346. /*
  347. **  If we matched on the entire domain name, this address is fully resolved,
  348. **  and we plug <user> into it.  If we matched on only part of the domain
  349. **  name, we plug <domain>!<user> in.
  350. */
  351.     build(domain, user, (step == 0) ? LOCAL : UUCP, temp);
  352.     (void) sprintf(result, path, temp);
  353.     return( EX_OK );
  354. }
  355. @
  356.  
  357.  
  358. 1.1
  359. log
  360. @Initial revision
  361. @
  362. text
  363. @d20 3
  364. a22 1
  365.  * $Log$
  366. d24 1
  367. d27 1
  368. a27 1
  369. static char     *rcsid="$Id$";
  370. d130 7
  371. a136 2
  372.  
  373.             if((routing == REROUTE) && (i == 0)) {
  374. d267 1
  375. d273 6
  376. d287 1
  377. a287 2
  378.             if((look_smart == 0)
  379.             || (getpath(smarthost, path, cost) != EX_OK)) {
  380. @
  381.