xref: /illumos-gate/usr/src/cmd/mailx/quit.c (revision 2a8bcb4e)
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
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
237c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*48bbca81SDaniel Hoffman /*
25*48bbca81SDaniel Hoffman  * Copyright (c) 2016 by Delphix. All rights reserved.
26*48bbca81SDaniel Hoffman  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
307c478bd9Sstevel@tonic-gate  * The Regents of the University of California
317c478bd9Sstevel@tonic-gate  * All Rights Reserved
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
347c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
357c478bd9Sstevel@tonic-gate  * contributors.
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include "rcv.h"
397c478bd9Sstevel@tonic-gate #include <locale.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * mailx -- a modified version of a University of California at Berkeley
437c478bd9Sstevel@tonic-gate  *	mail program
447c478bd9Sstevel@tonic-gate  *
457c478bd9Sstevel@tonic-gate  * Rcv -- receive mail rationally.
467c478bd9Sstevel@tonic-gate  *
477c478bd9Sstevel@tonic-gate  * Termination processing.
487c478bd9Sstevel@tonic-gate  */
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate static void		writeback(int noremove);
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #define PRIV(x)		setgid(myegid), (x), setgid(myrgid);
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /*
557c478bd9Sstevel@tonic-gate  * Save all of the undetermined messages at the top of "mbox"
567c478bd9Sstevel@tonic-gate  * Save all untouched messages back in the system mailbox.
577c478bd9Sstevel@tonic-gate  * Remove the system mailbox, if none saved there.
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate 
60*48bbca81SDaniel Hoffman void
quit(int noremove)617c478bd9Sstevel@tonic-gate quit(
627c478bd9Sstevel@tonic-gate     int noremove	/* don't remove system mailbox, trunc it instead */
637c478bd9Sstevel@tonic-gate )
647c478bd9Sstevel@tonic-gate {
657c478bd9Sstevel@tonic-gate 	int mcount, p, modify, autohold, anystat, holdbit, nohold, fd;
667c478bd9Sstevel@tonic-gate 	FILE *ibuf, *obuf, *fbuf, *readstat;
677c478bd9Sstevel@tonic-gate 	register struct message *mp;
687c478bd9Sstevel@tonic-gate 	register int c;
697c478bd9Sstevel@tonic-gate 	char *id;
707c478bd9Sstevel@tonic-gate 	int appending;
717c478bd9Sstevel@tonic-gate 	char *mbox = Getf("MBOX");
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 	/*
747c478bd9Sstevel@tonic-gate 	 * If we are read only, we can't do anything,
757c478bd9Sstevel@tonic-gate 	 * so just return quickly.
767c478bd9Sstevel@tonic-gate 	 */
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	mcount = 0;
797c478bd9Sstevel@tonic-gate 	if (readonly)
807c478bd9Sstevel@tonic-gate 		return;
817c478bd9Sstevel@tonic-gate 	/*
827c478bd9Sstevel@tonic-gate 	 * See if there any messages to save in mbox.  If no, we
837c478bd9Sstevel@tonic-gate 	 * can save copying mbox to /tmp and back.
847c478bd9Sstevel@tonic-gate 	 *
857c478bd9Sstevel@tonic-gate 	 * Check also to see if any files need to be preserved.
867c478bd9Sstevel@tonic-gate 	 * Delete all untouched messages to keep them out of mbox.
877c478bd9Sstevel@tonic-gate 	 * If all the messages are to be preserved, just exit with
887c478bd9Sstevel@tonic-gate 	 * a message.
897c478bd9Sstevel@tonic-gate 	 *
907c478bd9Sstevel@tonic-gate 	 * If the luser has sent mail to himself, refuse to do
917c478bd9Sstevel@tonic-gate 	 * anything with the mailbox, unless mail locking works.
927c478bd9Sstevel@tonic-gate 	 */
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate #ifndef CANLOCK
957c478bd9Sstevel@tonic-gate 	if (selfsent) {
967c478bd9Sstevel@tonic-gate 		printf(gettext("You have new mail.\n"));
977c478bd9Sstevel@tonic-gate 		return;
987c478bd9Sstevel@tonic-gate 	}
997c478bd9Sstevel@tonic-gate #endif
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	/*
1027c478bd9Sstevel@tonic-gate 	 * Adjust the message flags in each message.
1037c478bd9Sstevel@tonic-gate 	 */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	anystat = 0;
1067c478bd9Sstevel@tonic-gate 	autohold = value("hold") != NOSTR;
1077c478bd9Sstevel@tonic-gate 	appending = value("append") != NOSTR;
1087c478bd9Sstevel@tonic-gate 	holdbit = autohold ? MPRESERVE : MBOX;
1097c478bd9Sstevel@tonic-gate 	nohold = MBOXED|MBOX|MSAVED|MDELETED|MPRESERVE;
1107c478bd9Sstevel@tonic-gate 	if (value("keepsave") != NOSTR)
1117c478bd9Sstevel@tonic-gate 		nohold &= ~MSAVED;
1127c478bd9Sstevel@tonic-gate 	for (mp = &message[0]; mp < &message[msgCount]; mp++) {
1137c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MNEW) {
1147c478bd9Sstevel@tonic-gate 			receipt(mp);
1157c478bd9Sstevel@tonic-gate 			mp->m_flag &= ~MNEW;
1167c478bd9Sstevel@tonic-gate 			mp->m_flag |= MSTATUS;
1177c478bd9Sstevel@tonic-gate 		}
1187c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MSTATUS)
1197c478bd9Sstevel@tonic-gate 			anystat++;
1207c478bd9Sstevel@tonic-gate 		if ((mp->m_flag & MTOUCH) == 0)
1217c478bd9Sstevel@tonic-gate 			mp->m_flag |= MPRESERVE;
1227c478bd9Sstevel@tonic-gate 		if ((mp->m_flag & nohold) == 0)
1237c478bd9Sstevel@tonic-gate 			mp->m_flag |= holdbit;
1247c478bd9Sstevel@tonic-gate 	}
1257c478bd9Sstevel@tonic-gate 	modify = 0;
1267c478bd9Sstevel@tonic-gate 	if (Tflag != NOSTR) {
1277c478bd9Sstevel@tonic-gate 		if ((readstat = fopen(Tflag, "w")) == NULL)
1287c478bd9Sstevel@tonic-gate 			Tflag = NOSTR;
1297c478bd9Sstevel@tonic-gate 	}
1307c478bd9Sstevel@tonic-gate 	for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
1317c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MBOX)
1327c478bd9Sstevel@tonic-gate 			c++;
1337c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MPRESERVE)
1347c478bd9Sstevel@tonic-gate 			p++;
1357c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MODIFY)
1367c478bd9Sstevel@tonic-gate 			modify++;
1377c478bd9Sstevel@tonic-gate 		if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
1387c478bd9Sstevel@tonic-gate 			id = hfield("message-id", mp, addone);
1397c478bd9Sstevel@tonic-gate 			if (id != NOSTR)
1407c478bd9Sstevel@tonic-gate 				fprintf(readstat, "%s\n", id);
1417c478bd9Sstevel@tonic-gate 			else {
1427c478bd9Sstevel@tonic-gate 				id = hfield("article-id", mp, addone);
1437c478bd9Sstevel@tonic-gate 				if (id != NOSTR)
1447c478bd9Sstevel@tonic-gate 					fprintf(readstat, "%s\n", id);
1457c478bd9Sstevel@tonic-gate 			}
1467c478bd9Sstevel@tonic-gate 		}
1477c478bd9Sstevel@tonic-gate 	}
1487c478bd9Sstevel@tonic-gate 	if (Tflag != NOSTR)
1497c478bd9Sstevel@tonic-gate 		fclose(readstat);
1507c478bd9Sstevel@tonic-gate 	if (p == msgCount && !modify && !anystat) {
1517c478bd9Sstevel@tonic-gate 		if (p == 1)
1527c478bd9Sstevel@tonic-gate 			printf(gettext("Held 1 message in %s\n"), mailname);
1537c478bd9Sstevel@tonic-gate 		else
1547c478bd9Sstevel@tonic-gate 			printf(gettext("Held %d messages in %s\n"), p,
1557c478bd9Sstevel@tonic-gate 			    mailname);
1567c478bd9Sstevel@tonic-gate 		return;
1577c478bd9Sstevel@tonic-gate 	}
1587c478bd9Sstevel@tonic-gate 	if (c == 0) {
1597c478bd9Sstevel@tonic-gate 		writeback(noremove);
1607c478bd9Sstevel@tonic-gate 		return;
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	/*
1647c478bd9Sstevel@tonic-gate 	 * Create another temporary file and copy user's mbox file
1657c478bd9Sstevel@tonic-gate 	 * therein.  If there is no mbox, copy nothing.
166*48bbca81SDaniel Hoffman 	 * If they have specified "append" don't copy the mailbox,
1677c478bd9Sstevel@tonic-gate 	 * just copy saveable entries at the end.
1687c478bd9Sstevel@tonic-gate 	 */
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 	mcount = c;
1717c478bd9Sstevel@tonic-gate 	if (!appending) {
1727c478bd9Sstevel@tonic-gate 		if ((fd = open(tempQuit, O_RDWR|O_CREAT|O_EXCL, 0600)) < 0 ||
1737c478bd9Sstevel@tonic-gate 		(obuf = fdopen(fd, "w")) == NULL) {
1747c478bd9Sstevel@tonic-gate 			perror(tempQuit);
1757c478bd9Sstevel@tonic-gate 			return;
1767c478bd9Sstevel@tonic-gate 		}
1777c478bd9Sstevel@tonic-gate 		if ((ibuf = fopen(tempQuit, "r")) == NULL) {
1787c478bd9Sstevel@tonic-gate 			perror(tempQuit);
1797c478bd9Sstevel@tonic-gate 			removefile(tempQuit);
1807c478bd9Sstevel@tonic-gate 			fclose(obuf);
1817c478bd9Sstevel@tonic-gate 			return;
1827c478bd9Sstevel@tonic-gate 		}
1837c478bd9Sstevel@tonic-gate 		removefile(tempQuit);
1847c478bd9Sstevel@tonic-gate 		if ((fbuf = fopen(mbox, "r")) != NULL) {
1857c478bd9Sstevel@tonic-gate 			while ((c = getc(fbuf)) != EOF)
1867c478bd9Sstevel@tonic-gate 				putc(c, obuf);
1877c478bd9Sstevel@tonic-gate 			fclose(fbuf);
1887c478bd9Sstevel@tonic-gate 		}
1897c478bd9Sstevel@tonic-gate 		fflush(obuf);
1907c478bd9Sstevel@tonic-gate 		if (fferror(obuf)) {
1917c478bd9Sstevel@tonic-gate 			perror(tempQuit);
1927c478bd9Sstevel@tonic-gate 			fclose(ibuf);
1937c478bd9Sstevel@tonic-gate 			fclose(obuf);
1947c478bd9Sstevel@tonic-gate 			return;
1957c478bd9Sstevel@tonic-gate 		}
1967c478bd9Sstevel@tonic-gate 		fclose(obuf);
1977c478bd9Sstevel@tonic-gate 		if ((fd = open(mbox, O_RDWR|O_CREAT|O_TRUNC, MBOXPERM)) < 0 ||
1987c478bd9Sstevel@tonic-gate 		    (obuf = fdopen(fd, "r+")) == NULL) {
1997c478bd9Sstevel@tonic-gate 			perror(mbox);
2007c478bd9Sstevel@tonic-gate 			fclose(ibuf);
2017c478bd9Sstevel@tonic-gate 			return;
2027c478bd9Sstevel@tonic-gate 		}
2037c478bd9Sstevel@tonic-gate 		if (issysmbox)
2047c478bd9Sstevel@tonic-gate 			touchlock();
2057c478bd9Sstevel@tonic-gate 	} else {	/* we are appending */
2067c478bd9Sstevel@tonic-gate 		if ((fd = open(mbox, O_RDWR|O_CREAT, MBOXPERM)) < 0 ||
2077c478bd9Sstevel@tonic-gate 		    (obuf = fdopen(fd, "a")) == NULL) {
2087c478bd9Sstevel@tonic-gate 			perror(mbox);
2097c478bd9Sstevel@tonic-gate 			return;
2107c478bd9Sstevel@tonic-gate 		}
2117c478bd9Sstevel@tonic-gate 	}
2127c478bd9Sstevel@tonic-gate 	for (mp = &message[0]; mp < &message[msgCount]; mp++)
2137c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MBOX) {
2147c478bd9Sstevel@tonic-gate 			if (msend(mp, obuf, (int)value("alwaysignore") ?
2157c478bd9Sstevel@tonic-gate 			    M_IGNORE|M_SAVING : M_SAVING, fputs) < 0) {
2167c478bd9Sstevel@tonic-gate 				perror(mbox);
2177c478bd9Sstevel@tonic-gate 				if (!appending)
2187c478bd9Sstevel@tonic-gate 					fclose(ibuf);
2197c478bd9Sstevel@tonic-gate 				fclose(obuf);
2207c478bd9Sstevel@tonic-gate 				return;
2217c478bd9Sstevel@tonic-gate 			}
2227c478bd9Sstevel@tonic-gate 			mp->m_flag &= ~MBOX;
2237c478bd9Sstevel@tonic-gate 			mp->m_flag |= MBOXED;
2247c478bd9Sstevel@tonic-gate 			if (issysmbox)
2257c478bd9Sstevel@tonic-gate 				touchlock();
2267c478bd9Sstevel@tonic-gate 		}
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 	/*
2297c478bd9Sstevel@tonic-gate 	 * Copy the user's old mbox contents back
2307c478bd9Sstevel@tonic-gate 	 * to the end of the stuff we just saved.
2317c478bd9Sstevel@tonic-gate 	 * If we are appending, this is unnecessary.
2327c478bd9Sstevel@tonic-gate 	 */
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	if (!appending) {
2357c478bd9Sstevel@tonic-gate 		rewind(ibuf);
2367c478bd9Sstevel@tonic-gate 		c = getc(ibuf);
2377c478bd9Sstevel@tonic-gate 		while (c != EOF) {
2387c478bd9Sstevel@tonic-gate 			putc(c, obuf);
2397c478bd9Sstevel@tonic-gate 			if (ferror(obuf))
2407c478bd9Sstevel@tonic-gate 				break;
2417c478bd9Sstevel@tonic-gate 			c = getc(ibuf);
2427c478bd9Sstevel@tonic-gate 		}
2437c478bd9Sstevel@tonic-gate 		fclose(ibuf);
2447c478bd9Sstevel@tonic-gate 		fflush(obuf);
2457c478bd9Sstevel@tonic-gate 	}
2467c478bd9Sstevel@tonic-gate 	trunc(obuf);
2477c478bd9Sstevel@tonic-gate 	if (fferror(obuf)) {
2487c478bd9Sstevel@tonic-gate 		perror(mbox);
2497c478bd9Sstevel@tonic-gate 		fclose(obuf);
2507c478bd9Sstevel@tonic-gate 		return;
2517c478bd9Sstevel@tonic-gate 	}
2527c478bd9Sstevel@tonic-gate 	fclose(obuf);
2537c478bd9Sstevel@tonic-gate 	if (mcount == 1)
2547c478bd9Sstevel@tonic-gate 		printf(gettext("Saved 1 message in %s\n"), mbox);
2557c478bd9Sstevel@tonic-gate 	else
2567c478bd9Sstevel@tonic-gate 		printf(gettext("Saved %d messages in %s\n"), mcount, mbox);
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	/*
2597c478bd9Sstevel@tonic-gate 	 * Now we are ready to copy back preserved files to
2607c478bd9Sstevel@tonic-gate 	 * the system mailbox, if any were requested.
2617c478bd9Sstevel@tonic-gate 	 */
2627c478bd9Sstevel@tonic-gate 	writeback(noremove);
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate /*
2667c478bd9Sstevel@tonic-gate  * Preserve all the appropriate messages back in the system
2677c478bd9Sstevel@tonic-gate  * mailbox, and print a nice message indicating how many were
2687c478bd9Sstevel@tonic-gate  * saved.  Incorporate any new mail that we found.
2697c478bd9Sstevel@tonic-gate  */
270*48bbca81SDaniel Hoffman static void
writeback(int noremove)2717c478bd9Sstevel@tonic-gate writeback(int noremove)
2727c478bd9Sstevel@tonic-gate {
2737c478bd9Sstevel@tonic-gate 	register struct message *mp;
2747c478bd9Sstevel@tonic-gate 	register int p, c;
2757c478bd9Sstevel@tonic-gate 	struct stat st;
2767c478bd9Sstevel@tonic-gate 	FILE *obuf = 0, *fbuf = 0, *rbuf = 0;
2777c478bd9Sstevel@tonic-gate 	void (*fhup)(int), (*fint)(int), (*fquit)(int);
2787c478bd9Sstevel@tonic-gate 	int fd = -1;
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	fhup = sigset(SIGHUP, SIG_IGN);
2817c478bd9Sstevel@tonic-gate 	fint = sigset(SIGINT, SIG_IGN);
2827c478bd9Sstevel@tonic-gate 	fquit = sigset(SIGQUIT, SIG_IGN);
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 	if (issysmbox)
2857c478bd9Sstevel@tonic-gate 		lockmail();
2867c478bd9Sstevel@tonic-gate 	if ((fbuf = fopen(mailname, "r+")) == NULL) {
2877c478bd9Sstevel@tonic-gate 		perror(mailname);
2887c478bd9Sstevel@tonic-gate 		goto die;
2897c478bd9Sstevel@tonic-gate 	}
2907c478bd9Sstevel@tonic-gate 	if (!issysmbox)
2917c478bd9Sstevel@tonic-gate 		lock(fbuf, "r+", 1);
2927c478bd9Sstevel@tonic-gate 	fstat(fileno(fbuf), &st);
2937c478bd9Sstevel@tonic-gate 	if (st.st_size > mailsize) {
2947c478bd9Sstevel@tonic-gate 		printf(gettext("New mail has arrived.\n"));
2957c478bd9Sstevel@tonic-gate 		snprintf(tempResid, PATHSIZE, "%s/:saved/%s", maildir, myname);
2967c478bd9Sstevel@tonic-gate 		PRIV(rbuf = fopen(tempResid, "w+"));
2977c478bd9Sstevel@tonic-gate 		if (rbuf == NULL) {
2987c478bd9Sstevel@tonic-gate 			snprintf(tempResid, PATHSIZE, "/tmp/Rq%-ld", mypid);
2997c478bd9Sstevel@tonic-gate 			fd = open(tempResid,O_RDWR|O_CREAT|O_EXCL, 0600);
3007c478bd9Sstevel@tonic-gate 			PRIV(rbuf = fdopen(fd, "w+"));
3017c478bd9Sstevel@tonic-gate 			if (rbuf == NULL) {
3027c478bd9Sstevel@tonic-gate 				snprintf(tempResid, PATHSIZE,
3037c478bd9Sstevel@tonic-gate 					"%s/:saved/%s", maildir,
3047c478bd9Sstevel@tonic-gate 				    myname);
3057c478bd9Sstevel@tonic-gate 				perror(tempResid);
3067c478bd9Sstevel@tonic-gate 				fclose(fbuf);
3077c478bd9Sstevel@tonic-gate 				goto die;
3087c478bd9Sstevel@tonic-gate 			}
3097c478bd9Sstevel@tonic-gate 		}
3107c478bd9Sstevel@tonic-gate #ifdef APPEND
3117c478bd9Sstevel@tonic-gate 		fseek(fbuf, mailsize, 0);
3127c478bd9Sstevel@tonic-gate 		while ((c = getc(fbuf)) != EOF)
3137c478bd9Sstevel@tonic-gate 			putc(c, rbuf);
3147c478bd9Sstevel@tonic-gate #else
3157c478bd9Sstevel@tonic-gate 		p = st.st_size - mailsize;
3167c478bd9Sstevel@tonic-gate 		while (p-- > 0) {
3177c478bd9Sstevel@tonic-gate 			c = getc(fbuf);
3187c478bd9Sstevel@tonic-gate 			if (c == EOF) {
3197c478bd9Sstevel@tonic-gate 				perror(mailname);
3207c478bd9Sstevel@tonic-gate 				fclose(fbuf);
3217c478bd9Sstevel@tonic-gate 				goto die;
3227c478bd9Sstevel@tonic-gate 			}
3237c478bd9Sstevel@tonic-gate 			putc(c, rbuf);
3247c478bd9Sstevel@tonic-gate 		}
3257c478bd9Sstevel@tonic-gate #endif
3267c478bd9Sstevel@tonic-gate 		fclose(fbuf);
3277c478bd9Sstevel@tonic-gate 		fseek(rbuf, 0L, 0);
3287c478bd9Sstevel@tonic-gate 		if (issysmbox)
3297c478bd9Sstevel@tonic-gate 			touchlock();
3307c478bd9Sstevel@tonic-gate 	}
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 	if ((obuf = fopen(mailname, "r+")) == NULL) {
3337c478bd9Sstevel@tonic-gate 		perror(mailname);
3347c478bd9Sstevel@tonic-gate 		goto die;
3357c478bd9Sstevel@tonic-gate 	}
3367c478bd9Sstevel@tonic-gate #ifndef APPEND
3377c478bd9Sstevel@tonic-gate 	if (rbuf != NULL)
3387c478bd9Sstevel@tonic-gate 		while ((c = getc(rbuf)) != EOF)
3397c478bd9Sstevel@tonic-gate 			putc(c, obuf);
3407c478bd9Sstevel@tonic-gate #endif
3417c478bd9Sstevel@tonic-gate 	p = 0;
3427c478bd9Sstevel@tonic-gate 	for (mp = &message[0]; mp < &message[msgCount]; mp++)
3437c478bd9Sstevel@tonic-gate 		if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
3447c478bd9Sstevel@tonic-gate 			p++;
3457c478bd9Sstevel@tonic-gate 			if (msend(mp, obuf, 0, fputs) < 0) {
3467c478bd9Sstevel@tonic-gate 				perror(mailname);
3477c478bd9Sstevel@tonic-gate 				goto die;
3487c478bd9Sstevel@tonic-gate 			}
3497c478bd9Sstevel@tonic-gate 			if (issysmbox)
3507c478bd9Sstevel@tonic-gate 				touchlock();
3517c478bd9Sstevel@tonic-gate 		}
3527c478bd9Sstevel@tonic-gate #ifdef APPEND
3537c478bd9Sstevel@tonic-gate 	if (rbuf != NULL)
3547c478bd9Sstevel@tonic-gate 		while ((c = getc(rbuf)) != EOF)
3557c478bd9Sstevel@tonic-gate 			putc(c, obuf);
3567c478bd9Sstevel@tonic-gate #endif
3577c478bd9Sstevel@tonic-gate 	fflush(obuf);
3587c478bd9Sstevel@tonic-gate 	trunc(obuf);
3597c478bd9Sstevel@tonic-gate 	if (fferror(obuf)) {
3607c478bd9Sstevel@tonic-gate 		perror(mailname);
3617c478bd9Sstevel@tonic-gate 		goto die;
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate 	alter(mailname);
3647c478bd9Sstevel@tonic-gate 	if (p) {
3657c478bd9Sstevel@tonic-gate 		if (p == 1)
3667c478bd9Sstevel@tonic-gate 			printf(gettext("Held 1 message in %s\n"), mailname);
3677c478bd9Sstevel@tonic-gate 		else
3687c478bd9Sstevel@tonic-gate 			printf(gettext("Held %d messages in %s\n"), p,
3697c478bd9Sstevel@tonic-gate 			    mailname);
3707c478bd9Sstevel@tonic-gate 	}
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	if (!noremove && (fsize(obuf) == 0) && (value("keep") == NOSTR)) {
3737c478bd9Sstevel@tonic-gate 		if (stat(mailname, &st) >= 0)
3747c478bd9Sstevel@tonic-gate 			PRIV(delempty(st.st_mode, mailname));
3757c478bd9Sstevel@tonic-gate 	}
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate die:
3787c478bd9Sstevel@tonic-gate 	if (rbuf) {
3797c478bd9Sstevel@tonic-gate 		fclose(rbuf);
3807c478bd9Sstevel@tonic-gate 		PRIV(removefile(tempResid));
3817c478bd9Sstevel@tonic-gate 	}
382*48bbca81SDaniel Hoffman 	if (obuf)
3837c478bd9Sstevel@tonic-gate 		fclose(obuf);
3847c478bd9Sstevel@tonic-gate 	if (issysmbox)
3857c478bd9Sstevel@tonic-gate 		unlockmail();
3867c478bd9Sstevel@tonic-gate 	sigset(SIGHUP, fhup);
3877c478bd9Sstevel@tonic-gate 	sigset(SIGINT, fint);
3887c478bd9Sstevel@tonic-gate 	sigset(SIGQUIT, fquit);
3897c478bd9Sstevel@tonic-gate }
3907c478bd9Sstevel@tonic-gate 
391*48bbca81SDaniel Hoffman void
lockmail(void)3927c478bd9Sstevel@tonic-gate lockmail(void)
3937c478bd9Sstevel@tonic-gate {
3947c478bd9Sstevel@tonic-gate     PRIV(maillock(lockname,10));
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate 
397*48bbca81SDaniel Hoffman void
unlockmail(void)3987c478bd9Sstevel@tonic-gate unlockmail(void)
3997c478bd9Sstevel@tonic-gate {
4007c478bd9Sstevel@tonic-gate     PRIV(mailunlock());
4017c478bd9Sstevel@tonic-gate }
402