changed pclose() to sighold/sigrelse instead of old signal jazz.
[unix-history] / usr / src / usr.bin / mail / quit.c
CommitLineData
865dca9a
KS
1#
2
3#include "rcv.h"
4#include <sys/stat.h>
5
6/*
7 * Rcv -- receive mail rationally.
8 *
9 * Termination processing.
10 */
11
c2483c81 12static char *SccsId = "@(#)quit.c 2.3 %G%";
865dca9a
KS
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
20quit()
21{
c2483c81 22 int mcount, p, modify, autohold, anystat, holdbit, nohold;
f0d15113 23 FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat;
865dca9a
KS
24 register struct message *mp;
25 register int c;
26 extern char tempQuit[], tempResid[];
27 struct stat minfo;
f0d15113 28 char *id;
865dca9a 29
3ecebc0f
KS
30 /*
31 * If we are read only, we can't do anything,
32 * so just return quickly.
33 */
34
35 if (readonly)
36 return;
865dca9a
KS
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 }
63e83a9b
KS
84
85 /*
86 * Adjust the message flags in each message.
87 */
88
89 anystat = 0;
252cba79
KS
90 autohold = value("hold") != NOSTR;
91 holdbit = autohold ? MPRESERVE : MBOX;
c2483c81
KS
92 nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
93 if (value("keepsave") != NOSTR)
94 nohold &= ~MSAVED;
865dca9a 95 for (mp = &message[0]; mp < &message[msgCount]; mp++) {
63e83a9b
KS
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++;
865dca9a 102 if ((mp->m_flag & MTOUCH) == 0)
252cba79 103 mp->m_flag |= MPRESERVE;
c2483c81 104 if ((mp->m_flag & nohold) == 0)
252cba79 105 mp->m_flag |= holdbit;
865dca9a
KS
106 }
107 modify = 0;
f0d15113
KS
108 if (Tflag != NOSTR) {
109 if ((readstat = fopen(Tflag, "w")) == NULL)
110 Tflag = NOSTR;
111 }
865dca9a 112 for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
252cba79 113 if (mp->m_flag & MBOX)
865dca9a 114 c++;
252cba79 115 if (mp->m_flag & MPRESERVE)
865dca9a
KS
116 p++;
117 if (mp->m_flag & MODIFY)
118 modify++;
f0d15113
KS
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 }
865dca9a 124 }
f0d15113
KS
125 if (Tflag != NOSTR)
126 fclose(readstat);
63e83a9b 127 if (p == msgCount && !modify && !anystat) {
865dca9a
KS
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++)
252cba79 194 if (mp->m_flag & MBOX)
865dca9a
KS
195 if (send(mp, obuf) < 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
249cream:
250 if (rbuf != NULL) {
251 fbuf = fopen(mailname, "w");
252 if (fbuf == NULL)
253 goto newmail;
254 while ((c = getc(rbuf)) != EOF)
255 putc(c, fbuf);
256 fclose(rbuf);
257 fclose(fbuf);
258 alter(mailname);
259 unlock();
260 return;
261 }
262 demail();
263 unlock();
264 return;
265
266newmail:
267 printf("Thou hast new mail.\n");
268 unlock();
269}
270
271/*
272 * Preserve all the appropriate messages back in the system
273 * mailbox, and print a nice message indicated how many were
274 * saved. On any error, just return -1. Else return 0.
275 * Incorporate the any new mail that we found.
276 */
277
278writeback(res)
279 register FILE *res;
280{
281 register struct message *mp;
282 register int p, c;
283 FILE *obuf;
284
285 p = 0;
286 if ((obuf = fopen(mailname, "w")) == NULL) {
287 perror(mailname);
288 return(-1);
289 }
290#ifndef APPEND
291 if (res != NULL)
292 while ((c = getc(res)) != EOF)
293 putc(c, obuf);
294#endif
295 for (mp = &message[0]; mp < &message[msgCount]; mp++)
296 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
297 p++;
298 if (send(mp, obuf) < 0) {
299 perror(mailname);
300 fclose(obuf);
301 return(-1);
302 }
303 }
304#ifdef APPEND
305 if (res != NULL)
306 while ((c = getc(res)) != EOF)
307 putc(c, obuf);
308#endif
309 fflush(obuf);
310 if (ferror(obuf)) {
311 perror(mailname);
312 fclose(obuf);
313 return(-1);
314 }
315 if (res != NULL)
316 fclose(res);
317 fclose(obuf);
318 alter(mailname);
319 if (p == 1)
320 printf("Held 1 message in %s\n", mailname);
321 else
322 printf("Held %d messages in %s\n", p, mailname);
323 return(0);
324}