rsalz@uunet.uu.net (Rich Salz) (11/14/88)
Submitted-by: Lennart Lovstrand <lovstran@arisia.xerox.com> Posting-number: Volume 16, Issue 75 Archive-name: ida2/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 8)." # Contents: ida/aux/rmail.c ida/aux/xalparse.c # ida/patches/alias.c.diff ida/patches/deliver.c.diff # ida/patches/main.c.diff ida/patches/recipient.c.diff # ida/patches/sendmail.h.diff PATH=/bin:/usr/bin:/usr/ucb ; export PATH 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\" \(7381 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** The following definitions below are optional: X** LOGFILE -- If defined, should be the name of a file in which to X** log the raw addresses of each message. X** DEFAULT_HOST -- If no host is found in the envelope recipients, X** this host is assumed [defaults to your local host]. X** DEFAULT_DOMAIN -- If the sending host is unqualifed, add this X** domain to the host for use in the Received: line. X** DOMAINTABLE -- If defined, should point to your local domain X** lookup database. It is used for the same purpose as X** the DEFAULT_DOMAIN. 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 = ""; 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#ifdef DEFAULT_DOMAIN X domain = DEFAULT_DOMAIN; X#endif DEFAULT_DOMAIN 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 && *domain != '\0') 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 7381 -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\" \(9228 characters\) sed "s/^X//" >ida/patches/alias.c.diff <<'END_OF_ida/patches/alias.c.diff' X*** alias.c.orig Sat Apr 2 01:22:15 1988 X--- alias.c Tue Aug 30 04:19:45 1988 X*************** X*** 58,71 **** 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--- 58,66 ---- 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*** 76,82 **** X X # ifdef DEBUG X if (tTd(27, 1)) X! printf("alias(%s)\n", a->q_paddr); X # endif X X /* don't realias already aliased names */ X--- 71,77 ---- X X # ifdef DEBUG X if (tTd(27, 1)) X! printf("alias(%s)\n", a->q_user); X # endif X X /* don't realias already aliased names */ X*************** X*** 125,131 **** X ** none. X ** X ** Warnings: X! ** The return value will be trashed across calls. X */ X X char * X--- 120,127 ---- X ** none. X ** X ** Warnings: X! ** The return value will be trashed across calls X! ** unless NDBM is defined and we're using mapkey(). X */ X X char * X*************** X*** 133,149 **** X char *name; 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--- 129,178 ---- X char *name; X { X # ifdef DBM X+ # ifdef NDBM X+ char *newname; X+ X+ # ifdef DEBUG X+ if (tTd(27, 3)) X+ printf("aliaslookup(\"%s\") => ", name); X+ # endif DEBUG X+ newname = (char *) mapkey(DB_ALIAS, name, 0, 0); X+ # ifdef DEBUG X+ if (tTd(27, 3)) X+ printf("%s\n", newname == NULL ? "NOT_FOUND" : newname); X+ # endif DEBUG X+ return newname; X+ X+ # else NDBM X+ X DATUM rhs, lhs; X+ char *lowname = xalloc(strlen(name) + 1); /* potential space hog */ X X /* create a key for fetch */ X! (void) strcpy(lowname, name); X! (void) 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 rhs = fetch(lhs); 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+ # endif !NDBM 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*************** X*** 155,161 **** X ** Very different depending on whether we are running DBM or not. X ** X ** Parameters: X- ** aliasfile -- location of aliases. X ** init -- if set and if DBM, initialize the DBM files. X ** X ** Returns: X--- 184,189 ---- X*************** X*** 169,176 **** X X # define DBMMODE 0666 X X! initaliases(aliasfile, init) X! char *aliasfile; X bool init; X { X #ifdef DBM X--- 197,203 ---- X X # define DBMMODE 0666 X X! initaliases(init) X bool init; X { X #ifdef DBM X*************** X*** 186,195 **** X return; X initialized = TRUE; X X! if (aliasfile == NULL || stat(aliasfile, &stb) < 0) X { X! if (aliasfile != NULL && init) X! syserr("Cannot open %s", aliasfile); X NoAlias = TRUE; X errno = 0; X return; X--- 213,229 ---- X return; X initialized = TRUE; X X! if (AliasFile == NULL || X! #ifdef YPMARK X! (AliasFile[0] != YPMARK && X! #endif YPMARK X! stat(AliasFile, &stb) < 0) X! #ifdef YPMARK X! ) X! #endif YPMARK X { X! if (AliasFile != NULL && init) X! syserr("Cannot open %s", AliasFile); X NoAlias = TRUE; X errno = 0; X return; X*************** X*** 202,230 **** X ** to us to rebuild it. X */ X X if (!init) X! dbminit(aliasfile); X atcnt = SafeAlias * 2; X if (atcnt > 0) X- { X while (!init && atcnt-- >= 0 && aliaslookup("@") == NULL) X- { X- /* X- ** Reinitialize alias file in case the new X- ** one is mv'ed in instead of cp'ed in. X- ** X- ** Only works with new DBM -- old one will X- ** just consume file descriptors forever. X- ** If you have a dbmclose() it can be X- ** added before the sleep(30). X- */ X- X sleep(30); X- # ifdef NDBM X- dbminit(aliasfile); X- # endif NDBM X- } X- } X else X atcnt = 1; X X--- 236,249 ---- X ** to us to rebuild it. X */ X X+ #ifndef NDBM X if (!init) X! dbminit(AliasFile); X! #endif !NDBM X atcnt = SafeAlias * 2; X if (atcnt > 0) X while (!init && atcnt-- >= 0 && aliaslookup("@") == NULL) X sleep(30); X else X atcnt = 1; X X*************** X*** 238,247 **** X */ 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 errno = 0; X if (AutoRebuild && stb.st_ino != 0 && X--- 257,270 ---- X */ 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 && X! #ifdef YPMARK X! AliasFile[0] != YPMARK && X! #endif YPMARK X! (stat(buf, &stb) < 0 || stb.st_mtime < modtime || atcnt < 0)) X { X errno = 0; X if (AutoRebuild && stb.st_ino != 0 && X*************** X*** 282,291 **** X automatic ? "auto" : "", username()); X } X #endif LOG X! readaliases(aliasfile, TRUE); X } X # else DBM X! readaliases(aliasfile, init); X # endif DBM X } X /* X--- 305,314 ---- X automatic ? "auto" : "", username()); X } X #endif LOG X! readaliases(TRUE); X } X # else DBM X! readaliases(init); X # endif DBM X } X /* X*************** X*** 295,301 **** X ** when we are not going to use the DBM stuff. X ** X ** Parameters: X- ** aliasfile -- the pathname of the alias file master. X ** init -- if set, initialize the DBM stuff. X ** X ** Returns: X--- 318,323 ---- X*************** X*** 302,314 **** X ** none. X ** X ** Side Effects: X! ** Reads aliasfile into the symbol table. X ** Optionally, builds the .dir & .pag files. X */ X X static X! readaliases(aliasfile, init) X! char *aliasfile; X bool init; X { X register char *p; X--- 324,335 ---- X ** none. X ** X ** Side Effects: X! ** Reads AliasFile into the symbol table. X ** Optionally, builds the .dir & .pag files. X */ X X static X! readaliases(init) X bool init; X { X register char *p; X*************** X*** 321,331 **** X register STAB *s; X char line[BUFSIZ]; X X! if ((af = fopen(aliasfile, "r")) == NULL) X { X # ifdef DEBUG X if (tTd(27, 1)) X! printf("Can't open %s\n", aliasfile); X # endif X errno = 0; X NoAlias++; X--- 342,364 ---- X register STAB *s; X char line[BUFSIZ]; X X! # ifdef YPMARK X! if (AliasFile[0] == YPMARK) { X! # ifdef DEBUG X! if (tTd(27, 1)) X! printf("Can't reinit YP databases: \"%s\"\n", AliasFile); X! # endif X! /* reuse old aliases */ X! errno = 0; X! return; X! } X! # endif YPMARK X! X! if ((af = fopen(AliasFile, "r")) == NULL) X { X # ifdef DEBUG X if (tTd(27, 1)) X! printf("Can't open %s\n", AliasFile); X # endif X errno = 0; X NoAlias++; X*************** X*** 356,363 **** X if (init) 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--- 389,396 ---- X if (init) 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,371 **** X (void) signal(SIGINT, oldsigint); 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--- 397,404 ---- X (void) signal(SIGINT, oldsigint); 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*** 372,378 **** X (void) signal(SIGINT, oldsigint); X return; X } X! dbminit(aliasfile); X } X X /* X--- 405,415 ---- X (void) signal(SIGINT, oldsigint); X return; X } X! # ifdef NDBM X! mapinit(DB_ALIAS); X! # else NDBM X! dbminit(AliasFile); X! # endif NDBM X } X X /* X*************** X*** 379,385 **** X ** Read and interpret lines X */ X X! FileName = aliasfile; X LineNumber = 0; X naliases = bytes = longest = 0; X skipping = FALSE; X--- 416,422 ---- X ** Read and interpret lines X */ X X! FileName = AliasFile; X LineNumber = 0; X naliases = bytes = longest = 0; X skipping = FALSE; X*************** X*** 498,504 **** X--- 535,545 ---- X key.dptr = al.q_user; X content.dsize = rhssize; X content.dptr = rhs; X+ # ifdef NDBM X+ (void) dbm_store(AliasDbm, key, content); X+ # else NDBM X store(key, content); X+ # endif NDBM X } X else X # endif DBM X*************** X*** 522,528 **** X--- 563,573 ---- X X key.dsize = 2; X key.dptr = "@"; X+ # ifdef NDBM X+ (void) dbm_store(AliasDbm, 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 9228 -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/deliver.c.diff -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ida/patches/deliver.c.diff\" else echo shar: Extracting \"ida/patches/deliver.c.diff\" \(6664 characters\) sed "s/^X//" >ida/patches/deliver.c.diff <<'END_OF_ida/patches/deliver.c.diff' X*** deliver.c.orig Thu May 5 20:40:23 1988 X--- deliver.c Fri Sep 23 19:56:56 1988 X*************** X*** 28,33 **** X--- 28,85 ---- X #include <resolv.h> X X /* X+ ** Status error messages X+ */ X+ #define MAXENDERR (sizeof(Enderr) / sizeof(*Enderr)) X+ char *Enderr[] = { X+ "IMPOSSIBLE", X+ /* SIGHUP */ "hangup", X+ /* SIGINT */ "interrupt", X+ /* SIGQUIT */ "quit", X+ /* SIGILL */ "illegal instruction", X+ /* SIGTRAP */ "trace trap", X+ /* SIGIOT */ "IOT instruction", X+ /* SIGEMT */ "EMT instruction", X+ /* SIGFPE */ "floating point exception", X+ /* SIGKILL */ "kill", X+ /* SIGBUS */ "bus error", X+ /* SIGSEGV */ "segmentation violation", X+ /* SIGSYS */ "bad argument to system call", X+ /* SIGPIPE */ "write on a pipe with no one to read it", X+ /* SIGALRM */ "alarm clock", X+ /* SIGTERM */ "software termination signal", X+ /* SIGURG */ "urgent condition present on socket", X+ /* SIGSTOP */ "stop", X+ /* SIGTSTP */ "stop signal generated from keyboard", X+ /* SIGCONT */ "continue after stop", X+ /* SIGCHLD */ "child status has changed", X+ /* SIGTTIN */ "background read attempted from control terminal", X+ /* SIGTTOU */ "background write attempted to control terminal", X+ /* SIGIO */ "I/O is possible on a descriptor", X+ /* SIGXCPU */ "cpu time limit exceeded", X+ /* SIGXFSZ */ "file size limit exceeded", X+ /* SIGVTALRM */ "virtual time alarm", X+ /* SIGPROF */ "profiling timer alarm", X+ /* SIGWINCH */ "window changed", X+ /* SIGLOST */ "resource lost", X+ /* SIGUSR1 */ "user-defined signal 1", X+ /* SIGUSR2 */ "user-defined signal 2" X+ }; X+ X+ /* X+ ** Name server error messages X+ */ X+ #define MAXH_ERR (sizeof(H_Errmsg) / sizeof(*H_Errmsg)) X+ char *H_Errmsg[] = { X+ /* XXX */ "[Unknown error]", X+ /* HOST_NOT_FOUND */ "Authoritative answer from name server", X+ /* TRY_AGAIN */ "Non-authoritiatve answer or name server failure", X+ /* NO_RECOVERY */ "Non recoverable name server error", X+ /* NO_DATA */ "Valid name but no data [address]" X+ }; X+ X+ X+ /* X ** DELIVER -- Deliver a message to a list of addresses. X ** X ** This routine delivers to everyone on the same host as the X*************** X*** 131,137 **** X X /* rewrite from address, using rewriting rules */ X expand("\001f", buf, &buf[sizeof buf - 1], e); X! (void) strcpy(tfrombuf, remotename(buf, m, TRUE, TRUE)); X X define('g', tfrombuf, e); /* translated sender address */ X define('h', host, e); /* to host */ X--- 183,189 ---- X X /* rewrite from address, using rewriting rules */ X expand("\001f", buf, &buf[sizeof buf - 1], e); X! (void) strcpy(tfrombuf, remotename(buf, m, TRUE, TRUE, FALSE)); X X define('g', tfrombuf, e); /* translated sender address */ X define('h', host, e); /* to host */ X*************** X*** 371,377 **** X X if (ctladdr == NULL) X ctladdr = &e->e_from; X! _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */ X #ifdef SMTP X if (clever) { X expand("\001w", buf, &buf[sizeof(buf) - 1], e); X--- 423,429 ---- X X if (ctladdr == NULL) X ctladdr = &e->e_from; X! /* _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */ X #ifdef SMTP X if (clever) { X expand("\001w", buf, &buf[sizeof(buf) - 1], e); X*************** X*** 421,427 **** X message(Arpa_Info, "Connecting to %s (%s)...", host, m->m_name); X rcode = sendoff(e, m, pv, ctladdr); X } X! _res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */ X X /* X ** Do final status disposal. X--- 473,479 ---- X message(Arpa_Info, "Connecting to %s (%s)...", host, m->m_name); X rcode = sendoff(e, m, pv, ctladdr); X } X! /* _res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */ X X /* X ** Do final status disposal. X*************** X*** 647,653 **** X /* see if it died a horrid death */ X if ((st & 0377) != 0) X { X! syserr("mailer %s died with signal %o", name, st); X ExitStat = EX_TEMPFAIL; X return (EX_TEMPFAIL); X } X--- 699,707 ---- X /* see if it died a horrid death */ X if ((st & 0377) != 0) X { X! syserr("%s died because of %s (%d)--requeueing message", X! name, ((st >= 0) && (st < MAXENDERR)) ? X! Enderr[st] : "unknown error code", st); X ExitStat = EX_TEMPFAIL; X return (EX_TEMPFAIL); X } X*************** X*** 1006,1013 **** X message(Arpa_Info, &statmsg[4]); X else X { X Errors++; X! usrerr(statmsg); X } X X /* X--- 1060,1073 ---- X message(Arpa_Info, &statmsg[4]); X else X { X+ extern char Arpa_Usrerr[]; X+ X Errors++; X! if (stat == EX_NOHOST && h_errno != 0) X! usrerr("%s (%s)", statmsg, X! H_Errmsg[h_errno > MAXH_ERR ? 0 : h_errno]); X! else X! usrerr(statmsg); X } X X /* X*************** X*** 1079,1110 **** X register FILE *fp; X register MAILER *m; X { X! char *template = "\001l\n"; X char buf[MAXLINE]; X X if (bitnset(M_NHDR, m->m_flags)) X return; X X # ifdef UGLYUUCP X if (bitnset(M_UGLYUUCP, m->m_flags)) X { X char *bang; X- char xbuf[MAXLINE]; X X expand("\001g", buf, &buf[sizeof buf - 1], CurEnv); X bang = index(buf, '!'); X if (bang == NULL) X! syserr("No ! in UUCP! (%s)", buf); X else X { X *bang++ = '\0'; X! (void) sprintf(xbuf, "From %s \001d remote from %s\n", bang, buf); X! template = xbuf; X } X } X # endif UGLYUUCP X expand(template, buf, &buf[sizeof buf - 1], CurEnv); X putline(buf, fp, m); X } X /* X ** PUTBODY -- put the body of a message. X--- 1139,1192 ---- X register FILE *fp; X register MAILER *m; X { X! extern char *macvalue(); X! char *oldg = macvalue('g', CurEnv); X! char template[MAXLINE]; X! char newg[MAXLINE]; X char buf[MAXLINE]; X X+ strcpy(template, "\001l\n"); X+ X if (bitnset(M_NHDR, m->m_flags)) X return; X X+ /* construct path through us if needed */ X+ if (bitnset(M_FROMPATH, m->m_flags)) { X+ char myname[MAXLINE]; X+ X+ expand("\001k", myname, &myname[sizeof myname - 1], CurEnv); X+ if (index(oldg, '!') == NULL X+ || strncmp(oldg, myname, strlen(myname)) != 0) { X+ sprintf(newg, "%s!%s", myname, oldg); X+ define('g', newg, CurEnv); X+ } X+ } X+ X # ifdef UGLYUUCP X if (bitnset(M_UGLYUUCP, m->m_flags)) X { X char *bang; X X expand("\001g", buf, &buf[sizeof buf - 1], CurEnv); X bang = index(buf, '!'); X if (bang == NULL) X! syserr("No `!' in UUCP envelope \"from\" address! (%s)", X! buf); X else X { X *bang++ = '\0'; X! (void) sprintf(template, X! "From %s \001d remote from %s\n", X! bang, buf); X } X } X # endif UGLYUUCP X expand(template, buf, &buf[sizeof buf - 1], CurEnv); X putline(buf, fp, m); X+ X+ /* redefine old from address */ X+ if (bitnset(M_FROMPATH, m->m_flags)) X+ define('g', oldg, CurEnv); X } X /* X ** PUTBODY -- put the body of a message. END_OF_ida/patches/deliver.c.diff if test 6664 -ne `wc -c <ida/patches/deliver.c.diff`; then echo shar: \"ida/patches/deliver.c.diff\" unpacked with wrong size! fi # end of overwriting check fi if test -f ida/patches/main.c.diff -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ida/patches/main.c.diff\" else echo shar: Extracting \"ida/patches/main.c.diff\" \(8294 characters\) sed "s/^X//" >ida/patches/main.c.diff <<'END_OF_ida/patches/main.c.diff' X*** main.c.orig Tue Apr 19 21:40:01 1988 X--- main.c Fri Aug 26 03:10:02 1988 X*************** X*** 110,116 **** X bool queuemode = FALSE; /* process queue requests */ X bool nothaw; X static bool reenter = FALSE; X! char jbuf[30]; /* holds MyHostName */ X extern bool safefile(); X extern time_t convtime(); X extern putheader(), putbody(); X--- 110,116 ---- X bool queuemode = FALSE; /* process queue requests */ X bool nothaw; X static bool reenter = FALSE; X! char jbuf[60]; /* holds MyHostName */ X extern bool safefile(); X extern time_t convtime(); X extern putheader(), putbody(); X*************** X*** 118,123 **** X--- 118,124 ---- X extern intsig(); X extern char **myhostname(); X extern char *arpadate(); X+ extern char *index(); X extern char **environ; X X /* X*************** X*** 134,140 **** X--- 135,143 ---- X reenter = TRUE; X X /* Enforce use of local time */ X+ #ifndef sun X unsetenv("TZ"); X+ #endif !sun X X /* X ** Be sure we have enough file descriptors. X*************** X*** 187,192 **** X--- 190,203 ---- X } X else if (strncmp(p, "-bz", 3) == 0) X nothaw = TRUE; X+ else if (strncmp(p, "-Z", 2) == 0) X+ { X+ FreezeFile = &p[2]; X+ if (FreezeFile[0] == '\0') X+ FreezeFile = "sendmail.fc"; X+ (void) setgid(getrgid()); X+ (void) setuid(getruid()); X+ } X # ifdef DEBUG X else if (strncmp(p, "-d", 2) == 0) X { X*************** X*** 236,242 **** X--- 247,257 ---- X FullName = getenv("NAME"); X X # ifdef LOG X+ #ifndef sun X openlog("sendmail", LOG_PID, LOG_MAIL); X+ #else X+ openlog("sendmail", LOG_PID); X+ #endif X # endif LOG X errno = 0; X from = NULL; X*************** X*** 257,262 **** X--- 272,281 ---- X p = newstr(jbuf); X define('w', p, CurEnv); X setclass('w', p); X+ if ((p = index(jbuf, '.')) != NULL) X+ *p = '\0'; X+ makelower(jbuf); X+ define('k', newstr(jbuf), CurEnv); X } X while (av != NULL && *av != NULL) X { X*************** X*** 288,293 **** X--- 307,314 ---- X OpMode = MD_PRINT; X else if (strcmp(p, "smtpd") == 0) X OpMode = MD_DAEMON; X+ else if (strcmp(p, "bsmtp") == 0) X+ OpMode = MD_BSMTP; X while ((p = *++av) != NULL && p[0] == '-') X { X switch (p[1]) X*************** X*** 301,306 **** X--- 322,328 ---- X break; X # endif DAEMON X case MD_SMTP: X+ case MD_BSMTP: X # ifndef SMTP X syserr("I don't speak SMTP"); X break; X*************** X*** 324,335 **** X case 'C': /* select configuration file (already done) */ X break; X X #ifdef DEBUG X case 'd': /* debugging -- redo in case frozen */ X tTsetup(tTdvect, sizeof tTdvect, "0-99.1"); X tTflag(&p[2]); X setbuf(stdout, (char *) NULL); X! _res.options |= RES_DEBUG; X break; X #endif X X--- 346,361 ---- X case 'C': /* select configuration file (already done) */ X break; X X+ case 'Z': /* select frozen config file (already done) */ X+ break; X+ X #ifdef DEBUG X case 'd': /* debugging -- redo in case frozen */ X tTsetup(tTdvect, sizeof tTdvect, "0-99.1"); X tTflag(&p[2]); X setbuf(stdout, (char *) NULL); X! if (tTd(8, 8)) X! _res.options |= RES_DEBUG; X break; X #endif X X*************** X*** 496,502 **** X X case MD_INITALIAS: X /* initialize alias database */ X! initaliases(AliasFile, TRUE); X exit(EX_OK); X X case MD_DAEMON: X--- 522,528 ---- X X case MD_INITALIAS: X /* initialize alias database */ X! initaliases(TRUE); X exit(EX_OK); X X case MD_DAEMON: X*************** X*** 505,511 **** X X default: X /* open the alias database */ X! initaliases(AliasFile, FALSE); X break; X } X X--- 531,537 ---- X X default: X /* open the alias database */ X! initaliases(FALSE); X break; X } X X*************** X*** 521,529 **** X X if (m == NULL) X continue; X! printf("mailer %d (%s): P=%s S=%d R=%d M=%ld F=", i, m->m_name, X! m->m_mailer, m->m_s_rwset, m->m_r_rwset, X! m->m_maxsize); X for (j = '\0'; j <= '\177'; j++) X if (bitnset(j, m->m_flags)) X (void) putchar(j); X--- 547,556 ---- X X if (m == NULL) X continue; X! printf("mailer %d (%s): P=%s S=%d/%d R=%d/%d M=%ld F=", X! i, m->m_name, m->m_mailer, X! m->m_se_rwset, m->m_sh_rwset, X! m->m_re_rwset, m->m_rh_rwset, m->m_maxsize); X for (j = '\0'; j <= '\177'; j++) X if (bitnset(j, m->m_flags)) X (void) putchar(j); X*************** X*** 550,555 **** X--- 577,583 ---- X char buf[MAXLINE]; X X printf("ADDRESS TEST MODE\nEnter <ruleset> <address>\n"); X+ printf("[Note: No initial ruleset 3 call]\n"); X for (;;) X { X register char **pvp; X*************** X*** 576,582 **** X pvp = prescan(++p, ',', pvpbuf); X if (pvp == NULL) X continue; X! rewrite(pvp, 3); X p = q; X while (*p != '\0') X { X--- 604,610 ---- X pvp = prescan(++p, ',', pvpbuf); X if (pvp == NULL) X continue; X! /* rewrite(pvp, 3); */ X p = q; X while (*p != '\0') X { X*************** X*** 654,661 **** X ** commands. This will never return. X */ X X! if (OpMode == MD_SMTP) X! smtp(); X # endif SMTP X X /* X--- 682,694 ---- X ** commands. This will never return. X */ X X! if (OpMode == MD_SMTP || OpMode == MD_BSMTP) { X! bool batched = (OpMode == MD_BSMTP); X! OpMode = MD_SMTP; X! /* have to run unbuffered or else will lose synchronization */ X! setbuf(InChannel, (char *) NULL); X! smtp(batched); X! } X # endif SMTP X X /* X*************** X*** 794,805 **** X ** initializes several macros to be themselves. X */ X X- struct metamac X- { X- char metaname; X- char metaval; X- }; X- X struct metamac MetaMacros[] = X { X /* LHS pattern matching characters */ X--- 827,832 ---- X*************** X*** 812,820 **** X /* the conditional operations */ X '?', CONDIF, '|', CONDELSE, '.', CONDFI, X X! /* and finally the hostname lookup characters */ X '[', HOSTBEGIN, ']', HOSTEND, X X '\0' X }; X X--- 839,855 ---- X /* the conditional operations */ X '?', CONDIF, '|', CONDELSE, '.', CONDFI, X X! /* and finally the hostname and database lookup characters */ X '[', HOSTBEGIN, ']', HOSTEND, X+ '(', KEYBEGIN, ')', KEYEND, X X+ #ifdef MACVALUE X+ /* run-time macro expansion, not at freeze time */ X+ '&', MACVALUE, X+ #endif X+ #ifdef QUOTE822 X+ '!', QUOTE822, /* quote next macro if RFC822 requires it */ X+ #endif X '\0' X }; X X*************** X*** 863,868 **** X--- 898,904 ---- X char *frzedata; /* address of edata */ X char *frzend; /* address of end */ X char frzver[252]; /* sendmail version */ X+ char frzdatecompiled[64]; /* sendmail compilation date */ X } frzinfo; X }; X X*************** X*** 874,879 **** X--- 910,916 ---- X extern char edata, end; X extern char *sbrk(); X extern char Version[]; X+ extern char datecompiled[]; X X if (freezefile == NULL) X return; X*************** X*** 893,898 **** X--- 930,936 ---- X fhdr.frzinfo.frzedata = &edata; X fhdr.frzinfo.frzend = &end; X (void) strcpy(fhdr.frzinfo.frzver, Version); X+ (void) strcpy(fhdr.frzinfo.frzdatecompiled, datecompiled); X X /* write out the freeze header */ X if (write(f, (char *) &fhdr, sizeof fhdr) != sizeof fhdr || X*************** X*** 926,931 **** X--- 964,970 ---- X union frz fhdr; X extern char edata, end; X extern char Version[]; X+ extern char datecompiled[]; X extern caddr_t brk(); X X if (freezefile == NULL) X*************** X*** 943,949 **** X if (read(f, (char *) &fhdr, sizeof fhdr) < sizeof fhdr || X fhdr.frzinfo.frzedata != &edata || X fhdr.frzinfo.frzend != &end || X! strcmp(fhdr.frzinfo.frzver, Version) != 0) X { X (void) close(f); X return (FALSE); X--- 982,989 ---- X if (read(f, (char *) &fhdr, sizeof fhdr) < sizeof fhdr || X fhdr.frzinfo.frzedata != &edata || X fhdr.frzinfo.frzend != &end || X! strcmp(fhdr.frzinfo.frzver, Version) != 0 || X! strcmp(fhdr.frzinfo.frzdatecompiled, datecompiled) != 0) X { X (void) close(f); X return (FALSE); X*************** X*** 1010,1016 **** X X /* we can't communicate with our caller, so.... */ X HoldErrs = TRUE; X! ErrorMode = EM_MAIL; X Verbose = FALSE; X X /* all input from /dev/null */ X--- 1050,1056 ---- X X /* we can't communicate with our caller, so.... */ X HoldErrs = TRUE; X! setoption('e', "m", TRUE, TRUE); X Verbose = FALSE; X X /* all input from /dev/null */ END_OF_ida/patches/main.c.diff if test 8294 -ne `wc -c <ida/patches/main.c.diff`; then echo shar: \"ida/patches/main.c.diff\" unpacked with wrong size! fi # end of overwriting check fi if test -f ida/patches/recipient.c.diff -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ida/patches/recipient.c.diff\" else echo shar: Extracting \"ida/patches/recipient.c.diff\" \(5359 characters\) sed "s/^X//" >ida/patches/recipient.c.diff <<'END_OF_ida/patches/recipient.c.diff' X*** recipient.c.orig Mon Mar 14 05:31:54 1988 X--- recipient.c Wed Aug 24 16:44:19 1988 X*************** X*** 306,311 **** X--- 306,312 ---- X if (pw == NULL) X { X a->q_flags |= QBADADDR; X+ errno = 0; /* no special error */ X giveresponse(EX_NOUSER, m, CurEnv); X } X else X*************** X*** 351,356 **** X--- 352,360 ---- X ** may modify name. X */ X X+ #define WORST_MATCH -2 /* even worse than no match */ X+ #define NO_UID -999 /* any "impossible" uid will do */ X+ X struct passwd * X finduser(name) X char *name; X*************** X*** 357,365 **** X--- 361,374 ---- X { X register struct passwd *pw; X register char *p; X+ int best_match = WORST_MATCH; X+ int best_uid = NO_UID; X extern struct passwd *getpwent(); X extern struct passwd *getpwnam(); X+ extern struct passwd *getpwuid(); X X+ errno = 0; X+ X /* map upper => lower case */ X for (p = name; *p != '\0'; p++) X { X*************** X*** 367,395 **** X *p = tolower(*p); X } X X /* look up this login name using fast path */ X if ((pw = getpwnam(name)) != NULL) X return (pw); X X! /* search for a matching full name instead */ X! for (p = name; *p != '\0'; p++) X! { X! if (*p == (SpaceSub & 0177) || *p == '_') X! *p = ' '; X! } X (void) setpwent(); X while ((pw = getpwent()) != NULL) X { X char buf[MAXNAME]; X X! buildfname(pw->pw_gecos, pw->pw_name, buf); X! if (index(buf, ' ') != NULL && !strcasecmp(buf, name)) X! { X! message(Arpa_Info, "sending to login name %s", pw->pw_name); X! return (pw); X } X } X! return (NULL); X } X /* X ** WRITABLE -- predicate returning if the file is writable. X--- 376,521 ---- X *p = tolower(*p); X } X X+ # ifdef DEBUG X+ if (tTd(26, 6)) X+ printf("%s password entry for \"%s\"\n", X+ getpwnam(name) ? "found" : "can't find", name); X+ # endif DEBUG X+ X /* look up this login name using fast path */ X if ((pw = getpwnam(name)) != NULL) X return (pw); X X! # ifdef DEBUG X! if (tTd(26, 6)) X! printf("looking for partial match to \"%s\"\n", name); X! # endif DEBUG X (void) setpwent(); X while ((pw = getpwent()) != NULL) X { X char buf[MAXNAME]; X+ register int this_match; X X! if (strcasecmp(pw->pw_name, name) == 0) { X! # ifdef DEBUG X! if (tTd(26, 6)) X! printf("found password entry for \"%s\" as \"%s\"\n", X! name, pw->pw_name); X! # endif DEBUG X! return (pw); X } X+ X+ buildfname(pw->pw_gecos, pw->pw_name, buf); X+ this_match = partialstring(buf, name); X+ # ifdef DEBUG X+ if (tTd(26, 6 && this_match >= 0)) X+ printf("matched on level %d with \"%s\"\n", X+ this_match, buf); X+ # endif DEBUG X+ if (this_match < best_match) X+ continue; X+ else if (this_match > best_match) { X+ best_match = this_match; X+ best_uid = pw->pw_uid; X+ } else if (best_uid != pw->pw_uid) X+ best_uid = NO_UID; X } X! # ifdef DEBUG X! if (tTd(26, 6)) X! if (best_match == WORST_MATCH) X! printf("no match, failing...\n"); X! else if (best_uid == NO_UID) X! printf("ambiguous match, failing...\n"); X! else X! printf("succeding on level %d...\n", X! best_match); X! # endif DEBUG X! X! if (best_uid == NO_UID) X! return (NULL); X! X! pw = getpwuid(best_uid); X! message(Arpa_Info, "sending to login name %s", pw->pw_name); X! return (pw); X! } X! /* X! ** PARTIALSTRING -- is one string of words contained by another? X! ** X! ** See if one string of words can be found as part of X! ** another string of words. All substrings delimited by X! ** one or more non-alphanumeric characters are considered X! ** "words", and a partial match is such that all the words X! ** of the pattern string are either full prefixes X! ** of the target string. Upper or lower case letters are X! ** considered equal. X! ** X! ** Parameters: X! ** target -- target string X! ** pattern -- pattern string X! ** X! ** Returns: X! ** The number of fully matched words, or -1 if none. X! ** X! ** Side Effects: X! ** None. X! ** X! */ X! X! partialstring(target, pattern) X! char *target; X! char *pattern; X! { X! register char *t, *p, *q; X! int full_words = 0; X! X! /* skip initial delimiters */ X! for (t = target; *t != '\0' && !isalnum(*t); t++); X! for (p = pattern; *p != '\0' && !isalnum(*p); p++); X! q = p; X! X! while (*t != '\0' && *p != '\0') { X! /* X! * if at end of pattern word, find next, remember it, X! * and eat the current target word X! */ X! if (!isalnum(*p)) { X! while (*p != '\0' && !isalnum(*p)) p++; X! if (*p == '\0') X! continue; X! q = p; X! if (!isalnum(*t)) { X! full_words++; X! } X! while (*t != '\0' && isalnum(*t)) t++; X! while (*t != '\0' && !isalnum(*t)) t++; X! continue; X! } X! X! /* X! * if match, advance both pointers X! */ X! if ((isupper(*t) ? tolower(*t) : *t) == X! (isupper(*p) ? tolower(*p) : *p)) { X! t++, p++; X! continue; X! } X! X! /* X! * if no match, backtrack to last unmatched pattern word and X! * eat current target word X! */ X! p = q; X! while (*t != '\0' && isalnum(*t)) t++; X! while (*t != '\0' && !isalnum(*t)) t++; X! } X! X! /* X! * now, the pattern should be fully consumed if there was a match X! */ X! if (*p == '\0') X! return isalnum(*t) ? full_words : full_words + 1; X! else X! return -1; X } X /* X ** WRITABLE -- predicate returning if the file is writable. END_OF_ida/patches/recipient.c.diff if test 5359 -ne `wc -c <ida/patches/recipient.c.diff`; then echo shar: \"ida/patches/recipient.c.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\" \(7004 characters\) sed "s/^X//" >ida/patches/sendmail.h.diff <<'END_OF_ida/patches/sendmail.h.diff' X*** sendmail.h.orig Mon Mar 28 09:24:51 1988 X--- sendmail.h Fri Aug 26 03:59:10 1988 X*************** X*** 37,43 **** X # include "useful.h" X X # ifdef LOG X! # include <sys/syslog.h> X # endif LOG X X # ifdef DAEMON X--- 37,47 ---- 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*** 126,133 **** 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--- 130,139 ---- 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*** 135,140 **** X--- 141,147 ---- 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*** 152,157 **** X--- 159,165 ---- 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*** 249,254 **** X--- 257,265 ---- X #define EF_RESPONSE 000200 /* this is an error or return receipt */ X #define EF_RESENT 000400 /* this message is being forwarded */ X X+ /* special shadowing null for e_macro's */ X+ #define MACNULL ((char *) 1) /* don't check parent's value */ X+ X EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */ X /* X ** Message priority classes. X*************** X*** 322,331 **** 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--- 333,348 ---- 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+ /* other miscellaneous */ X+ # define MACVALUE '\016' /* delayed macro expansion $& */ X+ # define QUOTE822 '\015' /* quote next macro if RFC822 requires it */ X+ X /* \001 is also reserved as the macro expansion character */ X /* X ** Information about hosts that we have looked up recently. X*************** X*** 384,389 **** X--- 401,411 ---- 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 Suns */ 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*** 446,451 **** X--- 468,474 ---- X X X EXTERN char SendMode; /* send mode, see below */ X+ #define MD_BSMTP 'b' /* batched smtp mode */ X X #define SM_DELIVER 'i' /* interactive delivery */ X #define SM_QUICKD 'j' /* deliver w/o queueing */ X*************** X*** 470,475 **** X--- 493,537 ---- 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 *db_name; /* database file name */ X+ time_t db_mtime; /* last modify time */ X+ DBMFILE *db_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 opened */ X+ X+ # define DB_ALIAS '@' /* "name" of aliases database */ X+ # define AliasFile DbmTab[DB_ALIAS].db_name X+ # define AliasDbm DbmTab[DB_ALIAS].db_dbm X+ X+ # endif NDBM X+ #endif DBM X+ /* X ** Global variables. X */ X X*************** X*** 511,517 **** X--- 573,581 ---- X EXTERN int RefuseLA; /* load average refusing connections are */ X EXTERN int QueueFactor; /* slope of queue function */ X EXTERN time_t QueueIntvl; /* intervals between running the queue */ X+ #ifndef NDBM X EXTERN char *AliasFile; /* location of alias file */ X+ #endif !NDBM X EXTERN char *HelpFile; /* location of SMTP help file */ X EXTERN char *StatFile; /* location of statistics summary */ X EXTERN char *QueueDir; /* location of queue directory */ X*************** X*** 533,538 **** X--- 597,603 ---- X EXTERN int CheckPointLimit; /* deliveries before checkpointing */ X EXTERN int Nmx; /* number of MX RRs */ X EXTERN char *PostMasterCopy; /* address to get errs cc's */ X+ EXTERN bool SplitRewriting; /* use split envelope/header rewriting */ X EXTERN char *MxHosts[MAXMXHOSTS+1]; /* for MX RRs */ X EXTERN char *TrustedUsers[MAXTRUST+1]; /* list of trusted users */ X EXTERN char *UserEnviron[MAXUSERENVIRON+1]; /* saved user environment */ X*************** X*** 539,544 **** X--- 604,615 ---- X /* X ** Trace information X */ X+ #ifdef NDBM X+ EXTERN struct dbm_table DbmTab[128]; /* keyed database table */ X+ #ifdef YP X+ #define YPMARK '%' /* yellow pages indicator */ X+ #endif YP X+ #endif NDBM X X /* trace vector and macros for debugging flags */ X EXTERN u_char tTdvect[100]; X*************** X*** 579,581 **** X--- 650,664 ---- 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 7004 -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 8\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. echo "See ida/README and ida/INSTALL for further directions." 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 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.