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"
41 void
copyback()42 copyback()
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