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