home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
APPS
/
elm.lzh
/
ELM
/
SRC
/
DOMAINS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-11
|
9KB
|
310 lines
static char rcsid[] = "@(#)$Id: domains.c,v 4.1.1.1 90/07/12 23:19:14 syd Exp $";
/*******************************************************************************
* The Elm Mail System - $Revision: 4.1.1.1 $ $State: Exp $
*
* Copyright (c) 1986, 1987 Dave Taylor
* Copyright (c) 1988, 1989, 1990 USENET Community Trust
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Syd Weinstein, Elm Coordinator
* elm@DSI.COM dsinc!elm
*
*******************************************************************************
* $Log: domains.c,v $
* Revision 4.1.1.1 90/07/12 23:19:14 syd
* Make domain name checking case independent
* From: Syd, reported by Steven Baur
*
* Revision 4.1 90/04/28 22:42:44 syd
* checkin of Elm 2.3 as of Release PL0
*
*
******************************************************************************/
/** This file contains all the code dealing with the expansion of
domain based addresses in Elm. It uses the file "domains" as
defined in the sysdefs.h file.
From a file format and idea in "uumail" - designed by Stan Barber.
**/
#if defined(OPTIMIZE_RETURN) || !defined(DONT_TOUCH_ADDRESSES)
#include <ctype.h>
#include "headers.h"
#ifdef BSD
# undef toupper
# undef tolower
#endif
/** define the various characters that we can encounter after a "%" sign
in the template file...
**/
#define USERNAME 'U' /* %U = the name of the remote user */
#define RMTMNAME 'N' /* %N = the remote machine name */
#define FULLNAME 'D' /* %D = %N + domain info given */
#define NPATH 'R' /* %R = path to %N from pathalias */
#define PPATH 'P' /* %P = path to 'P' from pathalias */
#define OBSOLETE 'S' /* %S = (used to be suffix string) */
/** and finally some characters that are allowed in user/machine names **/
#define okay_others(c) (c == '-' || c == '^' || c == '$' || c == '_')
/** and some allowed ONLY in the username field **/
#define special_chars(c) (c == '%' || c == ':')
char *find_path_to(), *expand_domain(), *match_and_expand_domain();
char *strcpy(), *strcat(), *strtok();
void rewind();
open_domain_file()
{
if ((domainfd = fopen(domains, "r")) == NULL) {
dprint(2, (debugfile,"Warning: can't open file %s as domains file\n",
domains));
}
else {
dprint(3, (debugfile,
"Opened '%s' as the domain database\n\n", domains));
}
/* if it fails it'll instantiate domainfd to NULL which is
exactly what we want to have happen!! */
}
char *expand_domain(buffer)
char *buffer;
{
/** Expand the address 'buffer' based on the domain information,
if any. Returns NULL if it can't expand it for any reason.
**/
char name[NLEN], address[NLEN], domain[NLEN];
char *match_and_expand_domain();
if (domainfd == NULL) return(NULL); /* no file present! */
if (explode(buffer, name, address, domain))
return( match_and_expand_domain(domain, name, address) );
else { /* invalid format - not "user@host.domain" */
dprint(2, (debugfile,
"Invalid format for domain expansion: %s (expand_domain)\n",
buffer));
return(NULL);
}
}
int
explode(buffer, name, address, domain)
char *buffer, *name, *address, *domain;
{
/** Break buffer, if in format name@machine.domain, into the
component parts, otherwise return ZERO and don't worry
about the values of the parameters!
**/
register int i, j = 0;
/** First get the name... **/
for (i=0; buffer[i] != '@'; i++) {
if (! isalnum(buffer[i]) && ! okay_others(buffer[i]) && !
special_chars(buffer[i]))
return(0); /* invalid character in string! */
name[i] = buffer[i];
}
name[i++] = '\0';
/** now let's get the machinename **/
while (buffer[i] != '.') {
if (! isalnum(buffer[i]) && ! okay_others(buffer[i]))
return(0); /* invalid character in string! */
address[j++] = buffer[i++];
}
address[j] = '\0';
j = 0;
/** finally let's get the domain information (there better be some!) **/
while (buffer[i] != '\0') {
if (! isalnum(buffer[i]) && ! okay_others(buffer[i]) &&
buffer[i] != '.')
return(0); /* an you fail again, bozo! */
domain[j++] = toupper(buffer[i]);
i++;
}
domain[j] = '\0';
return(j); /* if j == 0 there's no domain info! */
}
char *match_and_expand_domain(domain, name, machine)
char *domain, *name, *machine;
{
/** Given the domain, try to find it in the domain file and
if found expand the entry and return the result as a
character string...
**/
static char address[SLEN];
char buffer[SLEN], domainbuff[NLEN];
char field1[NLEN], field2[NLEN], field3[NLEN];
char *path, *template, *expanded, *mydomain;
int matched = 0, in_percent = 0;
register int j = 0;
address[j] = '\0';
domainbuff[0] = '\0';
mydomain = (char *) domainbuff; /* set up buffer etc */
do {
rewind(domainfd); /* back to ground zero! */
if (strlen(mydomain) > 0) { /* already in a domain! */
mydomain++; /* skip leading '.' */
while (*mydomain != '.' && *mydomain != ',')
mydomain++; /* next character */
if (*mydomain == ',')
return (NULL); /* didn't find domain! */
}
else
sprintf(mydomain, "%s,", domain); /* match ENTIRELY! */
/* whip through file looking for the entry, please... */
while (fgets(buffer, SLEN, domainfd) != NULL) {
if (buffer[0] == '#') /* skip comments */
continue;
if (strincmp(buffer, mydomain, strlen(mydomain)) == 0) { /* match? */
matched++; /* Gotcha! Remember this momentous event! */
break;
}
}
if (! matched)
continue; /* Nothing. Not a sausage! Step through! */
/** We've matched the domain! **/
no_ret(buffer);
(void) strtok(buffer, ","); /* skip the domain info */
strcpy(field1, strtok(NULL, ",")); /* fun */
strcpy(field2, strtok(NULL, ",")); /* stuff */
strcpy(field3, strtok(NULL, ",")); /* eh? */
path = (char *) NULL;
/* now we merely need to figure out what permutation this is!
Fields are null if they have only a blank in them or are null.
If fields 2 and 3 are null, use field 1 as the template.
--else--
If field 3 is null and 2 is not, use field 2 as the template.
--else--
Field 3 is the template. */
if (strcmp(field3," ") == 0 || field3[0] == '\0'){
if (strcmp(field2," ") == 0 || field2[0] == '\0')
template = (char *) field1;
else {
path = (char *) field1;
template = (char *) field2;
}
}
else {
path = (char *) field1;
template = (char *) field3;
}
dprint(1, (debugfile,
"-> %s\n-> %s\n-> %s\n", field1, field2, field3));
dprint(1, (debugfile,
"Path-> %s\nTemplate-> %s\n", path, template));
if (strlen(path) > 0 && path[0] == '>')
path++; /* skip the '>' character, okay? */
j = 0; /* address is zero, right now, right?? */
address[j] = '\0'; /* make sure string is too! */
for (; *template; template++) {
if (*template == '%') {
if (! in_percent) /* just hit a NEW percent! */
in_percent = 1;
else { /* just another percent sign on the wall... */
address[j++] = '%';
address[j] = '\0'; /* ALWAYS NULL terminate */
in_percent = 0;
}
}
else if (in_percent) { /* Hey! a real command string */
in_percent = 0;
switch (*template) {
case USERNAME: strcat(address, name); break;
case RMTMNAME: strcat(address, machine); break;
case FULLNAME: strcat(address, machine);
strcat(address, domain); break;
case NPATH :
if ((expanded = find_path_to(machine, FALSE)) == NULL) {
dprint(3, (debugfile,
"\nCouldn't expand system path '%s' (%s)\n\n",
machine, "domains"));
error1("Couldn't find a path to %s!", machine);
sleep(2);
return(NULL); /* failed!! */
}
strcat(address, expanded); /* isn't this fun??? */
break;
case PPATH :
if ((expanded = find_path_to(path, FALSE)) == NULL) {
dprint(3, (debugfile,
"\nCouldn't expand system path '%s' (%s)\n\n",
path, "domains"));
error1("Couldn't find a path to %s!", path);
sleep(2);
return(NULL); /* failed!! */
}
strcat(address, expanded); /* isn't this fun??? */
break;
case OBSOLETE: /* fall through.. */
default : dprint(1, (debugfile,
"\nError: Bad sequence in template file for domain '%s': %%%c\n\n",
domain, *template));
}
j = strlen(address);
}
else {
address[j++] = *template;
address[j] = '\0'; /* null terminate */
}
}
address[j] = '\0';
} while (strlen(address) < 1);
return( (char *) address);
}
#endif