Print this page
5166 sendmail package should be replaceable
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Toomas Soome <tsoome@me.com>

*** 36,47 **** * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ - #pragma ident "%Z%%M% %I% %E% SMI" - /* * mailx -- a modified version of a University of California at Berkeley * mail program * * Handle name lists. --- 36,45 ----
*** 51,62 **** #include <locale.h> static struct name *nalloc(char str[]); static int isfileaddr(char *name); static int lengthof(struct name *name); ! static struct name *gexpand(struct name *nlist, struct grouphead *gh, int metoo, int arg_ntype); ! static char *norm(register char *user, register char *ubuf, int nbangs); static struct name *put(struct name *list, struct name *node); /* * Allocate a single element of a name list, * initialize its name field to the passed --- 49,62 ---- #include <locale.h> static struct name *nalloc(char str[]); static int isfileaddr(char *name); static int lengthof(struct name *name); ! static struct name *gexpand(struct name *nlist, struct grouphead *gh, ! int metoo, int arg_ntype); ! static char *norm(register char *user, register char *ubuf, ! int nbangs); static struct name *put(struct name *list, struct name *node); /* * Allocate a single element of a name list, * initialize its name field to the passed
*** 66,82 **** static struct name * nalloc(char str[]) { register struct name *np; ! np = (struct name *) salloc(sizeof *np); np->n_flink = NIL; np->n_blink = NIL; np->n_type = -1; np->n_full = savestr(str); np->n_name = skin(np->n_full); ! return(np); } /* * Find the tail of a list and return it. */ --- 66,82 ---- static struct name * nalloc(char str[]) { register struct name *np; ! np = (struct name *)salloc(sizeof (*np)); np->n_flink = NIL; np->n_blink = NIL; np->n_type = -1; np->n_full = savestr(str); np->n_name = skin(np->n_full); ! return (np); } /* * Find the tail of a list and return it. */
*** 86,99 **** { register struct name *np; np = name; if (np == NIL) ! return(NIL); while (np->n_flink != NIL) np = np->n_flink; ! return(np); } /* * Extract a list of names from a line, * and make a list of names from it. --- 86,99 ---- { register struct name *np; np = name; if (np == NIL) ! return (NIL); while (np->n_flink != NIL) np = np->n_flink; ! return (np); } /* * Extract a list of names from a line, * and make a list of names from it.
*** 108,118 **** register struct name *top, *np, *t; char nbuf[BUFSIZ], abuf[BUFSIZ]; int comma; if (line == NOSTR || strlen(line) == 0) ! return(NIL); comma = docomma(line); top = NIL; np = NIL; cp = line; while ((cp = yankword(cp, nbuf, sizeof (nbuf), comma)) != NOSTR) { --- 108,118 ---- register struct name *top, *np, *t; char nbuf[BUFSIZ], abuf[BUFSIZ]; int comma; if (line == NOSTR || strlen(line) == 0) ! return (NIL); comma = docomma(line); top = NIL; np = NIL; cp = line; while ((cp = yankword(cp, nbuf, sizeof (nbuf), comma)) != NOSTR) {
*** 136,146 **** else np->n_flink = t; t->n_blink = np; np = t; } ! return(top); } /* * Turn a list of names into a string of the same names. */ --- 136,146 ---- else np->n_flink = t; t->n_blink = np; np = t; } ! return (top); } /* * Turn a list of names into a string of the same names. */
*** 151,193 **** register int s; register char *cp, *top; register struct name *p; if (np == NIL) ! return(NOSTR); s = 0; for (p = np; p != NIL; p = p->n_flink) { ! if ((ntype && (p->n_type & GMASK) != ntype) ! || (p->n_type & GDEL)) continue; s += strlen(p->n_full) + 2; } if (s == 0) ! return(NOSTR); top = (char *)salloc((unsigned)(++s)); cp = top; for (p = np; p != NIL; p = p->n_flink) { ! if ((ntype && (p->n_type & GMASK) != ntype) ! || (p->n_type & GDEL)) continue; cp = copy(p->n_full, cp); *cp++ = ','; *cp++ = ' '; } *cp = 0; ! return(top); } struct name * outpre(struct name *to) { register struct name *np; for (np = to; np; np = np->n_flink) if (isfileaddr(np->n_name)) np->n_type |= GDEL; ! return to; } /* * For each recipient in the passed name list with a / * in the name, append the message to the end of the named file --- 151,193 ---- register int s; register char *cp, *top; register struct name *p; if (np == NIL) ! return (NOSTR); s = 0; for (p = np; p != NIL; p = p->n_flink) { ! if ((ntype && (p->n_type & GMASK) != ntype) || ! (p->n_type & GDEL)) continue; s += strlen(p->n_full) + 2; } if (s == 0) ! return (NOSTR); top = (char *)salloc((unsigned)(++s)); cp = top; for (p = np; p != NIL; p = p->n_flink) { ! if ((ntype && (p->n_type & GMASK) != ntype) || ! (p->n_type & GDEL)) continue; cp = copy(p->n_full, cp); *cp++ = ','; *cp++ = ' '; } *cp = 0; ! return (top); } struct name * outpre(struct name *to) { register struct name *np; for (np = to; np; np = np->n_flink) if (isfileaddr(np->n_name)) np->n_type |= GDEL; ! return (to); } /* * For each recipient in the passed name list with a / * in the name, append the message to the end of the named file
*** 280,303 **** sigset(SIGQUIT, SIG_IGN); close(0); dup(image); close(image); lseek(0, 0L, 0); ! if ((shell = value("SHELL")) == NOSTR || *shell=='\0') shell = SHELL; ! (void) execlp(shell, shell, "-c", fname, (char *)0); perror(shell); exit(1); break; case (pid_t)-1: perror("fork"); senderr++; goto cant; } ! } ! else { if ((fout = fopen(fname, "a")) == NULL) { perror(fname); senderr++; goto cant; } --- 280,304 ---- sigset(SIGQUIT, SIG_IGN); close(0); dup(image); close(image); lseek(0, 0L, 0); ! if ((shell = value("SHELL")) == NOSTR || ! *shell == '\0') shell = SHELL; ! (void) execlp(shell, shell, "-c", fname, ! (char *)0); perror(shell); exit(1); break; case (pid_t)-1: perror("fork"); senderr++; goto cant; } ! } else { if ((fout = fopen(fname, "a")) == NULL) { perror(fname); senderr++; goto cant; }
*** 310,321 **** goto cant; } rewind(fin); #ifdef preSVr4 putc(getc(fin), fout); ! while (fgets(line, sizeof line, fin)) { ! if (!strncmp(line, "From ", 5)) putc('>', fout); fputs(line, fout); } #else while ((c = getc(fin)) != EOF) --- 311,322 ---- goto cant; } rewind(fin); #ifdef preSVr4 putc(getc(fin), fout); ! while (fgets(line, sizeof (line), fin)) { ! if (strncmp(line, "From ", 5) == 0) putc('>', fout); fputs(line, fout); } #else while ((c = getc(fin)) != EOF)
*** 359,369 **** } if (image >= 0) { close(image); image = -1; } ! return(nout); } /* * Determine if the passed address is a local "send to file" address. * If any of the network metacharacters precedes any slashes, it can't --- 360,370 ---- } if (image >= 0) { close(image); image = -1; } ! return (nout); } /* * Determine if the passed address is a local "send to file" address. * If any of the network metacharacters precedes any slashes, it can't
*** 376,399 **** { register char *cp; char *fcc = value("fcc"); if (any('@', name)) ! return(0); if (*name == '+') ! return(1); if (fcc == NOSTR) ! return(0); for (cp = name; *cp; cp++) { if (*cp == '.') continue; if (any(*cp, metanet)) ! return(0); if (*cp == '/') ! return(1); } ! return(0); } /* * Map all of the aliased users in the invoker's mailrc * file and insert them into the list. --- 377,400 ---- { register char *cp; char *fcc = value("fcc"); if (any('@', name)) ! return (0); if (*name == '+') ! return (1); if (fcc == NOSTR) ! return (0); for (cp = name; *cp; cp++) { if (*cp == '.') continue; if (any(*cp, metanet)) ! return (0); if (*cp == '/') ! return (1); } ! return (0); } /* * Map all of the aliased users in the invoker's mailrc * file and insert them into the list.
*** 424,434 **** newnames = gexpand(newnames, gh, metoo, np->n_type); else newnames = put(newnames, np); np = cp; } ! return(newnames); } /* * Recursively expand a group name. We limit the expansion to some * fixed level to keep things from going haywire. --- 425,435 ---- newnames = gexpand(newnames, gh, metoo, np->n_type); else newnames = put(newnames, np); np = cp; } ! return (newnames); } /* * Recursively expand a group name. We limit the expansion to some * fixed level to keep things from going haywire.
*** 446,456 **** register char *cp; if (depth > MAXEXP) { printf(gettext("Expanding alias to depth larger than %d\n"), MAXEXP); ! return(nlist); } depth++; for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) { cp = gp->ge_name; if (*cp == '\\') --- 447,457 ---- register char *cp; if (depth > MAXEXP) { printf(gettext("Expanding alias to depth larger than %d\n"), MAXEXP); ! return (nlist); } depth++; for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) { cp = gp->ge_name; if (*cp == '\\')
*** 474,484 **** np->n_type |= GDEL; skip: nlist = put(nlist, np); } depth--; ! return(nlist); } /* * Normalize a network name for comparison purposes. */ --- 475,485 ---- np->n_type |= GDEL; skip: nlist = put(nlist, np); } depth--; ! return (nlist); } /* * Normalize a network name for comparison purposes. */
*** 486,506 **** norm(register char *user, register char *ubuf, int nbangs) { register char *cp; int inubuf = 0; ! while (*user++ == '!'); user--; if (!strchr(user, '!')) { snprintf(ubuf, BUFSIZ, "%s!%s", host, user); user = ubuf; inubuf++; } if (nbangs) { cp = user + strlen(user); while (nbangs--) ! while (cp > user && *--cp != '!'); user = (cp > user) ? ++cp : cp; /* * Now strip off all Internet-type * hosts. */ --- 487,509 ---- norm(register char *user, register char *ubuf, int nbangs) { register char *cp; int inubuf = 0; ! while (*user++ == '!') ! ; user--; if (!strchr(user, '!')) { snprintf(ubuf, BUFSIZ, "%s!%s", host, user); user = ubuf; inubuf++; } if (nbangs) { cp = user + strlen(user); while (nbangs--) ! while (cp > user && *--cp != '!') ! ; user = (cp > user) ? ++cp : cp; /* * Now strip off all Internet-type * hosts. */
*** 513,534 **** user = ubuf; } else *cp = '\0'; } } ! return user; } /* * Implement allnet options. */ int samebody(register char *user, register char *addr, int fuzzy) { char ubuf[BUFSIZ], abuf[BUFSIZ]; char *allnet = value("allnet"); ! int nbangs = allnet ? !strcmp(allnet, "uucp") ? 2 : 1 : 0; if (fuzzy && value("fuzzymatch")) { int i; (void) strlcpy(ubuf, user, BUFSIZ); --- 516,537 ---- user = ubuf; } else *cp = '\0'; } } ! return (user); } /* * Implement allnet options. */ int samebody(register char *user, register char *addr, int fuzzy) { char ubuf[BUFSIZ], abuf[BUFSIZ]; char *allnet = value("allnet"); ! int nbangs = allnet ? (strcmp(allnet, "uucp") == 0) ? 2 : 1 : 0; if (fuzzy && value("fuzzymatch")) { int i; (void) strlcpy(ubuf, user, BUFSIZ);
*** 539,549 **** abuf[i] = tolower(abuf[i]); return (strstr(abuf, ubuf) != NOSTR); } user = norm(user, ubuf, nbangs); addr = norm(addr, abuf, nbangs); ! return strcmp(user, addr) == 0; } /* * Compute the length of the passed name list and * return it. --- 542,552 ---- abuf[i] = tolower(abuf[i]); return (strstr(abuf, ubuf) != NOSTR); } user = norm(user, ubuf, nbangs); addr = norm(addr, abuf, nbangs); ! return (strcmp(user, addr) == 0); } /* * Compute the length of the passed name list and * return it.
*** 554,564 **** register struct name *np; register int c; for (c = 0, np = name; np != NIL; c++, np = np->n_flink) ; ! return(c); } /* * Concatenate the two passed name lists, return the result. */ --- 557,567 ---- register struct name *np; register int c; for (c = 0, np = name; np != NIL; c++, np = np->n_flink) ; ! return (c); } /* * Concatenate the two passed name lists, return the result. */
*** 567,583 **** cat(struct name *n1, struct name *n2) { register struct name *tail; if (n1 == NIL) ! return(n2); if (n2 == NIL) ! return(n1); tail = tailof(n1); tail->n_flink = n2; n2->n_blink = tail; ! return(n1); } /* * Unpack the name list onto a vector of strings. * Return an error if the name list won't fit. --- 570,586 ---- cat(struct name *n1, struct name *n2) { register struct name *tail; if (n1 == NIL) ! return (n2); if (n2 == NIL) ! return (n1); tail = tailof(n1); tail->n_flink = n2; n2->n_blink = tail; ! return (n1); } /* * Unpack the name list onto a vector of strings. * Return an error if the name list won't fit.
*** 605,654 **** extra = 2; if (rflag != NOSTR) extra += 2; - #ifdef SENDMAIL extra++; metoo = value("metoo") != NOSTR; if (metoo) extra++; verbose = value("verbose") != NOSTR; if (verbose) extra++; if (hflag) extra += 2; ! #endif /* SENDMAIL */ ! top = (char **) salloc((t + extra) * sizeof (char *)); ap = top; ! *ap++ = "mail"; if (rflag != NOSTR) { *ap++ = "-r"; *ap++ = rflag; } - #ifdef SENDMAIL *ap++ = "-i"; if (metoo) *ap++ = "-m"; if (verbose) *ap++ = "-v"; if (hflag) { *ap++ = "-h"; snprintf(hbuf, sizeof (hbuf), "%d", hflag); *ap++ = savestr(hbuf); } - #endif /* SENDMAIL */ while (n != NIL) { if (n->n_type & GDEL) { n = n->n_flink; continue; } *ap++ = n->n_name; n = n->n_flink; } *ap = NOSTR; ! return(top); } /* * See if the user named himself as a destination * for outgoing mail. If so, set the global flag --- 608,653 ---- extra = 2; if (rflag != NOSTR) extra += 2; extra++; metoo = value("metoo") != NOSTR; if (metoo) extra++; verbose = value("verbose") != NOSTR; if (verbose) extra++; if (hflag) extra += 2; ! top = (char **)salloc((t + extra) * sizeof (char *)); ap = top; ! *ap++ = "sendmail"; if (rflag != NOSTR) { *ap++ = "-r"; *ap++ = rflag; } *ap++ = "-i"; if (metoo) *ap++ = "-m"; if (verbose) *ap++ = "-v"; if (hflag) { *ap++ = "-h"; snprintf(hbuf, sizeof (hbuf), "%d", hflag); *ap++ = savestr(hbuf); } while (n != NIL) { if (n->n_type & GDEL) { n = n->n_flink; continue; } *ap++ = n->n_name; n = n->n_flink; } *ap = NOSTR; ! return (top); } /* * See if the user named himself as a destination * for outgoing mail. If so, set the global flag
*** 679,689 **** { register struct name *np, *t, *newnames; struct name *x; if (names == NIL) ! return(NIL); newnames = names; np = names; np = np->n_flink; if (np != NIL) np->n_blink = NIL; --- 678,688 ---- { register struct name *np, *t, *newnames; struct name *x; if (names == NIL) ! return (NIL); newnames = names; np = names; np = np->n_flink; if (np != NIL) np->n_blink = NIL;
*** 750,760 **** while (np != NIL) { int type; t = np; type = np->n_type; ! while (t->n_flink!=NIL && strcmp(np->n_name, t->n_flink->n_name) == 0) { t = t->n_flink; /* "To" before "Cc" before "Bcc" */ if (t->n_type < type) type = t->n_type; --- 749,759 ---- while (np != NIL) { int type; t = np; type = np->n_type; ! while (t->n_flink != NIL && strcmp(np->n_name, t->n_flink->n_name) == 0) { t = t->n_flink; /* "To" before "Cc" before "Bcc" */ if (t->n_type < type) type = t->n_type;
*** 773,783 **** if (t->n_flink != NIL) t->n_flink->n_blink = np; np->n_type = type; np = np->n_flink; } ! return(newnames); } /* * Put another node onto a list of names and return * the list. --- 772,782 ---- if (t->n_flink != NIL) t->n_flink->n_blink = np; np->n_type = type; np = np->n_flink; } ! return (newnames); } /* * Put another node onto a list of names and return * the list.
*** 788,798 **** { node->n_flink = list; node->n_blink = NIL; if (list != NIL) list->n_blink = node; ! return(node); } /* * Delete the given name from a namelist. --- 787,797 ---- { node->n_flink = list; node->n_blink = NIL; if (list != NIL) list->n_blink = node; ! return (node); } /* * Delete the given name from a namelist.
*** 816,826 **** continue; } p->n_blink->n_flink = p->n_flink; p->n_flink->n_blink = p->n_blink; } ! return(np); } /* * Call the given routine on each element of the name * list, replacing said value if need be. --- 815,825 ---- continue; } p->n_blink->n_flink = p->n_flink; p->n_flink->n_blink = p->n_blink; } ! return (np); } /* * Call the given routine on each element of the name * list, replacing said value if need be.