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 5*23a1cceaSRoger A. Faulkner * Common Development and Distribution License (the "License"). 6*23a1cceaSRoger A. Faulkner * 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) 1985, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 266c83d09fSrobbin /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 276c83d09fSrobbin /* All Rights Reserved */ 286c83d09fSrobbin 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 317c478bd9Sstevel@tonic-gate * The Regents of the University of California 327c478bd9Sstevel@tonic-gate * All Rights Reserved 337c478bd9Sstevel@tonic-gate * 347c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 357c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 367c478bd9Sstevel@tonic-gate * contributors. 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #include "rcv.h" 407c478bd9Sstevel@tonic-gate #include <locale.h> 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate /* 437c478bd9Sstevel@tonic-gate * mailx -- a modified version of a University of California at Berkeley 447c478bd9Sstevel@tonic-gate * mail program 457c478bd9Sstevel@tonic-gate * 467c478bd9Sstevel@tonic-gate * Mail to others. 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate static void fmt(register char *str, register FILE *fo); 507c478bd9Sstevel@tonic-gate static FILE *infix(struct header *hp, FILE *fi); 517c478bd9Sstevel@tonic-gate static void statusput(register struct message *mp, register FILE *obuf, int doign, int (*fp)(const char *, FILE *)); 527c478bd9Sstevel@tonic-gate static int savemail(char name[], struct header *hp, FILE *fi); 537c478bd9Sstevel@tonic-gate static int sendmail(char *str); 547c478bd9Sstevel@tonic-gate static int Sendmail(char *str); 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate static off_t textpos; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /* 597c478bd9Sstevel@tonic-gate * Send message described by the passed pointer to the 607c478bd9Sstevel@tonic-gate * passed output buffer. Return -1 on error, but normally 617c478bd9Sstevel@tonic-gate * the number of lines written. Adjust the status: field 627c478bd9Sstevel@tonic-gate * if need be. If doign is set, suppress ignored header fields. 637c478bd9Sstevel@tonic-gate * Call (*fp)(line, obuf) to print the line. 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate long 667c478bd9Sstevel@tonic-gate msend( 677c478bd9Sstevel@tonic-gate struct message *mailp, 687c478bd9Sstevel@tonic-gate FILE *obuf, 697c478bd9Sstevel@tonic-gate int flag, 707c478bd9Sstevel@tonic-gate int (*fp)(const char *, FILE *)) 717c478bd9Sstevel@tonic-gate { 727c478bd9Sstevel@tonic-gate register struct message *mp; 737c478bd9Sstevel@tonic-gate long clen, n, c; 747c478bd9Sstevel@tonic-gate FILE *ibuf; 757c478bd9Sstevel@tonic-gate char line[LINESIZE], field[BUFSIZ]; 767c478bd9Sstevel@tonic-gate int ishead, infld, fline, dostat, doclen, nread, unused; 777c478bd9Sstevel@tonic-gate char *cp, *cp2; 787c478bd9Sstevel@tonic-gate int doign = flag & M_IGNORE; 797c478bd9Sstevel@tonic-gate int oldign = 0; /* previous line was ignored */ 807c478bd9Sstevel@tonic-gate long lc; 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate mp = mailp; 837c478bd9Sstevel@tonic-gate if (mp->m_clen == 0) 847c478bd9Sstevel@tonic-gate setclen(mp); 857c478bd9Sstevel@tonic-gate ibuf = setinput(mp); 867c478bd9Sstevel@tonic-gate c = mp->m_size; 877c478bd9Sstevel@tonic-gate ishead = 1; 887c478bd9Sstevel@tonic-gate dostat = 1; 897c478bd9Sstevel@tonic-gate doclen = 1; 907c478bd9Sstevel@tonic-gate infld = 0; 917c478bd9Sstevel@tonic-gate fline = 1; 927c478bd9Sstevel@tonic-gate lc = 0; 937c478bd9Sstevel@tonic-gate clearerr(obuf); 947c478bd9Sstevel@tonic-gate while (c > 0L) { 95*23a1cceaSRoger A. Faulkner nread = getaline(line, LINESIZE, ibuf, &unused); 967c478bd9Sstevel@tonic-gate c -= nread; 977c478bd9Sstevel@tonic-gate lc++; 987c478bd9Sstevel@tonic-gate if (ishead) { 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * First line is the From line, so no headers 1017c478bd9Sstevel@tonic-gate * there to worry about 1027c478bd9Sstevel@tonic-gate */ 1037c478bd9Sstevel@tonic-gate if (fline) { 1047c478bd9Sstevel@tonic-gate fline = 0; 1057c478bd9Sstevel@tonic-gate goto writeit; 1067c478bd9Sstevel@tonic-gate } 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * If line is blank, we've reached end of 1097c478bd9Sstevel@tonic-gate * headers, so force out status: field 1107c478bd9Sstevel@tonic-gate * and note that we are no longer in header 1117c478bd9Sstevel@tonic-gate * fields. Also force out Content-Length: field. 1127c478bd9Sstevel@tonic-gate */ 1137c478bd9Sstevel@tonic-gate if (line[0] == '\n') { 1147c478bd9Sstevel@tonic-gate if (dostat) { 1157c478bd9Sstevel@tonic-gate statusput(mailp, obuf, doign, fp); 1167c478bd9Sstevel@tonic-gate dostat = 0; 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate if (doclen && 1197c478bd9Sstevel@tonic-gate !isign("content-length", flag&M_SAVING)) { 1207c478bd9Sstevel@tonic-gate snprintf(field, sizeof (field), 1217c478bd9Sstevel@tonic-gate "Content-Length: %ld\n", 1227c478bd9Sstevel@tonic-gate mp->m_clen - 1); 1237c478bd9Sstevel@tonic-gate (*fp)(field, obuf); 1247c478bd9Sstevel@tonic-gate if (ferror(obuf)) 1257c478bd9Sstevel@tonic-gate return(-1); 1267c478bd9Sstevel@tonic-gate doclen = 0; 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate ishead = 0; 1297c478bd9Sstevel@tonic-gate goto writeit; 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate /* 1327c478bd9Sstevel@tonic-gate * If this line is a continuation 1337c478bd9Sstevel@tonic-gate * of a previous header field, just echo it. 1347c478bd9Sstevel@tonic-gate */ 1357c478bd9Sstevel@tonic-gate if (isspace(line[0]) && infld) 1367c478bd9Sstevel@tonic-gate if (oldign) 1377c478bd9Sstevel@tonic-gate continue; 1387c478bd9Sstevel@tonic-gate else 1397c478bd9Sstevel@tonic-gate goto writeit; 1407c478bd9Sstevel@tonic-gate infld = 0; 1417c478bd9Sstevel@tonic-gate /* 1427c478bd9Sstevel@tonic-gate * If we are no longer looking at real 1437c478bd9Sstevel@tonic-gate * header lines, force out status: 1447c478bd9Sstevel@tonic-gate * This happens in uucp style mail where 1457c478bd9Sstevel@tonic-gate * there are no headers at all. 1467c478bd9Sstevel@tonic-gate */ 1477c478bd9Sstevel@tonic-gate if (!headerp(line)) { 1487c478bd9Sstevel@tonic-gate if (dostat) { 1497c478bd9Sstevel@tonic-gate statusput(mailp, obuf, doign, fp); 1507c478bd9Sstevel@tonic-gate dostat = 0; 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate (*fp)("\n", obuf); 1537c478bd9Sstevel@tonic-gate ishead = 0; 1547c478bd9Sstevel@tonic-gate goto writeit; 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate infld++; 1577c478bd9Sstevel@tonic-gate /* 1587c478bd9Sstevel@tonic-gate * Pick up the header field. 1597c478bd9Sstevel@tonic-gate * If it is an ignored field and 1607c478bd9Sstevel@tonic-gate * we care about such things, skip it. 1617c478bd9Sstevel@tonic-gate */ 1627c478bd9Sstevel@tonic-gate cp = line; 1637c478bd9Sstevel@tonic-gate cp2 = field; 1647c478bd9Sstevel@tonic-gate while (*cp && *cp != ':' && !isspace(*cp)) 1657c478bd9Sstevel@tonic-gate *cp2++ = *cp++; 1667c478bd9Sstevel@tonic-gate *cp2 = 0; 1677c478bd9Sstevel@tonic-gate oldign = doign && isign(field, flag&M_SAVING); 1687c478bd9Sstevel@tonic-gate if (oldign) 1697c478bd9Sstevel@tonic-gate continue; 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * If the field is "status," go compute and print the 1727c478bd9Sstevel@tonic-gate * real Status: field 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate if (icequal(field, "status")) { 1757c478bd9Sstevel@tonic-gate if (dostat) { 1767c478bd9Sstevel@tonic-gate statusput(mailp, obuf, doign, fp); 1777c478bd9Sstevel@tonic-gate dostat = 0; 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate continue; 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate if (icequal(field, "content-length")) { 1827c478bd9Sstevel@tonic-gate if (doclen) { 1837c478bd9Sstevel@tonic-gate snprintf(line, sizeof (line), 1847c478bd9Sstevel@tonic-gate "Content-Length: %ld\n", 1857c478bd9Sstevel@tonic-gate mp->m_clen - 1); 1867c478bd9Sstevel@tonic-gate (*fp)(line, obuf); 1877c478bd9Sstevel@tonic-gate if (ferror(obuf)) 1887c478bd9Sstevel@tonic-gate return(-1); 1897c478bd9Sstevel@tonic-gate doclen = 0; 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate continue; 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate writeit: 1957c478bd9Sstevel@tonic-gate if (!ishead && !mp->m_text && mp->m_clen != 0) { 1967c478bd9Sstevel@tonic-gate if (line[0] == '\n') 1977c478bd9Sstevel@tonic-gate putc('\n', obuf); 1987c478bd9Sstevel@tonic-gate clen = mp->m_clen-1; 1997c478bd9Sstevel@tonic-gate for (;;) { 2007c478bd9Sstevel@tonic-gate n = clen < sizeof line ? clen : sizeof line; 2017c478bd9Sstevel@tonic-gate if ((n = fread(line, 1, (int)n, ibuf)) <= 0) { 2027c478bd9Sstevel@tonic-gate fprintf(stderr, gettext( 2037c478bd9Sstevel@tonic-gate "\t(Unexpected end-of-file).\n")); 2047c478bd9Sstevel@tonic-gate clen = 0; 2057c478bd9Sstevel@tonic-gate } else { 2067c478bd9Sstevel@tonic-gate if (fwrite(line, 1, (int)n, obuf) != n) { 2077c478bd9Sstevel@tonic-gate fprintf(stderr, gettext( 2087c478bd9Sstevel@tonic-gate "\tError writing to the new file.\n")); 2097c478bd9Sstevel@tonic-gate fflush(obuf); 2107c478bd9Sstevel@tonic-gate if (fferror(obuf)) 2117c478bd9Sstevel@tonic-gate return (-1); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate clen -= n; 2157c478bd9Sstevel@tonic-gate if (clen <= 0) { 2167c478bd9Sstevel@tonic-gate break; 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate c = 0L; 2207c478bd9Sstevel@tonic-gate } else { 2217c478bd9Sstevel@tonic-gate (*fp)(line, obuf); 2227c478bd9Sstevel@tonic-gate if (ferror(obuf)) 2237c478bd9Sstevel@tonic-gate return(-1); 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate fflush(obuf); 2277c478bd9Sstevel@tonic-gate if (ferror(obuf)) 2287c478bd9Sstevel@tonic-gate return(-1); 2297c478bd9Sstevel@tonic-gate if (ishead && (mailp->m_flag & MSTATUS)) 2307c478bd9Sstevel@tonic-gate printf(gettext("failed to fix up status field\n")); 2317c478bd9Sstevel@tonic-gate return(lc); 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate /* 2357c478bd9Sstevel@tonic-gate * Test if the passed line is a header line, RFC 822 style. 2367c478bd9Sstevel@tonic-gate */ 2377c478bd9Sstevel@tonic-gate int 2387c478bd9Sstevel@tonic-gate headerp(register char *line) 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate register char *cp = line; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate while (*cp && *cp != ' ' && *cp != '\t' && *cp != ':') 2437c478bd9Sstevel@tonic-gate cp++; 2447c478bd9Sstevel@tonic-gate return(*cp == ':'); 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate /* 2487c478bd9Sstevel@tonic-gate * Output a reasonable looking status field. 2497c478bd9Sstevel@tonic-gate * But if "status" is ignored and doign, forget it. 2507c478bd9Sstevel@tonic-gate */ 2517c478bd9Sstevel@tonic-gate static void 2527c478bd9Sstevel@tonic-gate statusput( 2537c478bd9Sstevel@tonic-gate register struct message *mp, 2547c478bd9Sstevel@tonic-gate register FILE *obuf, 2557c478bd9Sstevel@tonic-gate int doign, 2567c478bd9Sstevel@tonic-gate int (*fp)(const char *, FILE *)) 2577c478bd9Sstevel@tonic-gate { 2587c478bd9Sstevel@tonic-gate char statout[12]; 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate if (doign && isign("status", 0)) 2617c478bd9Sstevel@tonic-gate return; 2627c478bd9Sstevel@tonic-gate if ((mp->m_flag & (MNEW|MREAD)) == MNEW) 2637c478bd9Sstevel@tonic-gate return; 2647c478bd9Sstevel@tonic-gate strcpy(statout, "Status: "); 2657c478bd9Sstevel@tonic-gate if (mp->m_flag & MREAD) 2667c478bd9Sstevel@tonic-gate strcat(statout, "R"); 2677c478bd9Sstevel@tonic-gate if ((mp->m_flag & MNEW) == 0) 2687c478bd9Sstevel@tonic-gate strcat(statout, "O"); 2697c478bd9Sstevel@tonic-gate strcat(statout, "\n"); 2707c478bd9Sstevel@tonic-gate (*fp)(statout, obuf); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate /* 2747c478bd9Sstevel@tonic-gate * Interface between the argument list and the mail1 routine 2757c478bd9Sstevel@tonic-gate * which does all the dirty work. 2767c478bd9Sstevel@tonic-gate */ 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate int 2797c478bd9Sstevel@tonic-gate mail(char **people) 2807c478bd9Sstevel@tonic-gate { 2817c478bd9Sstevel@tonic-gate register char *cp2, *cp3; 2827c478bd9Sstevel@tonic-gate register int s; 2837c478bd9Sstevel@tonic-gate char *buf, **ap; 2847c478bd9Sstevel@tonic-gate struct header head; 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate for (s = 0, ap = people; *ap; ap++) 2877c478bd9Sstevel@tonic-gate s += strlen(*ap) + 2; 2887c478bd9Sstevel@tonic-gate buf = (char *)salloc((unsigned)(s+1)); 2897c478bd9Sstevel@tonic-gate cp2 = buf; 2907c478bd9Sstevel@tonic-gate for (ap = people; *ap; ap++) { 2917c478bd9Sstevel@tonic-gate for (cp3 = *ap; *cp3; ) { 2927c478bd9Sstevel@tonic-gate if (*cp3 == ' ' || *cp3 == '\t') { 2937c478bd9Sstevel@tonic-gate *cp3++ = ','; 2947c478bd9Sstevel@tonic-gate while (*cp3 == ' ' || *cp3 == '\t') 2957c478bd9Sstevel@tonic-gate cp3++; 2967c478bd9Sstevel@tonic-gate } else 2977c478bd9Sstevel@tonic-gate cp3++; 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate cp2 = copy(*ap, cp2); 3007c478bd9Sstevel@tonic-gate *cp2++ = ','; 3017c478bd9Sstevel@tonic-gate *cp2++ = ' '; 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate *cp2 = '\0'; 3047c478bd9Sstevel@tonic-gate head.h_to = buf; 3057c478bd9Sstevel@tonic-gate head.h_subject = head.h_cc = head.h_bcc = head.h_defopt = NOSTR; 3067c478bd9Sstevel@tonic-gate head.h_others = NOSTRPTR; 3077c478bd9Sstevel@tonic-gate head.h_seq = 0; 3087c478bd9Sstevel@tonic-gate mail1(&head, Fflag, NOSTR); 3097c478bd9Sstevel@tonic-gate return(0); 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate int 3137c478bd9Sstevel@tonic-gate sendm(char *str) 3147c478bd9Sstevel@tonic-gate { 3157c478bd9Sstevel@tonic-gate if (value("flipm") != NOSTR) 3167c478bd9Sstevel@tonic-gate return(Sendmail(str)); 3177c478bd9Sstevel@tonic-gate else return(sendmail(str)); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate int 3217c478bd9Sstevel@tonic-gate Sendm(char *str) 3227c478bd9Sstevel@tonic-gate { 3237c478bd9Sstevel@tonic-gate if (value("flipm") != NOSTR) 3247c478bd9Sstevel@tonic-gate return(sendmail(str)); 3257c478bd9Sstevel@tonic-gate else return(Sendmail(str)); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * Interface to the mail1 routine for the -t flag 3307c478bd9Sstevel@tonic-gate * (read headers from text). 3317c478bd9Sstevel@tonic-gate */ 3327c478bd9Sstevel@tonic-gate int 3337c478bd9Sstevel@tonic-gate tmail(void) 3347c478bd9Sstevel@tonic-gate { 3357c478bd9Sstevel@tonic-gate struct header head; 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate head.h_to = NOSTR; 3387c478bd9Sstevel@tonic-gate head.h_subject = head.h_cc = head.h_bcc = head.h_defopt = NOSTR; 3397c478bd9Sstevel@tonic-gate head.h_others = NOSTRPTR; 3407c478bd9Sstevel@tonic-gate head.h_seq = 0; 3417c478bd9Sstevel@tonic-gate mail1(&head, Fflag, NOSTR); 3427c478bd9Sstevel@tonic-gate return(0); 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate /* 3467c478bd9Sstevel@tonic-gate * Send mail to a bunch of user names. The interface is through 3477c478bd9Sstevel@tonic-gate * the mail routine below. 3487c478bd9Sstevel@tonic-gate */ 3497c478bd9Sstevel@tonic-gate static int 3507c478bd9Sstevel@tonic-gate sendmail(char *str) 3517c478bd9Sstevel@tonic-gate { 3527c478bd9Sstevel@tonic-gate struct header head; 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate if (blankline(str)) 3557c478bd9Sstevel@tonic-gate head.h_to = NOSTR; 3567c478bd9Sstevel@tonic-gate else 3577c478bd9Sstevel@tonic-gate head.h_to = addto(NOSTR, str); 3587c478bd9Sstevel@tonic-gate head.h_subject = head.h_cc = head.h_bcc = head.h_defopt = NOSTR; 3597c478bd9Sstevel@tonic-gate head.h_others = NOSTRPTR; 3607c478bd9Sstevel@tonic-gate head.h_seq = 0; 3617c478bd9Sstevel@tonic-gate mail1(&head, 0, NOSTR); 3627c478bd9Sstevel@tonic-gate return(0); 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate /* 3667c478bd9Sstevel@tonic-gate * Send mail to a bunch of user names. The interface is through 3677c478bd9Sstevel@tonic-gate * the mail routine below. 3687c478bd9Sstevel@tonic-gate * save a copy of the letter 3697c478bd9Sstevel@tonic-gate */ 3707c478bd9Sstevel@tonic-gate static int 3717c478bd9Sstevel@tonic-gate Sendmail(char *str) 3727c478bd9Sstevel@tonic-gate { 3737c478bd9Sstevel@tonic-gate struct header head; 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate if (blankline(str)) 3767c478bd9Sstevel@tonic-gate head.h_to = NOSTR; 3777c478bd9Sstevel@tonic-gate else 3787c478bd9Sstevel@tonic-gate head.h_to = addto(NOSTR, str); 3797c478bd9Sstevel@tonic-gate head.h_subject = head.h_cc = head.h_bcc = head.h_defopt = NOSTR; 3807c478bd9Sstevel@tonic-gate head.h_others = NOSTRPTR; 3817c478bd9Sstevel@tonic-gate head.h_seq = 0; 3827c478bd9Sstevel@tonic-gate mail1(&head, 1, NOSTR); 3837c478bd9Sstevel@tonic-gate return(0); 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate /* 3877c478bd9Sstevel@tonic-gate * Walk the list of fds, closing all but one. 3887c478bd9Sstevel@tonic-gate */ 3897c478bd9Sstevel@tonic-gate static int 3907c478bd9Sstevel@tonic-gate closefd_walk(void *special_fd, int fd) 3917c478bd9Sstevel@tonic-gate { 3927c478bd9Sstevel@tonic-gate if (fd > STDERR_FILENO && fd != *(int *)special_fd) 3937c478bd9Sstevel@tonic-gate (void) close(fd); 3947c478bd9Sstevel@tonic-gate return (0); 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* 3987c478bd9Sstevel@tonic-gate * Mail a message on standard input to the people indicated 3997c478bd9Sstevel@tonic-gate * in the passed header. (Internal interface). 4007c478bd9Sstevel@tonic-gate */ 4017c478bd9Sstevel@tonic-gate void 4027c478bd9Sstevel@tonic-gate mail1(struct header *hp, int use_to, char *orig_to) 4037c478bd9Sstevel@tonic-gate { 4047c478bd9Sstevel@tonic-gate pid_t p, pid; 4057c478bd9Sstevel@tonic-gate int i, s, gotcha; 4067c478bd9Sstevel@tonic-gate char **namelist, *deliver; 4077c478bd9Sstevel@tonic-gate struct name *to, *np; 4087c478bd9Sstevel@tonic-gate FILE *mtf, *fp; 4097c478bd9Sstevel@tonic-gate int remote = rflag != NOSTR || rmail; 4107c478bd9Sstevel@tonic-gate char **t; 4117c478bd9Sstevel@tonic-gate char *deadletter; 4127c478bd9Sstevel@tonic-gate char recfile[PATHSIZE]; 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate /* 4157c478bd9Sstevel@tonic-gate * Collect user's mail from standard input. 4167c478bd9Sstevel@tonic-gate * Get the result as mtf. 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate pid = (pid_t)-1; 4207c478bd9Sstevel@tonic-gate if ((mtf = collect(hp)) == NULL) 4217c478bd9Sstevel@tonic-gate return; 4227c478bd9Sstevel@tonic-gate hp->h_seq = 1; 4237c478bd9Sstevel@tonic-gate if (hp->h_subject == NOSTR) 4247c478bd9Sstevel@tonic-gate hp->h_subject = sflag; 4257c478bd9Sstevel@tonic-gate if (fsize(mtf) == 0 && hp->h_subject == NOSTR) { 4267c478bd9Sstevel@tonic-gate printf(gettext("No message !?!\n")); 4277c478bd9Sstevel@tonic-gate goto out; 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate if (intty) { 4307c478bd9Sstevel@tonic-gate printf(gettext("EOT\n")); 4317c478bd9Sstevel@tonic-gate flush(); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate /* 4357c478bd9Sstevel@tonic-gate * If we need to use the To: line to determine the record 4367c478bd9Sstevel@tonic-gate * file, save a copy of it before it's sorted below. 4377c478bd9Sstevel@tonic-gate */ 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate if (use_to && orig_to == NOSTR && hp->h_to != NOSTR) 4407c478bd9Sstevel@tonic-gate orig_to = strcpy((char *)salloc(strlen(hp->h_to)+1), hp->h_to); 4417c478bd9Sstevel@tonic-gate else if (orig_to == NOSTR) 4427c478bd9Sstevel@tonic-gate orig_to = ""; 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate /* 4457c478bd9Sstevel@tonic-gate * Now, take the user names from the combined 4467c478bd9Sstevel@tonic-gate * to and cc lists and do all the alias 4477c478bd9Sstevel@tonic-gate * processing. 4487c478bd9Sstevel@tonic-gate */ 4497c478bd9Sstevel@tonic-gate 4507c478bd9Sstevel@tonic-gate senderr = 0; 4517c478bd9Sstevel@tonic-gate to = cat(extract(hp->h_bcc, GBCC), 4527c478bd9Sstevel@tonic-gate cat(extract(hp->h_to, GTO), 4537c478bd9Sstevel@tonic-gate extract(hp->h_cc, GCC))); 4547c478bd9Sstevel@tonic-gate to = translate(outpre(elide(usermap(to)))); 4557c478bd9Sstevel@tonic-gate if (!senderr) 4567c478bd9Sstevel@tonic-gate mapf(to, myname); 4577c478bd9Sstevel@tonic-gate mechk(to); 4587c478bd9Sstevel@tonic-gate for (gotcha = 0, np = to; np != NIL; np = np->n_flink) 4597c478bd9Sstevel@tonic-gate if ((np->n_type & GDEL) == 0) 4607c478bd9Sstevel@tonic-gate gotcha++; 4617c478bd9Sstevel@tonic-gate hp->h_to = detract(to, GTO); 4627c478bd9Sstevel@tonic-gate hp->h_cc = detract(to, GCC); 4637c478bd9Sstevel@tonic-gate hp->h_bcc = detract(to, GBCC); 4647c478bd9Sstevel@tonic-gate if ((mtf = infix(hp, mtf)) == NULL) { 4657c478bd9Sstevel@tonic-gate fprintf(stderr, gettext(". . . message lost, sorry.\n")); 4667c478bd9Sstevel@tonic-gate return; 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate rewind(mtf); 4697c478bd9Sstevel@tonic-gate if (askme && isatty(0)) { 4707c478bd9Sstevel@tonic-gate char ans[64]; 4717c478bd9Sstevel@tonic-gate puthead(hp, stdout, GTO|GCC|GBCC, 0); 4727c478bd9Sstevel@tonic-gate printf(gettext("Send? ")); 4737c478bd9Sstevel@tonic-gate printf("[yes] "); 4747c478bd9Sstevel@tonic-gate if (fgets(ans, sizeof(ans), stdin) && ans[0] && 4757c478bd9Sstevel@tonic-gate (tolower(ans[0]) != 'y' && ans[0] != '\n')) 4767c478bd9Sstevel@tonic-gate goto dead; 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate if (senderr) 4797c478bd9Sstevel@tonic-gate goto dead; 4807c478bd9Sstevel@tonic-gate /* 4817c478bd9Sstevel@tonic-gate * Look through the recipient list for names with /'s 4827c478bd9Sstevel@tonic-gate * in them which we write to as files directly. 4837c478bd9Sstevel@tonic-gate */ 4847c478bd9Sstevel@tonic-gate i = outof(to, mtf); 4857c478bd9Sstevel@tonic-gate rewind(mtf); 4867c478bd9Sstevel@tonic-gate if (!gotcha && !i) { 4877c478bd9Sstevel@tonic-gate printf(gettext("No recipients specified\n")); 4887c478bd9Sstevel@tonic-gate goto dead; 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate if (senderr) 4917c478bd9Sstevel@tonic-gate goto dead; 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate getrecf(orig_to, recfile, use_to, sizeof (recfile)); 4947c478bd9Sstevel@tonic-gate if (recfile != NOSTR && *recfile) 4957c478bd9Sstevel@tonic-gate savemail(safeexpand(recfile), hp, mtf); 4967c478bd9Sstevel@tonic-gate if (!gotcha) 4977c478bd9Sstevel@tonic-gate goto out; 4987c478bd9Sstevel@tonic-gate namelist = unpack(to); 4997c478bd9Sstevel@tonic-gate if (debug) { 5007c478bd9Sstevel@tonic-gate fprintf(stderr, "Recipients of message:\n"); 5017c478bd9Sstevel@tonic-gate for (t = namelist; *t != NOSTR; t++) 5027c478bd9Sstevel@tonic-gate fprintf(stderr, " \"%s\"", *t); 5037c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 5047c478bd9Sstevel@tonic-gate return; 5057c478bd9Sstevel@tonic-gate } 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate /* 5087c478bd9Sstevel@tonic-gate * Wait, to absorb a potential zombie, then 5097c478bd9Sstevel@tonic-gate * fork, set up the temporary mail file as standard 5107c478bd9Sstevel@tonic-gate * input for "mail" and exec with the user list we generated 5117c478bd9Sstevel@tonic-gate * far above. Return the process id to caller in case he 5127c478bd9Sstevel@tonic-gate * wants to await the completion of mail. 5137c478bd9Sstevel@tonic-gate */ 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate #ifdef VMUNIX 5167c478bd9Sstevel@tonic-gate while (wait3((int *)0, WNOHANG, (struct rusage *)0) > 0) 5177c478bd9Sstevel@tonic-gate ; 5187c478bd9Sstevel@tonic-gate #else 5197c478bd9Sstevel@tonic-gate #ifdef preSVr4 5207c478bd9Sstevel@tonic-gate wait((int *)0); 5217c478bd9Sstevel@tonic-gate #else 5227c478bd9Sstevel@tonic-gate while (waitpid((pid_t)-1, (int *)0, WNOHANG) > 0) 5237c478bd9Sstevel@tonic-gate ; 5247c478bd9Sstevel@tonic-gate #endif 5257c478bd9Sstevel@tonic-gate #endif 5267c478bd9Sstevel@tonic-gate rewind(mtf); 5277c478bd9Sstevel@tonic-gate pid = fork(); 5287c478bd9Sstevel@tonic-gate if (pid == (pid_t)-1) { 5297c478bd9Sstevel@tonic-gate perror("fork"); 5307c478bd9Sstevel@tonic-gate dead: 5317c478bd9Sstevel@tonic-gate deadletter = Getf("DEAD"); 5327c478bd9Sstevel@tonic-gate if (fp = fopen(deadletter, 5337c478bd9Sstevel@tonic-gate value("appenddeadletter") == NOSTR ? "w" : "a")) { 5347c478bd9Sstevel@tonic-gate chmod(deadletter, DEADPERM); 5357c478bd9Sstevel@tonic-gate puthead(hp, fp, GMASK|GCLEN, fsize(mtf) - textpos); 5367c478bd9Sstevel@tonic-gate fseek(mtf, textpos, 0); 5377c478bd9Sstevel@tonic-gate lcwrite(deadletter, mtf, fp, 5387c478bd9Sstevel@tonic-gate value("appenddeadletter") != NOSTR); 5397c478bd9Sstevel@tonic-gate fclose(fp); 5407c478bd9Sstevel@tonic-gate } else 5417c478bd9Sstevel@tonic-gate perror(deadletter); 5427c478bd9Sstevel@tonic-gate goto out; 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate if (pid == 0) { 5457c478bd9Sstevel@tonic-gate sigchild(); 5467c478bd9Sstevel@tonic-gate #ifdef SIGTSTP 5477c478bd9Sstevel@tonic-gate if (remote == 0) { 5487c478bd9Sstevel@tonic-gate sigset(SIGTSTP, SIG_IGN); 5497c478bd9Sstevel@tonic-gate sigset(SIGTTIN, SIG_IGN); 5507c478bd9Sstevel@tonic-gate sigset(SIGTTOU, SIG_IGN); 5517c478bd9Sstevel@tonic-gate } 5527c478bd9Sstevel@tonic-gate #endif 5537c478bd9Sstevel@tonic-gate sigset(SIGHUP, SIG_IGN); 5547c478bd9Sstevel@tonic-gate sigset(SIGINT, SIG_IGN); 5557c478bd9Sstevel@tonic-gate sigset(SIGQUIT, SIG_IGN); 5567c478bd9Sstevel@tonic-gate s = fileno(mtf); 5577c478bd9Sstevel@tonic-gate (void) fdwalk(closefd_walk, &s); 5587c478bd9Sstevel@tonic-gate close(0); 5597c478bd9Sstevel@tonic-gate dup(s); 5607c478bd9Sstevel@tonic-gate close(s); 5617c478bd9Sstevel@tonic-gate #ifdef CC 5627c478bd9Sstevel@tonic-gate submit(getpid()); 5637c478bd9Sstevel@tonic-gate #endif /* CC */ 5647c478bd9Sstevel@tonic-gate if ((deliver = value("sendmail")) == NOSTR) 5657c478bd9Sstevel@tonic-gate #ifdef SENDMAIL 5667c478bd9Sstevel@tonic-gate deliver = SENDMAIL; 5677c478bd9Sstevel@tonic-gate #else 5687c478bd9Sstevel@tonic-gate deliver = MAIL; 5697c478bd9Sstevel@tonic-gate #endif 5707c478bd9Sstevel@tonic-gate execvp(safeexpand(deliver), namelist); 5717c478bd9Sstevel@tonic-gate perror(deliver); 5727c478bd9Sstevel@tonic-gate exit(1); 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate if (value("sendwait")!=NOSTR) 5767c478bd9Sstevel@tonic-gate remote++; 5777c478bd9Sstevel@tonic-gate out: 5787c478bd9Sstevel@tonic-gate if (remote) { 5797c478bd9Sstevel@tonic-gate while ((p = wait(&s)) != pid && p != (pid_t)-1) 5807c478bd9Sstevel@tonic-gate ; 5817c478bd9Sstevel@tonic-gate if (s != 0) 5827c478bd9Sstevel@tonic-gate senderr++; 5837c478bd9Sstevel@tonic-gate pid = 0; 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate fclose(mtf); 5867c478bd9Sstevel@tonic-gate return; 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate /* 5907c478bd9Sstevel@tonic-gate * Prepend a header in front of the collected stuff 5917c478bd9Sstevel@tonic-gate * and return the new file. 5927c478bd9Sstevel@tonic-gate */ 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate static FILE * 5957c478bd9Sstevel@tonic-gate infix(struct header *hp, FILE *fi) 5967c478bd9Sstevel@tonic-gate { 5977c478bd9Sstevel@tonic-gate register FILE *nfo, *nfi; 5987c478bd9Sstevel@tonic-gate register int c; 5997c478bd9Sstevel@tonic-gate char *postmark, *returnaddr; 6007c478bd9Sstevel@tonic-gate int fd = -1; 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate rewind(fi); 6037c478bd9Sstevel@tonic-gate if ((fd = open(tempMail, O_RDWR|O_CREAT|O_EXCL, 0600)) < 0 || 6047c478bd9Sstevel@tonic-gate (nfo = fdopen(fd, "w")) == NULL) { 6057c478bd9Sstevel@tonic-gate perror(tempMail); 6067c478bd9Sstevel@tonic-gate return(fi); 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate if ((nfi = fopen(tempMail, "r")) == NULL) { 6097c478bd9Sstevel@tonic-gate perror(tempMail); 6107c478bd9Sstevel@tonic-gate fclose(nfo); 6117c478bd9Sstevel@tonic-gate return(fi); 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate removefile(tempMail); 6147c478bd9Sstevel@tonic-gate postmark = value("postmark"); 6157c478bd9Sstevel@tonic-gate returnaddr = value("returnaddr"); 6167c478bd9Sstevel@tonic-gate if ((postmark != NOSTR) || (returnaddr != NOSTR)) { 6177c478bd9Sstevel@tonic-gate if (returnaddr && *returnaddr) 6187c478bd9Sstevel@tonic-gate fprintf(nfo, "From: %s", returnaddr); 6197c478bd9Sstevel@tonic-gate else 6207c478bd9Sstevel@tonic-gate fprintf(nfo, "From: %s@%s", myname, host); 6217c478bd9Sstevel@tonic-gate if (postmark && *postmark) 6227c478bd9Sstevel@tonic-gate fprintf(nfo, " (%s)", postmark); 6237c478bd9Sstevel@tonic-gate putc('\n', nfo); 6247c478bd9Sstevel@tonic-gate } 6257c478bd9Sstevel@tonic-gate puthead(hp, nfo, (GMASK & ~GBCC) | GCLEN, fsize(fi)); 6267c478bd9Sstevel@tonic-gate textpos = ftell(nfo); 6277c478bd9Sstevel@tonic-gate while ((c = getc(fi)) != EOF) 6287c478bd9Sstevel@tonic-gate putc(c, nfo); 6297c478bd9Sstevel@tonic-gate if (ferror(fi)) { 6307c478bd9Sstevel@tonic-gate perror("read"); 6317c478bd9Sstevel@tonic-gate return(fi); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate fflush(nfo); 6347c478bd9Sstevel@tonic-gate if (fferror(nfo)) { 6357c478bd9Sstevel@tonic-gate perror(tempMail); 6367c478bd9Sstevel@tonic-gate fclose(nfo); 6377c478bd9Sstevel@tonic-gate fclose(nfi); 6387c478bd9Sstevel@tonic-gate return(fi); 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate fclose(nfo); 6417c478bd9Sstevel@tonic-gate fclose(fi); 6427c478bd9Sstevel@tonic-gate rewind(nfi); 6437c478bd9Sstevel@tonic-gate return(nfi); 6447c478bd9Sstevel@tonic-gate } 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate /* 6477c478bd9Sstevel@tonic-gate * Dump the message header on the 6487c478bd9Sstevel@tonic-gate * passed file buffer. 6497c478bd9Sstevel@tonic-gate */ 6507c478bd9Sstevel@tonic-gate 6516c83d09fSrobbin int 6527c478bd9Sstevel@tonic-gate puthead(struct header *hp, FILE *fo, int w, long clen) 6537c478bd9Sstevel@tonic-gate { 6547c478bd9Sstevel@tonic-gate register int gotcha; 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate gotcha = 0; 6577c478bd9Sstevel@tonic-gate if (hp->h_to != NOSTR && (w & GTO)) 6587c478bd9Sstevel@tonic-gate fprintf(fo, "To: "), fmt(hp->h_to, fo), gotcha++; 6597c478bd9Sstevel@tonic-gate if ((w & GSUBJECT) && (int)value("bsdcompat")) 6607c478bd9Sstevel@tonic-gate if (hp->h_subject != NOSTR && *hp->h_subject) 6617c478bd9Sstevel@tonic-gate fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++; 6627c478bd9Sstevel@tonic-gate else 6637c478bd9Sstevel@tonic-gate if (sflag && *sflag) 6647c478bd9Sstevel@tonic-gate fprintf(fo, "Subject: %s\n", sflag), gotcha++; 6657c478bd9Sstevel@tonic-gate if (hp->h_cc != NOSTR && (w & GCC)) 6667c478bd9Sstevel@tonic-gate fprintf(fo, "Cc: "), fmt(hp->h_cc, fo), gotcha++; 6677c478bd9Sstevel@tonic-gate if (hp->h_bcc != NOSTR && (w & GBCC)) 6687c478bd9Sstevel@tonic-gate fprintf(fo, "Bcc: "), fmt(hp->h_bcc, fo), gotcha++; 6697c478bd9Sstevel@tonic-gate if (hp->h_defopt != NOSTR && (w & GDEFOPT)) 6707c478bd9Sstevel@tonic-gate if (receipt_flg) 6717c478bd9Sstevel@tonic-gate fprintf(fo, "Return-Receipt-To: %s\n", 6727c478bd9Sstevel@tonic-gate hp->h_defopt), gotcha++; 6737c478bd9Sstevel@tonic-gate else 6747c478bd9Sstevel@tonic-gate fprintf(fo, "Default-Options: %s\n", hp->h_defopt), gotcha++; 6757c478bd9Sstevel@tonic-gate if ((w & GSUBJECT) && !(int)value("bsdcompat")) 6767c478bd9Sstevel@tonic-gate if (hp->h_subject != NOSTR && *hp->h_subject) 6777c478bd9Sstevel@tonic-gate fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++; 6787c478bd9Sstevel@tonic-gate else 6797c478bd9Sstevel@tonic-gate if (sflag && *sflag) 6807c478bd9Sstevel@tonic-gate fprintf(fo, "Subject: %s\n", sflag), gotcha++; 6817c478bd9Sstevel@tonic-gate if (hp->h_others != NOSTRPTR && (w & GOTHER)) { 6827c478bd9Sstevel@tonic-gate char **p; 6837c478bd9Sstevel@tonic-gate for (p = hp->h_others; *p; p++) 6847c478bd9Sstevel@tonic-gate fprintf(fo, "%s\n", *p); 6857c478bd9Sstevel@tonic-gate gotcha++; 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate #ifndef preSVr4 6887c478bd9Sstevel@tonic-gate if (w & GCLEN) 6897c478bd9Sstevel@tonic-gate fprintf(fo, "Content-Length: %ld\n", clen), gotcha++; 6907c478bd9Sstevel@tonic-gate #endif 6917c478bd9Sstevel@tonic-gate if (gotcha && (w & GNL)) 6927c478bd9Sstevel@tonic-gate putc('\n', fo); 6937c478bd9Sstevel@tonic-gate return(0); 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate /* 6977c478bd9Sstevel@tonic-gate * Format the given text to not exceed 78 characters. 6987c478bd9Sstevel@tonic-gate */ 6997c478bd9Sstevel@tonic-gate static void 7007c478bd9Sstevel@tonic-gate fmt(register char *str, register FILE *fo) 7017c478bd9Sstevel@tonic-gate { 7027c478bd9Sstevel@tonic-gate register int col = 4; 7037c478bd9Sstevel@tonic-gate char name[256]; 7047c478bd9Sstevel@tonic-gate int len; 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate str = strcpy((char *)salloc(strlen(str)+1), str); 7077c478bd9Sstevel@tonic-gate while (str = yankword(str, name, sizeof (name), 1)) { 7087c478bd9Sstevel@tonic-gate len = strlen(name); 7097c478bd9Sstevel@tonic-gate if (col > 4) { 7107c478bd9Sstevel@tonic-gate if (col + len > 76) { 7117c478bd9Sstevel@tonic-gate fputs(",\n ", fo); 7127c478bd9Sstevel@tonic-gate col = 4; 7137c478bd9Sstevel@tonic-gate } else { 7147c478bd9Sstevel@tonic-gate fputs(", ", fo); 7157c478bd9Sstevel@tonic-gate col += 2; 7167c478bd9Sstevel@tonic-gate } 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate fputs(name, fo); 7197c478bd9Sstevel@tonic-gate col += len; 7207c478bd9Sstevel@tonic-gate } 7217c478bd9Sstevel@tonic-gate putc('\n', fo); 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate /* 7257c478bd9Sstevel@tonic-gate * Save the outgoing mail on the passed file. 7267c478bd9Sstevel@tonic-gate */ 7277c478bd9Sstevel@tonic-gate static int 7287c478bd9Sstevel@tonic-gate savemail(char name[], struct header *hp, FILE *fi) 7297c478bd9Sstevel@tonic-gate { 7307c478bd9Sstevel@tonic-gate register FILE *fo; 7317c478bd9Sstevel@tonic-gate time_t now; 7327c478bd9Sstevel@tonic-gate char *n; 7337c478bd9Sstevel@tonic-gate #ifdef preSVr4 7347c478bd9Sstevel@tonic-gate char line[BUFSIZ]; 7357c478bd9Sstevel@tonic-gate #else 7367c478bd9Sstevel@tonic-gate int c; 7377c478bd9Sstevel@tonic-gate #endif 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate if (debug) 7407c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("save in '%s'\n"), name); 7417c478bd9Sstevel@tonic-gate if ((fo = fopen(name, "a")) == NULL) { 7427c478bd9Sstevel@tonic-gate perror(name); 7437c478bd9Sstevel@tonic-gate return(-1); 7447c478bd9Sstevel@tonic-gate } 7457c478bd9Sstevel@tonic-gate time(&now); 7467c478bd9Sstevel@tonic-gate n = rflag; 7477c478bd9Sstevel@tonic-gate if (n == NOSTR) 7487c478bd9Sstevel@tonic-gate n = myname; 7497c478bd9Sstevel@tonic-gate fprintf(fo, "From %s %s", n, ctime(&now)); 7507c478bd9Sstevel@tonic-gate puthead(hp, fo, GMASK|GCLEN, fsize(fi) - textpos); 7517c478bd9Sstevel@tonic-gate fseek(fi, textpos, 0); 7527c478bd9Sstevel@tonic-gate #ifdef preSVr4 7537c478bd9Sstevel@tonic-gate while (fgets(line, sizeof line, fi)) { 7547c478bd9Sstevel@tonic-gate if (!strncmp(line, "From ", 5)) 7557c478bd9Sstevel@tonic-gate putc('>', fo); 7567c478bd9Sstevel@tonic-gate fputs(line, fo); 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate #else 7597c478bd9Sstevel@tonic-gate while ((c = getc(fi)) != EOF) 7607c478bd9Sstevel@tonic-gate putc(c, fo); 7617c478bd9Sstevel@tonic-gate #endif 7627c478bd9Sstevel@tonic-gate putc('\n', fo); 7637c478bd9Sstevel@tonic-gate fflush(fo); 7647c478bd9Sstevel@tonic-gate if (fferror(fo)) 7657c478bd9Sstevel@tonic-gate perror(name); 7667c478bd9Sstevel@tonic-gate fclose(fo); 7677c478bd9Sstevel@tonic-gate return(0); 7687c478bd9Sstevel@tonic-gate } 769