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