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 >
Wrap
Text File
|
1993-12-21
|
10KB
|
381 lines
head 1.2;
access;
symbols
C_1:1.2;
locks; strict;
comment @ * @;
1.2
date 93.10.26.23.05.24; author Aussem; state Exp;
branches;
next 1.1;
1.1
date 93.10.24.00.20.08; author Aussem; state Exp;
branches;
next ;
desc
@resolving the UUCP address
(the earlier versions are lost :-(
@
1.2
log
@smail -OA torfhh!test!root now reports really
torfhh!test!root
@
text
@/*
* resolve.c
*
* Routines to resolve mail address
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: resolve.c,v $
* Revision 1.1 1993/10/24 00:20:08 Aussem
* Initial revision
*
*
*/
static char *rcsid="$Id: resolve.c,v 1.1 1993/10/24 00:20:08 Aussem Exp Aussem $";
#include <ctype.h>
#include <stdio.h>
#include "defs.h"
extern int exitstat; /* set if address doesn't resolve */
extern enum ehandle handle; /* what mail we can handle */
extern enum edebug debug; /* verbose and debug modes */
extern enum erouting routing; /* when to route addresses */
extern char hostdomain[]; /* */
extern char hostname[]; /* */
extern char *pathfile; /* location of path database */
extern int getcost; /* get path cost even if not routing */
extern char smarthost[];
char *sform();
/*
**
** rsvp(): how to resolve addresses.
**
** After parsing an address into <form>, the resolved form will be
** rsvp( form ). If == ROUTE, we route the parsed address and parse again.
**
*/
# define rsvp(a) table[(int)a][(int)handle]
enum eform table[5][3] = {
/* all justuucp none */
{ ERROR, ERROR, ERROR }, /* error */
{ LOCAL, LOCAL, LOCAL }, /* local */
{ ROUTE, LOCAL, LOCAL }, /* domain */
{ UUCP, UUCP, LOCAL }, /* uucp */
{ ERROR, ERROR, ERROR }}; /* route */
/*
**
** resolve(): resolve addresses to <host, user, form>.
**
** This is a gnarly piece of code, but it does it all. Each section
** is documented.
**
*/
enum eform
resolve( address, domain, user , cost)
char *address; /* the input address */
char *domain; /* the returned domain */
char *user; /* the returned user */
int *cost; /* the returned cost */
{
enum eform form; /* the returned form */
enum eform parse(); /* to crack addresses */
int parts; /* to ssplit addresses */
char *partv[MAXPATH]; /* " " " */
char temp[SMLBUF]; /* " " " */
int i;
/*
** If we set REROUTE and are prepared to deliver UUCP mail, we split the
** address apart at !'s and try to resolve successively larger righthand
** substrings until we succeed. Otherwise, we just resolve the whole thing
** once.
*/
if ((routing == REROUTE) && (rsvp( UUCP ) == UUCP)) {
parts = ssplit( address, '!', partv );
} else {
parts = 1;
partv[0] = address;
}
/*
** This for(i) loop selects successively larger
** righthand substrings of the address.
*/
for( i = parts - 1; i >= 0; i-- ) {
/*
** Parse the address.
*/
(void) strcpy( temp, partv[i] );
form = parse( temp, domain, user );
DEBUG("resolve: parse address '%s' = '%s' @@ '%s' (%s)\n",
temp,user,domain,sform(form));
/*
** If we are looking at a substring (that's not the entire string)
** which parses to a LOCAL address, we skip to the next larger substring.
*/
if((i != 0) && (form == LOCAL))
continue;
/*
** Routing, when required, is the next step.
** We route the address if we have a ROUTE form
** or if we have a UUCP form and we are told to
** route ALWAYS or REROUTE (i.e., routing != JUSTDOMAIN)
*/
if((rsvp( form ) == ROUTE)
||((rsvp( form ) == UUCP) && (routing != JUSTDOMAIN ))) {
int look_smart = 0;
/*
** if the host is not found the mail cannot be delivered
** if((routing == REROUTE) && (i == 0)) {
**
** Now the mail will be delivered to smarthost anyway
*/
if(i == 0) {
look_smart = 1; /* last chance */
}
/* route() puts the new route in 'temp' */
if(route(domain,user,look_smart,temp,cost) != EX_OK) {
continue; /* If routing fails, try
/* next larger substring.
/* */
}
/*
** After routing, reparse the new route into domain and user.
*/
form = parse( temp, domain, user );
DEBUG("resolve: parse route '%s' = '%s' @@ '%s' (%s)\n",
temp,user,domain,sform(form));
if(debug==NO)
printf("Ok, mail sent to %s via %s\n", user, domain);
} else if((getcost) && (rsvp(form) == UUCP)) {
/* get the cost of the route
** even if we're not going route the mail.
** this allows smart decisions about using
** the -r flag to uux when we're not routing.
*/
char junk[SMLBUF];
if(route(domain,user,0,junk,cost) != EX_OK) {
continue; /* If routing fails, try
/* next larger substring.
/* */
}
}
break; /* route is resolved */
}
/*
** For LOCAL mail in non-local format, we rewrite the full address into
** <user> and leave <domain> blank.
*/
if ((rsvp( form ) == LOCAL) && (form != LOCAL )) {
build( domain, user, form, temp );
(void) strcpy( user, temp );
(void) strcpy( domain, "" );
form = LOCAL;
}
/*
** If we were supposed to route an address but failed (form == ERROR),
** or after routing we are left with an address that still needs to
** be routed (rsvp( form ) == ROUTE), complain.
*/
if ((form == ERROR) || (rsvp( form ) == ROUTE )) {
exitstat = EX_NOHOST;
ADVISE("resolve failed '%s' = '%s' @@ '%s' (%s)\n",
address, user, domain, sform(form));
form = ERROR;
} else {
ADVISE("resolve '%s' = '%s' @@ '%s' (%s)\n",
address, user, domain, sform(form));
}
return ( form );
}
/*
**
** route(): route domain, plug in user.
**
** Less complicated than it looks. Each section is documented.
**
*/
route(domain, user, look_smart, result, cost)
char *domain; /* domain or host name */
char *user; /* user name */
int look_smart; /* do we try to route through a smarter host? */
char *result; /* output route */
int *cost; /* cost of output route */
{
int uucpdom = 0;
int domains, step; /* to split domain */
char *domainv[MAXDOMS]; /* " " " */
char temp[SMLBUF], path[SMLBUF];
char *p_tmp;
/*
** Fully qualify the domain, and then strip the last (top level domain)
** component off, so that we look it up separately.
*/
temp[0] = '.';
(void) strcpy(temp+1, domain );
domains = ssplit( temp+1, '.', domainv );
/*
** check target domain for the local host name and host domain.
** if it matches, then skip the lookup in the database.
** this prevents mail loops for cases where SMARTHOST is defined
** in the routing table, but the local host is not. It also is
** a little faster when the local host is the target domain.
*/
if((strcmpic(domain, hostname) == 0)
|| (strcmpic(domain, hostdomain) == 0)) {
step = 0;
*cost = 0;
(void) strcpy(path, "%s");
DEBUG("route: '%s' is local\n", domain);
goto route_complete;
}
/* If the domain ends in .UUCP, trim that off. */
if((domains > 0) && isuucp(domainv[domains-1])) {
domains--;
domainv[domains][-1] = '\0';
uucpdom = 1;
}
/*
** Try to get the path for successive components of the domain.
** Example for osgd.cb.att.uucp:
** osgd.cb.att
** cb.att
** att
** uucp ( remember stripping top level? )
** SMARTHOST
** Returns with error if we find no path.
*/
for(step = 0; (step < domains); step++) {
if((getpath(domainv[step]-1, path, cost) == EX_OK) /* w/ dot */
|| (getpath(domainv[step] , path, cost) == EX_OK))/* no dot */
break;
}
if(step == domains) {
/*
** we've looked at each component of the domain without success
*/
/*
** if we don't look up for smarthost return (RTA)
*/
if(look_smart==0)
return( EX_NOHOST );
/*
** If domain is a UUCP address, look for a UUCP gateway.
*/
if((uucpdom == 0) || (getpath(".UUCP", path, cost) != EX_OK)) {
/*
** The domain not is a UUCP address, or we can't
** find a UUCP gateway. If this is our last chance,
** look for a smarter host to deliver the mail.
*/
if(getpath(smarthost, path, cost) != EX_OK) {
/*
** All our efforts have been in vain.
** Tell them the bad news.
*/
#ifdef SMARTMAIL
DEBUG("route '%s' failed, sending it to smarthost '%s'\n", domain,smarthost);
/* only use the last component of smarthost */
p_tmp=index(smarthost,'.');
if(p_tmp)
*p_tmp='\0';
p_tmp=index(smarthost,'!');
if(p_tmp)
*p_tmp='\0';
step=0;sprintf(path,"%s!%s!%%s",smarthost,domain);
*cost=0;
#else
DEBUG("route '%s' failed\n", domain);
return( EX_NOHOST );
#endif
}
}
}
route_complete:
DEBUG("route: '%s' (%s) = '%s' (%d)\n", domain, domainv[step]?domainv[step]:"NULL", path, *cost);
/*
** If we matched on the entire domain name, this address is fully resolved,
** and we plug <user> into it. If we matched on only part of the domain
** name, we plug <domain>!<user> in.
*/
build(domain, user, (step == 0) ? LOCAL : UUCP, temp);
(void) sprintf(result, path, temp);
return( EX_OK );
}
@
1.1
log
@Initial revision
@
text
@d20 3
a22 1
* $Log$
d24 1
d27 1
a27 1
static char *rcsid="$Id$";
d130 7
a136 2
if((routing == REROUTE) && (i == 0)) {
d267 1
d273 6
d287 1
a287 2
if((look_smart == 0)
|| (getpath(smarthost, path, cost) != EX_OK)) {
@