summaryrefslogtreecommitdiffstats
path: root/usr.bin/mail/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/mail/send.c')
-rw-r--r--usr.bin/mail/send.c556
1 files changed, 0 insertions, 556 deletions
diff --git a/usr.bin/mail/send.c b/usr.bin/mail/send.c
deleted file mode 100644
index c8b8fea..0000000
--- a/usr.bin/mail/send.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * Copyright (c) 1980, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)send.c 8.1 (Berkeley) 6/6/93";
-#endif /* not lint */
-
-#include "rcv.h"
-#include "extern.h"
-
-/*
- * Mail -- a mail program
- *
- * Mail to others.
- */
-
-/*
- * Send message described by the passed pointer to the
- * passed output buffer. Return -1 on error.
- * Adjust the status: field if need be.
- * If doign is given, suppress ignored header fields.
- * prefix is a string to prepend to each output line.
- */
-int
-send(mp, obuf, doign, prefix)
- register struct message *mp;
- FILE *obuf;
- struct ignoretab *doign;
- char *prefix;
-{
- long count;
- register FILE *ibuf;
- char line[LINESIZE];
- int ishead, infld, ignoring, dostat, firstline;
- register char *cp, *cp2;
- register int c;
- int length;
- int prefixlen;
-
- /*
- * Compute the prefix string, without trailing whitespace
- */
- if (prefix != NOSTR) {
- cp2 = 0;
- for (cp = prefix; *cp; cp++)
- if (*cp != ' ' && *cp != '\t')
- cp2 = cp;
- prefixlen = cp2 == 0 ? 0 : cp2 - prefix + 1;
- }
- ibuf = setinput(mp);
- count = mp->m_size;
- ishead = 1;
- dostat = doign == 0 || !isign("status", doign);
- infld = 0;
- firstline = 1;
- /*
- * Process headers first
- */
- while (count > 0 && ishead) {
- if (fgets(line, LINESIZE, ibuf) == NULL)
- break;
- count -= length = strlen(line);
- if (firstline) {
- /*
- * First line is the From line, so no headers
- * there to worry about
- */
- firstline = 0;
- ignoring = doign == ignoreall;
- } else if (line[0] == '\n') {
- /*
- * If line is blank, we've reached end of
- * headers, so force out status: field
- * and note that we are no longer in header
- * fields
- */
- if (dostat) {
- statusput(mp, obuf, prefix);
- dostat = 0;
- }
- ishead = 0;
- ignoring = doign == ignoreall;
- } else if (infld && (line[0] == ' ' || line[0] == '\t')) {
- /*
- * If this line is a continuation (via space or tab)
- * of a previous header field, just echo it
- * (unless the field should be ignored).
- * In other words, nothing to do.
- */
- } else {
- /*
- * Pick up the header field if we have one.
- */
- for (cp = line; (c = *cp++) && c != ':' && !isspace(c);)
- ;
- cp2 = --cp;
- while (isspace(*cp++))
- ;
- if (cp[-1] != ':') {
- /*
- * Not a header line, force out status:
- * This happens in uucp style mail where
- * there are no headers at all.
- */
- if (dostat) {
- statusput(mp, obuf, prefix);
- dostat = 0;
- }
- if (doign != ignoreall)
- /* add blank line */
- (void) putc('\n', obuf);
- ishead = 0;
- ignoring = 0;
- } else {
- /*
- * If it is an ignored field and
- * we care about such things, skip it.
- */
- *cp2 = 0; /* temporarily null terminate */
- if (doign && isign(line, doign))
- ignoring = 1;
- else if ((line[0] == 's' || line[0] == 'S') &&
- strcasecmp(line, "status") == 0) {
- /*
- * If the field is "status," go compute
- * and print the real Status: field
- */
- if (dostat) {
- statusput(mp, obuf, prefix);
- dostat = 0;
- }
- ignoring = 1;
- } else {
- ignoring = 0;
- *cp2 = c; /* restore */
- }
- infld = 1;
- }
- }
- if (!ignoring) {
- /*
- * Strip trailing whitespace from prefix
- * if line is blank.
- */
- if (prefix != NOSTR)
- if (length > 1)
- fputs(prefix, obuf);
- else
- (void) fwrite(prefix, sizeof *prefix,
- prefixlen, obuf);
- (void) fwrite(line, sizeof *line, length, obuf);
- if (ferror(obuf))
- return -1;
- }
- }
- /*
- * Copy out message body
- */
- if (doign == ignoreall)
- count--; /* skip final blank line */
- if (prefix != NOSTR)
- while (count > 0) {
- if (fgets(line, LINESIZE, ibuf) == NULL) {
- c = 0;
- break;
- }
- count -= c = strlen(line);
- /*
- * Strip trailing whitespace from prefix
- * if line is blank.
- */
- if (c > 1)
- fputs(prefix, obuf);
- else
- (void) fwrite(prefix, sizeof *prefix,
- prefixlen, obuf);
- (void) fwrite(line, sizeof *line, c, obuf);
- if (ferror(obuf))
- return -1;
- }
- else
- while (count > 0) {
- c = count < LINESIZE ? count : LINESIZE;
- if ((c = fread(line, sizeof *line, c, ibuf)) <= 0)
- break;
- count -= c;
- if (fwrite(line, sizeof *line, c, obuf) != c)
- return -1;
- }
- if (doign == ignoreall && c > 0 && line[c - 1] != '\n')
- /* no final blank line */
- if ((c = getc(ibuf)) != EOF && putc(c, obuf) == EOF)
- return -1;
- return 0;
-}
-
-/*
- * Output a reasonable looking status field.
- */
-void
-statusput(mp, obuf, prefix)
- register struct message *mp;
- FILE *obuf;
- char *prefix;
-{
- char statout[3];
- register char *cp = statout;
-
- if (mp->m_flag & MREAD)
- *cp++ = 'R';
- if ((mp->m_flag & MNEW) == 0)
- *cp++ = 'O';
- *cp = 0;
- if (statout[0])
- fprintf(obuf, "%sStatus: %s\n",
- prefix == NOSTR ? "" : prefix, statout);
-}
-
-/*
- * Interface between the argument list and the mail1 routine
- * which does all the dirty work.
- */
-int
-mail(to, cc, bcc, smopts, subject)
- struct name *to, *cc, *bcc, *smopts;
- char *subject;
-{
- struct header head;
-
- head.h_to = to;
- head.h_subject = subject;
- head.h_cc = cc;
- head.h_bcc = bcc;
- head.h_smopts = smopts;
- mail1(&head, 0);
- return(0);
-}
-
-
-/*
- * Send mail to a bunch of user names. The interface is through
- * the mail routine below.
- */
-int
-sendmail(str)
- char *str;
-{
- struct header head;
-
- head.h_to = extract(str, GTO);
- head.h_subject = NOSTR;
- head.h_cc = NIL;
- head.h_bcc = NIL;
- head.h_smopts = NIL;
- mail1(&head, 0);
- return(0);
-}
-
-/*
- * Mail a message on standard input to the people indicated
- * in the passed header. (Internal interface).
- */
-void
-mail1(hp, printheaders)
- struct header *hp;
- int printheaders;
-{
- char *cp;
- int pid;
- char **namelist;
- struct name *to;
- FILE *mtf;
-
- /*
- * Collect user's mail from standard input.
- * Get the result as mtf.
- */
- if ((mtf = collect(hp, printheaders)) == NULL)
- return;
- if (value("interactive") != NOSTR)
- if (value("askcc") != NOSTR)
- grabh(hp, GCC);
- else {
- printf("EOT\n");
- (void) fflush(stdout);
- }
- if (fsize(mtf) == 0)
- if (hp->h_subject == NOSTR)
- printf("No message, no subject; hope that's ok\n");
- else
- printf("Null message body; hope that's ok\n");
- /*
- * Now, take the user names from the combined
- * to and cc lists and do all the alias
- * processing.
- */
- senderr = 0;
- to = usermap(cat(hp->h_bcc, cat(hp->h_to, hp->h_cc)));
- if (to == NIL) {
- printf("No recipients specified\n");
- senderr++;
- }
- /*
- * Look through the recipient list for names with /'s
- * in them which we write to as files directly.
- */
- to = outof(to, mtf, hp);
- if (senderr)
- savedeadletter(mtf);
- to = elide(to);
- if (count(to) == 0)
- goto out;
- fixhead(hp, to);
- if ((mtf = infix(hp, mtf)) == NULL) {
- fprintf(stderr, ". . . message lost, sorry.\n");
- return;
- }
- namelist = unpack(cat(hp->h_smopts, to));
- if (debug) {
- char **t;
-
- printf("Sendmail arguments:");
- for (t = namelist; *t != NOSTR; t++)
- printf(" \"%s\"", *t);
- printf("\n");
- goto out;
- }
- if ((cp = value("record")) != NOSTR)
- (void) savemail(expand(cp), mtf);
- /*
- * Fork, set up the temporary mail file as standard
- * input for "mail", and exec with the user list we generated
- * far above.
- */
- pid = fork();
- if (pid == -1) {
- perror("fork");
- savedeadletter(mtf);
- goto out;
- }
- if (pid == 0) {
- prepare_child(sigmask(SIGHUP)|sigmask(SIGINT)|sigmask(SIGQUIT)|
- sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU),
- fileno(mtf), -1);
- if ((cp = value("sendmail")) != NOSTR)
- cp = expand(cp);
- else
- cp = _PATH_SENDMAIL;
- execv(cp, namelist);
- perror(cp);
- _exit(1);
- }
- if (value("verbose") != NOSTR)
- (void) wait_child(pid);
- else
- free_child(pid);
-out:
- (void) Fclose(mtf);
-}
-
-/*
- * Fix the header by glopping all of the expanded names from
- * the distribution list into the appropriate fields.
- */
-void
-fixhead(hp, tolist)
- struct header *hp;
- struct name *tolist;
-{
- register struct name *np;
-
- hp->h_to = NIL;
- hp->h_cc = NIL;
- hp->h_bcc = NIL;
- for (np = tolist; np != NIL; np = np->n_flink)
- if ((np->n_type & GMASK) == GTO)
- hp->h_to =
- cat(hp->h_to, nalloc(np->n_name, np->n_type));
- else if ((np->n_type & GMASK) == GCC)
- hp->h_cc =
- cat(hp->h_cc, nalloc(np->n_name, np->n_type));
- else if ((np->n_type & GMASK) == GBCC)
- hp->h_bcc =
- cat(hp->h_bcc, nalloc(np->n_name, np->n_type));
-}
-
-/*
- * Prepend a header in front of the collected stuff
- * and return the new file.
- */
-FILE *
-infix(hp, fi)
- struct header *hp;
- FILE *fi;
-{
- extern char tempMail[];
- register FILE *nfo, *nfi;
- register int c;
-
- if ((nfo = Fopen(tempMail, "w")) == NULL) {
- perror(tempMail);
- return(fi);
- }
- if ((nfi = Fopen(tempMail, "r")) == NULL) {
- perror(tempMail);
- (void) Fclose(nfo);
- return(fi);
- }
- (void) rm(tempMail);
- (void) puthead(hp, nfo, GTO|GSUBJECT|GCC|GBCC|GNL|GCOMMA);
- c = getc(fi);
- while (c != EOF) {
- (void) putc(c, nfo);
- c = getc(fi);
- }
- if (ferror(fi)) {
- perror("read");
- rewind(fi);
- return(fi);
- }
- (void) fflush(nfo);
- if (ferror(nfo)) {
- perror(tempMail);
- (void) Fclose(nfo);
- (void) Fclose(nfi);
- rewind(fi);
- return(fi);
- }
- (void) Fclose(nfo);
- (void) Fclose(fi);
- rewind(nfi);
- return(nfi);
-}
-
-/*
- * Dump the to, subject, cc header on the
- * passed file buffer.
- */
-int
-puthead(hp, fo, w)
- struct header *hp;
- FILE *fo;
- int w;
-{
- register int gotcha;
-
- gotcha = 0;
- if (hp->h_to != NIL && w & GTO)
- fmt("To:", hp->h_to, fo, w&GCOMMA), gotcha++;
- if (hp->h_subject != NOSTR && w & GSUBJECT)
- fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++;
- if (hp->h_cc != NIL && w & GCC)
- fmt("Cc:", hp->h_cc, fo, w&GCOMMA), gotcha++;
- if (hp->h_bcc != NIL && w & GBCC)
- fmt("Bcc:", hp->h_bcc, fo, w&GCOMMA), gotcha++;
- if (gotcha && w & GNL)
- (void) putc('\n', fo);
- return(0);
-}
-
-/*
- * Format the given header line to not exceed 72 characters.
- */
-void
-fmt(str, np, fo, comma)
- char *str;
- register struct name *np;
- FILE *fo;
- int comma;
-{
- register col, len;
-
- comma = comma ? 1 : 0;
- col = strlen(str);
- if (col)
- fputs(str, fo);
- for (; np != NIL; np = np->n_flink) {
- if (np->n_flink == NIL)
- comma = 0;
- len = strlen(np->n_name);
- col++; /* for the space */
- if (col + len + comma > 72 && col > 4) {
- fputs("\n ", fo);
- col = 4;
- } else
- putc(' ', fo);
- fputs(np->n_name, fo);
- if (comma)
- putc(',', fo);
- col += len + comma;
- }
- putc('\n', fo);
-}
-
-/*
- * Save the outgoing mail on the passed file.
- */
-
-/*ARGSUSED*/
-int
-savemail(name, fi)
- char name[];
- register FILE *fi;
-{
- register FILE *fo;
- char buf[BUFSIZ];
- register i;
- time_t now, time();
- char *ctime();
-
- if ((fo = Fopen(name, "a")) == NULL) {
- perror(name);
- return (-1);
- }
- (void) time(&now);
- fprintf(fo, "From %s %s", myname, ctime(&now));
- while ((i = fread(buf, 1, sizeof buf, fi)) > 0)
- (void) fwrite(buf, 1, i, fo);
- (void) putc('\n', fo);
- (void) fflush(fo);
- if (ferror(fo))
- perror(name);
- (void) Fclose(fo);
- rewind(fi);
- return (0);
-}
OpenPOWER on IntegriCloud