xref: /illumos-gate/usr/src/cmd/mail/copyback.c (revision d48be21240dfd051b689384ce2b23479d757f2d8)
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 /*
26  *  NAME
27  *	copyback - copy temp or whatever back to /var/mail
28  *
29  *  SYNOPSIS
30  *	void copyback()
31  *
32  *  DESCRIPTION
33  *	Copy the reduced contents of lettmp back to
34  *	the mail file. First copy any new mail from
35  *	the mail file to the end of lettmp.
36  */
37 
38 #include "mail.h"
39 void
40 copyback()
41 {
42 	register int	i, n;
43 	int		new = 0;
44 	mode_t		mailmode, omask;
45 	struct stat	stbuf;
46 	void (*hstat)(), (*istat)(), (*qstat)();
47 
48 	istat = signal(SIGINT, SIG_IGN);
49 	qstat = signal(SIGQUIT, SIG_IGN);
50 	hstat = signal(SIGHUP, SIG_IGN);
51 	lock(my_name);
52 	stat(mailfile, &stbuf);
53 	mailmode = stbuf.st_mode;
54 
55 	/*
56 	 *	Has new mail arrived?
57 	 */
58 	if (stbuf.st_size != let[nlet].adr) {
59 		malf = doopen(mailfile, "r", E_FILE);
60 		fseek(malf, let[nlet].adr, 0);
61 		fclose(tmpf);
62 		tmpf = doopen(lettmp, "a", E_TMP);
63 		/*
64 		 *	Append new mail assume only one new letter
65 		 */
66 		if (!copystream(malf, tmpf)) {
67 			fclose(malf);
68 			tmperr();
69 			done(0);
70 		}
71 		fclose(malf);
72 		fclose(tmpf);
73 		tmpf = doopen(lettmp, "r+", E_TMP);
74 		if (nlet == (MAXLET-2)) {
75 			errmsg(E_SPACE, "");
76 			done(0);
77 		}
78 		let[++nlet].adr = stbuf.st_size;
79 		new = 1;
80 	}
81 
82 	/*
83 	 *	Copy mail back to mail file
84 	 */
85 	omask = umask(0117);
86 
87 	/*
88 	 *	The invoker must own the mailfile being copied to
89 	 */
90 	if ((stbuf.st_uid != my_euid) && (stbuf.st_uid != my_uid)) {
91 		errmsg(E_OWNR, "");
92 		done(0);
93 	}
94 
95 	/*
96 	 *	If user specified the '-f' option we dont do
97 	 *	the routines to handle :saved files.
98 	 *	As we would(incorrectly) restore to the user's
99 	 *	mailfile upon next execution!
100 	 */
101 	if (flgf) {
102 		(void) strlcpy(savefile, mailfile, sizeof (savefile));
103 	} else {
104 		cat(savefile, mailsave, my_name);
105 	}
106 
107 	if ((malf = fopen(savefile, "w")) == NULL) {
108 		if (!flgf) {
109 			errmsg(E_FILE, "Cannot open savefile");
110 		} else {
111 			errmsg(E_FILE, "Cannot re-write the alternate file");
112 		}
113 		done(0);
114 	}
115 
116 	if (chown(savefile, mf_uid, mf_gid) == -1) {
117 		errmsg(E_FILE, "Cannot chown savefile");
118 		done(0);
119 	}
120 	umask(omask);
121 	n = 0;
122 
123 	for (i = 0; i < nlet; i++) {
124 		/*
125 		 *	Note: any action other than an undelete, or a
126 		 *	plain read causes the letter acted upon to be
127 		 *	deleted
128 		 */
129 		if (let[i].change == ' ') {
130 			if (copylet(i, malf, ORDINARY) == FALSE) {
131 				errmsg(E_FILE, "Cannot copy mail to savefile");
132 				(void) fprintf(stderr, "%s: A copy of your "
133 				    "mailfile is in '%s'\n", program, lettmp);
134 				done(1);	/* keep temp file */
135 			}
136 			n++;
137 		}
138 	}
139 	fclose(malf);
140 
141 	if (!flgf) {
142 		if (unlink(mailfile) != 0) {
143 			errmsg(E_FILE, "Cannot unlink mailfile");
144 			done(0);
145 		}
146 		chmod(savefile, mailmode);
147 #ifdef SVR4
148 		if (rename(savefile, mailfile) != 0) {
149 			errmsg(E_FILE, "Cannot rename savefile to mailfile");
150 			done(0);
151 		}
152 #else
153 		if (link(savefile, mailfile) != 0) {
154 			errmsg(E_FILE, "Cannot link savefile to mailfile");
155 			done(0);
156 		}
157 		if (unlink(savefile) != 0) {
158 			errmsg(E_FILE, "Cannot unlink save file");
159 			done(0);
160 		}
161 #endif
162 	}
163 
164 	/*
165 	 *	Empty mailbox?
166 	 */
167 	if (n == 0) {
168 		delempty(stbuf.st_mode, mailfile);
169 	}
170 
171 	if (new && !flgf) {
172 		printf("New mail arrived\n");
173 	}
174 
175 	unlock();
176 	(void) signal(SIGINT, istat);
177 	(void) signal(SIGQUIT, qstat);
178 	(void) signal(SIGHUP, hstat);
179 }
180