#include "mail.h"
#include <sys/param.h>
void
sendmail(int argc, char **argv)
{
char **args;
char *tp, *zp;
char buf[2048], last1c;
FILE *input;
struct stat64 sbuf;
int aret;
int i, n;
int oldn = 1;
int ttyf = 0;
int pushrest = 0;
int hdrtyp = 0;
int ctf = FALSE;
int binflg = 0;
long count = 0L;
struct tm *bp;
struct hdrs *hptr;
static char pn[] = "sendmail";
reciplist list;
Dout(pn, 0, "entered\n");
new_reciplist(&list);
for (i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
if (argv[i][1] == '\0') {
errmsg(E_SYNTAX,
"Hyphens MAY NOT be followed by spaces");
}
if (i > 1) {
errmsg(E_SYNTAX,
"Options MUST PRECEDE persons");
}
done(0);
}
if (argv[i][0] == '\0' || argv[i][strlen(argv[i])-1] == '!') {
errmsg(E_SYNTAX, "Null names are not allowed");
done(0);
}
add_recip(&list, argv[i], FALSE);
}
mktmp();
time(&iop);
bp = localtime(&iop);
tp = asctime(bp);
zp = tzname[bp->tm_isdst];
sprintf(datestring, "%.16s %.3s %.5s", tp, zp, tp+20);
trimnl(datestring);
sprintf(RFC822datestring, "%.3s, %.2s %.3s %.4s %.5s %.3s",
tp, tp+8, tp+4, tp+20, tp+11, zp);
if (fromflag && deliverflag && from_user[0] != '\0') {
(void) snprintf(buf, sizeof (buf), "%s%s %s\n",
header[H_FROM].tag, from_user, datestring);
} else {
(void) snprintf(buf, sizeof (buf), "%s%s %s\n",
header[H_FROM].tag, my_name, datestring);
}
if (!wtmpf(buf, strlen(buf))) {
done(0);
}
savehdrs(buf, H_FROM);
if (flgt == 1 && argc > 1) {
aret = argc;
args = argv;
while (--aret > 0) {
(void) snprintf(buf, sizeof (buf),
"%s %s\n", header[H_TO].tag, *++args);
if (!wtmpf(buf, strlen(buf))) {
done(0);
}
savehdrs(buf, H_TO);
}
}
flgf = 1;
saveint = setsig(SIGINT, savdead);
last1c = ' ';
ttyf = isatty(fileno(stdin));
pushrest = 0;
(void) strlcpy(fromU, my_name, sizeof (fromU));
fromS[0] = 0;
input = stdin;
if (fstat64(fileno(input), &sbuf) == 0) {
if ((sbuf.st_size > MAXOFF_T) || (sbuf.st_blocks > LONG_MAX)) {
fprintf(stderr, "%s: stdin: %s\n", program,
strerror(EOVERFLOW));
exit(1);
}
}
while ((n = getaline(line, sizeof (line), stdin)) > 0) {
last1c = line[n-1];
if (pushrest) {
if (!wtmpf(line, n)) {
done(0);
}
pushrest = (last1c != '\n');
continue;
}
pushrest = (last1c != '\n');
if ((hdrtyp = isheader(line, &ctf)) == FALSE) {
break;
}
flgf = 0;
switch (hdrtyp) {
case H_RVERS:
dflag = 9;
Dout(pn, 0, "dflag = 9\n");
break;
case H_FROM:
if (!wtmpf(">", 1)) {
done(0);
}
hdrtyp = H_FROM1;
case H_FROM1:
if (substr(line, "forwarded by") > -1) {
break;
}
pickFrom(line);
if (Rpath[0] != '\0') {
strcat(Rpath, "!");
}
(void) strlcat(Rpath, fromS, sizeof (Rpath));
n = 0;
break;
case H_MIMEVERS:
case H_CLEN:
case H_CTYPE:
n = 0;
break;
case H_TCOPY:
(void) snprintf(buf, sizeof (buf), "%s \n",
header[H_TCOPY].tag);
if (!wtmpf(buf, strlen(buf))) {
done(0);
}
n = 0;
break;
case H_MTYPE:
if (flgm) {
n = 0;
}
break;
case H_CONT:
if (oldn == 0) {
n = 0;
}
break;
}
oldn = n;
if (n && !wtmpf(line, n)) {
done(0);
}
if (!n) savehdrs(line, hdrtyp);
}
if (Rpath[0] != '\0') {
strcat(Rpath, "!");
}
(void) strlcat(Rpath, fromU, sizeof (Rpath));
if (flgm) {
snprintf(buf, sizeof (buf), "%s%s\n",
header[H_MTYPE].tag, msgtype);
if (!wtmpf(buf, strlen(buf))) {
done(0);
}
}
memcpy(buf, line, n);
if (n == 0 || (ttyf && !strncmp(buf, ".\n", 2))) {
if (flgf) {
return;
} else {
if ((hptr = hdrlines[H_MIMEVERS].head) !=
(struct hdrs *)NULL) {
(void) snprintf(line, sizeof (line), "%s \n",
header[H_MIMEVERS].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
}
if ((hptr = hdrlines[H_CTYPE].head) !=
(struct hdrs *)NULL) {
(void) snprintf(line, sizeof (line), "%s \n",
header[H_CTYPE].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
}
if ((hptr = hdrlines[H_CLEN].head) !=
(struct hdrs *)NULL) {
(void) snprintf(line, sizeof (line), "%s \n",
header[H_CLEN].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
}
goto wrapsend;
}
}
if (n == 1 && last1c == '\n') {
n = getaline(buf, sizeof (buf), stdin);
if (n == 0 || (ttyf && !strncmp(buf, ".\n", 2))) {
if ((hptr = hdrlines[H_MIMEVERS].head) !=
(struct hdrs *)NULL) {
(void) snprintf(line, sizeof (line), "%s \n",
header[H_MIMEVERS].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
}
if ((hptr = hdrlines[H_CTYPE].head) !=
(struct hdrs *)NULL) {
(void) snprintf(line, sizeof (line), "%s \n",
header[H_CTYPE].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
}
if ((hptr = hdrlines[H_CLEN].head) !=
(struct hdrs *)NULL) {
(void) snprintf(line, sizeof (line), "%s \n",
header[H_CLEN].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
}
goto wrapsend;
}
}
if (debug > 0) {
buf[n] = '\0';
Dout(pn, 0, "header scan complete, readahead %d = \"%s\"\n",
n, buf);
}
(void) snprintf(line, sizeof (line), "%s \n", header[H_MIMEVERS].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
if (hdrlines[H_MIMEVERS].head == (struct hdrs *)NULL) {
savehdrs(line, H_MIMEVERS);
}
(void) snprintf(line, sizeof (line), "%s \n", header[H_CTYPE].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
if (hdrlines[H_CTYPE].head == (struct hdrs *)NULL) {
savehdrs(line, H_CTYPE);
}
(void) snprintf(line, sizeof (line), "%s \n", header[H_CLEN].tag);
if (!wtmpf(line, strlen(line))) {
done(0);
}
if (hdrlines[H_CLEN].head == (struct hdrs *)NULL) {
savehdrs(line, H_CLEN);
}
if (!wtmpf("\n", 1)) {
done(0);
}
Dout(pn, 0, "header out completed\n");
pushrest = 0;
count = 0L;
if (!strncmp("***** UNDELIVERABLE MAIL sent to", buf, 32)) {
dflag = 9;
Dout(pn, 0, "found old-style UNDELIVERABLE line. dflag = 9\n");
}
while (n > 0) {
if (ttyf && !strcmp(buf, ".\n"))
break;
if (!binflg) {
binflg = !istext((unsigned char *)buf, n);
}
if (!wtmpf(buf, n)) {
done(0);
}
count += n;
n = ttyf
? getaline(buf, sizeof (buf), stdin)
: fread(buf, 1, sizeof (buf), stdin);
}
setsig(SIGINT, saveint);
wrapsend:
nlet = 1;
let[0].adr = 0;
let[1].adr = ftell(tmpf);
let[0].text = (binflg == 1 ? FALSE : TRUE);
Dout(pn, 0, "body copy complete, count %ld\n", count);
if ((hptr = hdrlines[H_MIMEVERS].head) != (struct hdrs *)NULL) {
if (strlen(hptr->value) == 0) {
(void) strlcpy(hptr->value, "1.0",
sizeof (hptr->value));
}
}
if ((hptr = hdrlines[H_CTYPE].head) != (struct hdrs *)NULL) {
if (strlen(hptr->value) == 0) {
(void) strlcpy(hptr->value, "text/plain",
sizeof (hptr->value));
}
}
if ((hptr = hdrlines[H_CLEN].head) != (struct hdrs *)NULL) {
(void) snprintf(hptr->value, sizeof (hptr->value),
"%ld", count);
}
if (fclose(tmpf) == EOF) {
tmperr();
done(0);
}
tmpf = doopen(lettmp, "r+", E_TMP);
if (dflag == 2) {
done(0);
}
sendlist(&list, 0, 0);
done(0);
}