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