BSD 3 development
[unix-history] / .ref-BSD-2 / src / Mail / quit.c
CommitLineData
0f5e4452
KS
1/* Copyright (c) 1979 Regents of the University of California */
2#
3
4#include "rcv.h"
5#include <sys/stat.h>
6
7/*
8 * Rcv -- receive mail rationally.
9 *
10 * Termination processing.
11 */
12
13/*
14 * Save all of the undetermined messages at the top of "mbox"
15 * Save all untouched messages back in the system mailbox.
16 * Remove the system mailbox, if none saved there.
17 */
18
19quit()
20{
21 int mcount, p, modify;
22 FILE *ibuf, *obuf, *fbuf, *rbuf;
23 register struct message *mp;
24 register int c;
25 extern char tempQuit[], tempResid[];
26 struct stat minfo;
27
28 /*
29 * See if there any messages to save in mbox. If no, we
30 * can save copying mbox to /tmp and back.
31 *
32 * Check also to see if any files need to be preserved.
33 * Delete all untouched messages to keep them out of mbox.
34 * If all the messages are to be preserved, just exit with
35 * a message.
36 *
37 * If the luser has sent mail to himself, refuse to do
38 * anything with the mailbox.
39 */
40
41 if (selfsent) {
42newmail:
43 printf("You have new mail.\n");
44 unlock();
45 return;
46 }
47 rbuf = NULL;
48 lock(mailname);
49 if (stat(mailname, &minfo) >= 0 && minfo.st_size > mailsize) {
50 printf("New mail has arrived.\n");
51 rbuf = fopen(tempResid, "w");
52 fbuf = fopen(mailname, "r");
53 if (rbuf == NULL || fbuf == NULL)
54 goto newmail;
55#ifdef APPENDS
56 fseek(fbuf, mailsize, 0);
57 while ((c = getc(fbuf)) != EOF)
58 putc(c, rbuf);
59#else
60 p = minfo.st_size - mailsize;
61 while (p-- > 0) {
62 c = getc(fbuf);
63 if (c == EOF)
64 goto newmail;
65 putc(c, rbuf);
66 }
67#endif
68 fclose(fbuf);
69 fclose(rbuf);
70 if ((rbuf = fopen(tempResid, "r")) == NULL)
71 goto newmail;
72 unlink(tempResid);
73 }
74 for (mp = &message[0]; mp < &message[msgCount]; mp++) {
75 if (mp->m_flag & MDELETED)
76 mp->m_flag = MDELETED|MTOUCH;
77 if ((mp->m_flag & MTOUCH) == 0)
78 mp->m_flag |= MDELETED;
79 }
80 modify = 0;
81 for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
82 if ((mp->m_flag & (MSAVED|MDELETED|MPRESERVE)) == 0)
83 c++;
84 if ((mp->m_flag & MPRESERVE) || (mp->m_flag & MTOUCH) == 0)
85 p++;
86 if (mp->m_flag & MODIFY)
87 modify++;
88 }
89 if (p == msgCount && !modify && rbuf == NULL) {
90 if (p == 1)
91 printf("Held 1 message in %s\n", mailname);
92 else
93 printf("Held %2d messages in %s\n", p, mailname);
94 unlock();
95 return;
96 }
97 if (c == 0) {
98 if (p != 0) {
99 writeback(rbuf);
100 unlock();
101 return;
102 }
103 goto remove;
104 }
105
106 /*
107 * Create another temporary file and copy user's mbox file
108 * darin. If there is no mbox, copy nothing.
109 * If he has specified "append" don't copy his mailbox,
110 * just copy saveable entries at the end.
111 */
112
113 mcount = c;
114 if (value("append") == NOSTR) {
115 if ((obuf = fopen(tempQuit, "w")) == NULL) {
116 perror(tempQuit);
117 unlock();
118 return;
119 }
120 if ((ibuf = fopen(tempQuit, "r")) == NULL) {
121 perror(tempQuit);
122 unlink(tempQuit);
123 fclose(obuf);
124 unlock();
125 return;
126 }
127 unlink(tempQuit);
128 if ((fbuf = fopen(mbox, "r")) != NULL) {
129 while ((c = getc(fbuf)) != EOF)
130 putc(c, obuf);
131 fclose(fbuf);
132 }
133 if (ferror(obuf)) {
134 perror(tempQuit);
135 fclose(ibuf);
136 fclose(obuf);
137 unlock();
138 return;
139 }
140 fclose(obuf);
141 close(creat(mbox, 0600));
142 if ((obuf = fopen(mbox, "w")) == NULL) {
143 perror(mbox);
144 fclose(ibuf);
145 unlock();
146 return;
147 }
148 }
149 if (value("append") != NOSTR)
150 if ((obuf = fopen(mbox, "a")) == NULL) {
151 perror(mbox);
152 unlock();
153 return;
154 }
155 for (mp = &message[0]; mp < &message[msgCount]; mp++)
156 if ((mp->m_flag & (MDELETED|MSAVED|MPRESERVE)) == 0)
157 if (send(mp, obuf) < 0) {
158 perror(mbox);
159 fclose(ibuf);
160 fclose(obuf);
161 unlock();
162 return;
163 }
164
165 /*
166 * Copy the user's old mbox contents back
167 * to the end of the stuff we just saved.
168 * If we are appending, this is unnecessary.
169 */
170
171 if (value("append") == NOSTR) {
172 rewind(ibuf);
173 c = getc(ibuf);
174 while (c != EOF) {
175 putc(c, obuf);
176 if (ferror(obuf))
177 break;
178 c = getc(ibuf);
179 }
180 fclose(ibuf);
181 fflush(obuf);
182 }
183 if (ferror(obuf)) {
184 perror(mbox);
185 fclose(obuf);
186 unlock();
187 return;
188 }
189 fclose(obuf);
190 if (mcount == 1)
191 printf("Saved 1 message in mbox\n");
192 else
193 printf("Saved %d messages in mbox\n", mcount);
194
195 /*
196 * Now we are ready to copy back preserved files to
197 * the system mailbox, if any were requested.
198 */
199
200 if (p != 0) {
201 writeback(rbuf);
202 unlock();
203 return;
204 }
205
206 /*
207 * Finally, remove his /usr/mail file.
208 * If new mail has arrived, copy it back.
209 */
210
211remove:
212 if (rbuf != NULL) {
213 fbuf = fopen(mailname, "w");
214 if (fbuf == NULL)
215 goto newmail;
216 while ((c = getc(rbuf)) != EOF)
217 putc(c, fbuf);
218 fclose(rbuf);
219 fclose(fbuf);
220 alter(mailname);
221 unlock();
222 return;
223 }
224 demail();
225 unlock();
226}
227
228/*
229 * Preserve all the appropriate messages back in the system
230 * mailbox, and print a nice message indicated how many were
231 * saved. On any error, just return -1. Else return 0.
232 * Incorporate the any new mail that we found.
233 */
234
235writeback(res)
236 register FILE *res;
237{
238 register struct message *mp;
239 register int p, c;
240 FILE *obuf;
241
242 p = 0;
243 if ((obuf = fopen(mailname, "w")) == NULL) {
244 perror(mailname);
245 return(-1);
246 }
247#ifndef APPEND
248 if (res != NULL)
249 while ((c = getc(res)) != EOF)
250 putc(c, obuf);
251#endif
252 for (mp = &message[0]; mp < &message[msgCount]; mp++)
253 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
254 p++;
255 if (send(mp, obuf) < 0) {
256 perror(mailname);
257 fclose(obuf);
258 return(-1);
259 }
260 }
261#ifdef APPEND
262 if (res != NULL)
263 while ((c = getc(res)) != EOF)
264 putc(c, obuf);
265#endif
266 fflush(obuf);
267 if (ferror(obuf)) {
268 perror(mailname);
269 fclose(obuf);
270 return(-1);
271 }
272 if (res != NULL)
273 fclose(res);
274 fclose(obuf);
275 alter(mailname);
276 if (p == 1)
277 printf("Held 1 message in %s\n", mailname);
278 else
279 printf("Held %d messages in %s\n", p, mailname);
280 return(0);
281}