17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 58e472857Sny155746 * Common Development and Distribution License (the "License"). 68e472857Sny155746 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate /* 23*23a1cceaSRoger A. Faulkner * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 26*23a1cceaSRoger A. Faulkner /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27*23a1cceaSRoger A. Faulkner /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include "mail.h" 308e472857Sny155746 #include <sys/param.h> 317c478bd9Sstevel@tonic-gate /* 328e472857Sny155746 * Send mail - High level sending routine 337c478bd9Sstevel@tonic-gate */ 348e472857Sny155746 void 358e472857Sny155746 sendmail(argc, argv) 367c478bd9Sstevel@tonic-gate char **argv; 377c478bd9Sstevel@tonic-gate { 387c478bd9Sstevel@tonic-gate char **args; 397c478bd9Sstevel@tonic-gate char *tp, *zp; 407c478bd9Sstevel@tonic-gate char buf[2048], last1c; 417c478bd9Sstevel@tonic-gate FILE *input; 428e472857Sny155746 struct stat64 sbuf; 437c478bd9Sstevel@tonic-gate int aret; 447c478bd9Sstevel@tonic-gate int i, n; 457c478bd9Sstevel@tonic-gate int oldn = 1; 467c478bd9Sstevel@tonic-gate int ttyf = 0; 477c478bd9Sstevel@tonic-gate int pushrest = 0; 487c478bd9Sstevel@tonic-gate int hdrtyp = 0; 497c478bd9Sstevel@tonic-gate int ctf = FALSE; 507c478bd9Sstevel@tonic-gate int binflg = 0; 517c478bd9Sstevel@tonic-gate long count = 0L; 527c478bd9Sstevel@tonic-gate struct tm *bp; 537c478bd9Sstevel@tonic-gate struct hdrs *hptr; 547c478bd9Sstevel@tonic-gate static char pn[] = "sendmail"; 557c478bd9Sstevel@tonic-gate reciplist list; 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate Dout(pn, 0, "entered\n"); 587c478bd9Sstevel@tonic-gate new_reciplist(&list); 597c478bd9Sstevel@tonic-gate for (i = 1; i < argc; ++i) { 607c478bd9Sstevel@tonic-gate if (argv[i][0] == '-') { 617c478bd9Sstevel@tonic-gate if (argv[i][1] == '\0') { 628e472857Sny155746 errmsg(E_SYNTAX, 638e472857Sny155746 "Hyphens MAY NOT be followed by spaces"); 647c478bd9Sstevel@tonic-gate } 657c478bd9Sstevel@tonic-gate if (i > 1) { 668e472857Sny155746 errmsg(E_SYNTAX, 678e472857Sny155746 "Options MUST PRECEDE persons"); 687c478bd9Sstevel@tonic-gate } 697c478bd9Sstevel@tonic-gate done(0); 707c478bd9Sstevel@tonic-gate } 717c478bd9Sstevel@tonic-gate /* 728e472857Sny155746 * Ensure no NULL names in list 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate if (argv[i][0] == '\0' || argv[i][strlen(argv[i])-1] == '!') { 757c478bd9Sstevel@tonic-gate errmsg(E_SYNTAX, "Null names are not allowed"); 767c478bd9Sstevel@tonic-gate done(0); 777c478bd9Sstevel@tonic-gate } 788e472857Sny155746 /* Don't check for duplication */ 798e472857Sny155746 add_recip(&list, argv[i], FALSE); 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate mktmp(); 837c478bd9Sstevel@tonic-gate /* 848e472857Sny155746 * Format time 857c478bd9Sstevel@tonic-gate */ 867c478bd9Sstevel@tonic-gate time(&iop); 877c478bd9Sstevel@tonic-gate bp = localtime(&iop); 887c478bd9Sstevel@tonic-gate tp = asctime(bp); 897c478bd9Sstevel@tonic-gate zp = tzname[bp->tm_isdst]; 907c478bd9Sstevel@tonic-gate sprintf(datestring, "%.16s %.3s %.5s", tp, zp, tp+20); 917c478bd9Sstevel@tonic-gate trimnl(datestring); 927c478bd9Sstevel@tonic-gate /* asctime: Fri Sep 30 00:00:00 1986\n */ 937c478bd9Sstevel@tonic-gate /* 0123456789012345678901234 */ 947c478bd9Sstevel@tonic-gate /* RFCtime: Fri, 28 Jul 89 10:30 EDT */ 957c478bd9Sstevel@tonic-gate sprintf(RFC822datestring, "%.3s, %.2s %.3s %.4s %.5s %.3s", 967c478bd9Sstevel@tonic-gate tp, tp+8, tp+4, tp+20, tp+11, zp); 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* 998e472857Sny155746 * Write out the from line header for the letter 1007c478bd9Sstevel@tonic-gate */ 1017c478bd9Sstevel@tonic-gate if (fromflag && deliverflag && from_user[0] != '\0') { 1027c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s%s %s\n", 1037c478bd9Sstevel@tonic-gate header[H_FROM].tag, from_user, datestring); 1047c478bd9Sstevel@tonic-gate } else { 1057c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s%s %s\n", 1067c478bd9Sstevel@tonic-gate header[H_FROM].tag, my_name, datestring); 1077c478bd9Sstevel@tonic-gate } 1087c478bd9Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 1097c478bd9Sstevel@tonic-gate done(0); 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate savehdrs(buf, H_FROM); 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /* 1148e472857Sny155746 * Copy to list in mail entry? 1157c478bd9Sstevel@tonic-gate */ 1167c478bd9Sstevel@tonic-gate if (flgt == 1 && argc > 1) { 1177c478bd9Sstevel@tonic-gate aret = argc; 1187c478bd9Sstevel@tonic-gate args = argv; 1197c478bd9Sstevel@tonic-gate while (--aret > 0) { 1208e472857Sny155746 (void) snprintf(buf, sizeof (buf), 1218e472857Sny155746 "%s %s\n", header[H_TO].tag, *++args); 1227c478bd9Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 1237c478bd9Sstevel@tonic-gate done(0); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate savehdrs(buf, H_TO); 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate flgf = 1; /* reset when first read of message body succeeds */ 1307c478bd9Sstevel@tonic-gate /* 1318e472857Sny155746 * Read mail message, allowing for lines of infinite 1328e472857Sny155746 * length. This is tricky, have to watch for newlines. 1337c478bd9Sstevel@tonic-gate */ 1347c478bd9Sstevel@tonic-gate saveint = setsig(SIGINT, savdead); 1357c478bd9Sstevel@tonic-gate last1c = ' '; /* anything other than newline */ 1367c478bd9Sstevel@tonic-gate ttyf = isatty(fileno(stdin)); 1377c478bd9Sstevel@tonic-gate pushrest = 0; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* 1407c478bd9Sstevel@tonic-gate * scan header & save relevant info. 1417c478bd9Sstevel@tonic-gate */ 1427c478bd9Sstevel@tonic-gate (void) strlcpy(fromU, my_name, sizeof (fromU)); 1437c478bd9Sstevel@tonic-gate fromS[0] = 0; /* set up for >From scan */ 1447c478bd9Sstevel@tonic-gate input = stdin; 1458e472857Sny155746 /* 1468e472857Sny155746 * Fifofs cannot handle if the inode number crosses 1478e472857Sny155746 * 32-bit limit. This results in overflow, if the 1488e472857Sny155746 * input steam is a pipe. Using 64-bit interface to 1498e472857Sny155746 * take care of that. 1508e472857Sny155746 */ 1518e472857Sny155746 if (fstat64(fileno(input), &sbuf) == 0) { 1528e472857Sny155746 /* Also care if we could not handle large mail. */ 1538e472857Sny155746 if ((sbuf.st_size > MAXOFF_T) || (sbuf.st_blocks > LONG_MAX)) { 1548e472857Sny155746 fprintf(stderr, "%s: stdin: %s\n", program, 1558e472857Sny155746 strerror(EOVERFLOW)); 1567c478bd9Sstevel@tonic-gate exit(1); 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate 160*23a1cceaSRoger A. Faulkner while ((n = getaline(line, sizeof (line), stdin)) > 0) { 1617c478bd9Sstevel@tonic-gate last1c = line[n-1]; 1627c478bd9Sstevel@tonic-gate if (pushrest) { 1637c478bd9Sstevel@tonic-gate if (!wtmpf(line, n)) { 1647c478bd9Sstevel@tonic-gate done(0); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate pushrest = (last1c != '\n'); 1677c478bd9Sstevel@tonic-gate continue; 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate pushrest = (last1c != '\n'); 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate if ((hdrtyp = isheader(line, &ctf)) == FALSE) { 1727c478bd9Sstevel@tonic-gate break; 1737c478bd9Sstevel@tonic-gate } 1747c478bd9Sstevel@tonic-gate flgf = 0; 1757c478bd9Sstevel@tonic-gate switch (hdrtyp) { 1767c478bd9Sstevel@tonic-gate case H_RVERS: 1777c478bd9Sstevel@tonic-gate /* Are we dealing with a delivery report? */ 1787c478bd9Sstevel@tonic-gate /* dflag = 9 ==> do not return on failure */ 1797c478bd9Sstevel@tonic-gate dflag = 9; 1807c478bd9Sstevel@tonic-gate Dout(pn, 0, "dflag = 9\n"); 1817c478bd9Sstevel@tonic-gate break; 1827c478bd9Sstevel@tonic-gate case H_FROM: 1837c478bd9Sstevel@tonic-gate if (!wtmpf(">", 1)) { 1847c478bd9Sstevel@tonic-gate done(0); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate /* note dropthru */ 1877c478bd9Sstevel@tonic-gate hdrtyp = H_FROM1; 1887c478bd9Sstevel@tonic-gate case H_FROM1: 1897c478bd9Sstevel@tonic-gate if (substr(line, "forwarded by") > -1) { 1907c478bd9Sstevel@tonic-gate break; 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate pickFrom(line); 1937c478bd9Sstevel@tonic-gate if (Rpath[0] != '\0') { 1947c478bd9Sstevel@tonic-gate strcat(Rpath, "!"); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate (void) strlcat(Rpath, fromS, sizeof (Rpath)); 1977c478bd9Sstevel@tonic-gate n = 0; /* don't copy remote from's into mesg. */ 1987c478bd9Sstevel@tonic-gate break; 1997c478bd9Sstevel@tonic-gate case H_MIMEVERS: 2007c478bd9Sstevel@tonic-gate case H_CLEN: 2017c478bd9Sstevel@tonic-gate case H_CTYPE: 2027c478bd9Sstevel@tonic-gate /* suppress it: only generated if needed */ 2037c478bd9Sstevel@tonic-gate n = 0; /* suppress */ 2047c478bd9Sstevel@tonic-gate break; 2057c478bd9Sstevel@tonic-gate case H_TCOPY: 2067c478bd9Sstevel@tonic-gate /* Write out placeholder for later */ 2078e472857Sny155746 (void) snprintf(buf, sizeof (buf), "%s \n", 2088e472857Sny155746 header[H_TCOPY].tag); 2097c478bd9Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 2107c478bd9Sstevel@tonic-gate done(0); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate n = 0; /* suppress */ 2137c478bd9Sstevel@tonic-gate break; 2147c478bd9Sstevel@tonic-gate case H_MTYPE: 2157c478bd9Sstevel@tonic-gate if (flgm) { 2167c478bd9Sstevel@tonic-gate /* suppress if message-type argument */ 2177c478bd9Sstevel@tonic-gate n = 0; 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate break; 2207c478bd9Sstevel@tonic-gate case H_CONT: 2217c478bd9Sstevel@tonic-gate if (oldn == 0) { 2227c478bd9Sstevel@tonic-gate /* suppress continuation line also */ 2237c478bd9Sstevel@tonic-gate n = 0; 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate break; 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate oldn = n; /* remember if this line was suppressed */ 2287c478bd9Sstevel@tonic-gate if (n && !wtmpf(line, n)) { 2297c478bd9Sstevel@tonic-gate done(0); 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate if (!n) savehdrs(line, hdrtyp); 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate if (Rpath[0] != '\0') { 2347c478bd9Sstevel@tonic-gate strcat(Rpath, "!"); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate (void) strlcat(Rpath, fromU, sizeof (Rpath)); 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate /* push out message type if so requested */ 2397c478bd9Sstevel@tonic-gate if (flgm) { /* message-type */ 2408e472857Sny155746 snprintf(buf, sizeof (buf), "%s%s\n", 2418e472857Sny155746 header[H_MTYPE].tag, msgtype); 2427c478bd9Sstevel@tonic-gate if (!wtmpf(buf, strlen(buf))) { 2437c478bd9Sstevel@tonic-gate done(0); 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate memcpy(buf, line, n); 2487c478bd9Sstevel@tonic-gate if (n == 0 || (ttyf && !strncmp(buf, ".\n", 2))) { 2497c478bd9Sstevel@tonic-gate if (flgf) { 2507c478bd9Sstevel@tonic-gate /* no input */ 2517c478bd9Sstevel@tonic-gate return; 2527c478bd9Sstevel@tonic-gate } else { 2537c478bd9Sstevel@tonic-gate /* 2547c478bd9Sstevel@tonic-gate * no content: put mime-version, content-type 2557c478bd9Sstevel@tonic-gate * and -length only if explicitly present. 2567c478bd9Sstevel@tonic-gate * Write out 'place-holders' only. (see below....) 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != 2597c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 2608e472857Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 2618e472857Sny155746 header[H_MIMEVERS].tag); 2627c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 2637c478bd9Sstevel@tonic-gate done(0); 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != 2677c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 2688e472857Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 2698e472857Sny155746 header[H_CTYPE].tag); 2707c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 2717c478bd9Sstevel@tonic-gate done(0); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != 2757c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 2768e472857Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 2778e472857Sny155746 header[H_CLEN].tag); 2787c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 2797c478bd9Sstevel@tonic-gate done(0); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate goto wrapsend; 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate if (n == 1 && last1c == '\n') { /* blank line -- suppress */ 287*23a1cceaSRoger A. Faulkner n = getaline(buf, sizeof (buf), stdin); 2887c478bd9Sstevel@tonic-gate if (n == 0 || (ttyf && !strncmp(buf, ".\n", 2))) { 2897c478bd9Sstevel@tonic-gate /* 2907c478bd9Sstevel@tonic-gate * no content: put mime-version, content-type 2917c478bd9Sstevel@tonic-gate * and -length only if explicitly present. 2927c478bd9Sstevel@tonic-gate * Write out 'place-holders' only. (see below....) 2937c478bd9Sstevel@tonic-gate */ 2947c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != 2957c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 2968e472857Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 2978e472857Sny155746 header[H_MIMEVERS].tag); 2987c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 2997c478bd9Sstevel@tonic-gate done(0); 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != 3037c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 3048e472857Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 3058e472857Sny155746 header[H_CTYPE].tag); 3067c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3077c478bd9Sstevel@tonic-gate done(0); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != 3117c478bd9Sstevel@tonic-gate (struct hdrs *)NULL) { 3128e472857Sny155746 (void) snprintf(line, sizeof (line), "%s \n", 3138e472857Sny155746 header[H_CLEN].tag); 3147c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3157c478bd9Sstevel@tonic-gate done(0); 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate goto wrapsend; 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate if (debug > 0) { 3237c478bd9Sstevel@tonic-gate buf[n] = '\0'; 3248e472857Sny155746 Dout(pn, 0, "header scan complete, readahead %d = \"%s\"\n", 3258e472857Sny155746 n, buf); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * Write out H_MIMEVERS, H_CTYPE & H_CLEN lines. These are used only as 3307c478bd9Sstevel@tonic-gate * placeholders in the tmp file. When the 'real' message is sent, 3317c478bd9Sstevel@tonic-gate * the proper values will be put out by copylet(). 3327c478bd9Sstevel@tonic-gate */ 3337c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_MIMEVERS].tag); 3347c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3357c478bd9Sstevel@tonic-gate done(0); 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate if (hdrlines[H_MIMEVERS].head == (struct hdrs *)NULL) { 3387c478bd9Sstevel@tonic-gate savehdrs(line, H_MIMEVERS); 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CTYPE].tag); 3417c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3427c478bd9Sstevel@tonic-gate done(0); 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate if (hdrlines[H_CTYPE].head == (struct hdrs *)NULL) { 3457c478bd9Sstevel@tonic-gate savehdrs(line, H_CTYPE); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), "%s \n", header[H_CLEN].tag); 3487c478bd9Sstevel@tonic-gate if (!wtmpf(line, strlen(line))) { 3497c478bd9Sstevel@tonic-gate done(0); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate if (hdrlines[H_CLEN].head == (struct hdrs *)NULL) { 3527c478bd9Sstevel@tonic-gate savehdrs(line, H_CLEN); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate /* and a blank line */ 3557c478bd9Sstevel@tonic-gate if (!wtmpf("\n", 1)) { 3567c478bd9Sstevel@tonic-gate done(0); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate Dout(pn, 0, "header out completed\n"); 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate pushrest = 0; 3617c478bd9Sstevel@tonic-gate count = 0L; 3627c478bd9Sstevel@tonic-gate /* 3637c478bd9Sstevel@tonic-gate * Are we returning mail from a delivery failure of an old-style 3647c478bd9Sstevel@tonic-gate * (SVR3.1 or SVR3.0) rmail? If so, we won't return THIS on failure 3657c478bd9Sstevel@tonic-gate * [This line should occur as the FIRST non-blank non-header line] 3667c478bd9Sstevel@tonic-gate */ 3677c478bd9Sstevel@tonic-gate if (!strncmp("***** UNDELIVERABLE MAIL sent to", buf, 32)) { 3687c478bd9Sstevel@tonic-gate dflag = 9; /* 9 says do not return on failure */ 3697c478bd9Sstevel@tonic-gate Dout(pn, 0, "found old-style UNDELIVERABLE line. dflag = 9\n"); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate /* scan body of message */ 3737c478bd9Sstevel@tonic-gate while (n > 0) { 3747c478bd9Sstevel@tonic-gate if (ttyf && !strcmp(buf, ".\n")) 3757c478bd9Sstevel@tonic-gate break; 3767c478bd9Sstevel@tonic-gate if (!binflg) { 3777c478bd9Sstevel@tonic-gate binflg = !istext((unsigned char *)buf, n); 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate if (!wtmpf(buf, n)) { 3817c478bd9Sstevel@tonic-gate done(0); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate count += n; 3847c478bd9Sstevel@tonic-gate n = ttyf 385*23a1cceaSRoger A. Faulkner ? getaline(buf, sizeof (buf), stdin) 3868e472857Sny155746 : fread(buf, 1, sizeof (buf), stdin); 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate setsig(SIGINT, saveint); 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate wrapsend: 3917c478bd9Sstevel@tonic-gate /* 3927c478bd9Sstevel@tonic-gate * In order to use some of the subroutines that are used to 3937c478bd9Sstevel@tonic-gate * read mail, the let array must be set up 3947c478bd9Sstevel@tonic-gate */ 3957c478bd9Sstevel@tonic-gate nlet = 1; 3967c478bd9Sstevel@tonic-gate let[0].adr = 0; 3977c478bd9Sstevel@tonic-gate let[1].adr = ftell(tmpf); 3987c478bd9Sstevel@tonic-gate let[0].text = (binflg == 1 ? FALSE : TRUE); 3997c478bd9Sstevel@tonic-gate Dout(pn, 0, "body copy complete, count %ld\n", count); 4007c478bd9Sstevel@tonic-gate /* 4017c478bd9Sstevel@tonic-gate * Modify value of H_MIMEVERS if necessary. 4027c478bd9Sstevel@tonic-gate */ 4037c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_MIMEVERS].head) != (struct hdrs *)NULL) { 4047c478bd9Sstevel@tonic-gate if (strlen(hptr->value) == 0) { 4057c478bd9Sstevel@tonic-gate (void) strlcpy(hptr->value, "1.0", 4067c478bd9Sstevel@tonic-gate sizeof (hptr->value)); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate /* 4107c478bd9Sstevel@tonic-gate * Modify value of H_CTYPE if necessary. 4117c478bd9Sstevel@tonic-gate */ 4127c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CTYPE].head) != (struct hdrs *)NULL) { 4137c478bd9Sstevel@tonic-gate if (strlen(hptr->value) == 0) { 4147c478bd9Sstevel@tonic-gate (void) strlcpy(hptr->value, "text/plain", 4157c478bd9Sstevel@tonic-gate sizeof (hptr->value)); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate /* 4197c478bd9Sstevel@tonic-gate * Set 'place-holder' value of content length to true value 4207c478bd9Sstevel@tonic-gate */ 4217c478bd9Sstevel@tonic-gate if ((hptr = hdrlines[H_CLEN].head) != (struct hdrs *)NULL) { 4227c478bd9Sstevel@tonic-gate (void) snprintf(hptr->value, sizeof (hptr->value), 4237c478bd9Sstevel@tonic-gate "%ld", count); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate if (fclose(tmpf) == EOF) { 4277c478bd9Sstevel@tonic-gate tmperr(); 4287c478bd9Sstevel@tonic-gate done(0); 4297c478bd9Sstevel@tonic-gate } 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate tmpf = doopen(lettmp, "r+", E_TMP); 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate /* Do not send mail on SIGINT */ 4347c478bd9Sstevel@tonic-gate if (dflag == 2) { 4357c478bd9Sstevel@tonic-gate done(0); 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate sendlist(&list, 0, 0); 4397c478bd9Sstevel@tonic-gate done(0); 4407c478bd9Sstevel@tonic-gate } 441