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