calls to nonexistant fonts (from gbergman@cartan)
[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
2fd8b883 8static char *sccsid = "@(#)quit.c 5.2 (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 }
195 if (value("append") != NOSTR)
196 if ((obuf = fopen(mbox, "a")) == NULL) {
197 perror(mbox);
4e161d3b 198 fclose(fbuf);
865dca9a
KS
199 return;
200 }
201 for (mp = &message[0]; mp < &message[msgCount]; mp++)
252cba79 202 if (mp->m_flag & MBOX)
c2146fa9 203 if (send(mp, obuf, 0) < 0) {
865dca9a
KS
204 perror(mbox);
205 fclose(ibuf);
206 fclose(obuf);
4e161d3b 207 fclose(fbuf);
865dca9a
KS
208 return;
209 }
210
211 /*
212 * Copy the user's old mbox contents back
213 * to the end of the stuff we just saved.
214 * If we are appending, this is unnecessary.
215 */
216
217 if (value("append") == NOSTR) {
218 rewind(ibuf);
219 c = getc(ibuf);
220 while (c != EOF) {
221 putc(c, obuf);
222 if (ferror(obuf))
223 break;
224 c = getc(ibuf);
225 }
226 fclose(ibuf);
227 fflush(obuf);
228 }
ed3b895e 229 trunc(obuf);
865dca9a
KS
230 if (ferror(obuf)) {
231 perror(mbox);
232 fclose(obuf);
4e161d3b 233 fclose(fbuf);
865dca9a
KS
234 return;
235 }
236 fclose(obuf);
237 if (mcount == 1)
238 printf("Saved 1 message in mbox\n");
239 else
240 printf("Saved %d messages in mbox\n", mcount);
241
242 /*
243 * Now we are ready to copy back preserved files to
244 * the system mailbox, if any were requested.
245 */
246
247 if (p != 0) {
248 writeback(rbuf);
4e161d3b 249 fclose(fbuf);
865dca9a
KS
250 return;
251 }
252
253 /*
254 * Finally, remove his /usr/mail file.
255 * If new mail has arrived, copy it back.
256 */
257
258cream:
259 if (rbuf != NULL) {
4e161d3b
RC
260 abuf = fopen(mailname, "r+");
261 if (abuf == NULL)
865dca9a
KS
262 goto newmail;
263 while ((c = getc(rbuf)) != EOF)
4e161d3b 264 putc(c, abuf);
865dca9a 265 fclose(rbuf);
4e161d3b
RC
266 trunc(abuf);
267 fclose(abuf);
865dca9a 268 alter(mailname);
4e161d3b 269 fclose(fbuf);
865dca9a
KS
270 return;
271 }
272 demail();
4e161d3b 273 fclose(fbuf);
865dca9a
KS
274 return;
275
276newmail:
277 printf("Thou hast new mail.\n");
cb674576
S
278 if (fbuf != NULL)
279 fclose(fbuf);
865dca9a
KS
280}
281
282/*
283 * Preserve all the appropriate messages back in the system
284 * mailbox, and print a nice message indicated how many were
285 * saved. On any error, just return -1. Else return 0.
286 * Incorporate the any new mail that we found.
287 */
865dca9a
KS
288writeback(res)
289 register FILE *res;
290{
291 register struct message *mp;
292 register int p, c;
293 FILE *obuf;
294
295 p = 0;
b1064dda 296 if ((obuf = fopen(mailname, "r+")) == NULL) {
865dca9a
KS
297 perror(mailname);
298 return(-1);
299 }
300#ifndef APPEND
301 if (res != NULL)
302 while ((c = getc(res)) != EOF)
303 putc(c, obuf);
304#endif
305 for (mp = &message[0]; mp < &message[msgCount]; mp++)
306 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
307 p++;
c2146fa9 308 if (send(mp, obuf, 0) < 0) {
865dca9a
KS
309 perror(mailname);
310 fclose(obuf);
311 return(-1);
312 }
313 }
314#ifdef APPEND
315 if (res != NULL)
316 while ((c = getc(res)) != EOF)
317 putc(c, obuf);
318#endif
319 fflush(obuf);
ed3b895e 320 trunc(obuf);
865dca9a
KS
321 if (ferror(obuf)) {
322 perror(mailname);
323 fclose(obuf);
324 return(-1);
325 }
326 if (res != NULL)
327 fclose(res);
328 fclose(obuf);
329 alter(mailname);
330 if (p == 1)
331 printf("Held 1 message in %s\n", mailname);
332 else
333 printf("Held %d messages in %s\n", p, mailname);
334 return(0);
335}