1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23/*	  All Rights Reserved  	*/
24
25#pragma ident	"%Z%%M%	%I%	%E% SMI"
26
27/*
28 *  NAME
29 *	copyback - copy temp or whatever back to /var/mail
30 *
31 *  SYNOPSIS
32 *	void copyback()
33 *
34 *  DESCRIPTION
35 *	Copy the reduced contents of lettmp back to
36 *	the mail file. First copy any new mail from
37 *	the mail file to the end of lettmp.
38 */
39
40#include "mail.h"
41void
42copyback()
43{
44	register int	i, n;
45	int		new = 0;
46	mode_t		mailmode, omask;
47	struct stat	stbuf;
48	void (*hstat)(), (*istat)(), (*qstat)();
49
50	istat = signal(SIGINT, SIG_IGN);
51	qstat = signal(SIGQUIT, SIG_IGN);
52	hstat = signal(SIGHUP, SIG_IGN);
53	lock(my_name);
54	stat(mailfile, &stbuf);
55	mailmode = stbuf.st_mode;
56
57	/*
58	 *	Has new mail arrived?
59	 */
60	if (stbuf.st_size != let[nlet].adr) {
61		malf = doopen(mailfile, "r", E_FILE);
62		fseek(malf, let[nlet].adr, 0);
63		fclose(tmpf);
64		tmpf = doopen(lettmp, "a", E_TMP);
65		/*
66		 *	Append new mail assume only one new letter
67		 */
68		if (!copystream(malf, tmpf)) {
69			fclose(malf);
70			tmperr();
71			done(0);
72		}
73		fclose(malf);
74		fclose(tmpf);
75		tmpf = doopen(lettmp, "r+", E_TMP);
76		if (nlet == (MAXLET-2)) {
77			errmsg(E_SPACE, "");
78			done(0);
79		}
80		let[++nlet].adr = stbuf.st_size;
81		new = 1;
82	}
83
84	/*
85	 *	Copy mail back to mail file
86	 */
87	omask = umask(0117);
88
89	/*
90	 *	The invoker must own the mailfile being copied to
91	 */
92	if ((stbuf.st_uid != my_euid) && (stbuf.st_uid != my_uid)) {
93		errmsg(E_OWNR, "");
94		done(0);
95	}
96
97	/*
98	 *	If user specified the '-f' option we dont do
99	 *	the routines to handle :saved files.
100	 *	As we would(incorrectly) restore to the user's
101	 *	mailfile upon next execution!
102	 */
103	if (flgf) {
104		(void) strlcpy(savefile, mailfile, sizeof (savefile));
105	} else {
106		cat(savefile, mailsave, my_name);
107	}
108
109	if ((malf = fopen(savefile, "w")) == NULL) {
110		if (!flgf) {
111			errmsg(E_FILE, "Cannot open savefile");
112		} else {
113			errmsg(E_FILE, "Cannot re-write the alternate file");
114		}
115		done(0);
116	}
117
118	if (chown(savefile, mf_uid, mf_gid) == -1) {
119		errmsg(E_FILE, "Cannot chown savefile");
120		done(0);
121	}
122	umask(omask);
123	n = 0;
124
125	for (i = 0; i < nlet; i++) {
126		/*
127		 *	Note: any action other than an undelete, or a
128		 *	plain read causes the letter acted upon to be
129		 *	deleted
130		 */
131		if (let[i].change == ' ') {
132			if (copylet(i, malf, ORDINARY) == FALSE) {
133				errmsg(E_FILE, "Cannot copy mail to savefile");
134				(void) fprintf(stderr, "%s: A copy of your "
135				    "mailfile is in '%s'\n", program, lettmp);
136				done(1);	/* keep temp file */
137			}
138			n++;
139		}
140	}
141	fclose(malf);
142
143	if (!flgf) {
144		if (unlink(mailfile) != 0) {
145			errmsg(E_FILE, "Cannot unlink mailfile");
146			done(0);
147		}
148		chmod(savefile, mailmode);
149#ifdef SVR4
150		if (rename(savefile, mailfile) != 0) {
151			errmsg(E_FILE, "Cannot rename savefile to mailfile");
152			done(0);
153		}
154#else
155		if (link(savefile, mailfile) != 0) {
156			errmsg(E_FILE, "Cannot link savefile to mailfile");
157			done(0);
158		}
159		if (unlink(savefile) != 0) {
160			errmsg(E_FILE, "Cannot unlink save file");
161			done(0);
162		}
163#endif
164	}
165
166	/*
167	 *	Empty mailbox?
168	 */
169	if (n == 0) {
170		delempty(stbuf.st_mode, mailfile);
171	}
172
173	if (new && !flgf) {
174		printf("New mail arrived\n");
175	}
176
177	unlock();
178	(void) signal(SIGINT, istat);
179	(void) signal(SIGQUIT, qstat);
180	(void) signal(SIGHUP, hstat);
181}
182