BSD 4 development
[unix-history] / usr / src / cmd / ucbmail / quit.c
CommitLineData
c8eb690c
BJ
1#
2
3#include "rcv.h"
4#include <sys/stat.h>
5
6/*
7 * Rcv -- receive mail rationally.
8 *
9 * Termination processing.
10 */
11
12/*
13 * Save all of the undetermined messages at the top of "mbox"
14 * Save all untouched messages back in the system mailbox.
15 * Remove the system mailbox, if none saved there.
16 */
17
18quit()
19{
20 int mcount, p, modify;
21 FILE *ibuf, *obuf, *fbuf, *rbuf;
22 register struct message *mp;
23 register int c;
24 extern char tempQuit[], tempResid[];
25 struct stat minfo;
26
27 /*
28 * See if there any messages to save in mbox. If no, we
29 * can save copying mbox to /tmp and back.
30 *
31 * Check also to see if any files need to be preserved.
32 * Delete all untouched messages to keep them out of mbox.
33 * If all the messages are to be preserved, just exit with
34 * a message.
35 *
36 * If the luser has sent mail to himself, refuse to do
37 * anything with the mailbox, unless mail locking works.
38 */
39
40 lock(mailname);
41#ifndef CANLOCK
42 if (selfsent) {
43 printf("You have new mail.\n");
44 unlock();
45 return;
46 }
47#endif
48 rbuf = NULL;
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 APPEND
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 remove(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) {
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 cream;
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 remove(tempQuit);
123 fclose(obuf);
124 unlock();
125 return;
126 }
127 remove(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
211cream:
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 return;
227
228newmail:
229 printf("Thou hast new mail.\n");
230 unlock();
231}
232
233/*
234 * Preserve all the appropriate messages back in the system
235 * mailbox, and print a nice message indicated how many were
236 * saved. On any error, just return -1. Else return 0.
237 * Incorporate the any new mail that we found.
238 */
239
240writeback(res)
241 register FILE *res;
242{
243 register struct message *mp;
244 register int p, c;
245 FILE *obuf;
246
247 p = 0;
248 if ((obuf = fopen(mailname, "w")) == NULL) {
249 perror(mailname);
250 return(-1);
251 }
252#ifndef APPEND
253 if (res != NULL)
254 while ((c = getc(res)) != EOF)
255 putc(c, obuf);
256#endif
257 for (mp = &message[0]; mp < &message[msgCount]; mp++)
258 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
259 p++;
260 if (send(mp, obuf) < 0) {
261 perror(mailname);
262 fclose(obuf);
263 return(-1);
264 }
265 }
266#ifdef APPEND
267 if (res != NULL)
268 while ((c = getc(res)) != EOF)
269 putc(c, obuf);
270#endif
271 fflush(obuf);
272 if (ferror(obuf)) {
273 perror(mailname);
274 fclose(obuf);
275 return(-1);
276 }
277 if (res != NULL)
278 fclose(res);
279 fclose(obuf);
280 alter(mailname);
281 if (p == 1)
282 printf("Held 1 message in %s\n", mailname);
283 else
284 printf("Held %d messages in %s\n", p, mailname);
285 return(0);
286}