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
copyback()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