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