rs@uunet.UUCP (06/23/87)
Mod.sources: Volume 10, Number 14
Submitted by: Lennart Lovstrand <mcvax!ida.liu.se!lel>
Archive-name: ida/Part03
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 3 (of 7)."
# Contents: ida/aux/dbm.c ida/aux/rmail.c ida/aux/xalparse.c
# ida/patches/alias.c.diff ida/patches/op.me.diff
# ida/patches/sendmail.h.diff
# Wrapped by lenlo@prefix on Wed Jun 10 15:39:53 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f ida/aux/dbm.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"ida/aux/dbm.c\"
else
echo shar: Extracting \"ida/aux/dbm.c\" \(10884 characters\)
sed "s/^X//" >ida/aux/dbm.c <<'END_OF_ida/aux/dbm.c'
X/*
X** DBM -- General dbm management tool.
X** Copyright (c) 1987 Lennart Lovstrand
X** CIS Dept, Univ of Linkoping, Sweden
X**
X** Use it, abuse it, but don't sell it.
X*/
X
X#include "useful.h"
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/file.h>
X#ifdef MDBM
X# include "mdbm_compat.h"
X#else MDBM
X# include <ndbm.h>
X# define DBMFILE DBM
X#endif MDBM
X
X#ifndef lint
Xstatic char SccsId[] = "@(#)dbm.c 2.0 (lel@ida.liu.se) 4/20/87";
X#endif !lint
X
X#define SAMECASE 0
X#define LOWERCASE 1
X#define UPPERCASE 2
X
X#define COMMENTCHAR '#'
X
X#define streq(s, t) (strcmp(s, t) == 0)
X#define MAKEDATUM(d, s) {(d).dptr = s; (d).dsize = strlen(s) + 1;}
X
Xvoid do_clear(), do_delete(), do_dump(), do_fetch(), do_load(), do_make(),
X do_parse(), do_store();
X
Xstruct comtab {
X char *c_name;
X void (*c_func)();
X} CommandTable[] = {
X {"clear", do_clear},
X {"delete", do_delete},
X {"dump", do_dump},
X {"fetch", do_fetch},
X {"load", do_load},
X {"make", do_make},
X {"parse", do_parse},
X {"store", do_store}
X};
X
X/* global arguments */
Xint Argc;
Xchar **Argv;
X
X/* options */
Xint Appending = FALSE;
Xint Casing = SAMECASE;
Xbool Debug = FALSE;
Xchar *Outfile = NULL;
Xint Mode = 0644;
Xchar *Progname;
Xbool Senteniel = FALSE;
Xint Storeflag = DBM_INSERT;
Xbool Storewarn = TRUE;
X
X/* Dbm globals */
XDBMFILE *Dbm;
Xchar *Dbmfile = NULL;
Xint Dbmaccess;
Xdatum key, val;
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X extern int optind;
X extern char *optarg;
X char *scantoken();
X struct comtab *cmd;
X int c;
X
X Argc = argc;
X Argv = argv;
X
X Progname = Argv[0];
X
X while ((c = getopt(Argc, Argv, "ADILRSUd:m:o:")) != EOF)
X switch (c) {
X case 'A':
X Appending = TRUE;
X break;
X case 'D':
X Debug = TRUE;
X break;
X case 'I':
X Storeflag = DBM_INSERT;
X Storewarn = FALSE;
X break;
X case 'L':
X Casing = LOWERCASE;
X break;
X case 'R':
X Storeflag = DBM_REPLACE;
X break;
X case 'S':
X Senteniel = TRUE;
X break;
X case 'U':
X Casing = UPPERCASE;
X break;
X case 'd':
X Dbmfile = optarg;
X break;
X case 'm':
X if (optarg[0] == '0')
X (void) sscanf(optarg, "%o", &Mode);
X else {
X (void) sscanf(optarg, "%d", &Mode);
X if (Mode == 0) {
X (void) fprintf(stderr, "%s: non-numeric mode: %s\n",
X Progname, optarg);
X exit(1);
X }
X }
X break;
X case 'o':
X Outfile = optarg;
X break;
X default:
X (void) fprintf(stderr,
X "usage: %s [-ADILNRSU] [-d dbm_file] [-m mode] %s",
X Progname, "[-o output_file] command [args]\n");
X exit(1);
X }
X
X Argc -= optind;
X Argv += optind;
X
X if (Argc > 0) {
X for (cmd = CommandTable; cmd < &CommandTable[sizeof(CommandTable) /
X sizeof(*CommandTable)];
X cmd++)
X if (streq(*Argv, cmd->c_name)) {
X (*cmd->c_func)();
X exit(0);
X }
X (void) fprintf(stderr, "%s: unknown dbm command %s", Progname, *Argv);
X } else
X (void) fprintf(stderr, "%s: missing dbm command", Progname);
X (void) fprintf(stderr, ", use one of the following:\n");
X for (cmd = CommandTable; cmd < &CommandTable[sizeof(CommandTable) /
X sizeof(*CommandTable)]; cmd++)
X (void) fprintf(stderr, "%s%s", cmd == CommandTable ? "" : "\t",
X cmd->c_name);
X (void) fprintf(stderr, "\n");
X exit(3);
X}
X
Xopendbm(access)
X int access;
X{
X if (Dbmfile == NULL) {
X if (Argc > 1) {
X /* use last argument */
X Dbmfile = Argv[Argc-1];
X Argc--;
X } else {
X (void) fprintf(stderr, "%s: dbm file not specified\n", Progname);
X exit(3);
X }
X }
X Dbm = dbm_open(Dbmfile, access, Mode);
X if (Dbm == NULL) {
X perror(Dbmfile);
X exit(4);
X }
X Dbmaccess = access;
X}
X
Xclosedbm()
X{
X if ((Dbmaccess & O_RDONLY) == 0 && Senteniel) {
X MAKEDATUM(key, "@@@");
X if (dbm_store(Dbm, key, key, DBM_REPLACE) != NULL) {
X (void) fprintf(stderr, "%s: could not store senteniel \"@@@\"\n",
X Progname);
X perror(Progname);
X exit(5);
X }
X }
X
X dbm_close(Dbm);
X}
X
XFILE *
Xopenfile(filename, access)
X char *filename;
X char *access;
X{
X FILE *f;
X
X if (streq(filename, "-"))
X if (streq(access, "r"))
X return stdin;
X else
X return stdout;
X else {
X f = fopen(filename, access);
X if (f == NULL) {
X perror(filename);
X exit(4);
X }
X return f;
X }
X}
X
Xvoid
Xclosefile(f)
X FILE *f;
X{
X if (f != stdin && f != stdout)
X (void) fclose(f);
X}
X/*
X** DO_CLEAR -- Clear out database leaving it emtpy.
X*/
X
Xvoid
Xdo_clear()
X{
X if (Dbmfile != NULL) {
X opendbm(O_RDWR | O_CREAT | O_TRUNC);
X closedbm();
X }
X while (Argc > 1) {
X opendbm(O_RDWR | O_CREAT | O_TRUNC);
X closedbm();
X }
X}
X
X
X/*
X** DO_DELETE -- Delete individual entries from the database.
X*/
X
Xvoid
Xdo_delete()
X{
X opendbm(O_RDWR | O_CREAT);
X
X for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
X casify(*Argv, Casing);
X MAKEDATUM(key, *Argv);
X if (dbm_delete(Dbm, key) != NULL) {
X perror(*Argv);
X exit(5);
X }
X }
X
X closedbm();
X}
X
X/*
X** DO_DUMP -- List all entries in the database.
X*/
X
Xvoid
Xdo_dump()
X{
X FILE *output;
X
X opendbm(O_RDONLY);
X
X if (Outfile == NULL)
X output = stdout;
X else
X output = openfile(Outfile, "w");
X
X#ifdef MDBM
X for (key = dbm_firstkey(Dbm); key.dptr != NULL; key = dbm_nextkey(Dbm, key
)) {
X#else MDBM
X for (key = dbm_firstkey(Dbm); key.dptr != NULL; key = dbm_nextkey(Dbm)) {
X#endif MDBM
X val = dbm_fetch(Dbm, key);
X if (val.dptr == NULL)
X perror(key.dptr);
X else
X (void) fprintf(output, "%s\t%s\n", key.dptr, val.dptr);
X }
X}
X/*
X** DO_FETCH -- Lookup individual keys in the database.
X*/
X
Xvoid
Xdo_fetch()
X{
X opendbm(O_RDONLY);
X
X for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
X casify(*Argv, Casing);
X MAKEDATUM(key, *Argv);
X val = dbm_fetch(Dbm, key);
X if (val.dptr == NULL)
X (void) printf("%s\t[NOT FOUND]\n", *Argv);
X else
X (void) printf("%s\t%s\n", *Argv, val.dptr);
X }
X
X closedbm();
X}
X
X/*
X** DO_STORE -- Insert individual entries into the database.
X*/
X
Xvoid
Xdo_store()
X{
X /* barf if # of args - 1 is even and no dbm file has been specified */
X if (Argc & 1 == 1 && Dbmfile == NULL) {
X (void) fprintf(stderr, "%s: no dbm file specified\n", Progname);
X exit(3);
X }
X
X opendbm(O_RDWR | O_CREAT);
X
X for (Argc--, Argv++; Argc > 1; Argc -= 2, Argv += 2) {
X casify(Argv[0], Casing);
X MAKEDATUM(key, Argv[0]);
X MAKEDATUM(val, Argv[1]);
X if (dbm_store(Dbm, key, val, Storeflag) != NULL) {
X extern int errno;
X
X if (errno != 0) {
X perror(Argv[0]);
X exit(5);
X } else if (Storewarn)
X (void) fprintf(stderr,
X "%s: duplicate key \"%s\" => \"%s\" ignored\n",
X Progname, Argv[0], Argv[1]);
X }
X }
X if (Argc > 0)
X (void) fprintf(stderr, "%s: no value for last key \"%s\"--ignored\n",
X Progname, Argv[0]);
X
X closedbm();
X}
X
X/*
X** DO_PARSE -- Parse a textual database file and produce key-value
X** pairs separated by a tab (suitable for input to the ``load''
X** function).
X*/
X
Xvoid
Xdo_parse()
X{
X FILE *input, *output;
X
X if (Outfile == NULL)
X output = stdout;
X else
X output = openfile(Outfile, "w");
X
X if (Argc == 1)
X parsefile(stdin, output);
X else
X for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
X input = openfile(*Argv, "r");
X parsefile(input, output);
X closefile(input);
X }
X}
X
X/*
X** DO_MAKE -- Parse the textual input and load the result into
X** the database.
X*/
X
Xvoid
Xdo_make()
X{
X FILE *input, *pipin, *pipout;
X int pipes[2];
X
X opendbm(O_RDWR | O_CREAT | (Appending ? 0 : O_TRUNC));
X
X if (pipe(pipes) != NULL) {
X perror("pipe");
X exit(9);
X }
X pipin = fdopen(pipes[0], "r");
X pipout = fdopen(pipes[1], "w");
X
X if (fork() == 0) {
X /* child process */
X (void) fclose(pipout);
X
X loadfile(pipin);
X } else {
X /* parent process */
X (void) fclose(pipin);
X
X if (Argc == 1)
X parsefile(stdin, pipout);
X else
X for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
X input = openfile(*Argv, "r");
X parsefile(input, pipout);
X closefile(input);
X }
X }
X closedbm();
X}
X
X/*
X** DO_LOAD -- Load the dbm database from a text file. The input should
X** be key-value pairs separated by a tab, each on a single line.
X*/
X
Xvoid
Xdo_load()
X{
X FILE *input;
X
X opendbm(O_RDWR | O_CREAT | (Appending ? 0 : O_TRUNC));
X
X if (Argc == 1)
X loadfile(stdin);
X else
X for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
X input = openfile(*Argv, "r");
X loadfile(input);
X closefile(input);
X }
X closedbm();
X}
X
X/*
X** PARSEFILE, LOADFILE
X*/
X
Xparsefile(input, output)
X FILE *input, *output;
X{
X extern char *index();
X char buf[BUFSIZ], *key, *val = NULL;
X register char *p;
X
X while (fgets(buf, sizeof(buf), input) != NULL) {
X if (buf[0] == COMMENTCHAR || buf[0] == '\n' || buf[0] == '\0')
X continue;
X if (!isspace(buf[0])) {
X /* extract value */
X p = scantoken(buf);
X if (val != NULL)
X free(val);
X val = (char *) malloc(p - buf + 1);
X (void) strncpy(val, buf, p - buf);
X val[p - buf] = '\0';
X }
X casify(buf, Casing);
X for (p = buf; *p != '\0';) {
X while (*p != '\0' && isspace(*p)) p++;
X if (*p == '\0' || *p == COMMENTCHAR)
X break;
X key = p;
X p = scantoken(p);
X if (*p == COMMENTCHAR)
X *p = '\0';
X else if (*p != '\0')
X *p++ = '\0';
X (void) fprintf(output, "%s\t%s\n", key, val);
X }
X }
X}
X
Xloadfile(input)
X FILE *input;
X{
X char buf[BUFSIZ];
X register char *tab, *nl;
X extern char *index();
X
X while (fgets(buf, sizeof(buf), input) != NULL) {
X nl = index(buf, '\n');
X if (nl != NULL)
X *nl = '\0';
X
X tab = index(buf, '\t');
X if (tab == NULL) {
X (void) fprintf(stderr, "%s: missing tab in \"%s\"--ignored\n",
X Progname, buf);
X continue;
X }
X *tab++ = '\0';
X casify(buf, Casing);
X MAKEDATUM(key, buf);
X MAKEDATUM(val, tab);
X if (dbm_store(Dbm, key, val, Storeflag) != NULL && Storewarn) {
X extern int errno;
X
X if (errno != 0) {
X perror(buf);
X exit(5);
X } else if (Storewarn)
X (void) fprintf(stderr,
X "%s: duplicate key \"%s\" => \"%s\" ignored\n",
X Progname, buf, tab);
X }
X }
X}
X
Xchar *
Xscantoken(p)
X register char *p;
X{
X register bool quotedchar = FALSE, insidestring = FALSE, insideroute = FALSE;
X
X /* hidious address scanner */
X while (*p != '\0' && (quotedchar || insidestring || insideroute ||
X (*p != COMMENTCHAR && !isspace(*p)))) {
X /* special quote character handling */
X if (quotedchar)
X quotedchar = FALSE;
X else {
X quotedchar = (*p == '\\');
X if (!insidestring)
X if (*p == '<')
X insideroute = TRUE;
X else if (*p == '>')
X insideroute = FALSE;
X if (*p == '"')
X insidestring = !insidestring;
X }
X p++;
X }
X
X return p;
X}
X
Xcasify(p, c)
X register char *p;
X int c;
X{
X switch (c) {
X case LOWERCASE:
X for (; *p != '\0'; p++)
X if (isupper(*p))
X *p = tolower(*p);
X break;
X case UPPERCASE:
X for (; *p != '\0'; p++)
X if (islower(*p))
X *p = toupper(*p);
X break;
X }
X}
END_OF_ida/aux/dbm.c
if test 10884 -ne `wc -c <ida/aux/dbm.c`; then
echo shar: \"ida/aux/dbm.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ida/aux/rmail.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"ida/aux/rmail.c\"
else
echo shar: Extracting \"ida/aux/rmail.c\" \(6732 characters\)
sed "s/^X//" >ida/aux/rmail.c <<'END_OF_ida/aux/rmail.c'
X/*
X** RMAIL -- Receive remote mail requests.
X** Copyright (c) 1987 Lennart Lovstrand
X** CIS Dept, Univ of Linkoping, Sweden
X**
X** Use it, abuse it, but don't sell it.
X**
X** Version 2.6 of 5-May-87.
X**
X** This time logging selected header lines + more liberal parsing of
X** the initial from-line but not yet with accounting & like; 14-Apr-85.
X** Dbm lookup of UUCP domain names added 5-May-87.
X*/
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <ctype.h>
X#include <sys/time.h>
X#include <strings.h>
X#ifdef MDBM
X# include "mdbm_compat.h"
X#else MDBM
X# include <ndbm.h>
X# define DBMFILE DBM
X#endif MDBM
X#include "useful.h"
X
X#define STRSIZ 1024
X#define COMMA ','
X#define LOGFILE "/usr/lib/uucp/rmail.log"
X#define SENDMAIL "/usr/lib/sendmail"
X#define NETCHRS "%@!:"
X#define DEFAULT_HOST "liuida"
X#define DEFAULT_DOMAIN "UUCP"
X#define DOMAINTABLE "/usr/lib/mail/domaintable"
X
X#define H_CC "cc"
X#define H_FROM "from"
X#define H_MESSAGE_ID "message_id"
X#define H_RETURN_PATH "return-path"
X#define H_TO "to"
X#define H_VIA "via"
X
X#define MAKELC(C) (isupper(C) ? tolower(C) : C)
X#define EATSPACE(P) while (*P == ' ') P++
X
XFILE *popen();
Xchar *Progname;
Xint Debug = FALSE;
XDBMFILE *Dbm;
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X char from_[STRSIZ], cmd[STRSIZ], s_mac[STRSIZ], f_opt[STRSIZ], s[STRSIZ];
X char *v_opt = "";
X char *p, *user, *host, *domain = DEFAULT_DOMAIN;
X char *acctsys = (char *) getenv("ACCTSYS");
X FILE *outf;
X#ifdef LOGFILE
X FILE *logf = NULL;
X#endif LOGFILE
X#ifdef DOMAINTABLE
X datum key, val;
X#endif DOMAINTABLE
X int insideheader, printedlast = FALSE;
X int c, errflg = FALSE;
X
X extern int optind;
X extern char *optarg;
X
X Progname = argv[0];
X while ((c = getopt(argc, argv, "D:dv")) != EOF) {
X switch (c) {
X case 'D':
X domain = optarg;
X break;
X case 'd':
X Debug++;
X break;
X case 'v':
X v_opt = " -v";
X break;
X default:
X errflg = TRUE;
X break;
X }
X }
X if (errflg || optind >= argc) {
X (void) fprintf(stderr, "usage: %s [-Ddomain] user ...\n", Progname);
X exit(2);
X }
X
X /*
X * set our real uid to root as well as our effective uid so
X * make sendmail accept the -oM options
X */
X (void) setreuid(0, 0);
X
X#ifdef DOMAINTABLE
X Dbm = dbm_open(DOMAINTABLE, O_RDONLY);
X if (Dbm == NULL)
X perror(DOMAINTABLE);
X#endif DOMAINTABLE
X
X#ifdef LOGFILE
X if ((logf = fopen(Debug ? "/dev/tty" : LOGFILE, "a")) != NULL) {
X struct timeval t;
X int a;
X
X (void) gettimeofday(&t, (struct timezone *) NULL);
X (void) fprintf(logf, "\n[%.12s] ", ctime(&t.tv_sec) + 4);
X for (a = 0; a < argc; a++)
X (void) fprintf(logf, " '%s'", argv[a]);
X (void) putc('\n', logf);
X } else
X (void) fprintf(stderr, "%s: couldn't open log file \"%s\"\n",
X Progname, LOGFILE);
X#endif LOGFILE
X
X user = NULL;
X host = NULL;
X (void) gets(from_);
X
X#ifdef LOGFILE
X if (logf != NULL)
X (void) fprintf(logf, "%s\n", from_);
X#endif LOGFILE
X
X if (strncmp(from_, "From ", 5) == 0 || strncmp(from_, ">From ", 6) == 0) {
X user = index(from_, ' ') + 1;
X EATSPACE(user);
X if ((p = index(user, ' ')) != NULL) {
X *p = '\0';
X while ((p = index(p + 1, 'r')) != NULL) {
X if (strncmp(p, "remote from ", 12) == 0) {
X host = p + 12;
X EATSPACE(host);
X if ((p = index(host, '\n')) != NULL)
X *p = '\0';
X if (strcmp(host, "somewhere") == 0)
X host = NULL;
X break;
X }
X }
X }
X }
X
X if (acctsys == NULL)
X acctsys = host;
X
X if (host)
X (void) sprintf(f_opt, " -f%s!%s", host, user);
X else if (user)
X (void) sprintf(f_opt, " -f%s", user);
X else
X *f_opt = '\0';
X
X if (acctsys) {
X#ifdef DOMAINTABLE
X if (Dbm != NULL) {
X key.dptr = acctsys;
X key.dsize = strlen(acctsys) + 1;
X val = dbm_fetch(Dbm, key);
X if (val.dptr != NULL)
X acctsys = val.dptr;
X }
X#endif DOMAINTABLE
X if (index(acctsys, '.') == NULL)
X (void) sprintf(s_mac, " -oMs%s.%s", acctsys, domain);
X else
X (void) sprintf(s_mac, " -oMs%s", acctsys);
X } else
X *s_mac = '\0';
X
X (void) sprintf(cmd, "exec %s -ee -i -oMrUUCP%s%s%s",
X SENDMAIL, s_mac, f_opt, v_opt);
X
X for (; optind < argc; optind++) {
X (void) strcat(cmd, " '");
X#ifdef DEFAULT_HOST
X if (anyin(argv[optind], NETCHRS) == NULL) {
X (void) strcat(cmd, DEFAULT_HOST);
X (void) strcat(cmd, "!");
X }
X#endif DEFAULT_HOST
X if (*argv[optind] == '(')
X (void) strncat(cmd, &argv[optind][1], strlen(argv[optind])-2);
X else
X (void) strcat(cmd, argv[optind]);
X (void) strcat(cmd, "'");
X }
X
X#ifdef LOGFILE
X if (logf != NULL)
X (void) fprintf(logf, "%s\n", cmd);
X#endif LOGFILE
X if (Debug)
X outf = stdout;
X else {
X outf = popen(cmd, "w");
X if (outf == NULL) {
X (void) fprintf(stderr, "%s: could not open pipe thru %s\n",
X Progname, cmd);
X exit(1);
X }
X }
X
X insideheader = TRUE;
X while (gets(s)) {
X if (*s == NULL)
X insideheader = FALSE;
X
X#ifdef LOGFILE
X if (logf != NULL && insideheader &&
X ((printedlast && isspace(*s)) ||
X iskey(H_FROM, s) || iskey(H_TO, s) || iskey(H_CC, s) ||
X iskey(H_RETURN_PATH, s) || iskey(H_MESSAGE_ID, s))) {
X (void) fprintf(logf, "\t%s\n", s);
X printedlast = TRUE;
X } else
X printedlast = FALSE;
X#endif LOGFILE
X (void) fprintf(outf, "%s\n", s);
X }
X
X#ifdef LOGFILE
X if (logf != NULL)
X (void) fclose(logf);
X#endif LOGFILE
X
X if (!Debug)
X exit((pclose(outf) >> 8) & 0377);
X}
X
X/*
X** ANYIN -- Does the target string contain chars from the pattern string?
X*/
Xanyin(t, p)
X char *t;
X register char *p;
X{
X for (; *p != '\0'; p++)
X if (index(t, *p) != NULL)
X return TRUE;
X return FALSE;
X}
X
X/*
X** ISKEY -- Checks if the line is prefixed by the supplied keyword
X** (immediately followed by a colon)
X*/
Xiskey(key, line)
X char *key, *line;
X{
X for (; *key != NULL && *line != NULL; key++, line++)
X if (MAKELC(*key) != MAKELC(*line))
X break;
X
X return *key == NULL && *line == ':';
X}
X
X/*
X** EXTRACT_ADDRESS -- Finds and extracts the machine address part
X** of an address field.
X*/
X
Xchar *
Xextract_address(field, address)
X char *field, *address;
X{
X char *address_start = address;
X
X while(*field && *field != COMMA && *field != '>')
X switch (*field) {
X case '<':
X return extract_address(field, address_start);
X case '(':
X while (*field && *field != ')');
X field++;
X break;
X case '"':
X do
X *address++ = *field++;
X while (*field && *field != '"');
X if (*field)
X *address++ = *field++;
X break;
X case ' ':
X *address++ = *field++;
X EATSPACE(field);
X break;
X case '\\':
X *address++ = *field++;
X /* fall through */
X default:
X *address++ = *field++;
X }
X *address = NULL;
X if (*field)
X return index(field, COMMA)+1;
X else
X return field;
X}
X
X
END_OF_ida/aux/rmail.c
if test 6732 -ne `wc -c <ida/aux/rmail.c`; then
echo shar: \"ida/aux/rmail.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ida/aux/xalparse.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"ida/aux/xalparse.c\"
else
echo shar: Extracting \"ida/aux/xalparse.c\" \(6648 characters\)
sed "s/^X//" >ida/aux/xalparse.c <<'END_OF_ida/aux/xalparse.c'
X/*
X** XALPARSE -- Xaliases file parser.
X** Copyright (c) 1987 Lennart Lovstrand
X** CIS Dept, Univ of Linkoping, Sweden
X**
X** Use it, abuse it, but don't sell it.
X*/
X
X#include "useful.h"
X#include <stdio.h>
X#include <ctype.h>
X
X#ifndef lint
Xstatic char SccsId[] = "@(#)xalparse.c 1.1 (lel@ida.liu.se) 4/12/87";
X#endif !lint
X
Xstruct alias {
X bool a_in, a_out;
X char *a_name;
X};
X
X#define ANULL (struct alias *) NULL
X
X/*
X** XPARSE -- Parse an xaliases file, producing aliases + generics files.
X**
X** This program parses a file in ``xaliases'' format, producing
X** a standard aliases file + a generics file. The xaliases input
X** file has entry of the following format:
X** generic_list: mbox_list
X** where elements in both lists are separated by commas. In
X** addition, each element in the mbox_list may be prefixed with
X** either or both of the ``redirection characters,'' "<" and ">".
X
X** In its simplest form, the generic_list has just one member and
X** the mbox_list uses no redirection characters. This
X** corresponds exactly to the standard aliases format and
X** function.
X
X** The first extention is made by allowing more than one entry on
X** the left hand side, thus making "a, b: c" as shorthand for the
X** two entries "a: c" and "b: c".
X
X** The second extension is made by adding the previously
X** mentioned redirection characters to the addresses on the right
X** hand side. These control in what direction the aliases should
X** be used.
X**
X** etc.
X*/
X
Xint iflag = FALSE, Iflag = FALSE, Oflag = FALSE;
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X extern int optind;
X extern char *optarg;
X char c;
X FILE *xaliases, *aliases, *generics;
X
X
X if (argc != 4) {
X fprintf(stderr, "usage: %s xaliases aliases generics\n", argv[0]);
X exit(1);
X }
X
X if (strcmp(argv[1], "-") == 0)
X xaliases = stdin;
X else {
X xaliases = fopen(argv[1], "r");
X if (xaliases == NULL)
X perror(argv[1]), exit(2);
X }
X aliases = fopen(argv[2], "w");
X if (aliases == NULL)
X perror(argv[2]), exit(2);
X generics = fopen(argv[3], "w");
X if (generics == NULL)
X perror(argv[3]), exit(2);
X
X parsefile(xaliases, aliases, generics);
X exit(0);
X}
X
Xparsefile(xaliases, aliases, generics)
X FILE *xaliases, *aliases, *generics;
X{
X extern char *index();
X char line[BUFSIZ];
X struct alias *rhs[BUFSIZ], *lhs[BUFSIZ];
X struct alias **a, **r, **first;
X
X while (readline(line, sizeof(line), xaliases) >= 0) {
X parseline(line, lhs, rhs);
X
X for (first = rhs; *first != ANULL; first++)
X if ((*first)->a_in)
X break;
X if (*first != ANULL)
X for (a = lhs; *a != ANULL; a++) {
X fprintf(aliases, "%s:%s", (*a)->a_name, (*first)->a_name);
X for (r = first+1; *r != ANULL; r++)
X if ((*r)->a_in)
X fprintf(aliases, ",%s", (*r)->a_name);
X fprintf(aliases, "\n");
X }
X
X for (first = rhs; *first != ANULL; first++)
X if ((*first)->a_out)
X break;
X if (*first != ANULL) {
X fprintf(generics, "%s\t%s", lhs[0]->a_name, (*first)->a_name);
X for (r = first+1; *r != ANULL; r++)
X if ((*r)->a_out)
X fprintf(generics, " %s", (*r)->a_name);
X fprintf(generics, "\n");
X }
X
X freebufs(lhs, rhs);
X }
X}
X
X/**
X ** PEEKC -- Return the next char to be read.
X **/
X
Xpeekc(stream)
X FILE *stream;
X{
X int c;
X
X c = getc(stream);
X if (c != EOF)
X ungetc(c, stream);
X return c;
X}
X
X/**
X ** READLINE -- Read a (logical) line and return the # of chars read
X **/
X
Xreadline(buf, bufsiz, stream)
X char *buf;
X int bufsiz;
X FILE *stream;
X{
X int len;
X char *sharp;
X
X if (fgets(buf, bufsiz, stream) == NULL)
X return -1;
X buf[strlen(buf)-1] = '\0';
X
X /*
X if ((sharp = index(buf, '#')) != NULL)
X *sharp = '\0';
X */
X if (buf[0] == '#')
X buf[0] = '\0';
X
X len = strlen(buf);
X if (isspace(peekc(stream)))
X return len + readline(&buf[len], bufsiz-len, stream);
X else
X return len;
X}
X
X/**
X ** PARSETHING
X **/
X
X
X#define LHS 1
X#define RHS 2
X
Xchar *
Xparsething(line, thing, side)
X char *line;
X struct alias **thing;
X int side;
X{
X register char *s, *d;
X register bool
X insideroute = FALSE,
X insidestring = FALSE,
X quotedchar = FALSE;
X bool i_mark, o_mark;
X char buf[BUFSIZ];
X extern char *malloc();
X
X s = line;
X d = buf;
X
X while (*s != '\0' && isspace(*s)) s++;
X if (side == RHS) {
X if (o_mark = (*s == '<')) s++;
X if (i_mark = (*s == '>')) s++;
X i_mark = i_mark || !o_mark; /* default to '>' */
X while (*s != '\0' && isspace(*s)) s++;
X }
X
X for (;*s != '\0'; s++) {
X /* exit if non-quoted comma (or colon & LHS) */
X if (!insidestring && !quotedchar && !insideroute &&
X *s == ',' || ((side == LHS) && *s == ':'))
X break;
X
X /* copy if not unquoted whitespace */
X if (insidestring || quotedchar || !isspace(*s))
X *d++ = *s;
X
X /* special quote character handling */
X if (quotedchar)
X quotedchar = FALSE;
X else {
X quotedchar = (*s == '\\');
X if (!insidestring)
X if (*s == '<')
X insideroute = TRUE;
X else if (*s == '>')
X insideroute = FALSE;
X if (*s == '"')
X insidestring = !insidestring;
X }
X }
X while (d > buf && isspace(d[-1])) d--;
X *d = '\0';
X
X if (d == buf && *s == '\0') {
X *thing = ANULL;
X return NULL;
X } else {
X *thing = (struct alias *) malloc(sizeof(struct alias));
X (*thing)->a_in = i_mark;
X (*thing)->a_out = o_mark;
X (*thing)->a_name = malloc(strlen(buf) + 1);
X strcpy((*thing)->a_name, buf);
X return s;
X }
X}
X
X/**
X ** PARSELINE
X **/
X
Xparseline(line, lhs, rhs)
X char *line;
X struct alias **lhs, **rhs;
X{
X line--;
X
X while ((line = parsething(line+1, lhs++, LHS)) != NULL)
X if (*line == ':')
X break;
X *lhs = NULL;
X
X if (line != NULL)
X while ((line = parsething(line+1, rhs++, RHS)) != NULL);
X *rhs = ANULL;
X}
X
X/**
X ** FREEBUFS
X **/
X
Xfreebufs(lhs, rhs)
X struct alias **lhs, **rhs;
X{
X while (*lhs != ANULL) {
X free((*lhs)->a_name);
X free(*lhs);
X lhs++;
X }
X while (*rhs != ANULL) {
X free((*rhs)->a_name);
X free(*rhs);
X rhs++;
X }
X}
X
X/**
X ** COMPRESSLINE -- Remove all heading & trailing whitespace around items.
X **/
X
Xcompressline(line)
X char *line;
X{
X register char *d, *s, *b, *e;
X
X for (d = s = line; *s != '\0'; s++) {
X /* eat initial whitespace */
X while (*s != '\0' && isspace(*s)) s++;
X if (*s == '\0')
X break;
X /* remember beginning of "word" and find end */
X b = s;
X while (*s != '\0' && *s != ',' && *s != ':') s++;
X e = s - 1;
X /* backspace end thru whitespace */
X while (e >= b && isspace(*e)) e--;
X /* copy "word" w/o whitespace */
X while (b <= e) *d++ = *b++;
X /* copy separator */
X *d++ = *s;
X if (*s == '\0')
X return;
X }
X *d = '\0';
X}
END_OF_ida/aux/xalparse.c
if test 6648 -ne `wc -c <ida/aux/xalparse.c`; then
echo shar: \"ida/aux/xalparse.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ida/patches/alias.c.diff -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"ida/patches/alias.c.diff\"
else
echo shar: Extracting \"ida/patches/alias.c.diff\" \(5555 characters\)
sed "s/^X//" >ida/patches/alias.c.diff <<'END_OF_ida/patches/alias.c.diff'
X*** alias.c.orig Fri Mar 13 18:51:08 1987
X--- alias.c Wed May 27 02:03:20 1987
X***************
X*** 55,68 ****
X */
X
X
X! #ifdef DBM
X! typedef struct
X! {
X! char *dptr;
X! int dsize;
X! } DATUM;
X extern DATUM fetch();
X! #endif DBM
X
X alias(a, sendq)
X register ADDRESS *a;
X--- 55,63 ----
X */
X
X
X! #if defined(DBM) && !defined(NDBM)
X extern DATUM fetch();
X! #endif DBM && !NDBM
X
X alias(a, sendq)
X register ADDRESS *a;
X***************
X*** 122,128 ****
X ** none.
X **
X ** Warnings:
X! ** The return value will be trashed across calls.
X */
X
X char *
X--- 117,124 ----
X ** none.
X **
X ** Warnings:
X! ** The return value will be trashed across calls
X! ** unless using a multi-file dbm (mdbm or ndbm).
X */
X
X char *
X***************
X*** 131,151 ****
X {
X # ifdef DBM
X DATUM rhs, lhs;
X
X /* create a key for fetch */
X! lhs.dptr = name;
X lhs.dsize = strlen(name) + 1;
X rhs = fetch(lhs);
X return (rhs.dptr);
X # else DBM
X register STAB *s;
X
X s = stab(name, ST_ALIAS, ST_FIND);
X if (s == NULL)
X return (NULL);
X return (s->s_alias);
X # endif DBM
X }
X /*
X ** INITALIASES -- initialize for aliasing
X **
X--- 127,204 ----
X {
X # ifdef DBM
X DATUM rhs, lhs;
X+ char *lowname = xalloc(strlen(name) + 1);
X
X /* create a key for fetch */
X! strcpy(lowname, name);
X! makelower(lowname);
X! lhs.dptr = lowname;
X lhs.dsize = strlen(name) + 1;
X+ # ifdef DEBUG
X+ if (tTd(27, 3))
X+ printf("aliaslookup(\"%s\") => ", lhs.dptr);
X+ # endif DEBUG
X+ # ifdef NDBM
X+ rhs = dbm_fetch(AliasDbm.dbm, lhs);
X+ if (rhs.dptr != NULL)
X+ rhs.dptr = newstr(rhs.dptr);
X+ # else NDBM
X rhs = fetch(lhs);
X+ # endif NDBM
X+ # ifdef DEBUG
X+ if (tTd(27, 3))
X+ printf("%s\n", rhs.dptr == NULL ? "NOT_FOUND" : rhs.dptr);
X+ # endif DEBUG
X+ (void) free(lowname);
X return (rhs.dptr);
X # else DBM
X register STAB *s;
X
X s = stab(name, ST_ALIAS, ST_FIND);
X+ # ifdef DEBUG
X+ if (tTd(27, 3))
X+ printf("%s\n", s == NULL ? "NOT_FOUND" : s->s_alias);
X+ # endif DEBUG
X if (s == NULL)
X return (NULL);
X return (s->s_alias);
X # endif DBM
X }
X+
X+ #ifdef NDBM
X+ /*
X+ ** NDBMINIT -- initialize the ndbm database
X+ **
X+ ** Only for use with NDBM and the keyed database table.
X+ **
X+ ** Parameters:
X+ ** aliasfile -- name of alias database file
X+ **
X+ ** Returns:
X+ ** None.
X+ **
X+ ** Side Effects:
X+ ** Opens the named database and initializes the DB_ALIAS
X+ ** entry of DbmTab.
X+ */
X+ ndbminit(aliasfile)
X+ char *aliasfile;
X+ {
X+ AliasDbm.name = aliasfile;
X+
X+ if (AliasDbm.dbm != DB_NOTYETOPEN)
X+ (void) dbm_close(AliasDbm.dbm);
X+
X+ AliasDbm.dbm = dbm_open(AliasDbm.name, O_RDWR, 0);
X+ if (AliasDbm.dbm == DB_NOSUCHFILE) {
X+ syserr("Cannot open %s", AliasDbm.name);
X+ NoAlias = TRUE;
X+ errno = 0;
X+ return;
X+ }
X+ }
X+
X+ #endif NDBM
X /*
X ** INITALIASES -- initialize for aliasing
X **
X***************
X*** 200,206 ****
X--- 253,263 ----
X */
X
X if (!init)
X+ # ifdef NDBM
X+ ndbminit(aliasfile);
X+ # else NDBM
X dbminit(aliasfile);
X+ # endif NDBM
X atcnt = SafeAlias * 2;
X if (atcnt > 0)
X {
X***************
X*** 218,224 ****
X
X sleep(30);
X # ifdef NDBM
X! dbminit(aliasfile);
X # endif NDBM
X }
X }
X--- 275,281 ----
X
X sleep(30);
X # ifdef NDBM
X! ndbminit(aliasfile);
X # endif NDBM
X }
X }
X***************
X*** 236,242 ****
X
X modtime = stb.st_mtime;
X (void) strcpy(buf, aliasfile);
X! (void) strcat(buf, ".pag");
X stb.st_ino = 0;
X if (!init && (stat(buf, &stb) < 0 || stb.st_mtime < modtime || atcnt <
0))
X {
X--- 293,299 ----
X
X modtime = stb.st_mtime;
X (void) strcpy(buf, aliasfile);
X! (void) strcat(buf, DB_PAGEXT);
X stb.st_ino = 0;
X if (!init && (stat(buf, &stb) < 0 || stb.st_mtime < modtime || atcnt <
0))
X {
X***************
X*** 356,362 ****
X {
X oldsigint = signal(SIGINT, SIG_IGN);
X (void) strcpy(line, aliasfile);
X! (void) strcat(line, ".dir");
X if (close(creat(line, DBMMODE)) < 0)
X {
X syserr("cannot make %s", line);
X--- 413,419 ----
X {
X oldsigint = signal(SIGINT, SIG_IGN);
X (void) strcpy(line, aliasfile);
X! (void) strcat(line, DB_PAGEXT);
X if (close(creat(line, DBMMODE)) < 0)
X {
X syserr("cannot make %s", line);
X***************
X*** 364,370 ****
X return;
X }
X (void) strcpy(line, aliasfile);
X! (void) strcat(line, ".pag");
X if (close(creat(line, DBMMODE)) < 0)
X {
X syserr("cannot make %s", line);
X--- 421,427 ----
X return;
X }
X (void) strcpy(line, aliasfile);
X! (void) strcat(line, DB_DIREXT);
X if (close(creat(line, DBMMODE)) < 0)
X {
X syserr("cannot make %s", line);
X***************
X*** 371,377 ****
X--- 428,438 ----
X (void) signal(SIGINT, oldsigint);
X return;
X }
X+ # ifdef NDBM
X+ ndbminit(aliasfile);
X+ # else NDBM
X dbminit(aliasfile);
X+ # endif NDBM
X }
X
X /*
X***************
X*** 475,480 ****
X--- 536,542 ----
X break;
X LineNumber++;
X }
X+
X if (al.q_mailer != LocalMailer)
X {
X syserr("cannot alias non-local names");
X***************
X*** 497,503 ****
X--- 559,569 ----
X key.dptr = al.q_user;
X content.dsize = rhssize;
X content.dptr = rhs;
X+ # ifdef NDBM
X+ (void) dbm_store(AliasDbm.dbm, key, content);
X+ # else NDBM
X store(key, content);
X+ # endif NDBM
X }
X else
X # endif DBM
X***************
X*** 521,527 ****
X--- 587,597 ----
X
X key.dsize = 2;
X key.dptr = "@";
X+ # ifdef NDBM
X+ (void) dbm_store(AliasDbm.dbm, key, key);
X+ # else NDBM
X store(key, key);
X+ # endif NDBM
X
X /* restore the old signal */
X (void) signal(SIGINT, oldsigint);
END_OF_ida/patches/alias.c.diff
if test 5555 -ne `wc -c <ida/patches/alias.c.diff`; then
echo shar: \"ida/patches/alias.c.diff\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ida/patches/op.me.diff -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"ida/patches/op.me.diff\"
else
echo shar: Extracting \"ida/patches/op.me.diff\" \(12488 characters\)
sed "s/^X//" >ida/patches/op.me.diff <<'END_OF_ida/patches/op.me.diff'
X*** op.me.orig Fri Mar 13 18:47:47 1987
X--- op.me Tue Apr 28 18:20:28 1987
X***************
X*** 7,13 ****
X .\"
X .\" @(#)op.me 5.8 (Berkeley) 5/9/86
X .\"
X! .\" eqn % | troff -me
X .\"if n .ls 2
X .\".he 'Sendmail Installation and Operation Guide''%'
X .\".fo 'Version 5.8''Last Mod 5/9/86'
X--- 7,13 ----
X .\"
X .\" @(#)op.me 5.8 (Berkeley) 5/9/86
X .\"
X! .\" pic % | eqn | troff -me
X .\"if n .ls 2
X .\".he 'Sendmail Installation and Operation Guide''%'
X .\".fo 'Version 5.8''Last Mod 5/9/86'
X***************
X*** 40,46 ****
X Eric Allman
X Britton-Lee, Inc.
X .sp
X! Version 5.8
X .)l
X .sp 2
X .pp
X--- 40,51 ----
X Eric Allman
X Britton-Lee, Inc.
X .sp
X! .sz 8
X! Enhancements by Lennart L\o"o\(um"vstrand
X! Dept of Comp and Info Sci, U of Link\o"o\(um"ping, Sweden
X! .sz 10
X! .sp
X! Version 5.8++
X .)l
X .sp 2
X .pp
X***************
X*** 524,529 ****
X--- 529,546 ----
X will print the contents of the mail queue;
X see below).
X This should be a link to /usr/lib/sendmail.
X+ .sh 3 "/usr/ucb/bsmtp"
X+ .pp
X+ If
X+ .i sendmail
X+ is invoked as
X+ .q bsmtp,
X+ it will simulate the
X+ .b \-bb
X+ flag (i.e.,
X+ .i sendmail
X+ will start accepting batched SMTP commands from stdin; see below).
X+ This should be a link to /usr/lib/sendmail.
X .sh 1 "NORMAL OPERATIONS"
X .sh 2 "Quick Configuration Startup"
X .pp
X***************
X*** 823,834 ****
X .(b
X name: name1, name2, ...
X .)b
X! Only local names may be aliased;
X e.g.,
X .(b
X eric@mit-xx: eric@berkeley.EDU
X .)b
X! will not have the desired effect.
X Aliases may be continued by starting any continuation lines
X with a space or a tab.
X Blank lines and lines beginning with a sharp sign
X--- 840,855 ----
X .(b
X name: name1, name2, ...
X .)b
X! It is possible not
X! only local names may be aliased,
X! but even non-locals if the configuration file is properly set up;
X e.g.,
X .(b
X eric@mit-xx: eric@berkeley.EDU
X .)b
X! will have the desired effect if the
X! .i aliases
X! database is searched before determining mailer in ruleset 0.
X Aliases may be continued by starting any continuation lines
X with a space or a tab.
X Blank lines and lines beginning with a sharp sign
X***************
X*** 1136,1141 ****
X--- 1157,1170 ----
X it defaults to
X .i sendmail.cf
X in the current directory.
X+ .pp
X+ You can also specify a different frozen configuration file with the
X+ .b \-Z
X+ option. It is used the same way as the
X+ .b \-C
X+ flag and defaults to
X+ .i sendmail.fc
X+ in the current directory.
X .sh 2 "Changing the Values of Options"
X .pp
X Options can be overridden using the
X***************
X*** 1705,1712 ****
X .ta 1i
X Path The pathname of the mailer
X Flags Special flags for this mailer
X! Sender A rewriting set for sender addresses
X! Recipient A rewriting set for recipient addresses
X Argv An argument vector to pass to this mailer
X Eol The end-of-line string for this mailer
X Maxsize The maximum message length to this mailer
X--- 1734,1741 ----
X .ta 1i
X Path The pathname of the mailer
X Flags Special flags for this mailer
X! Sender Rewriting sets for sender addresses
X! Recipient Rewriting sets for recipient addresses
X Argv An argument vector to pass to this mailer
X Eol The end-of-line string for this mailer
X Maxsize The maximum message length to this mailer
X***************
X*** 1879,1886 ****
X l The format of the UNIX from line
X n The name of the daemon (for error messages)
X o The set of "operators" in addresses
X! q default format of sender address
X .)b
X The
X .b $e
X macro is printed out when SMTP starts up.
X--- 1908,1926 ----
X l The format of the UNIX from line
X n The name of the daemon (for error messages)
X o The set of "operators" in addresses
X! q Default format of sender address
X .)b
X+ In addition, you also have the
X+ .b $k
X+ macro:
X+ .(b
X+ .ta 4n
X+ k Your node's UUCP hostname
X+ .)b
X+ which is optional to define (it defaults to the value of
X+ .b $w,
X+ your normal hostname).
X+ .pp
X The
X .b $e
X macro is printed out when SMTP starts up.
X***************
X*** 2107,2114 ****
X \fB$*\fP Match zero or more tokens
X \fB$+\fP Match one or more tokens
X \fB$\-\fP Match exactly one token
X! \fB$=\fP\fIx\fP Match any token in class \fIx\fP
X! \fB$~\fP\fIx\fP Match any token not in class \fIx\fP
X .)b
X If any of these match,
X they are assigned to the symbol
X--- 2147,2154 ----
X \fB$*\fP Match zero or more tokens
X \fB$+\fP Match one or more tokens
X \fB$\-\fP Match exactly one token
X! \fB$=\fP\fIx\fP Match any sequence of tokens in class \fIx\fP
X! \fB$~\fP\fIx\fP Match any sequence of tokens not in class \fIx\fP
X .)b
X If any of these match,
X they are assigned to the symbol
X***************
X*** 2141,2149 ****
X unless they begin with a dollar sign.
X Metasymbols are:
X .(b
X! .ta \w'$#mailer 'u
X \fB$\fP\fIn\fP Substitute indefinite token \fIn\fP from LHS
X! \fB$[\fP\fIname\fP\fB$]\fP Canonicalize \fIname\fP
X \fB$>\fP\fIn\fP \*(lqCall\*(rq ruleset \fIn\fP
X \fB$#\fP\fImailer\fP Resolve to \fImailer\fP
X \fB$@\fP\fIhost\fP Specify \fIhost\fP
X--- 2181,2190 ----
X unless they begin with a dollar sign.
X Metasymbols are:
X .(b
X! .ta \w'$(x key$@arg$:default$) 'u
X \fB$\fP\fIn\fP Substitute indefinite token \fIn\fP from LHS
X! \fB$[\fP\fIname\fP\fB$:\fP\fIdefault\fP\fB$]\fP Canonicalize \fIname\fP
X! \fB$(\fP\fIx key\fP\fB$@\fP\fIarg\fP\fB$:\fP\fIdefault\fP\fB$)\fP Lookup
the \fIkey\fP in database \fIx\fP, and sprintf \fIarg\fP through the result.
X \fB$>\fP\fIn\fP \*(lqCall\*(rq ruleset \fIn\fP
X \fB$#\fP\fImailer\fP Resolve to \fImailer\fP
X \fB$@\fP\fIhost\fP Specify \fIhost\fP
X***************
X*** 2178,2184 ****
X--- 2219,2270 ----
X .q $[[128.32.130.2]$]
X would become
X .q vangogh.berkeley.edu.
X+ The
X+ .b $: \c
X+ .i default
X+ part is optional and specifies what should be substituted
X+ in case that the
X+ .i name
X+ is not known to
X+ .i gethostent \|(3).
X .pp
X+ General
X+ .i dbm \|(3)
X+ databases may be searched using the
X+ .b $( \c
X+ .i "x key" \c
X+ .b $)
X+ syntax. The expression may be supplied with an optional result argument,
X+ .b $@ \c
X+ .i arg,
X+ and a default string,
X+ .b $: \c
X+ .i default.
X+ The database is specified by a single character and defined using the
X+ .q K
X+ option as in
X+ .(b
X+ OKP/usr/lib/mail/pathtable
X+ .)b
X+ which defines database
X+ .b P
X+ to be associated with the dbm files /usr/lib/mail/pathtable.{dir,pag}.
X+ An expression like
X+ .q "$(P sun $@ soren $: backbone!sun!soren $)"
X+ would look for the string
X+ .q sun
X+ in the
X+ .q P
X+ database and sprintf
X+ .q soren
X+ through the result, or substitute
X+ .q backbone!sun!soren
X+ if the key could not be found.
X+ If no
X+ .i default
X+ argument is supplied and the key could not be found, the whole
X+ expression is replaced with the key.
X+ .pp
X The
X .b $> \c
X .i n
X***************
X*** 2191,2197 ****
X then becomes
X the substitution for this rule.
X .pp
X! The
X .b $#
X syntax should
X .i only
X--- 2277,2283 ----
X then becomes
X the substitution for this rule.
X .pp
X! In most cases, the
X .b $#
X syntax should
X .i only
X***************
X*** 2236,2252 ****
X .b $@
X and
X .b $:
X! prefixes may precede a
X .b $>
X! spec;
X for example:
X .(b
X .ta 8n
X! R$+ $:$>7$1
X .)b
X matches anything,
X! passes that to ruleset seven,
X! and continues;
X the
X .b $:
X is necessary to avoid an infinite loop.
X--- 2322,2338 ----
X .b $@
X and
X .b $:
X! prefixes may precede
X .b $>
X! specs;
X for example:
X .(b
X .ta 8n
X! R$+ $:$>7$>8$1
X .)b
X matches anything,
X! passes that to ruleset eight and the result of that to ruleset seven,
X! and finally continues;
X the
X .b $:
X is necessary to avoid an infinite loop.
X***************
X*** 2854,2859 ****
X--- 2940,2946 ----
X Other flags are described
X in Appendix C.
X .pp
X+ .pp
X The S and R fields in the mailer description
X are per-mailer rewriting sets
X to be applied to sender and recipient addresses
X***************
X*** 2884,2889 ****
X--- 2971,2983 ----
X These sets can also be used
X to do special purpose output rewriting
X in cooperation with ruleset four.
X+ If required, the R and S rulesets may be specified independently for envelop
e
X+ and header addresses by separating them with a slash. E.g.,
X+ .q R=13/14
X+ means that envelope recipient addresses should be sent through ruleset 13
X+ while those in the header should be passed to ruleset 14.
X+ You can disable any mailer specific rewriting by specifying the ruleset as
X+ zero or by leaving it blank.
X .pp
X The E field defines the string to use
X as an end-of-line indication.
X***************
X*** 3026,3031 ****
X--- 3120,3126 ----
X i Initialize the alias database
X p Print the mail queue
X z Freeze the configuration file
X+ b Run in Batched SMTP mode
X .)b
X The special processing for the
X ARPANET
X***************
X*** 3050,3055 ****
X--- 3145,3155 ----
X .i Sendmail
X runs as the invoking user (rather than root)
X when this flag is specified.
X+ .ip \-Z\fIfile\fP
X+ Use a different frozen configuration file.
X+ .i Sendmail
X+ runs as the invoking user (rather than root)
X+ when this flag is specified.
X .ip \-d\fIlevel\fP
X Set debugging level.
X .ip \-o\fIx\|value\fP
X***************
X*** 3166,3171 ****
X--- 3266,3285 ----
X for SMTP.
X .ip i
X Ignore dots in incoming messages.
X+ .ip K\fIxfile\fP
X+ Declare the
X+ keyed database
X+ .i x
X+ to be associated with the
X+ .i dbm \|(3)
X+ file
X+ .i file.
X+ (\fIX\fP is a single letter.)
X+ The database
X+ .q @
X+ is always bound to the
X+ .i aliases
X+ database.
X .ip L\fIn\fP
X Set the default log level to
X .i n .
X***************
X*** 3406,3415 ****
X will not terminate the message prematurely.
X .ip L
X Limit the line lengths as specified in RFC821.
X! .ip P
X Use the return-path in the SMTP
X .q "MAIL FROM:"
X! command
X rather than just the return address;
X although this is required in RFC821,
X many hosts do not process return paths properly.
X--- 3520,3531 ----
X will not terminate the message prematurely.
X .ip L
X Limit the line lengths as specified in RFC821.
X! .ip p
X Use the return-path in the SMTP
X .q "MAIL FROM:"
X! command or in the UUCP
X! .q From_
X! line
X rather than just the return address;
X although this is required in RFC821,
X many hosts do not process return paths properly.
X***************
X*** 3450,3455 ****
X--- 3566,3587 ----
X Escape lines beginning with
X .q From
X in the message with a `>' sign.
X+ .ip V
X+ Make all header addresses UUCP !-relative with respect to ourselves
X+ and the recipient host. This means that all header lines will have
X+ working paths relative to the recipient host. Routes through the
X+ remote host, i.e. addresses that begin with
X+ .q remote!
X+ are stripped of that part unless the ultimate
X+ recipient resides on the remote host (i.e., there are no more bangs in
X+ the address). All other addresses are prefixed with
X+ .q ourhost!
X+ if not already there.
X+ .i Ourhost
X+ is fetched from the
X+ .b $k
X+ macro, which defaults to your hostname as supplied by
X+ .i gethostname \|(3).
X .+c "OTHER CONFIGURATION"
X .rm $0
X .nr ii 1i
X***************
X*** 3603,3608 ****
X--- 3735,3749 ----
X that allows multiple databases will be used.
X .q DBM
X must also be set.
X+ .ip MDBM
X+ If set, Maryland's
X+ .i mdbm \|(3)
X+ package should be substituted for the
X+ .i ndbm \|(3)
X+ routines. This should only be used if you want the keyed database
X+ functionality (\fB$(x key$)\fP), but don't have
X+ .i ndbm \|(3)
X+ available.
X .ip DEBUG
X If set, debugging information is compiled in.
X To actually get the debugging output,
X***************
X*** 3929,3935 ****
X .ip "/usr/lib/sendmail"
X The binary of
X .i sendmail .
X! .ip /usr/bin/newaliases
X A link to /usr/lib/sendmail;
X causes the alias database to be rebuilt.
X Running this program is completely equivalent to giving
X--- 4070,4076 ----
X .ip "/usr/lib/sendmail"
X The binary of
X .i sendmail .
X! .ip /usr/ucb/newaliases
X A link to /usr/lib/sendmail;
X causes the alias database to be rebuilt.
X Running this program is completely equivalent to giving
X***************
X*** 3937,3948 ****
X the
X .b \-bi
X flag.
X! .ip /usr/bin/mailq
X Prints a listing of the mail queue.
X This program is equivalent to using the
X .b \-bp
X flag to
X .i sendmail .
X .ip /usr/lib/sendmail.cf
X The configuration file,
X in textual form.
X--- 4078,4095 ----
X the
X .b \-bi
X flag.
X! .ip /usr/ucb/mailq
X Prints a listing of the mail queue.
X This program is equivalent to using the
X .b \-bp
X flag to
X .i sendmail .
X+ .ip /usr/ucb/bsmtp
X+ A link to /usr/lib/sendmail; starts up
X+ .i sendmail
X+ in Batched SMTP mode (as if supplied with the
X+ .b \-bb
X+ option).
X .ip /usr/lib/sendmail.cf
X The configuration file,
X in textual form.
END_OF_ida/patches/op.me.diff
if test 12488 -ne `wc -c <ida/patches/op.me.diff`; then
echo shar: \"ida/patches/op.me.diff\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ida/patches/sendmail.h.diff -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"ida/patches/sendmail.h.diff\"
else
echo shar: Extracting \"ida/patches/sendmail.h.diff\" \(5801 characters\)
sed "s/^X//" >ida/patches/sendmail.h.diff <<'END_OF_ida/patches/sendmail.h.diff
'
X*** sendmail.h.orig Fri Mar 13 18:51:00 1987
X--- sendmail.h Wed May 27 01:58:25 1987
X***************
X*** 32,38 ****
X # include "useful.h"
X
X # ifdef LOG
X! # include <sys/syslog.h>
X # endif LOG
X
X # ifdef DAEMON
X--- 32,42 ----
X # include "useful.h"
X
X # ifdef LOG
X! # ifdef vax
X! # include <sys/syslog.h>
X! # else vax
X! # include <syslog.h>
X! # endif vax
X # endif LOG
X
X # ifdef DAEMON
X***************
X*** 121,128 ****
X BITMAP m_flags; /* status flags, see below */
X short m_mno; /* mailer number internally */
X char **m_argv; /* template argument vector */
X! short m_s_rwset; /* rewriting set for sender addresses */
X! short m_r_rwset; /* rewriting set for recipient addresses */
X char *m_eol; /* end of line string */
X long m_maxsize; /* size limit on message to this mailer */
X };
X--- 125,134 ----
X BITMAP m_flags; /* status flags, see below */
X short m_mno; /* mailer number internally */
X char **m_argv; /* template argument vector */
X! short m_se_rwset; /* rewriting ruleset for envelope senders */
X! short m_sh_rwset; /* rewriting ruleset for header senders */
X! short m_re_rwset; /* rewriting ruleset for envelope recipients */
X! short m_rh_rwset; /* rewriting ruleset for header recipient */
X char *m_eol; /* end of line string */
X long m_maxsize; /* size limit on message to this mailer */
X };
X***************
X*** 130,135 ****
X--- 136,142 ----
X typedef struct mailer MAILER;
X
X /* bits for m_flags */
X+ # define M_BSMTP 'B' /* don't wait for SMTP responses */
X # define M_CANONICAL 'C' /* make addresses canonical "u@dom" */
X # define M_EXPENSIVE 'e' /* it costs to use this mailer.... */
X # define M_ESCFROM 'E' /* escape From lines to >From */
X***************
X*** 147,152 ****
X--- 154,160 ----
X # define M_RESTR 'S' /* must be daemon to execute */
X # define M_USR_UPPER 'u' /* preserve user case distinction */
X # define M_UGLYUUCP 'U' /* this wants an ugly UUCP from line */
X+ # define M_RELATIVIZE 'V' /* !-relativize all addresses */
X # define M_XDOT 'X' /* use hidden-dot algorithm */
X
X EXTERN MAILER *Mailer[MAXMAILERS+1];
X***************
X*** 317,326 ****
X # define CONDELSE '\033' /* conditional else */
X # define CONDFI '\034' /* conditional fi */
X
X! /* bracket characters for host name lookup */
X # define HOSTBEGIN '\035' /* hostname lookup begin */
X # define HOSTEND '\036' /* hostname lookup end */
X
X /* \001 is also reserved as the macro expansion character */
X /*
X ** Information about hosts that we have looked up recently.
X--- 325,338 ----
X # define CONDELSE '\033' /* conditional else */
X # define CONDFI '\034' /* conditional fi */
X
X! /* bracket characters for host name & database keyed lookup */
X # define HOSTBEGIN '\035' /* hostname lookup begin */
X # define HOSTEND '\036' /* hostname lookup end */
X+ # define KEYBEGIN '\037' /* keyed lookup begin */
X+ # define KEYEND '\017' /* keyed lookup end */
X
X+ /*
X+
X /* \001 is also reserved as the macro expansion character */
X /*
X ** Information about hosts that we have looked up recently.
X***************
X*** 379,384 ****
X--- 391,401 ----
X # define ST_ALIAS 4 /* an alias */
X # define ST_HOST 5 /* host information */
X
X+ /* s_host is defined is /usr/include/whatever on sun's */
X+ # ifdef s_host
X+ # undef s_host
X+ # endif
X+
X # define s_class s_value.sv_class
X # define s_address s_value.sv_addr
X # define s_mailer s_value.sv_mailer
X***************
X*** 438,443 ****
X--- 455,461 ----
X #define MD_INITALIAS 'i' /* initialize alias database */
X #define MD_PRINT 'p' /* print the queue */
X #define MD_FREEZE 'z' /* freeze the configuration file */
X+ #define MD_BSMTP 'b' /* batched smtp mode */
X
X
X EXTERN char SendMode; /* send mode, see below */
X***************
X*** 465,470 ****
X--- 483,525 ----
X */
X #define MAX_ERRNO 100
X /*
X+ ** Database ([n]dbm) definitions.
X+ */
X+
X+ #ifdef DBM
X+
X+ typedef struct {
X+ char *dptr;
X+ int dsize;
X+ } DATUM;
X+
X+ # define DB_DIREXT ".dir"
X+ # define DB_PAGEXT ".pag"
X+
X+ # ifdef NDBM
X+
X+ # undef DBM /* while including ndbm.h */
X+ # include <ndbm.h> /* DBM is typedef'ed here */
X+ typedef DBM DBMFILE; /* move typedef to DBMFILE */
X+ # define DBM /* and restore DBM definition */
X+ # include <fcntl.h> /* needed for dbm_open */
X+
X+ # define DATUM datum /* use the definition in ndbm.h */
X+
X+ struct dbm_table {
X+ char *name; /* database file name */
X+ DBMFILE *dbm; /* dbm file descriptor */
X+ };
X+
X+ # define DB_NOSUCHFILE ((DBMFILE *) 0) /* file could not be found */
X+ # define DB_NOTYETOPEN ((DBMFILE *) -1) /* file has not yet been opene
d */
X+
X+ # define DB_ALIAS '@' /* "name" of aliases database */
X+ # define AliasDbm DbmTab[DB_ALIAS]
X+
X+ # endif NDBM
X+ #endif DBM
X+ /*
X ** Global variables.
X */
X
X***************
X*** 525,534 ****
X--- 580,593 ----
X EXTERN int WkClassFact; /* multiplier for message class -> priority */
X EXTERN int WkRecipFact; /* multiplier for # of recipients -> priority *
/
X EXTERN int WkTimeFact; /* priority offset each time this job is run */
X+ EXTERN bool SplitRewriting; /* use split envelope/header rewriting */
X EXTERN int CheckPointLimit; /* deliveries before checkpointing */
X EXTERN char *PostMasterCopy; /* address to get errs cc's */
X EXTERN char *TrustedUsers[MAXTRUST+1]; /* list of trusted users */
X EXTERN char *UserEnviron[MAXUSERENVIRON+1]; /* saved user environment */
X+ #ifdef NDBM
X+ EXTERN struct dbm_table DbmTab[128]; /* keyed database table */
X+ #endif NDBM
X /*
X ** Trace information
X */
X***************
X*** 572,574 ****
X--- 631,645 ----
X extern char *sfgets();
X extern char *queuename();
X extern time_t curtime();
X+
X+ /*
X+ ** Metamacro definitions.
X+ */
X+
X+ struct metamac
X+ {
X+ char metaname;
X+ char metaval;
X+ };
X+
X+ extern struct metamac MetaMacros[];
END_OF_ida/patches/sendmail.h.diff
if test 5801 -ne `wc -c <ida/patches/sendmail.h.diff`; then
echo shar: \"ida/patches/sendmail.h.diff\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 3 \(of 7\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 7 archives.
echo "See ida/README and ida/INSTALL for further instructions."
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0