10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*5387Sny155746 * Common Development and Distribution License (the "License"). 6*5387Sny155746 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 220Sstevel@tonic-gate /* All Rights Reserved */ 230Sstevel@tonic-gate 240Sstevel@tonic-gate 250Sstevel@tonic-gate /* 26*5387Sny155746 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 270Sstevel@tonic-gate * Use is subject to license terms. 280Sstevel@tonic-gate */ 290Sstevel@tonic-gate 300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include "mail.h" 33*5387Sny155746 #include <sys/param.h> 340Sstevel@tonic-gate /* 35*5387Sny155746 * Send mail - High level sending routine 360Sstevel@tonic-gate */ 37*5387Sny155746 void 38*5387Sny155746 sendmail(argc, argv) 390Sstevel@tonic-gate char **argv; 400Sstevel@tonic-gate { 410Sstevel@tonic-gate char **args; 420Sstevel@tonic-gate char *tp, *zp; 43*5387Sny155746 char buf[2048], last1c; 440Sstevel@tonic-gate FILE *input; 45*5387Sny155746 struct stat64 sbuf; 460Sstevel@tonic-gate int aret; 470Sstevel@tonic-gate int i, n; 48*5387Sny155746 int oldn = 1; 490Sstevel@tonic-gate int ttyf = 0; 500Sstevel@tonic-gate int pushrest = 0; 510Sstevel@tonic-gate int hdrtyp = 0; 520Sstevel@tonic-gate int ctf = FALSE; 530Sstevel@tonic-gate int binflg = 0; 540Sstevel@tonic-gate long count = 0L; 550Sstevel@tonic-gate struct tm *bp; 560Sstevel@tonic-gate struct hdrs *hptr; 570Sstevel@tonic-gate static char pn[] = "sendmail"; 580Sstevel@tonic-gate reciplist list; 590Sstevel@tonic-gate 600Sstevel@tonic-gate Dout(pn, 0, "entered\n"); 610Sstevel@tonic-gate new_reciplist(&list); 620Sstevel@tonic-gate for (i = 1; i < argc; ++i) { 63*5387Sny155746 if (argv[i][0] == '-') { 64*5387Sny155746 if (argv[i][1] == '\0') { 65*5387Sny155746 errmsg(E_SYNTAX, 66*5387Sny155746 "Hyphens MAY NOT be followed by spaces"); 670Sstevel@tonic-gate } 68*5387Sny155746 if (i > 1) { 69*5387Sny155746 errmsg(E_SYNTAX, 70*5387Sny155746 "Options MUST PRECEDE persons"); 710Sstevel@tonic-gate } 72*5387Sny155746 done(0); 73*5387Sny155746 } 740Sstevel@tonic-gate /* 75*5387Sny155746 * Ensure no NULL names in list 76*5387Sny155746 */ 77*5387Sny155746 if (argv[i][0] == '\0' || argv[i][strlen(argv[i])-1] == '!') { 78*5387Sny155746 errmsg(E_SYNTAX, "Null names are not allowed"); 79*5387Sny155746 done(0); 800Sstevel@tonic-gate } 81*5387Sny155746 /* Don't check for duplication */ 82*5387Sny155746 add_recip(&list, argv[i], FALSE); 830Sstevel@tonic-gate } 840Sstevel@tonic-gate 850Sstevel@tonic-gate mktmp(); 860Sstevel@tonic-gate /* 87*5387Sny155746 * Format time 88*5387Sny155746 */ 890Sstevel@tonic-gate time(&iop); 900Sstevel@tonic-gate bp = localtime(&iop); 910Sstevel@tonic-gate tp = asctime(bp); 920Sstevel@tonic-gate zp = tzname[bp->tm_isdst]; 930Sstevel@tonic-gate sprintf(datestring, "%.16s %.3s %.5s", tp, zp, tp+20); 94*5387Sny155746 trimnl(datestring); 950Sstevel@tonic-gate /* asctime: Fri Sep 30 00:00:00 1986\n */ 96*5387Sny155746 /* 0123456789012345678901234 */ 970Sstevel@tonic-gate /* RFCtime: Fri, 28 Jul 89 10:30 EDT */ 980Sstevel@tonic-gate sprintf(RFC822datestring, "%.3s, %.2s %.3s %.4s %.5s %.3s", 990Sstevel@tonic-gate tp, tp+8, tp+4, tp+20, tp+11, zp); 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate /* 102*5387Sny155746 * Write out the from line header for the letter 103*5387Sny155746 */ 1040Sstevel@tonic-gate if (fromflag && deliverflag && from_user[0] != '\0') { 105*5387Sny155746 (void) snprintf(buf, sizeof (buf), "%s%s %s\n", 1060Sstevel@tonic-gate header[H_FROM].tag, from_user, datestring); 1070Sstevel@tonic-gate } else { 108*5387Sny155746 (void) snprintf(buf, sizeof (buf), "%s%s %s\n", 1090Sstevel@tonic-gate header[H_FROM].tag, my_name, datestring); 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 1120Sstevel@tonic-gate done(0); 1130Sstevel@tonic-gate } 1140Sstevel@tonic-gate savehdrs(buf, H_FROM); 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate /* 117*5387Sny155746 * Copy to list in mail entry? 118*5387Sny155746 */ 1190Sstevel@tonic-gate if (flgt == 1 && argc > 1) { 1200Sstevel@tonic-gate aret = argc; 1210Sstevel@tonic-gate args = argv; 1220Sstevel@tonic-gate while (--aret > 0) { 123*5387Sny155746 (void) snprintf(buf, sizeof (buf), 124*5387Sny155746 "%s %s\n", header[H_TO].tag, *++args); 1250Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 1260Sstevel@tonic-gate done(0); 1270Sstevel@tonic-gate } 1280Sstevel@tonic-gate savehdrs(buf, H_TO); 1290Sstevel@tonic-gate } 1300Sstevel@tonic-gate } 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate flgf = 1; /* reset when first read of message body succeeds */ 1330Sstevel@tonic-gate /* 134*5387Sny155746 * Read mail message, allowing for lines of infinite 135*5387Sny155746 * length. This is tricky, have to watch for newlines. 136*5387Sny155746 */ 1370Sstevel@tonic-gate saveint = setsig(SIGINT, savdead); 1380Sstevel@tonic-gate last1c = ' '; /* anything other than newline */ 139*5387Sny155746 ttyf = isatty(fileno(stdin)); 1400Sstevel@tonic-gate pushrest = 0; 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate /* 1430Sstevel@tonic-gate * scan header & save relevant info. 1440Sstevel@tonic-gate */ 1450Sstevel@tonic-gate (void) strlcpy(fromU, my_name, sizeof (fromU)); 1460Sstevel@tonic-gate fromS[0] = 0; /* set up for >From scan */ 1470Sstevel@tonic-gate input = stdin; 148*5387Sny155746 /* 149*5387Sny155746 * Fifofs cannot handle if the inode number crosses 150*5387Sny155746 * 32-bit limit. This results in overflow, if the 151*5387Sny155746 * input steam is a pipe. Using 64-bit interface to 152*5387Sny155746 * take care of that. 153*5387Sny155746 */ 154*5387Sny155746 if (fstat64(fileno(input), &sbuf) == 0) { 155*5387Sny155746 /* Also care if we could not handle large mail. */ 156*5387Sny155746 if ((sbuf.st_size > MAXOFF_T) || (sbuf.st_blocks > LONG_MAX)) { 157*5387Sny155746 fprintf(stderr, "%s: stdin: %s\n", program, 158*5387Sny155746 strerror(EOVERFLOW)); 1590Sstevel@tonic-gate exit(1); 1600Sstevel@tonic-gate } 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate 163*5387Sny155746 while ((n = getline(line, sizeof (line), stdin)) > 0) { 1640Sstevel@tonic-gate last1c = line[n-1]; 1650Sstevel@tonic-gate if (pushrest) { 166*5387Sny155746 if (!wtmpf(line, n)) { 1670Sstevel@tonic-gate done(0); 1680Sstevel@tonic-gate } 1690Sstevel@tonic-gate pushrest = (last1c != '\n'); 1700Sstevel@tonic-gate continue; 1710Sstevel@tonic-gate } 1720Sstevel@tonic-gate pushrest = (last1c != '\n'); 1730Sstevel@tonic-gate 174*5387Sny155746 if ((hdrtyp = isheader(line, &ctf)) == FALSE) { 1750Sstevel@tonic-gate break; 1760Sstevel@tonic-gate } 1770Sstevel@tonic-gate flgf = 0; 1780Sstevel@tonic-gate switch (hdrtyp) { 1790Sstevel@tonic-gate case H_RVERS: 1800Sstevel@tonic-gate /* Are we dealing with a delivery report? */ 1810Sstevel@tonic-gate /* dflag = 9 ==> do not return on failure */ 1820Sstevel@tonic-gate dflag = 9; 1830Sstevel@tonic-gate Dout(pn, 0, "dflag = 9\n"); 1840Sstevel@tonic-gate break; 1850Sstevel@tonic-gate case H_FROM: 1860Sstevel@tonic-gate if (!wtmpf(">", 1)) { 1870Sstevel@tonic-gate done(0); 1880Sstevel@tonic-gate } 1890Sstevel@tonic-gate /* note dropthru */ 1900Sstevel@tonic-gate hdrtyp = H_FROM1; 1910Sstevel@tonic-gate case H_FROM1: 1920Sstevel@tonic-gate if (substr(line, "forwarded by") > -1) { 1930Sstevel@tonic-gate break; 1940Sstevel@tonic-gate } 195*5387Sny155746 pickFrom(line); 1960Sstevel@tonic-gate if (Rpath[0] != '\0') { 1970Sstevel@tonic-gate strcat(Rpath, "!"); 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate (void) strlcat(Rpath, fromS, sizeof (Rpath)); 2000Sstevel@tonic-gate n = 0; /* don't copy remote from's into mesg. */ 2010Sstevel@tonic-gate break; 2020Sstevel@tonic-gate case H_MIMEVERS: 2030Sstevel@tonic-gate case H_CLEN: 2040Sstevel@tonic-gate case H_CTYPE: 2050Sstevel@tonic-gate /* suppress it: only generated if needed */ 2060Sstevel@tonic-gate n = 0; /* suppress */ 2070Sstevel@tonic-gate break; 2080Sstevel@tonic-gate case H_TCOPY: 2090Sstevel@tonic-gate /* Write out placeholder for later */ 210*5387Sny155746 (void) snprintf(buf, sizeof (buf), "%s \n", 211*5387Sny155746 header[H_TCOPY].tag); 2120Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 2130Sstevel@tonic-gate done(0); 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate n = 0; /* suppress */ 2160Sstevel@tonic-gate break; 2170Sstevel@tonic-gate case H_MTYPE: 2180Sstevel@tonic-gate if (flgm) { 2190Sstevel@tonic-gate /* suppress if message-type argument */ 2200Sstevel@tonic-gate n = 0; 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate break; 2230Sstevel@tonic-gate case H_CONT: 2240Sstevel@tonic-gate if (oldn == 0) { 2250Sstevel@tonic-gate /* suppress continuation line also */ 2260Sstevel@tonic-gate n = 0; 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate break; 2290Sstevel@tonic-gate } 2300Sstevel@tonic-gate oldn = n; /* remember if this line was suppressed */ 231*5387Sny155746 if (n && !wtmpf(line, n)) { 2320Sstevel@tonic-gate done(0); 2330Sstevel@tonic-gate } 2340Sstevel@tonic-gate if (!n) savehdrs(line, hdrtyp); 2350Sstevel@tonic-gate } 2360Sstevel@tonic-gate if (Rpath[0] != '\0') { 2370Sstevel@tonic-gate strcat(Rpath, "!"); 2380Sstevel@tonic-gate } 2390Sstevel@tonic-gate (void) strlcat(Rpath, fromU, sizeof (Rpath)); 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate /* push out message type if so requested */ 2420Sstevel@tonic-gate if (flgm) { /* message-type */ 243*5387Sny155746 snprintf(buf, sizeof (buf), "%s%s\n", 244*5387Sny155746 header[H_MTYPE].tag, msgtype); 2450Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 2460Sstevel@tonic-gate done(0); 2470Sstevel@tonic-gate } 2480Sstevel@tonic-gate } 2490Sstevel@tonic-gate 250*5387Sny155746 memcpy(buf, line, n); 251*5387Sny155746 if (n == 0 || (ttyf && !strncmp(buf, ".\n", 2))) { 2520Sstevel@tonic-gate if (flgf) { 2530Sstevel@tonic-gate /* no input */ 2540Sstevel@tonic-gate return; 2550Sstevel@tonic-gate } else { 2560Sstevel@tonic-gate /* 2570Sstevel@tonic-gate * no content: put mime-version, content-type 2580Sstevel@tonic-gate * and -length only if explicitly present. 2590Sstevel@tonic-gate * Write out 'place-holders' only. (see below....) 2600Sstevel@tonic-gate */ 2610Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != 2620Sstevel@tonic-gate (struct hdrs *)NULL) { 263*5387Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 264*5387Sny155746 header[H_MIMEVERS].tag); 2650Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 2660Sstevel@tonic-gate done(0); 2670Sstevel@tonic-gate } 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != 2700Sstevel@tonic-gate (struct hdrs *)NULL) { 271*5387Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 272*5387Sny155746 header[H_CTYPE].tag); 2730Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 2740Sstevel@tonic-gate done(0); 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate } 2770Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != 2780Sstevel@tonic-gate (struct hdrs *)NULL) { 279*5387Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 280*5387Sny155746 header[H_CLEN].tag); 2810Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 2820Sstevel@tonic-gate done(0); 2830Sstevel@tonic-gate } 2840Sstevel@tonic-gate } 2850Sstevel@tonic-gate goto wrapsend; 2860Sstevel@tonic-gate } 2870Sstevel@tonic-gate } 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate if (n == 1 && last1c == '\n') { /* blank line -- suppress */ 290*5387Sny155746 n = getline(buf, sizeof (buf), stdin); 291*5387Sny155746 if (n == 0 || (ttyf && !strncmp(buf, ".\n", 2))) { 2920Sstevel@tonic-gate /* 2930Sstevel@tonic-gate * no content: put mime-version, content-type 2940Sstevel@tonic-gate * and -length only if explicitly present. 2950Sstevel@tonic-gate * Write out 'place-holders' only. (see below....) 2960Sstevel@tonic-gate */ 2970Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != 2980Sstevel@tonic-gate (struct hdrs *)NULL) { 299*5387Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 300*5387Sny155746 header[H_MIMEVERS].tag); 3010Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3020Sstevel@tonic-gate done(0); 3030Sstevel@tonic-gate } 3040Sstevel@tonic-gate } 3050Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != 3060Sstevel@tonic-gate (struct hdrs *)NULL) { 307*5387Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 308*5387Sny155746 header[H_CTYPE].tag); 3090Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3100Sstevel@tonic-gate done(0); 3110Sstevel@tonic-gate } 3120Sstevel@tonic-gate } 3130Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != 3140Sstevel@tonic-gate (struct hdrs *)NULL) { 315*5387Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 316*5387Sny155746 header[H_CLEN].tag); 3170Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3180Sstevel@tonic-gate done(0); 3190Sstevel@tonic-gate } 3200Sstevel@tonic-gate } 3210Sstevel@tonic-gate goto wrapsend; 3220Sstevel@tonic-gate } 3230Sstevel@tonic-gate } 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate if (debug > 0) { 3260Sstevel@tonic-gate buf[n] = '\0'; 327*5387Sny155746 Dout(pn, 0, "header scan complete, readahead %d = \"%s\"\n", 328*5387Sny155746 n, buf); 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate 331*5387Sny155746 /* 332*5387Sny155746 * Write out H_MIMEVERS, H_CTYPE & H_CLEN lines. These are used only as 3330Sstevel@tonic-gate * placeholders in the tmp file. When the 'real' message is sent, 3340Sstevel@tonic-gate * the proper values will be put out by copylet(). 3350Sstevel@tonic-gate */ 3360Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_MIMEVERS].tag); 3370Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3380Sstevel@tonic-gate done(0); 3390Sstevel@tonic-gate } 3400Sstevel@tonic-gate if (hdrlines[H_MIMEVERS].head == (struct hdrs *)NULL) { 3410Sstevel@tonic-gate savehdrs(line, H_MIMEVERS); 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CTYPE].tag); 3440Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3450Sstevel@tonic-gate done(0); 3460Sstevel@tonic-gate } 3470Sstevel@tonic-gate if (hdrlines[H_CTYPE].head == (struct hdrs *)NULL) { 348*5387Sny155746 savehdrs(line, H_CTYPE); 3490Sstevel@tonic-gate } 3500Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CLEN].tag); 3510Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3520Sstevel@tonic-gate done(0); 3530Sstevel@tonic-gate } 3540Sstevel@tonic-gate if (hdrlines[H_CLEN].head == (struct hdrs *)NULL) { 355*5387Sny155746 savehdrs(line, H_CLEN); 3560Sstevel@tonic-gate } 3570Sstevel@tonic-gate /* and a blank line */ 3580Sstevel@tonic-gate if (!wtmpf("\n", 1)) { 3590Sstevel@tonic-gate done(0); 3600Sstevel@tonic-gate } 3610Sstevel@tonic-gate Dout(pn, 0, "header out completed\n"); 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate pushrest = 0; 3640Sstevel@tonic-gate count = 0L; 3650Sstevel@tonic-gate /* 3660Sstevel@tonic-gate * Are we returning mail from a delivery failure of an old-style 3670Sstevel@tonic-gate * (SVR3.1 or SVR3.0) rmail? If so, we won't return THIS on failure 3680Sstevel@tonic-gate * [This line should occur as the FIRST non-blank non-header line] 3690Sstevel@tonic-gate */ 370*5387Sny155746 if (!strncmp("***** UNDELIVERABLE MAIL sent to", buf, 32)) { 371*5387Sny155746 dflag = 9; /* 9 says do not return on failure */ 372*5387Sny155746 Dout(pn, 0, "found old-style UNDELIVERABLE line. dflag = 9\n"); 3730Sstevel@tonic-gate } 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate /* scan body of message */ 3760Sstevel@tonic-gate while (n > 0) { 377*5387Sny155746 if (ttyf && !strcmp(buf, ".\n")) 3780Sstevel@tonic-gate break; 3790Sstevel@tonic-gate if (!binflg) { 380*5387Sny155746 binflg = !istext((unsigned char *)buf, n); 3810Sstevel@tonic-gate } 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate if (!wtmpf(buf, n)) { 3840Sstevel@tonic-gate done(0); 3850Sstevel@tonic-gate } 3860Sstevel@tonic-gate count += n; 3870Sstevel@tonic-gate n = ttyf 388*5387Sny155746 ? getline(buf, sizeof (buf), stdin) 389*5387Sny155746 : fread(buf, 1, sizeof (buf), stdin); 3900Sstevel@tonic-gate } 3910Sstevel@tonic-gate setsig(SIGINT, saveint); 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate wrapsend: 3940Sstevel@tonic-gate /* 3950Sstevel@tonic-gate * In order to use some of the subroutines that are used to 3960Sstevel@tonic-gate * read mail, the let array must be set up 3970Sstevel@tonic-gate */ 3980Sstevel@tonic-gate nlet = 1; 3990Sstevel@tonic-gate let[0].adr = 0; 4000Sstevel@tonic-gate let[1].adr = ftell(tmpf); 4010Sstevel@tonic-gate let[0].text = (binflg == 1 ? FALSE : TRUE); 4020Sstevel@tonic-gate Dout(pn, 0, "body copy complete, count %ld\n", count); 4030Sstevel@tonic-gate /* 4040Sstevel@tonic-gate * Modify value of H_MIMEVERS if necessary. 4050Sstevel@tonic-gate */ 4060Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != (struct hdrs *)NULL) { 4070Sstevel@tonic-gate if (strlen(hptr->value) == 0) { 4080Sstevel@tonic-gate (void) strlcpy(hptr->value, "1.0", 4090Sstevel@tonic-gate sizeof (hptr->value)); 4100Sstevel@tonic-gate } 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate /* 4130Sstevel@tonic-gate * Modify value of H_CTYPE if necessary. 4140Sstevel@tonic-gate */ 4150Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != (struct hdrs *)NULL) { 4160Sstevel@tonic-gate if (strlen(hptr->value) == 0) { 4170Sstevel@tonic-gate (void) strlcpy(hptr->value, "text/plain", 4180Sstevel@tonic-gate sizeof (hptr->value)); 4190Sstevel@tonic-gate } 4200Sstevel@tonic-gate } 4210Sstevel@tonic-gate /* 4220Sstevel@tonic-gate * Set 'place-holder' value of content length to true value 4230Sstevel@tonic-gate */ 4240Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != (struct hdrs *)NULL) { 4250Sstevel@tonic-gate (void) snprintf(hptr->value, sizeof (hptr->value), 4260Sstevel@tonic-gate "%ld", count); 4270Sstevel@tonic-gate } 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate if (fclose(tmpf) == EOF) { 4300Sstevel@tonic-gate tmperr(); 4310Sstevel@tonic-gate done(0); 4320Sstevel@tonic-gate } 4330Sstevel@tonic-gate 434*5387Sny155746 tmpf = doopen(lettmp, "r+", E_TMP); 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate /* Do not send mail on SIGINT */ 4370Sstevel@tonic-gate if (dflag == 2) { 4380Sstevel@tonic-gate done(0); 4390Sstevel@tonic-gate } 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate sendlist(&list, 0, 0); 4420Sstevel@tonic-gate done(0); 4430Sstevel@tonic-gate } 444