rewritten from the manual page; add Berkeley specific header
[unix-history] / usr / src / usr.bin / mail / quit.c
CommitLineData
761330fe
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
0c5f72fb
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of California at Berkeley. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific prior written permission. This software
10 * is provided ``as is'' without express or implied warranty.
761330fe
DF
11 */
12
0c5f72fb
KB
13#ifdef notdef
14static char sccsid[] = "@(#)quit.c 5.4 (Berkeley) %G%";
15#endif /* notdef */
865dca9a
KS
16
17#include "rcv.h"
18#include <sys/stat.h>
4e161d3b 19#include <sys/file.h>
865dca9a
KS
20
21/*
22 * Rcv -- receive mail rationally.
23 *
24 * Termination processing.
25 */
26
865dca9a
KS
27/*
28 * Save all of the undetermined messages at the top of "mbox"
29 * Save all untouched messages back in the system mailbox.
30 * Remove the system mailbox, if none saved there.
31 */
32
33quit()
34{
c2483c81 35 int mcount, p, modify, autohold, anystat, holdbit, nohold;
4e161d3b 36 FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
865dca9a
KS
37 register struct message *mp;
38 register int c;
39 extern char tempQuit[], tempResid[];
40 struct stat minfo;
f0d15113 41 char *id;
865dca9a 42
3ecebc0f
KS
43 /*
44 * If we are read only, we can't do anything,
45 * so just return quickly.
46 */
47
48 if (readonly)
49 return;
865dca9a
KS
50 /*
51 * See if there any messages to save in mbox. If no, we
52 * can save copying mbox to /tmp and back.
53 *
54 * Check also to see if any files need to be preserved.
55 * Delete all untouched messages to keep them out of mbox.
56 * If all the messages are to be preserved, just exit with
57 * a message.
58 *
59 * If the luser has sent mail to himself, refuse to do
60 * anything with the mailbox, unless mail locking works.
61 */
62
4e161d3b
RC
63 fbuf = fopen(mailname, "r");
64 if (fbuf == NULL)
65 goto newmail;
66 flock(fileno(fbuf), LOCK_EX);
865dca9a
KS
67#ifndef CANLOCK
68 if (selfsent) {
69 printf("You have new mail.\n");
4e161d3b 70 fclose(fbuf);
865dca9a
KS
71 return;
72 }
73#endif
74 rbuf = NULL;
4e161d3b 75 if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
865dca9a
KS
76 printf("New mail has arrived.\n");
77 rbuf = fopen(tempResid, "w");
865dca9a
KS
78 if (rbuf == NULL || fbuf == NULL)
79 goto newmail;
80#ifdef APPEND
81 fseek(fbuf, mailsize, 0);
82 while ((c = getc(fbuf)) != EOF)
83 putc(c, rbuf);
84#else
85 p = minfo.st_size - mailsize;
86 while (p-- > 0) {
87 c = getc(fbuf);
88 if (c == EOF)
89 goto newmail;
90 putc(c, rbuf);
91 }
92#endif
865dca9a
KS
93 fclose(rbuf);
94 if ((rbuf = fopen(tempResid, "r")) == NULL)
95 goto newmail;
96 remove(tempResid);
97 }
63e83a9b
KS
98
99 /*
100 * Adjust the message flags in each message.
101 */
102
103 anystat = 0;
252cba79
KS
104 autohold = value("hold") != NOSTR;
105 holdbit = autohold ? MPRESERVE : MBOX;
c2483c81
KS
106 nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
107 if (value("keepsave") != NOSTR)
108 nohold &= ~MSAVED;
865dca9a 109 for (mp = &message[0]; mp < &message[msgCount]; mp++) {
63e83a9b
KS
110 if (mp->m_flag & MNEW) {
111 mp->m_flag &= ~MNEW;
112 mp->m_flag |= MSTATUS;
113 }
114 if (mp->m_flag & MSTATUS)
115 anystat++;
865dca9a 116 if ((mp->m_flag & MTOUCH) == 0)
252cba79 117 mp->m_flag |= MPRESERVE;
c2483c81 118 if ((mp->m_flag & nohold) == 0)
252cba79 119 mp->m_flag |= holdbit;
865dca9a
KS
120 }
121 modify = 0;
f0d15113
KS
122 if (Tflag != NOSTR) {
123 if ((readstat = fopen(Tflag, "w")) == NULL)
124 Tflag = NOSTR;
125 }
865dca9a 126 for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
252cba79 127 if (mp->m_flag & MBOX)
865dca9a 128 c++;
252cba79 129 if (mp->m_flag & MPRESERVE)
865dca9a
KS
130 p++;
131 if (mp->m_flag & MODIFY)
132 modify++;
f0d15113
KS
133 if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
134 id = hfield("article-id", mp);
135 if (id != NOSTR)
136 fprintf(readstat, "%s\n", id);
137 }
865dca9a 138 }
f0d15113
KS
139 if (Tflag != NOSTR)
140 fclose(readstat);
63e83a9b 141 if (p == msgCount && !modify && !anystat) {
865dca9a
KS
142 if (p == 1)
143 printf("Held 1 message in %s\n", mailname);
144 else
145 printf("Held %2d messages in %s\n", p, mailname);
4e161d3b 146 fclose(fbuf);
865dca9a
KS
147 return;
148 }
149 if (c == 0) {
150 if (p != 0) {
151 writeback(rbuf);
4e161d3b 152 fclose(fbuf);
865dca9a
KS
153 return;
154 }
155 goto cream;
156 }
157
158 /*
159 * Create another temporary file and copy user's mbox file
160 * darin. If there is no mbox, copy nothing.
161 * If he has specified "append" don't copy his mailbox,
162 * just copy saveable entries at the end.
163 */
164
165 mcount = c;
166 if (value("append") == NOSTR) {
167 if ((obuf = fopen(tempQuit, "w")) == NULL) {
168 perror(tempQuit);
4e161d3b 169 fclose(fbuf);
865dca9a
KS
170 return;
171 }
172 if ((ibuf = fopen(tempQuit, "r")) == NULL) {
173 perror(tempQuit);
174 remove(tempQuit);
175 fclose(obuf);
4e161d3b 176 fclose(fbuf);
865dca9a
KS
177 return;
178 }
179 remove(tempQuit);
4e161d3b
RC
180 if ((abuf = fopen(mbox, "r")) != NULL) {
181 while ((c = getc(abuf)) != EOF)
865dca9a 182 putc(c, obuf);
4e161d3b 183 fclose(abuf);
865dca9a
KS
184 }
185 if (ferror(obuf)) {
186 perror(tempQuit);
187 fclose(ibuf);
188 fclose(obuf);
4e161d3b 189 fclose(fbuf);
865dca9a
KS
190 return;
191 }
192 fclose(obuf);
193 close(creat(mbox, 0600));
b1064dda 194 if ((obuf = fopen(mbox, "r+")) == NULL) {
865dca9a
KS
195 perror(mbox);
196 fclose(ibuf);
4e161d3b 197 fclose(fbuf);
865dca9a
KS
198 return;
199 }
200 }
8fd89bb1 201 if (value("append") != NOSTR) {
865dca9a
KS
202 if ((obuf = fopen(mbox, "a")) == NULL) {
203 perror(mbox);
4e161d3b 204 fclose(fbuf);
865dca9a
KS
205 return;
206 }
8fd89bb1
KM
207 fchmod(fileno(obuf), 0600);
208 }
865dca9a 209 for (mp = &message[0]; mp < &message[msgCount]; mp++)
252cba79 210 if (mp->m_flag & MBOX)
c2146fa9 211 if (send(mp, obuf, 0) < 0) {
865dca9a
KS
212 perror(mbox);
213 fclose(ibuf);
214 fclose(obuf);
4e161d3b 215 fclose(fbuf);
865dca9a
KS
216 return;
217 }
218
219 /*
220 * Copy the user's old mbox contents back
221 * to the end of the stuff we just saved.
222 * If we are appending, this is unnecessary.
223 */
224
225 if (value("append") == NOSTR) {
226 rewind(ibuf);
227 c = getc(ibuf);
228 while (c != EOF) {
229 putc(c, obuf);
230 if (ferror(obuf))
231 break;
232 c = getc(ibuf);
233 }
234 fclose(ibuf);
235 fflush(obuf);
236 }
ed3b895e 237 trunc(obuf);
865dca9a
KS
238 if (ferror(obuf)) {
239 perror(mbox);
240 fclose(obuf);
4e161d3b 241 fclose(fbuf);
865dca9a
KS
242 return;
243 }
244 fclose(obuf);
245 if (mcount == 1)
246 printf("Saved 1 message in mbox\n");
247 else
248 printf("Saved %d messages in mbox\n", mcount);
249
250 /*
251 * Now we are ready to copy back preserved files to
252 * the system mailbox, if any were requested.
253 */
254
255 if (p != 0) {
256 writeback(rbuf);
4e161d3b 257 fclose(fbuf);
865dca9a
KS
258 return;
259 }
260
261 /*
262 * Finally, remove his /usr/mail file.
263 * If new mail has arrived, copy it back.
264 */
265
266cream:
267 if (rbuf != NULL) {
4e161d3b
RC
268 abuf = fopen(mailname, "r+");
269 if (abuf == NULL)
865dca9a
KS
270 goto newmail;
271 while ((c = getc(rbuf)) != EOF)
4e161d3b 272 putc(c, abuf);
865dca9a 273 fclose(rbuf);
4e161d3b
RC
274 trunc(abuf);
275 fclose(abuf);
865dca9a 276 alter(mailname);
4e161d3b 277 fclose(fbuf);
865dca9a
KS
278 return;
279 }
280 demail();
4e161d3b 281 fclose(fbuf);
865dca9a
KS
282 return;
283
284newmail:
285 printf("Thou hast new mail.\n");
cb674576
S
286 if (fbuf != NULL)
287 fclose(fbuf);
865dca9a
KS
288}
289
290/*
291 * Preserve all the appropriate messages back in the system
292 * mailbox, and print a nice message indicated how many were
293 * saved. On any error, just return -1. Else return 0.
294 * Incorporate the any new mail that we found.
295 */
865dca9a
KS
296writeback(res)
297 register FILE *res;
298{
299 register struct message *mp;
300 register int p, c;
301 FILE *obuf;
302
303 p = 0;
b1064dda 304 if ((obuf = fopen(mailname, "r+")) == NULL) {
865dca9a
KS
305 perror(mailname);
306 return(-1);
307 }
308#ifndef APPEND
309 if (res != NULL)
310 while ((c = getc(res)) != EOF)
311 putc(c, obuf);
312#endif
313 for (mp = &message[0]; mp < &message[msgCount]; mp++)
314 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
315 p++;
c2146fa9 316 if (send(mp, obuf, 0) < 0) {
865dca9a
KS
317 perror(mailname);
318 fclose(obuf);
319 return(-1);
320 }
321 }
322#ifdef APPEND
323 if (res != NULL)
324 while ((c = getc(res)) != EOF)
325 putc(c, obuf);
326#endif
327 fflush(obuf);
ed3b895e 328 trunc(obuf);
865dca9a
KS
329 if (ferror(obuf)) {
330 perror(mailname);
331 fclose(obuf);
332 return(-1);
333 }
334 if (res != NULL)
335 fclose(res);
336 fclose(obuf);
337 alter(mailname);
338 if (p == 1)
339 printf("Held 1 message in %s\n", mailname);
340 else
341 printf("Held %d messages in %s\n", p, mailname);
342 return(0);
343}