|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 8109 (0x1fad)
Types: TextFile
Names: »rmail.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦bfebc70e2⟧ »EurOpenD3/mail/sendmail-5.65b+IDA-1.4.3.tar.Z«
└─⟦f9e35cd84⟧
└─⟦this⟧ »sendmail/ida/aux/rmail.c«
/*
** RMAIL -- Receive remote mail requests.
** Copyright (c) 1987 Lennart Lovstrand
** CIS Dept, Univ of Linkoping, Sweden
**
** Use it, abuse it, but don't sell it.
**
** Version 2.6 of 5-May-87.
**
** This time logging selected header lines + more liberal parsing of
** the initial from-line but not yet with accounting & like; 14-Apr-85.
** Dbm lookup of UUCP domain names added 5-May-87.
**
** The following definitions below are optional:
** LOGFILE -- If defined, should be the name of a file in which to
** log the raw addresses of each message.
** DEFAULT_HOST -- If no host is found in the envelope recipients,
** this host is assumed [defaults to your local host].
** DEFAULT_DOMAIN -- If the sending host is unqualifed, add this
** domain to the host for use in the Received: line.
** DOMAINTABLE -- If defined, should point to your local domain
** lookup database. It is used for the same purpose as
** the DEFAULT_DOMAIN.
*/
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/time.h>
#include <strings.h>
#include "useful.h"
#ifdef GDBM
# define OTHERDBM
# include <ndbm.h> /* DBM is typedef'ed here */
#endif /* GDBM */
#ifdef SDBM
# ifdef OTHERDBM
MULTIPLE_DBM_TYPES_DEFINED
# else
# define OTHERDBM
# include <sdbm.h> /* DBM is typedef'ed here */
# endif /* OTHERDBM */
#endif /* SDBM */
#ifndef OTHERDBM
# undef DBM /* while including ndbm.h */
# include <ndbm.h> /* DBM is typedef'ed here */
#endif /* !OTHERDBM */
#define DBMFILE DBM
#define DB_DIREXT ".dir"
#define DB_PAGEXT ".pag"
#define STRSIZ 1024
#define COMMA ','
/* #define LOGFILE "/usr/lib/uucp/rmail.log" */
#define SENDMAIL "/usr/lib/sendmail"
#define NETCHRS "%@!:"
/* #define DEFAULT_HOST "liuida" */
#define DEFAULT_DOMAIN "UUCP"
/* #define DOMAINTABLE "/usr/lib/mail/domaintable" */
#define H_CC "cc"
#define H_FROM "from"
#define H_MESSAGE_ID "message_id"
#define H_RETURN_PATH "return-path"
#define H_TO "to"
#define H_VIA "via"
#define MAKELC(C) (isupper(C) ? tolower(C) : C)
#define EATSPACE(P) while (*P == ' ') P++
#ifdef __STDC__
int anyin(const char *, const char *);
int iskey(const char *, const char *);
char * extract_address(char *, char *);
#else /* !__STDC__ */
# define const
int anyin();
int iskey();
char * extract_address();
#endif /* __STDC__ */
FILE *popen();
char *Progname;
int Debug = FALSE;
DBMFILE *Dbm;
main(argc, argv)
int argc;
char **argv;
{
char from_[STRSIZ], cmd[STRSIZ], s_mac[STRSIZ], f_opt[STRSIZ], s[STRSIZ];
char *v_opt = "";
char *p, *user, *host, *domain = "";
char *acctsys = (char *) getenv("ACCTSYS");
FILE *outf;
#ifdef LOGFILE
FILE *logf = NULL;
#endif /* LOGFILE */
#ifdef DOMAINTABLE
datum key, val;
#endif /* DOMAINTABLE */
int insideheader, printedlast = FALSE;
int c, errflg = FALSE;
extern int optind;
extern char *optarg;
#ifdef DEFAULT_DOMAIN
domain = DEFAULT_DOMAIN;
#endif /* DEFAULT_DOMAIN */
Progname = argv[0];
while ((c = getopt(argc, argv, "D:dv")) != EOF) {
switch (c) {
case 'D':
domain = optarg;
break;
case 'd':
Debug++;
break;
case 'v':
v_opt = " -v";
break;
default:
errflg = TRUE;
break;
}
}
if (errflg || optind >= argc) {
(void) fprintf(stderr, "usage: %s [-Ddomain] user ...\n", Progname);
exit(2);
}
/*
* set our real uid to root as well as our effective uid so
* make sendmail accept the -oM options
*/
(void) setreuid(0, 0);
#ifdef DOMAINTABLE
Dbm = dbm_open(DOMAINTABLE, O_RDONLY);
if (Dbm == NULL)
perror(DOMAINTABLE);
#endif /* DOMAINTABLE */
#ifdef LOGFILE
if ((logf = fopen(Debug ? "/dev/tty" : LOGFILE, "a")) != NULL) {
struct timeval t;
int a;
(void) gettimeofday(&t, (struct timezone *) NULL);
(void) fprintf(logf, "\n[%.12s] ", ctime(&t.tv_sec) + 4);
for (a = 0; a < argc; a++)
(void) fprintf(logf, " '%s'", argv[a]);
(void) putc('\n', logf);
} else
(void) fprintf(stderr, "%s: couldn't open log file \"%s\"\n",
Progname, LOGFILE);
#endif /* LOGFILE */
user = NULL;
host = NULL;
(void) gets(from_);
#ifdef LOGFILE
if (logf != NULL)
(void) fprintf(logf, "%s\n", from_);
#endif /* LOGFILE */
if (strncmp(from_, "From ", 5) == 0 || strncmp(from_, ">From ", 6) == 0) {
user = index(from_, ' ') + 1;
EATSPACE(user);
if ((p = index(user, ' ')) != NULL) {
*p = '\0';
while ((p = index(p + 1, 'r')) != NULL) {
if (strncmp(p, "remote from ", 12) == 0) {
host = p + 12;
EATSPACE(host);
if ((p = index(host, '\n')) != NULL)
*p = '\0';
if (strcmp(host, "somewhere") == 0)
host = NULL;
break;
}
}
}
}
if (acctsys == NULL)
acctsys = host;
if (host)
(void) sprintf(f_opt, " -f%s!%s", host, user);
else if (user)
(void) sprintf(f_opt, " -f%s", user);
else
*f_opt = '\0';
if (acctsys) {
#ifdef DOMAINTABLE
if (Dbm != NULL) {
key.dptr = acctsys;
key.dsize = strlen(acctsys) + 1;
val = dbm_fetch(Dbm, key);
if (val.dptr != NULL)
acctsys = val.dptr;
}
#endif /* DOMAINTABLE */
if (index(acctsys, '.') == NULL && *domain != '\0')
(void) sprintf(s_mac, " -oMs%s.%s", acctsys, domain);
else
(void) sprintf(s_mac, " -oMs%s", acctsys);
} else
*s_mac = '\0';
(void) sprintf(cmd, "exec %s -ee -i -oMrUUCP%s%s%s",
SENDMAIL, s_mac, f_opt, v_opt);
for (; optind < argc; optind++) {
(void) strcat(cmd, " '");
#ifdef DEFAULT_HOST
if (anyin(argv[optind], NETCHRS) == NULL) {
(void) strcat(cmd, DEFAULT_HOST);
(void) strcat(cmd, "!");
}
#endif /* DEFAULT_HOST */
if (*argv[optind] == '(')
(void) strncat(cmd, &argv[optind][1], strlen(argv[optind])-2);
else
(void) strcat(cmd, argv[optind]);
(void) strcat(cmd, "'");
}
#ifdef LOGFILE
if (logf != NULL)
(void) fprintf(logf, "%s\n", cmd);
#endif /* LOGFILE */
if (Debug)
outf = stdout;
else {
outf = popen(cmd, "w");
if (outf == NULL) {
(void) fprintf(stderr, "%s: could not open pipe thru %s\n",
Progname, cmd);
exit(1);
}
}
insideheader = TRUE;
while (gets(s)) {
if (*s == '\0')
insideheader = FALSE;
#ifdef LOGFILE
if (logf != NULL && insideheader &&
((printedlast && isspace(*s)) ||
iskey(H_FROM, s) || iskey(H_TO, s) || iskey(H_CC, s) ||
iskey(H_RETURN_PATH, s) || iskey(H_MESSAGE_ID, s))) {
(void) fprintf(logf, "\t%s\n", s);
printedlast = TRUE;
} else
printedlast = FALSE;
#endif /* LOGFILE */
(void) fprintf(outf, "%s\n", s);
}
#ifdef LOGFILE
if (logf != NULL)
(void) fclose(logf);
#endif /* LOGFILE */
if (!Debug)
exit((pclose(outf) >> 8) & 0377);
}
/*
** ANYIN -- Does the target string contain chars from the pattern string?
*/
anyin(t, p)
const char *t;
register const char *p;
{
for (; *p != '\0'; p++)
if (index(t, *p) != NULL)
return TRUE;
return FALSE;
}
/*
** ISKEY -- Checks if the line is prefixed by the supplied keyword
** (immediately followed by a colon)
*/
iskey(key, line)
const char *key, *line;
{
for (; *key != '\0' && *line != '\0'; key++, line++)
if (MAKELC(*key) != MAKELC(*line))
break;
return *key == '\0' && *line == ':';
}
/*
** EXTRACT_ADDRESS -- Finds and extracts the machine address part
** of an address field.
*/
char *
extract_address(field, address)
char *field, *address;
{
char *address_start = address;
while(*field && *field != COMMA && *field != '>')
switch (*field) {
case '<':
return extract_address(field, address_start);
case '(':
while (*field && *field != ')');
field++;
break;
case '"':
do
*address++ = *field++;
while (*field && *field != '"');
if (*field)
*address++ = *field++;
break;
case ' ':
*address++ = *field++;
EATSPACE(field);
break;
case '\\':
*address++ = *field++;
/* fall through */
default:
*address++ = *field++;
}
*address = '\0';
if (*field)
return index(field, COMMA)+1;
else
return field;
}