not strings; h_seq deleted; now understands <...> addresses; and many more.
should be much cleaner and somewhat faster.
SCCS-vsn: usr.bin/mail/names.c 5.9
SCCS-vsn: usr.bin/mail/collect.c 5.9
SCCS-vsn: usr.bin/mail/send.c 5.11
SCCS-vsn: usr.bin/mail/glob.h 5.10
SCCS-vsn: usr.bin/mail/tty.c 5.6
SCCS-vsn: usr.bin/mail/cmd3.c 5.11
SCCS-vsn: usr.bin/mail/main.c 5.15
SCCS-vsn: usr.bin/mail/def.h 5.11
-static char sccsid[] = "@(#)cmd3.c 5.10 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmd3.c 5.11 (Berkeley) %G%";
#endif /* notdef */
#include "rcv.h"
#endif /* notdef */
#include "rcv.h"
* Reply to a list of messages. Extract each name from the
* message header and send them off to mail1()
*/
* Reply to a list of messages. Extract each name from the
* message header and send them off to mail1()
*/
_respond(msgvec)
int *msgvec;
{
struct message *mp;
char *cp, *rcv, *replyto;
_respond(msgvec)
int *msgvec;
{
struct message *mp;
char *cp, *rcv, *replyto;
- char buf[2 * LINESIZE], **ap;
struct name *np;
struct header head;
struct name *np;
struct header head;
}
mp = &message[msgvec[0] - 1];
dot = mp;
}
mp = &message[msgvec[0] - 1];
dot = mp;
- rcv = NOSTR;
- cp = skin(nameof(mp, 1));
- if (cp != NOSTR)
- rcv = cp;
- cp = skin(hfield("from", mp));
- if (cp != NOSTR)
- rcv = cp;
- replyto = skin(hfield("reply-to", mp));
- strcpy(buf, "");
- if (replyto != NOSTR)
- strcpy(buf, replyto);
- else {
- cp = skin(hfield("to", mp));
- if (cp != NOSTR)
- strcpy(buf, cp);
- }
- np = elide(extract(buf, GTO));
+ if ((rcv = skin(hfield("from", mp))) == NOSTR)
+ rcv = skin(nameof(mp, 1));
+ if ((replyto = skin(hfield("reply-to", mp))) != NOSTR)
+ np = extract(replyto, GTO);
+ else if ((cp = skin(hfield("to", mp))) != NOSTR)
+ np = extract(cp, GTO);
+ else
+ np = NIL;
+ np = elide(np);
/*
* Delete my name from the reply list,
* and with it, all my alternate names.
/*
* Delete my name from the reply list,
* and with it, all my alternate names.
if (altnames)
for (ap = altnames; *ap; ap++)
np = delname(np, *ap, icequal);
if (altnames)
for (ap = altnames; *ap; ap++)
np = delname(np, *ap, icequal);
- head.h_seq = 1;
- cp = detract(np, 0);
- if (cp != NOSTR && replyto == NOSTR) {
- strcpy(buf, cp);
- strcat(buf, " ");
- strcat(buf, rcv);
- }
- else {
- if (cp == NOSTR && replyto != NOSTR)
+ if (np != NIL && replyto == NOSTR)
+ np = cat(np, extract(rcv, GTO));
+ else if (np == NIL) {
+ if (replyto != NOSTR)
printf("Empty reply-to field -- replying to author\n");
printf("Empty reply-to field -- replying to author\n");
- if (cp == NOSTR)
- strcpy(buf, rcv);
- else
- strcpy(buf, cp);
+ np = extract(rcv, GTO);
- head.h_to = buf;
- head.h_subject = hfield("subject", mp);
- if (head.h_subject == NOSTR)
+ head.h_to = np;
+ if ((head.h_subject = hfield("subject", mp)) == NOSTR)
head.h_subject = hfield("subj", mp);
head.h_subject = reedit(head.h_subject);
head.h_subject = hfield("subj", mp);
head.h_subject = reedit(head.h_subject);
- head.h_cc = NOSTR;
- if (replyto == NOSTR) {
- cp = skin(hfield("cc", mp));
- if (cp != NOSTR) {
- np = elide(extract(cp, GCC));
- np = delname(np, myname, icequal);
- if (altnames != 0)
- for (ap = altnames; *ap; ap++)
- np = delname(np, *ap, icequal);
- head.h_cc = detract(np, 0);
- }
- }
- head.h_bcc = NOSTR;
- head.h_smopts = NOSTR;
- mail1(&head);
+ if (replyto == NOSTR && (cp = skin(hfield("cc", mp))) != NOSTR) {
+ np = elide(extract(cp, GCC));
+ np = delname(np, myname, icequal);
+ if (altnames != 0)
+ for (ap = altnames; *ap; ap++)
+ np = delname(np, *ap, icequal);
+ head.h_cc = np;
+ } else
+ head.h_cc = NIL;
+ head.h_bcc = NIL;
+ head.h_smopts = NIL;
+ mail1(&head, 1);
* Modify the subject we are replying to to begin with Re: if
* it does not already.
*/
* Modify the subject we are replying to to begin with Re: if
* it does not already.
*/
- char sbuf[10];
- register char *newsubj;
- return(NOSTR);
- strncpy(sbuf, subj, 3);
- sbuf[3] = 0;
- if (icequal(sbuf, "re:"))
- return(subj);
- newsubj = salloc(strlen(subj) + 6);
- sprintf(newsubj, "Re: %s", subj);
- return(newsubj);
+ return NOSTR;
+ if ((subj[0] == 'r' || subj[0] == 'R') &&
+ (subj[1] == 'e' || subj[1] == 'E') &&
+ subj[2] == ':')
+ return subj;
+ newsubj = salloc(strlen(subj) + 5);
+ strcpy(newsubj, "Re: ");
+ strcpy(subj, newsubj + 4);
+ return newsubj;
/*
* Expand file names like echo
*/
/*
* Expand file names like echo
*/
echo(argv)
char **argv;
{
echo(argv)
char **argv;
{
* and not messing around with the To: and Cc: lists as in normal
* reply.
*/
* and not messing around with the To: and Cc: lists as in normal
* reply.
*/
_Respond(msgvec)
int msgvec[];
{
struct header head;
struct message *mp;
_Respond(msgvec)
int msgvec[];
{
struct header head;
struct message *mp;
- register int s, *ap;
- register char *cp, *cp2, *subject;
+ register int *ap;
+ register char *cp;
- for (s = 0, ap = msgvec; *ap != 0; ap++) {
- mp = &message[*ap - 1];
- dot = mp;
- if ((cp = skin(hfield("from", mp))) != NOSTR)
- s+= strlen(cp) + 1;
- else
- s += strlen(skin(nameof(mp, 2))) + 1;
- }
- if (s == 0)
- return(0);
- cp = salloc(s + 2);
- head.h_to = cp;
for (ap = msgvec; *ap != 0; ap++) {
mp = &message[*ap - 1];
for (ap = msgvec; *ap != 0; ap++) {
mp = &message[*ap - 1];
- if ((cp2 = skin(hfield("from", mp))) == NOSTR)
- cp2 = skin(nameof(mp, 2));
- cp = copy(cp2, cp);
- *cp++ = ' ';
+ dot = mp;
+ if ((cp = skin(hfield("from", mp))) == NOSTR)
+ cp = skin(nameof(mp, 2));
+ head.h_to = cat(head.h_to, extract(cp, GTO));
+ if (head.h_to == NIL)
+ return 0;
mp = &message[msgvec[0] - 1];
mp = &message[msgvec[0] - 1];
- subject = hfield("subject", mp);
- head.h_seq = 0;
- if (subject == NOSTR)
- subject = hfield("subj", mp);
- head.h_subject = reedit(subject);
- if (subject != NOSTR)
- head.h_seq++;
- head.h_cc = NOSTR;
- head.h_bcc = NOSTR;
- head.h_smopts = NOSTR;
- mail1(&head);
- return(0);
+ if ((head.h_subject = hfield("subject", mp)) == NOSTR)
+ head.h_subject = hfield("subj", mp);
+ head.h_subject = reedit(head.h_subject);
+ head.h_cc = NIL;
+ head.h_bcc = NIL;
+ head.h_smopts = NIL;
+ mail1(&head, 1);
+ return 0;
-static char sccsid[] = "@(#)collect.c 5.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)collect.c 5.9 (Berkeley) %G%";
static jmp_buf coljmp; /* To get back to work */
FILE *
static jmp_buf coljmp; /* To get back to work */
FILE *
+collect(hp, printheaders)
struct header *hp;
{
FILE *fp, *fbuf;
struct header *hp;
{
FILE *fp, *fbuf;
if (hp->h_subject == NOSTR && value("interactive") != NOSTR &&
value("ask"))
t &= ~GNL, getsub++;
if (hp->h_subject == NOSTR && value("interactive") != NOSTR &&
value("ask"))
t &= ~GNL, getsub++;
puthead(hp, stdout, t);
fflush(stdout);
}
puthead(hp, stdout, t);
fflush(stdout);
}
/*
* Add to the To list.
*/
/*
* Add to the To list.
*/
- hp->h_to = addto(hp->h_to, &linebuf[2]);
- hp->h_seq++;
+ hp->h_to = cat(hp->h_to, extract(&linebuf[2], GTO));
while (isspace(*cp))
cp++;
hp->h_subject = savestr(cp);
while (isspace(*cp))
cp++;
hp->h_subject = savestr(cp);
break;
case 'c':
/*
* Add to the CC list.
*/
break;
case 'c':
/*
* Add to the CC list.
*/
- hp->h_cc = addto(hp->h_cc, &linebuf[2]);
- hp->h_seq++;
+ hp->h_cc = cat(hp->h_cc, extract(&linebuf[2], GCC));
break;
case 'b':
/*
* Add stuff to blind carbon copies list.
*/
break;
case 'b':
/*
* Add stuff to blind carbon copies list.
*/
- hp->h_bcc = addto(hp->h_bcc, &linebuf[2]);
- hp->h_seq++;
+ hp->h_bcc = cat(hp->h_bcc, extract(&linebuf[2], GBCC));
break;
case 'd':
strcpy(linebuf + 2, deadletter);
break;
case 'd':
strcpy(linebuf + 2, deadletter);
* line. Return a count of the characters sent, or -1
* on error.
*/
* line. Return a count of the characters sent, or -1
* on error.
*/
long
transmit(mailp, fp)
struct message *mailp;
long
transmit(mailp, fp)
struct message *mailp;
* signal routine. We only come here if signals
* were previously set anyway.
*/
* signal routine. We only come here if signals
* were previously set anyway.
*/
collrub(s)
{
register FILE *dbuf;
collrub(s)
{
register FILE *dbuf;
while ((c = getc(collf)) != EOF)
putc(c, dbuf);
fclose(dbuf);
while ((c = getc(collf)) != EOF)
putc(c, dbuf);
fclose(dbuf);
done:
fclose(collf);
signal(SIGINT, saveint);
done:
fclose(collf);
signal(SIGINT, saveint);
/*
* Acknowledge an interrupt signal from the tty by typing an @
*/
/*
* Acknowledge an interrupt signal from the tty by typing an @
*/
fflush(stdout);
clearerr(stdin);
}
fflush(stdout);
clearerr(stdin);
}
-
-/*
- * Add a string to the end of a header entry field.
- */
-
-char *
-addto(hf, news)
- char hf[], news[];
-{
- register char *cp, *cp2, *linebuf;
-
- if (hf == NOSTR)
- hf = "";
- if (*news == '\0')
- return(hf);
- linebuf = salloc(strlen(hf) + strlen(news) + 2);
- for (cp = hf; any(*cp, " \t"); cp++)
- ;
- for (cp2 = linebuf; *cp;)
- *cp2++ = *cp++;
- *cp2++ = ' ';
- for (cp = news; any(*cp, " \t"); cp++)
- ;
- while (*cp != '\0')
- *cp2++ = *cp++;
- *cp2 = '\0';
- return(linebuf);
-}
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
- * @(#)def.h 5.10 (Berkeley) %G%
+ * @(#)def.h 5.11 (Berkeley) %G%
*/
#include <sys/param.h> /* includes <sys/types.h> */
*/
#include <sys/param.h> /* includes <sys/types.h> */
- char *h_to; /* Dynamic "To:" string */
- char *h_subject; /* Subject string */
- char *h_cc; /* Carbon copies string */
- char *h_bcc; /* Blind carbon copies */
- char *h_smopts; /* Sendmail options */
- int h_seq; /* Sequence for optimization */
+ struct name *h_to; /* Dynamic "To:" string */
+ char *h_subject; /* Subject string */
+ struct name *h_cc; /* Carbon copies string */
+ struct name *h_bcc; /* Blind carbon copies */
+ struct name *h_smopts; /* Sendmail options */
off_t fsize();
struct cmd *lex();
struct grouphead *findgroup();
off_t fsize();
struct cmd *lex();
struct grouphead *findgroup();
struct name *cat();
struct name *delname();
struct name *elide();
struct name *cat();
struct name *delname();
struct name *elide();
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
- * @(#)glob.h 5.9 (Berkeley) %G%
+ * @(#)glob.h 5.10 (Berkeley) %G%
int sawcom; /* Set after first command */
char *Tflag; /* -T temp file for netnews */
char nosrc; /* Don't source /usr/lib/Mail.rc */
int sawcom; /* Set after first command */
char *Tflag; /* -T temp file for netnews */
char nosrc; /* Don't source /usr/lib/Mail.rc */
-int selfsent; /* User sent self something */
int senderr; /* An error while checking */
int edit; /* Indicates editing a file */
int readonly; /* Will be unable to rewrite file */
int senderr; /* An error while checking */
int edit; /* Indicates editing a file */
int readonly; /* Will be unable to rewrite file */
FILE *pipef; /* Pipe file we have opened */
int image; /* File descriptor for image of msg */
FILE *input; /* Current command input file */
FILE *pipef; /* Pipe file we have opened */
int image; /* File descriptor for image of msg */
FILE *input; /* Current command input file */
-char *sflag; /* Subject given from non tty */
char mailname[PATHSIZE]; /* Name of current file */
char prevfile[PATHSIZE]; /* Name of previous file */
int uid; /* The invoker's user id */
char mailname[PATHSIZE]; /* Name of current file */
char prevfile[PATHSIZE]; /* Name of previous file */
int uid; /* The invoker's user id */
#endif /* notdef */
#ifdef notdef
#endif /* notdef */
#ifdef notdef
-static char sccsid[] = "@(#)main.c 5.14 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c 5.15 (Berkeley) %G%";
#endif /* notdef */
#include "rcv.h"
#endif /* notdef */
#include "rcv.h"
main(argc, argv)
char **argv;
{
main(argc, argv)
char **argv;
{
register int i;
struct name *to, *cc, *bcc, *smopts;
register int i;
struct name *to, *cc, *bcc, *smopts;
- int mustsend, hdrstop(), (*prevint)();
+ char *subject;
+ char *ef;
+ int hdrstop(), (*prevint)();
extern int getopt(), optind, opterr;
extern char *optarg;
extern int getopt(), optind, opterr;
extern char *optarg;
* first of these users.
*/
ef = NOSTR;
* first of these users.
*/
ef = NOSTR;
- to = NULL;
- cc = NULL;
- bcc = NULL;
- smopts = NULL;
- mustsend = 0;
+ to = NIL;
+ cc = NIL;
+ bcc = NIL;
+ smopts = NIL;
+ subject = NOSTR;
while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) {
switch (i) {
case 'T':
while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) {
switch (i) {
case 'T':
* Give a subject field for sending from
* non terminal
*/
* Give a subject field for sending from
* non terminal
*/
- mustsend++;
- sflag = optarg;
/*
* Get Carbon Copy Recipient list
*/
/*
* Get Carbon Copy Recipient list
*/
- cc = cat(cc, nalloc(optarg));
- mustsend++;
+ cc = cat(cc, nalloc(optarg, GCC));
break;
case 'b':
/*
* Get Blind Carbon Copy Recipient list
*/
break;
case 'b':
/*
* Get Blind Carbon Copy Recipient list
*/
- bcc = cat(bcc, nalloc(optarg));
- mustsend++;
+ bcc = cat(bcc, nalloc(optarg, GBCC));
break;
case '?':
fputs("\
break;
case '?':
fputs("\
}
}
for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
}
}
for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
- to = cat(to, nalloc(argv[i]));
+ to = cat(to, nalloc(argv[i], GTO));
- smopts = cat(smopts, nalloc(argv[i]));
+ smopts = cat(smopts, nalloc(argv[i], 0));
/*
* Check for inconsistent arguments.
*/
/*
* Check for inconsistent arguments.
*/
- if (!to && (cc || bcc)) {
- fputs("You must also specify direct recipients of mail.\n", stderr);
+ if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
+ fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
- if ((ef != NOSTR) && to) {
+ if (ef != NOSTR && to != NIL) {
fprintf(stderr, "Cannot give -f and people to send to.\n");
exit(1);
}
fprintf(stderr, "Cannot give -f and people to send to.\n");
exit(1);
}
- if (mustsend && !to) {
- fprintf(stderr, "The flags you gave make no sense since you're not sending mail.\n");
- exit(1);
- }
tinit();
setscreensize();
input = stdin;
tinit();
setscreensize();
input = stdin;
load(MASTER);
load(mailrc);
if (!rcvmode) {
load(MASTER);
load(mailrc);
if (!rcvmode) {
- mail(to, cc, bcc, smopts);
-
+ mail(to, cc, bcc, smopts, subject);
/*
* Ok, we are reading mail.
* Decide whether we are editing a mailbox or reading
/*
* Ok, we are reading mail.
* Decide whether we are editing a mailbox or reading
-static char sccsid[] = "@(#)names.c 5.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)names.c 5.9 (Berkeley) %G%";
#include "rcv.h"
#include <sys/wait.h>
#include "rcv.h"
#include <sys/wait.h>
-/*
- * Set of network separator characters.
- */
-char *metanet = "!%@";
-
/*
* Allocate a single element of a name list,
* initialize its name field to the passed
* name and return it.
*/
/*
* Allocate a single element of a name list,
* initialize its name field to the passed
* name and return it.
*/
char str[];
{
register struct name *np;
char str[];
{
register struct name *np;
np = (struct name *) salloc(sizeof *np);
np->n_flink = NIL;
np->n_blink = NIL;
np = (struct name *) salloc(sizeof *np);
np->n_flink = NIL;
np->n_blink = NIL;
np->n_name = savestr(str);
return(np);
}
np->n_name = savestr(str);
return(np);
}
/*
* Find the tail of a list and return it.
*/
/*
* Find the tail of a list and return it.
*/
struct name *
tailof(name)
struct name *name;
struct name *
tailof(name)
struct name *name;
* and make a list of names from it.
* Return the list or NIL if none found.
*/
* and make a list of names from it.
* Return the list or NIL if none found.
*/
struct name *
extract(line, ntype)
char line[];
{
register char *cp;
register struct name *top, *np, *t;
struct name *
extract(line, ntype)
char line[];
{
register char *cp;
register struct name *top, *np, *t;
- char nbuf[BUFSIZ], abuf[BUFSIZ];
- if (line == NOSTR || strlen(line) == 0)
- return(NIL);
+ if (line == NOSTR || *line == '\0')
+ return NIL;
top = NIL;
np = NIL;
cp = line;
while ((cp = yankword(cp, nbuf)) != NOSTR) {
top = NIL;
np = NIL;
cp = line;
while ((cp = yankword(cp, nbuf)) != NOSTR) {
- if (np != NIL && equal(nbuf, "at")) {
- (void) strcpy(abuf, nbuf);
- if ((cp = yankword(cp, nbuf)) == NOSTR) {
- (void) strcpy(nbuf, abuf);
- goto normal;
- }
- (void) strcpy(abuf, np->n_name);
- stradd(abuf, '@');
- (void) strcat(abuf, nbuf);
- np->n_name = savestr(abuf);
- continue;
- }
-normal:
- t = nalloc(nbuf);
- t->n_type = ntype;
+ t = nalloc(nbuf, ntype);
if (top == NIL)
top = t;
else
if (top == NIL)
top = t;
else
t->n_blink = np;
np = t;
}
t->n_blink = np;
np = t;
}
}
/*
* Turn a list of names into a string of the same names.
*/
}
/*
* Turn a list of names into a string of the same names.
*/
char *
detract(np, ntype)
register struct name *np;
char *
detract(np, ntype)
register struct name *np;
/*
* Grab a single word (liberal word)
/*
* Grab a single word (liberal word)
- * Throw away things between ()'s.
+ * Throw away things between ()'s, and take anything between <>.
char *
yankword(ap, wbuf)
char *ap, wbuf[];
char *
yankword(ap, wbuf)
char *ap, wbuf[];
register char *cp, *cp2;
cp = ap;
register char *cp, *cp2;
cp = ap;
- do {
- while (*cp && any(*cp, " \t,"))
- cp++;
+ for (;;) {
+ if (*cp == '\0')
+ return NOSTR;
if (*cp == '(') {
register int nesting = 0;
if (*cp == '(') {
register int nesting = 0;
if (nesting <= 0)
break;
}
if (nesting <= 0)
break;
}
- }
- if (*cp == '\0')
- return(NOSTR);
- } while (any(*cp, " \t,("));
- for (cp2 = wbuf; *cp && !any(*cp, " \t,("); *cp2++ = *cp++)
- ;
+ } else if (*cp == ' ' || *cp == '\t' || *cp == ',')
+ cp++;
+ else
+ break;
+ }
+ if (*cp == '<')
+ for (cp2 = wbuf; *cp && (*cp2++ = *cp++) != '>';)
+ ;
+ else
+ for (cp2 = wbuf; *cp && !any(*cp, " \t,("); *cp2++ = *cp++)
+ ;
* Recipients whose name begins with | are piped through the given
* program and removed.
*/
* Recipients whose name begins with | are piped through the given
* program and removed.
*/
struct name *
outof(names, fo, hp)
struct name *names;
struct name *
outof(names, fo, hp)
struct name *names;
- if (any('@', name))
- return(0);
for (cp = name; *cp; cp++) {
for (cp = name; *cp; cp++) {
- if (*cp == '.')
- continue;
- if (any(*cp, metanet))
- return(0);
+ if (*cp == '!' || *cp == '%' || *cp == '@')
+ return 0;
- np = nalloc(cp);
- np->n_type = ntype;
+ np = nalloc(cp, ntype);
/*
* At this point should allow to expand
* to self if only person in group
/*
* At this point should allow to expand
* to self if only person in group
-
-
-/*
- * Compute the length of the passed name list and
- * return it.
- */
-
-lengthof(name)
- struct name *name;
-{
- 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.
*/
/*
* Concatenate the two passed name lists, return the result.
*/
struct name *
cat(n1, n2)
struct name *n1, *n2;
struct name *
cat(n1, n2)
struct name *n1, *n2;
* Unpack the name list onto a vector of strings.
* Return an error if the name list won't fit.
*/
* Unpack the name list onto a vector of strings.
* Return an error if the name list won't fit.
*/
char **
unpack(np)
struct name *np;
char **
unpack(np)
struct name *np;
int t, extra, metoo, verbose;
n = np;
int t, extra, metoo, verbose;
n = np;
- if ((t = lengthof(n)) == 0)
+ if ((t = count(n)) == 0)
panic("No names to unpack");
panic("No names to unpack");
/*
* Compute the number of extra arguments we will need.
* We need at least two extra -- one for "mail" and one for
* the terminating 0 pointer. Additional spots may be needed
* to pass along -f to the host mailer.
*/
/*
* Compute the number of extra arguments we will need.
* We need at least two extra -- one for "mail" and one for
* the terminating 0 pointer. Additional spots may be needed
* to pass along -f to the host mailer.
*/
extra = 2;
extra++;
metoo = value("metoo") != NOSTR;
extra = 2;
extra++;
metoo = value("metoo") != NOSTR;
* insertion sorting them, then checking for dups.
* Return the head of the new list.
*/
* insertion sorting them, then checking for dups.
* Return the head of the new list.
*/
struct name *
elide(names)
struct name *names;
struct name *
elide(names)
struct name *names;
/*
* Version of strcmp which ignores case differences.
*/
/*
* Version of strcmp which ignores case differences.
*/
nstrcmp(s1, s2)
register char *s1, *s2;
{
nstrcmp(s1, s2)
register char *s1, *s2;
{
* Put another node onto a list of names and return
* the list.
*/
* Put another node onto a list of names and return
* the list.
*/
struct name *
put(list, node)
struct name *list, *node;
struct name *
put(list, node)
struct name *list, *node;
* Determine the number of elements in
* a name list and return it.
*/
* Determine the number of elements in
* a name list and return it.
*/
count(np)
register struct name *np;
{
count(np)
register struct name *np;
{
- while (np != NIL) {
- c++;
- np = np->n_flink;
- }
- return(c);
+ for (c = 0; np != NIL; c++, np = np->n_flink)
+ ;
+ return c;
-static char sccsid[] = "@(#)send.c 5.10 (Berkeley) %G%";
+static char sccsid[] = "@(#)send.c 5.11 (Berkeley) %G%";
#endif /* notdef */
#include "rcv.h"
#endif /* notdef */
#include "rcv.h"
* which does all the dirty work.
*/
* which does all the dirty work.
*/
-mail(to, cc, bcc, smopts)
+mail(to, cc, bcc, smopts, subject)
struct name *to, *cc, *bcc, *smopts;
struct name *to, *cc, *bcc, *smopts;
- head.h_to = detract(to, 0);
- head.h_subject = NOSTR;
- head.h_cc = detract(cc, 0);
- head.h_bcc = detract(bcc, 0);
- head.h_smopts = detract(smopts, 0);
- head.h_seq = 0;
- (void) mail1(&head);
+ head.h_to = to;
+ head.h_subject = subject;
+ head.h_cc = cc;
+ head.h_bcc = bcc;
+ head.h_smopts = smopts;
+ (void) mail1(&head, 0);
- if (blankline(str))
- head.h_to = NOSTR;
- else
- head.h_to = str;
+ head.h_to = extract(str, GTO);
- head.h_cc = NOSTR;
- head.h_bcc = NOSTR;
- head.h_smopts = NOSTR;
- head.h_seq = 0;
- (void) mail1(&head);
+ head.h_cc = NIL;
+ head.h_bcc = NIL;
+ head.h_smopts = NIL;
+ (void) mail1(&head, 0);
* in the passed header. (Internal interface).
*/
* in the passed header. (Internal interface).
*/
struct header *hp;
{
register char *cp;
struct header *hp;
{
register char *cp;
- if (hp->h_subject == NOSTR)
- hp->h_subject = sflag;
- if ((mtf = collect(hp)) == NULL)
+ if ((mtf = collect(hp, printheaders)) == NULL)
if (value("interactive") != NOSTR)
if (value("askcc") != NOSTR)
grabh(hp, GCC);
if (value("interactive") != NOSTR)
if (value("askcc") != NOSTR)
grabh(hp, GCC);
printf("EOT\n");
(void) fflush(stdout);
}
printf("EOT\n");
(void) fflush(stdout);
}
/*
* Now, take the user names from the combined
* to and cc lists and do all the alias
* processing.
*/
/*
* Now, take the user names from the combined
* to and cc lists and do all the alias
* processing.
*/
- to = usermap(cat(extract(hp->h_bcc, GBCC),
- cat(extract(hp->h_to, GTO), extract(hp->h_cc, GCC))));
+ to = usermap(cat(hp->h_bcc, cat(hp->h_to, hp->h_cc)));
if (to == NIL) {
printf("No recipients specified\n");
goto topdog;
}
if (to == NIL) {
printf("No recipients specified\n");
goto topdog;
}
/*
* Look through the recipient list for names with /'s
* in them which we write to as files directly.
*/
/*
* Look through the recipient list for names with /'s
* in them which we write to as files directly.
*/
to = outof(to, mtf, hp);
rewind(mtf);
if (senderr) {
to = outof(to, mtf, hp);
rewind(mtf);
if (senderr) {
if (!gotcha)
goto out;
to = elide(to);
if (!gotcha)
goto out;
to = elide(to);
- if (count(to) > 1)
- hp->h_seq++;
- if (hp->h_seq > 0) {
- fixhead(hp, to);
- if (fsize(mtf) == 0)
- if (hp->h_subject == NOSTR)
+ if (fsize(mtf) == 0)
+ if (hp->h_subject == NOSTR)
printf("No message, no subject; hope that's ok\n");
printf("No message, no subject; hope that's ok\n");
printf("Null message body; hope that's ok\n");
printf("Null message body; hope that's ok\n");
+ if (count(to) > 0 || hp->h_subject != NOSTR) {
+ /* don't do this unless we have to */
+ fixhead(hp, to);
if ((mtf = infix(hp, mtf)) == NULL) {
fprintf(stderr, ". . . message lost, sorry.\n");
return(-1);
}
}
if ((mtf = infix(hp, mtf)) == NULL) {
fprintf(stderr, ". . . message lost, sorry.\n");
return(-1);
}
}
- namelist = unpack(cat(extract(hp->h_smopts, 0), to));
+ namelist = unpack(cat(hp->h_smopts, to));
- printf("Recipients of message:\n");
+ printf("Sendmail arguments:");
for (t = namelist; *t != NOSTR; t++)
printf(" \"%s\"", *t);
printf("\n");
for (t = namelist; *t != NOSTR; t++)
printf(" \"%s\"", *t);
printf("\n");
}
if ((cp = value("record")) != NOSTR)
(void) savemail(expand(cp), mtf);
}
if ((cp = value("record")) != NOSTR)
(void) savemail(expand(cp), mtf);
/*
* Wait, to absorb a potential zombie, then
* fork, set up the temporary mail file as standard
/*
* Wait, to absorb a potential zombie, then
* fork, set up the temporary mail file as standard
* far above. Return the process id to caller in case he
* wants to await the completion of mail.
*/
* far above. Return the process id to caller in case he
* wants to await the completion of mail.
*/
while (wait3(&s, WNOHANG, (struct timeval *) 0) > 0)
;
rewind(mtf);
while (wait3(&s, WNOHANG, (struct timeval *) 0) > 0)
;
rewind(mtf);
perror(deliver);
exit(1);
}
perror(deliver);
exit(1);
}
out:
if (value("verbose") != NOSTR) {
while ((p = wait(&s)) != pid && p != -1)
out:
if (value("verbose") != NOSTR) {
while ((p = wait(&s)) != pid && p != -1)
pid = 0;
}
(void) fclose(mtf);
pid = 0;
}
(void) fclose(mtf);
}
/*
* Fix the header by glopping all of the expanded names from
* the distribution list into the appropriate fields.
}
/*
* Fix the header by glopping all of the expanded names from
* the distribution list into the appropriate fields.
- * If there are any ARPA net recipients in the message,
- * we must insert commas, alas.
fixhead(hp, tolist)
struct header *hp;
struct name *tolist;
{
fixhead(hp, tolist)
struct header *hp;
struct name *tolist;
{
register struct name *np;
register struct name *np;
- for (f = 0, np = tolist; np != NIL; np = np->n_flink)
- if (any('@', np->n_name)) {
- f |= GCOMMA;
- break;
- }
-
- if (debug && f & GCOMMA)
- fprintf(stderr, "Should be inserting commas in recip lists\n");
- hp->h_to = detract(tolist, GTO|f);
- hp->h_cc = detract(tolist, GCC|f);
- hp->h_bcc = detract(tolist, GBCC|f);
+ 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));
return(fi);
}
(void) remove(tempMail);
return(fi);
}
(void) remove(tempMail);
- (void) puthead(hp, nfo, GTO|GSUBJECT|GCC|GBCC|GNL);
+ (void) puthead(hp, nfo, GTO|GSUBJECT|GCC|GBCC|GNL|GCOMMA);
c = getc(fi);
while (c != EOF) {
(void) putc(c, nfo);
c = getc(fi);
while (c != EOF) {
(void) putc(c, nfo);
* Dump the to, subject, cc header on the
* passed file buffer.
*/
* Dump the to, subject, cc header on the
* passed file buffer.
*/
puthead(hp, fo, w)
struct header *hp;
FILE *fo;
puthead(hp, fo, w)
struct header *hp;
FILE *fo;
register int gotcha;
gotcha = 0;
register int gotcha;
gotcha = 0;
- if (hp->h_to != NOSTR && w & GTO)
- fmt("To: ", hp->h_to, fo), gotcha++;
+ 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_subject != NOSTR && w & GSUBJECT)
fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++;
- if (hp->h_cc != NOSTR && w & GCC)
- fmt("Cc: ", hp->h_cc, fo), gotcha++;
- if (hp->h_bcc != NOSTR && w & GBCC)
- fmt("Bcc: ", hp->h_bcc, fo), 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);
if (gotcha && w & GNL)
(void) putc('\n', fo);
return(0);
/*
* Format the given text to not exceed 72 characters.
*/
/*
* Format the given text to not exceed 72 characters.
*/
-
-fmt(str, txt, fo)
- register char *str, *txt;
- register FILE *fo;
+fmt(str, np, fo, comma)
+ char *str;
+ register struct name *np;
+ FILE *fo;
+ int comma;
- register int col;
- register char *bg, *bl, *pt, ch;
col = strlen(str);
if (col)
col = strlen(str);
if (col)
- fprintf(fo, "%s", str);
- pt = bg = txt;
- bl = 0;
- while (*bg) {
- pt++;
- if (++col > 72) {
- if (!bl) {
- bl = bg;
- while (*bl && !isspace(*bl))
- bl++;
- }
- if (!*bl)
- goto finish;
- ch = *bl;
- *bl = '\0';
- fprintf(fo, "%s\n ", bg);
- col = 4;
- *bl = ch;
- pt = bg = ++bl;
- bl = 0;
+ fputs(str, fo);
+ len = strlen(np->n_name);
+ for (;;) {
+ fputs(np->n_name, fo);
+ col += len;
+ if (comma) {
+ putc(',', fo);
+ col++;
- if (!*pt) {
-finish:
- fprintf(fo, "%s\n", bg);
- return;
+ if ((np = np->n_flink) == NIL)
+ break;
+ if (np->n_flink == NIL)
+ comma = 0;
+ len = strlen(np->n_name);
+ if (col + len + comma > 72) {
+ fputs("\n ", fo);
+ col = 4;
+ } else {
+ putc(' ', fo);
+ col++;
- if (isspace(*pt))
- bl = pt;
-static char sccsid[] = "@(#)tty.c 5.5 (Berkeley) %G%";
+static char sccsid[] = "@(#)tty.c 5.6 (Berkeley) %G%";
#endif
if (gflags & GTO) {
#ifndef TIOCSTI
#endif
if (gflags & GTO) {
#ifndef TIOCSTI
- if (!ttyset && hp->h_to != NOSTR)
+ if (!ttyset && hp->h_to != NIL)
ttyset++, stty(fileno(stdin), &ttybuf);
#endif
ttyset++, stty(fileno(stdin), &ttybuf);
#endif
- hp->h_to = readtty("To: ", hp->h_to);
- if (hp->h_to != NOSTR)
- hp->h_seq++;
+ hp->h_to =
+ extract(readtty("To: ", detract(hp->h_to, 0)), GTO);
}
if (gflags & GSUBJECT) {
#ifndef TIOCSTI
}
if (gflags & GSUBJECT) {
#ifndef TIOCSTI
ttyset++, stty(fileno(stdin), &ttybuf);
#endif
hp->h_subject = readtty("Subject: ", hp->h_subject);
ttyset++, stty(fileno(stdin), &ttybuf);
#endif
hp->h_subject = readtty("Subject: ", hp->h_subject);
- if (hp->h_subject != NOSTR)
- hp->h_seq++;
}
if (gflags & GCC) {
#ifndef TIOCSTI
}
if (gflags & GCC) {
#ifndef TIOCSTI
- if (!ttyset && hp->h_cc != NOSTR)
+ if (!ttyset && hp->h_cc != NIL)
ttyset++, stty(fileno(stdin), &ttybuf);
#endif
ttyset++, stty(fileno(stdin), &ttybuf);
#endif
- hp->h_cc = readtty("Cc: ", hp->h_cc);
- if (hp->h_cc != NOSTR)
- hp->h_seq++;
+ hp->h_cc =
+ extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC);
}
if (gflags & GBCC) {
#ifndef TIOCSTI
}
if (gflags & GBCC) {
#ifndef TIOCSTI
- if (!ttyset && hp->h_bcc != NOSTR)
+ if (!ttyset && hp->h_bcc != NIL)
ttyset++, stty(fileno(stdin), &ttybuf);
#endif
ttyset++, stty(fileno(stdin), &ttybuf);
#endif
- hp->h_bcc = readtty("Bcc: ", hp->h_bcc);
- if (hp->h_bcc != NOSTR)
- hp->h_seq++;
+ hp->h_bcc =
+ extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC);
}
signal(SIGCONT, savecont);
#ifndef TIOCSTI
}
signal(SIGCONT, savecont);
#ifndef TIOCSTI