|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
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.
11: */
12:
13: #ifdef notdef
14: static char sccsid[] = "@(#)quit.c 5.4 (Berkeley) 2/18/88";
15: #endif /* notdef */
16:
17: #include "rcv.h"
18: #include <sys/stat.h>
19: #include <sys/file.h>
20:
21: /*
22: * Rcv -- receive mail rationally.
23: *
24: * Termination processing.
25: */
26:
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:
33: quit()
34: {
35: int mcount, p, modify, autohold, anystat, holdbit, nohold;
36: FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
37: register struct message *mp;
38: register int c;
39: extern char tempQuit[], tempResid[];
40: struct stat minfo;
41: char *id;
42:
43: /*
44: * If we are read only, we can't do anything,
45: * so just return quickly.
46: */
47:
48: if (readonly)
49: return;
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:
63: fbuf = fopen(mailname, "r");
64: if (fbuf == NULL)
65: goto newmail;
66: flock(fileno(fbuf), LOCK_EX);
67: #ifndef CANLOCK
68: if (selfsent) {
69: printf("You have new mail.\n");
70: fclose(fbuf);
71: return;
72: }
73: #endif
74: rbuf = NULL;
75: if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
76: printf("New mail has arrived.\n");
77: rbuf = fopen(tempResid, "w");
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
93: fclose(rbuf);
94: if ((rbuf = fopen(tempResid, "r")) == NULL)
95: goto newmail;
96: remove(tempResid);
97: }
98:
99: /*
100: * Adjust the message flags in each message.
101: */
102:
103: anystat = 0;
104: autohold = value("hold") != NOSTR;
105: holdbit = autohold ? MPRESERVE : MBOX;
106: nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
107: if (value("keepsave") != NOSTR)
108: nohold &= ~MSAVED;
109: for (mp = &message[0]; mp < &message[msgCount]; mp++) {
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++;
116: if ((mp->m_flag & MTOUCH) == 0)
117: mp->m_flag |= MPRESERVE;
118: if ((mp->m_flag & nohold) == 0)
119: mp->m_flag |= holdbit;
120: }
121: modify = 0;
122: if (Tflag != NOSTR) {
123: if ((readstat = fopen(Tflag, "w")) == NULL)
124: Tflag = NOSTR;
125: }
126: for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
127: if (mp->m_flag & MBOX)
128: c++;
129: if (mp->m_flag & MPRESERVE)
130: p++;
131: if (mp->m_flag & MODIFY)
132: modify++;
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: }
138: }
139: if (Tflag != NOSTR)
140: fclose(readstat);
141: if (p == msgCount && !modify && !anystat) {
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);
146: fclose(fbuf);
147: return;
148: }
149: if (c == 0) {
150: if (p != 0) {
151: writeback(rbuf);
152: fclose(fbuf);
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);
169: fclose(fbuf);
170: return;
171: }
172: if ((ibuf = fopen(tempQuit, "r")) == NULL) {
173: perror(tempQuit);
174: remove(tempQuit);
175: fclose(obuf);
176: fclose(fbuf);
177: return;
178: }
179: remove(tempQuit);
180: if ((abuf = fopen(mbox, "r")) != NULL) {
181: while ((c = getc(abuf)) != EOF)
182: putc(c, obuf);
183: fclose(abuf);
184: }
185: if (ferror(obuf)) {
186: perror(tempQuit);
187: fclose(ibuf);
188: fclose(obuf);
189: fclose(fbuf);
190: return;
191: }
192: fclose(obuf);
193: close(creat(mbox, 0600));
194: if ((obuf = fopen(mbox, "r+")) == NULL) {
195: perror(mbox);
196: fclose(ibuf);
197: fclose(fbuf);
198: return;
199: }
200: }
201: if (value("append") != NOSTR) {
202: if ((obuf = fopen(mbox, "a")) == NULL) {
203: perror(mbox);
204: fclose(fbuf);
205: return;
206: }
207: fchmod(fileno(obuf), 0600);
208: }
209: for (mp = &message[0]; mp < &message[msgCount]; mp++)
210: if (mp->m_flag & MBOX)
211: if (send(mp, obuf, 0) < 0) {
212: perror(mbox);
213: fclose(ibuf);
214: fclose(obuf);
215: fclose(fbuf);
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: }
237: trunc(obuf);
238: if (ferror(obuf)) {
239: perror(mbox);
240: fclose(obuf);
241: fclose(fbuf);
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);
257: fclose(fbuf);
258: return;
259: }
260:
261: /*
262: * Finally, remove his /usr/mail file.
263: * If new mail has arrived, copy it back.
264: */
265:
266: cream:
267: if (rbuf != NULL) {
268: abuf = fopen(mailname, "r+");
269: if (abuf == NULL)
270: goto newmail;
271: while ((c = getc(rbuf)) != EOF)
272: putc(c, abuf);
273: fclose(rbuf);
274: trunc(abuf);
275: fclose(abuf);
276: alter(mailname);
277: fclose(fbuf);
278: return;
279: }
280: demail();
281: fclose(fbuf);
282: return;
283:
284: newmail:
285: printf("Thou hast new mail.\n");
286: if (fbuf != NULL)
287: fclose(fbuf);
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: */
296: writeback(res)
297: register FILE *res;
298: {
299: register struct message *mp;
300: register int p, c;
301: FILE *obuf;
302:
303: p = 0;
304: if ((obuf = fopen(mailname, "r+")) == NULL) {
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++;
316: if (send(mp, obuf, 0) < 0) {
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);
328: trunc(obuf);
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.