|
|
1.1 root 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:
7: #ifndef lint
8: static char *sccsid = "@(#)quit.c 5.3 (Berkeley) 3/6/86";
9: #endif not lint
10:
11: #include "rcv.h"
12: #include <sys/stat.h>
13: #include <sys/file.h>
14:
15: /*
16: * Rcv -- receive mail rationally.
17: *
18: * Termination processing.
19: */
20:
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:
27: quit()
28: {
29: int mcount, p, modify, autohold, anystat, holdbit, nohold;
30: FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
31: register struct message *mp;
32: register int c;
33: extern char tempQuit[], tempResid[];
34: struct stat minfo;
35: char *id;
36:
37: /*
38: * If we are read only, we can't do anything,
39: * so just return quickly.
40: */
41:
42: if (readonly)
43: return;
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:
57: fbuf = fopen(mailname, "r");
58: if (fbuf == NULL)
59: goto newmail;
60: flock(fileno(fbuf), LOCK_EX);
61: #ifndef CANLOCK
62: if (selfsent) {
63: printf("You have new mail.\n");
64: fclose(fbuf);
65: return;
66: }
67: #endif
68: rbuf = NULL;
69: if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
70: printf("New mail has arrived.\n");
71: rbuf = fopen(tempResid, "w");
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
87: fclose(rbuf);
88: if ((rbuf = fopen(tempResid, "r")) == NULL)
89: goto newmail;
90: remove(tempResid);
91: }
92:
93: /*
94: * Adjust the message flags in each message.
95: */
96:
97: anystat = 0;
98: autohold = value("hold") != NOSTR;
99: holdbit = autohold ? MPRESERVE : MBOX;
100: nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
101: if (value("keepsave") != NOSTR)
102: nohold &= ~MSAVED;
103: for (mp = &message[0]; mp < &message[msgCount]; mp++) {
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++;
110: if ((mp->m_flag & MTOUCH) == 0)
111: mp->m_flag |= MPRESERVE;
112: if ((mp->m_flag & nohold) == 0)
113: mp->m_flag |= holdbit;
114: }
115: modify = 0;
116: if (Tflag != NOSTR) {
117: if ((readstat = fopen(Tflag, "w")) == NULL)
118: Tflag = NOSTR;
119: }
120: for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
121: if (mp->m_flag & MBOX)
122: c++;
123: if (mp->m_flag & MPRESERVE)
124: p++;
125: if (mp->m_flag & MODIFY)
126: modify++;
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: }
132: }
133: if (Tflag != NOSTR)
134: fclose(readstat);
135: if (p == msgCount && !modify && !anystat) {
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);
140: fclose(fbuf);
141: return;
142: }
143: if (c == 0) {
144: if (p != 0) {
145: writeback(rbuf);
146: fclose(fbuf);
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);
163: fclose(fbuf);
164: return;
165: }
166: if ((ibuf = fopen(tempQuit, "r")) == NULL) {
167: perror(tempQuit);
168: remove(tempQuit);
169: fclose(obuf);
170: fclose(fbuf);
171: return;
172: }
173: remove(tempQuit);
174: if ((abuf = fopen(mbox, "r")) != NULL) {
175: while ((c = getc(abuf)) != EOF)
176: putc(c, obuf);
177: fclose(abuf);
178: }
179: if (ferror(obuf)) {
180: perror(tempQuit);
181: fclose(ibuf);
182: fclose(obuf);
183: fclose(fbuf);
184: return;
185: }
186: fclose(obuf);
187: close(creat(mbox, 0600));
188: if ((obuf = fopen(mbox, "r+")) == NULL) {
189: perror(mbox);
190: fclose(ibuf);
191: fclose(fbuf);
192: return;
193: }
194: }
195: if (value("append") != NOSTR) {
196: if ((obuf = fopen(mbox, "a")) == NULL) {
197: perror(mbox);
198: fclose(fbuf);
199: return;
200: }
201: fchmod(fileno(obuf), 0600);
202: }
203: for (mp = &message[0]; mp < &message[msgCount]; mp++)
204: if (mp->m_flag & MBOX)
205: if (send(mp, obuf, 0) < 0) {
206: perror(mbox);
207: fclose(ibuf);
208: fclose(obuf);
209: fclose(fbuf);
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: }
231: trunc(obuf);
232: if (ferror(obuf)) {
233: perror(mbox);
234: fclose(obuf);
235: fclose(fbuf);
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);
251: fclose(fbuf);
252: return;
253: }
254:
255: /*
256: * Finally, remove his /usr/mail file.
257: * If new mail has arrived, copy it back.
258: */
259:
260: cream:
261: if (rbuf != NULL) {
262: abuf = fopen(mailname, "r+");
263: if (abuf == NULL)
264: goto newmail;
265: while ((c = getc(rbuf)) != EOF)
266: putc(c, abuf);
267: fclose(rbuf);
268: trunc(abuf);
269: fclose(abuf);
270: alter(mailname);
271: fclose(fbuf);
272: return;
273: }
274: demail();
275: fclose(fbuf);
276: return;
277:
278: newmail:
279: printf("Thou hast new mail.\n");
280: if (fbuf != NULL)
281: fclose(fbuf);
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: */
290: writeback(res)
291: register FILE *res;
292: {
293: register struct message *mp;
294: register int p, c;
295: FILE *obuf;
296:
297: p = 0;
298: if ((obuf = fopen(mailname, "r+")) == NULL) {
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++;
310: if (send(mp, obuf, 0) < 0) {
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);
322: trunc(obuf);
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.