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