1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include "mail.h" 34*7c478bd9Sstevel@tonic-gate /* 35*7c478bd9Sstevel@tonic-gate Send mail - High level sending routine 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate void sendmail(argc, argv) 38*7c478bd9Sstevel@tonic-gate char **argv; 39*7c478bd9Sstevel@tonic-gate { 40*7c478bd9Sstevel@tonic-gate char **args; 41*7c478bd9Sstevel@tonic-gate char *tp, *zp; 42*7c478bd9Sstevel@tonic-gate char buf[2048],last1c; 43*7c478bd9Sstevel@tonic-gate FILE *input; 44*7c478bd9Sstevel@tonic-gate struct stat sbuf; 45*7c478bd9Sstevel@tonic-gate int aret; 46*7c478bd9Sstevel@tonic-gate int i, n; 47*7c478bd9Sstevel@tonic-gate int oldn = 1; 48*7c478bd9Sstevel@tonic-gate int ttyf = 0; 49*7c478bd9Sstevel@tonic-gate int pushrest = 0; 50*7c478bd9Sstevel@tonic-gate int hdrtyp = 0; 51*7c478bd9Sstevel@tonic-gate int ctf = FALSE; 52*7c478bd9Sstevel@tonic-gate int binflg = 0; 53*7c478bd9Sstevel@tonic-gate long count = 0L; 54*7c478bd9Sstevel@tonic-gate struct tm *bp; 55*7c478bd9Sstevel@tonic-gate struct hdrs *hptr; 56*7c478bd9Sstevel@tonic-gate static char pn[] = "sendmail"; 57*7c478bd9Sstevel@tonic-gate reciplist list; 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "entered\n"); 60*7c478bd9Sstevel@tonic-gate new_reciplist(&list); 61*7c478bd9Sstevel@tonic-gate for (i = 1; i < argc; ++i) { 62*7c478bd9Sstevel@tonic-gate if (argv[i][0] == '-') { 63*7c478bd9Sstevel@tonic-gate if (argv[i][1] == '\0') { 64*7c478bd9Sstevel@tonic-gate errmsg(E_SYNTAX,"Hyphens MAY NOT be followed by spaces"); 65*7c478bd9Sstevel@tonic-gate } 66*7c478bd9Sstevel@tonic-gate if (i > 1) { 67*7c478bd9Sstevel@tonic-gate errmsg(E_SYNTAX,"Options MUST PRECEDE persons"); 68*7c478bd9Sstevel@tonic-gate } 69*7c478bd9Sstevel@tonic-gate done(0); 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate /* 72*7c478bd9Sstevel@tonic-gate Ensure no NULL names in list 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate if (argv[i][0] == '\0' || argv[i][strlen(argv[i])-1] == '!') { 75*7c478bd9Sstevel@tonic-gate errmsg(E_SYNTAX,"Null names are not allowed"); 76*7c478bd9Sstevel@tonic-gate done(0); 77*7c478bd9Sstevel@tonic-gate } 78*7c478bd9Sstevel@tonic-gate add_recip(&list, argv[i], FALSE); /* Don't check for duplication */ 79*7c478bd9Sstevel@tonic-gate } 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate mktmp(); 82*7c478bd9Sstevel@tonic-gate /* 83*7c478bd9Sstevel@tonic-gate Format time 84*7c478bd9Sstevel@tonic-gate */ 85*7c478bd9Sstevel@tonic-gate time(&iop); 86*7c478bd9Sstevel@tonic-gate bp = localtime(&iop); 87*7c478bd9Sstevel@tonic-gate tp = asctime(bp); 88*7c478bd9Sstevel@tonic-gate zp = tzname[bp->tm_isdst]; 89*7c478bd9Sstevel@tonic-gate sprintf(datestring, "%.16s %.3s %.5s", tp, zp, tp+20); 90*7c478bd9Sstevel@tonic-gate trimnl (datestring); 91*7c478bd9Sstevel@tonic-gate /* asctime: Fri Sep 30 00:00:00 1986\n */ 92*7c478bd9Sstevel@tonic-gate /* 0123456789012345678901234 */ 93*7c478bd9Sstevel@tonic-gate /* RFCtime: Fri, 28 Jul 89 10:30 EDT */ 94*7c478bd9Sstevel@tonic-gate sprintf(RFC822datestring, "%.3s, %.2s %.3s %.4s %.5s %.3s", 95*7c478bd9Sstevel@tonic-gate tp, tp+8, tp+4, tp+20, tp+11, zp); 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate /* 98*7c478bd9Sstevel@tonic-gate Write out the from line header for the letter 99*7c478bd9Sstevel@tonic-gate */ 100*7c478bd9Sstevel@tonic-gate if (fromflag && deliverflag && from_user[0] != '\0') { 101*7c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s%s %s\n", 102*7c478bd9Sstevel@tonic-gate header[H_FROM].tag, from_user, datestring); 103*7c478bd9Sstevel@tonic-gate } else { 104*7c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s%s %s\n", 105*7c478bd9Sstevel@tonic-gate header[H_FROM].tag, my_name, datestring); 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 108*7c478bd9Sstevel@tonic-gate done(0); 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate savehdrs(buf, H_FROM); 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* 113*7c478bd9Sstevel@tonic-gate Copy to list in mail entry? 114*7c478bd9Sstevel@tonic-gate */ 115*7c478bd9Sstevel@tonic-gate if (flgt == 1 && argc > 1) { 116*7c478bd9Sstevel@tonic-gate aret = argc; 117*7c478bd9Sstevel@tonic-gate args = argv; 118*7c478bd9Sstevel@tonic-gate while (--aret > 0) { 119*7c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s %s\n", header[H_TO].tag, *++args); 120*7c478bd9Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 121*7c478bd9Sstevel@tonic-gate done(0); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate savehdrs(buf, H_TO); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate flgf = 1; /* reset when first read of message body succeeds */ 128*7c478bd9Sstevel@tonic-gate /* 129*7c478bd9Sstevel@tonic-gate Read mail message, allowing for lines of infinite 130*7c478bd9Sstevel@tonic-gate length. This is tricky, have to watch for newlines. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate saveint = setsig(SIGINT, savdead); 133*7c478bd9Sstevel@tonic-gate last1c = ' '; /* anything other than newline */ 134*7c478bd9Sstevel@tonic-gate ttyf = isatty (fileno(stdin)); 135*7c478bd9Sstevel@tonic-gate pushrest = 0; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate /* 138*7c478bd9Sstevel@tonic-gate * scan header & save relevant info. 139*7c478bd9Sstevel@tonic-gate */ 140*7c478bd9Sstevel@tonic-gate (void) strlcpy(fromU, my_name, sizeof (fromU)); 141*7c478bd9Sstevel@tonic-gate fromS[0] = 0; /* set up for >From scan */ 142*7c478bd9Sstevel@tonic-gate input = stdin; 143*7c478bd9Sstevel@tonic-gate if (fstat(fileno(input), &sbuf) < 0) { 144*7c478bd9Sstevel@tonic-gate if (errno == EOVERFLOW) { 145*7c478bd9Sstevel@tonic-gate perror("stdin"); 146*7c478bd9Sstevel@tonic-gate exit(1); 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate while ((n = getline (line, sizeof line, stdin)) > 0) { 151*7c478bd9Sstevel@tonic-gate last1c = line[n-1]; 152*7c478bd9Sstevel@tonic-gate if (pushrest) { 153*7c478bd9Sstevel@tonic-gate if (!wtmpf(line,n)) { 154*7c478bd9Sstevel@tonic-gate done(0); 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate pushrest = (last1c != '\n'); 157*7c478bd9Sstevel@tonic-gate continue; 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate pushrest = (last1c != '\n'); 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate if ((hdrtyp = isheader (line, &ctf)) == FALSE) { 162*7c478bd9Sstevel@tonic-gate break; 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate flgf = 0; 165*7c478bd9Sstevel@tonic-gate switch (hdrtyp) { 166*7c478bd9Sstevel@tonic-gate case H_RVERS: 167*7c478bd9Sstevel@tonic-gate /* Are we dealing with a delivery report? */ 168*7c478bd9Sstevel@tonic-gate /* dflag = 9 ==> do not return on failure */ 169*7c478bd9Sstevel@tonic-gate dflag = 9; 170*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "dflag = 9\n"); 171*7c478bd9Sstevel@tonic-gate break; 172*7c478bd9Sstevel@tonic-gate case H_FROM: 173*7c478bd9Sstevel@tonic-gate if (!wtmpf(">", 1)) { 174*7c478bd9Sstevel@tonic-gate done(0); 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate /* note dropthru */ 177*7c478bd9Sstevel@tonic-gate hdrtyp = H_FROM1; 178*7c478bd9Sstevel@tonic-gate case H_FROM1: 179*7c478bd9Sstevel@tonic-gate if (substr(line, "forwarded by") > -1) { 180*7c478bd9Sstevel@tonic-gate break; 181*7c478bd9Sstevel@tonic-gate } 182*7c478bd9Sstevel@tonic-gate pickFrom (line); 183*7c478bd9Sstevel@tonic-gate if (Rpath[0] != '\0') { 184*7c478bd9Sstevel@tonic-gate strcat(Rpath, "!"); 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate (void) strlcat(Rpath, fromS, sizeof (Rpath)); 187*7c478bd9Sstevel@tonic-gate n = 0; /* don't copy remote from's into mesg. */ 188*7c478bd9Sstevel@tonic-gate break; 189*7c478bd9Sstevel@tonic-gate case H_MIMEVERS: 190*7c478bd9Sstevel@tonic-gate case H_CLEN: 191*7c478bd9Sstevel@tonic-gate case H_CTYPE: 192*7c478bd9Sstevel@tonic-gate /* suppress it: only generated if needed */ 193*7c478bd9Sstevel@tonic-gate n = 0; /* suppress */ 194*7c478bd9Sstevel@tonic-gate break; 195*7c478bd9Sstevel@tonic-gate case H_TCOPY: 196*7c478bd9Sstevel@tonic-gate /* Write out placeholder for later */ 197*7c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s \n", header[H_TCOPY].tag); 198*7c478bd9Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 199*7c478bd9Sstevel@tonic-gate done(0); 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate n = 0; /* suppress */ 202*7c478bd9Sstevel@tonic-gate break; 203*7c478bd9Sstevel@tonic-gate case H_MTYPE: 204*7c478bd9Sstevel@tonic-gate if (flgm) { 205*7c478bd9Sstevel@tonic-gate /* suppress if message-type argument */ 206*7c478bd9Sstevel@tonic-gate n = 0; 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate break; 209*7c478bd9Sstevel@tonic-gate case H_CONT: 210*7c478bd9Sstevel@tonic-gate if (oldn == 0) { 211*7c478bd9Sstevel@tonic-gate /* suppress continuation line also */ 212*7c478bd9Sstevel@tonic-gate n = 0; 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate break; 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate oldn = n; /* remember if this line was suppressed */ 217*7c478bd9Sstevel@tonic-gate if (n && !wtmpf(line,n)) { 218*7c478bd9Sstevel@tonic-gate done(0); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate if (!n) savehdrs(line, hdrtyp); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate if (Rpath[0] != '\0') { 223*7c478bd9Sstevel@tonic-gate strcat(Rpath, "!"); 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate (void) strlcat(Rpath, fromU, sizeof (Rpath)); 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate /* push out message type if so requested */ 228*7c478bd9Sstevel@tonic-gate if (flgm) { /* message-type */ 229*7c478bd9Sstevel@tonic-gate snprintf(buf, sizeof(buf), "%s%s\n", header[H_MTYPE].tag, msgtype); 230*7c478bd9Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 231*7c478bd9Sstevel@tonic-gate done(0); 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate memcpy (buf, line, n); 236*7c478bd9Sstevel@tonic-gate if (n == 0 || (ttyf && !strncmp (buf, ".\n", 2)) ) { 237*7c478bd9Sstevel@tonic-gate if (flgf) { 238*7c478bd9Sstevel@tonic-gate /* no input */ 239*7c478bd9Sstevel@tonic-gate return; 240*7c478bd9Sstevel@tonic-gate } else { 241*7c478bd9Sstevel@tonic-gate /* 242*7c478bd9Sstevel@tonic-gate * no content: put mime-version, content-type 243*7c478bd9Sstevel@tonic-gate * and -length only if explicitly present. 244*7c478bd9Sstevel@tonic-gate * Write out 'place-holders' only. (see below....) 245*7c478bd9Sstevel@tonic-gate */ 246*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != 247*7c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 248*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_MIMEVERS].tag); 249*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 250*7c478bd9Sstevel@tonic-gate done(0); 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != 254*7c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 255*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CTYPE].tag); 256*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 257*7c478bd9Sstevel@tonic-gate done(0); 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != 261*7c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 262*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CLEN].tag); 263*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 264*7c478bd9Sstevel@tonic-gate done(0); 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate goto wrapsend; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate if (n == 1 && last1c == '\n') { /* blank line -- suppress */ 272*7c478bd9Sstevel@tonic-gate n = getline (buf, sizeof buf, stdin); 273*7c478bd9Sstevel@tonic-gate if (n == 0 || (ttyf && !strncmp (buf, ".\n", 2)) ) { 274*7c478bd9Sstevel@tonic-gate /* 275*7c478bd9Sstevel@tonic-gate * no content: put mime-version, content-type 276*7c478bd9Sstevel@tonic-gate * and -length only if explicitly present. 277*7c478bd9Sstevel@tonic-gate * Write out 'place-holders' only. (see below....) 278*7c478bd9Sstevel@tonic-gate */ 279*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != 280*7c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 281*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_MIMEVERS].tag); 282*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 283*7c478bd9Sstevel@tonic-gate done(0); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != 287*7c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 288*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CTYPE].tag); 289*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 290*7c478bd9Sstevel@tonic-gate done(0); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != 294*7c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 295*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CLEN].tag); 296*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 297*7c478bd9Sstevel@tonic-gate done(0); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate goto wrapsend; 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate if (debug > 0) { 305*7c478bd9Sstevel@tonic-gate buf[n] = '\0'; 306*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "header scan complete, readahead %d = \"%s\"\n", n, buf); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate /* 310*7c478bd9Sstevel@tonic-gate * Write out H_MIMEVERS, H_CTYPE & H_CLEN lines. These are used only as 311*7c478bd9Sstevel@tonic-gate * placeholders in the tmp file. When the 'real' message is sent, 312*7c478bd9Sstevel@tonic-gate * the proper values will be put out by copylet(). 313*7c478bd9Sstevel@tonic-gate */ 314*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_MIMEVERS].tag); 315*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 316*7c478bd9Sstevel@tonic-gate done(0); 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate if (hdrlines[H_MIMEVERS].head == (struct hdrs *)NULL) { 319*7c478bd9Sstevel@tonic-gate savehdrs(line, H_MIMEVERS); 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CTYPE].tag); 322*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 323*7c478bd9Sstevel@tonic-gate done(0); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate if (hdrlines[H_CTYPE].head == (struct hdrs *)NULL) { 326*7c478bd9Sstevel@tonic-gate savehdrs(line,H_CTYPE); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CLEN].tag); 329*7c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 330*7c478bd9Sstevel@tonic-gate done(0); 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate if (hdrlines[H_CLEN].head == (struct hdrs *)NULL) { 333*7c478bd9Sstevel@tonic-gate savehdrs(line,H_CLEN); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate /* and a blank line */ 336*7c478bd9Sstevel@tonic-gate if (!wtmpf("\n", 1)) { 337*7c478bd9Sstevel@tonic-gate done(0); 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "header out completed\n"); 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate pushrest = 0; 342*7c478bd9Sstevel@tonic-gate count = 0L; 343*7c478bd9Sstevel@tonic-gate /* 344*7c478bd9Sstevel@tonic-gate * Are we returning mail from a delivery failure of an old-style 345*7c478bd9Sstevel@tonic-gate * (SVR3.1 or SVR3.0) rmail? If so, we won't return THIS on failure 346*7c478bd9Sstevel@tonic-gate * [This line should occur as the FIRST non-blank non-header line] 347*7c478bd9Sstevel@tonic-gate */ 348*7c478bd9Sstevel@tonic-gate if (!strncmp("***** UNDELIVERABLE MAIL sent to",buf,32)) { 349*7c478bd9Sstevel@tonic-gate dflag = 9; /* 9 says do not return on failure */ 350*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "found old-style UNDELIVERABLE line. dflag = 9\n"); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate /* scan body of message */ 354*7c478bd9Sstevel@tonic-gate while (n > 0) { 355*7c478bd9Sstevel@tonic-gate if (ttyf && !strcmp (buf, ".\n")) 356*7c478bd9Sstevel@tonic-gate break; 357*7c478bd9Sstevel@tonic-gate if (!binflg) { 358*7c478bd9Sstevel@tonic-gate binflg = !istext ((unsigned char *)buf, n); 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate if (!wtmpf(buf, n)) { 362*7c478bd9Sstevel@tonic-gate done(0); 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate count += n; 365*7c478bd9Sstevel@tonic-gate n = ttyf 366*7c478bd9Sstevel@tonic-gate ? getline (buf, sizeof buf, stdin) 367*7c478bd9Sstevel@tonic-gate : fread (buf, 1, sizeof buf, stdin); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate setsig(SIGINT, saveint); 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate wrapsend: 372*7c478bd9Sstevel@tonic-gate /* 373*7c478bd9Sstevel@tonic-gate * In order to use some of the subroutines that are used to 374*7c478bd9Sstevel@tonic-gate * read mail, the let array must be set up 375*7c478bd9Sstevel@tonic-gate */ 376*7c478bd9Sstevel@tonic-gate nlet = 1; 377*7c478bd9Sstevel@tonic-gate let[0].adr = 0; 378*7c478bd9Sstevel@tonic-gate let[1].adr = ftell(tmpf); 379*7c478bd9Sstevel@tonic-gate let[0].text = (binflg == 1 ? FALSE : TRUE); 380*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "body copy complete, count %ld\n", count); 381*7c478bd9Sstevel@tonic-gate /* 382*7c478bd9Sstevel@tonic-gate * Modify value of H_MIMEVERS if necessary. 383*7c478bd9Sstevel@tonic-gate */ 384*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != (struct hdrs *)NULL) { 385*7c478bd9Sstevel@tonic-gate if (strlen(hptr->value) == 0) { 386*7c478bd9Sstevel@tonic-gate (void) strlcpy(hptr->value, "1.0", 387*7c478bd9Sstevel@tonic-gate sizeof (hptr->value)); 388*7c478bd9Sstevel@tonic-gate } 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate /* 391*7c478bd9Sstevel@tonic-gate * Modify value of H_CTYPE if necessary. 392*7c478bd9Sstevel@tonic-gate */ 393*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != (struct hdrs *)NULL) { 394*7c478bd9Sstevel@tonic-gate if (strlen(hptr->value) == 0) { 395*7c478bd9Sstevel@tonic-gate (void) strlcpy(hptr->value, "text/plain", 396*7c478bd9Sstevel@tonic-gate sizeof (hptr->value)); 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate /* 400*7c478bd9Sstevel@tonic-gate * Set 'place-holder' value of content length to true value 401*7c478bd9Sstevel@tonic-gate */ 402*7c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != (struct hdrs *)NULL) { 403*7c478bd9Sstevel@tonic-gate (void) snprintf(hptr->value, sizeof (hptr->value), 404*7c478bd9Sstevel@tonic-gate "%ld", count); 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate if (fclose(tmpf) == EOF) { 408*7c478bd9Sstevel@tonic-gate tmperr(); 409*7c478bd9Sstevel@tonic-gate done(0); 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate tmpf = doopen(lettmp,"r+",E_TMP); 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate /* Do not send mail on SIGINT */ 415*7c478bd9Sstevel@tonic-gate if (dflag == 2) { 416*7c478bd9Sstevel@tonic-gate done(0); 417*7c478bd9Sstevel@tonic-gate } 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate sendlist(&list, 0, 0); 420*7c478bd9Sstevel@tonic-gate done(0); 421*7c478bd9Sstevel@tonic-gate } 422