added global Tflag which is set to the file name given after -T:
[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
f0d15113 12static char *SccsId = "@(#)quit.c 2.2 %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{
252cba79 22 int mcount, p, modify, autohold, anystat, holdbit;
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;
865dca9a 92 for (mp = &message[0]; mp < &message[msgCount]; mp++) {
63e83a9b
KS
93 if (mp->m_flag & MNEW) {
94 mp->m_flag &= ~MNEW;
95 mp->m_flag |= MSTATUS;
96 }
97 if (mp->m_flag & MSTATUS)
98 anystat++;
865dca9a 99 if ((mp->m_flag & MTOUCH) == 0)
252cba79
KS
100 mp->m_flag |= MPRESERVE;
101 if ((mp->m_flag & (MBOX|MSAVED|MDELETED|MPRESERVE)) == 0)
102 mp->m_flag |= holdbit;
865dca9a
KS
103 }
104 modify = 0;
f0d15113
KS
105 if (Tflag != NOSTR) {
106 if ((readstat = fopen(Tflag, "w")) == NULL)
107 Tflag = NOSTR;
108 }
865dca9a 109 for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
252cba79 110 if (mp->m_flag & MBOX)
865dca9a 111 c++;
252cba79 112 if (mp->m_flag & MPRESERVE)
865dca9a
KS
113 p++;
114 if (mp->m_flag & MODIFY)
115 modify++;
f0d15113
KS
116 if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
117 id = hfield("article-id", mp);
118 if (id != NOSTR)
119 fprintf(readstat, "%s\n", id);
120 }
865dca9a 121 }
f0d15113
KS
122 if (Tflag != NOSTR)
123 fclose(readstat);
63e83a9b 124 if (p == msgCount && !modify && !anystat) {
865dca9a
KS
125 if (p == 1)
126 printf("Held 1 message in %s\n", mailname);
127 else
128 printf("Held %2d messages in %s\n", p, mailname);
129 unlock();
130 return;
131 }
132 if (c == 0) {
133 if (p != 0) {
134 writeback(rbuf);
135 unlock();
136 return;
137 }
138 goto cream;
139 }
140
141 /*
142 * Create another temporary file and copy user's mbox file
143 * darin. If there is no mbox, copy nothing.
144 * If he has specified "append" don't copy his mailbox,
145 * just copy saveable entries at the end.
146 */
147
148 mcount = c;
149 if (value("append") == NOSTR) {
150 if ((obuf = fopen(tempQuit, "w")) == NULL) {
151 perror(tempQuit);
152 unlock();
153 return;
154 }
155 if ((ibuf = fopen(tempQuit, "r")) == NULL) {
156 perror(tempQuit);
157 remove(tempQuit);
158 fclose(obuf);
159 unlock();
160 return;
161 }
162 remove(tempQuit);
163 if ((fbuf = fopen(mbox, "r")) != NULL) {
164 while ((c = getc(fbuf)) != EOF)
165 putc(c, obuf);
166 fclose(fbuf);
167 }
168 if (ferror(obuf)) {
169 perror(tempQuit);
170 fclose(ibuf);
171 fclose(obuf);
172 unlock();
173 return;
174 }
175 fclose(obuf);
176 close(creat(mbox, 0600));
177 if ((obuf = fopen(mbox, "w")) == NULL) {
178 perror(mbox);
179 fclose(ibuf);
180 unlock();
181 return;
182 }
183 }
184 if (value("append") != NOSTR)
185 if ((obuf = fopen(mbox, "a")) == NULL) {
186 perror(mbox);
187 unlock();
188 return;
189 }
190 for (mp = &message[0]; mp < &message[msgCount]; mp++)
252cba79 191 if (mp->m_flag & MBOX)
865dca9a
KS
192 if (send(mp, obuf) < 0) {
193 perror(mbox);
194 fclose(ibuf);
195 fclose(obuf);
196 unlock();
197 return;
198 }
199
200 /*
201 * Copy the user's old mbox contents back
202 * to the end of the stuff we just saved.
203 * If we are appending, this is unnecessary.
204 */
205
206 if (value("append") == NOSTR) {
207 rewind(ibuf);
208 c = getc(ibuf);
209 while (c != EOF) {
210 putc(c, obuf);
211 if (ferror(obuf))
212 break;
213 c = getc(ibuf);
214 }
215 fclose(ibuf);
216 fflush(obuf);
217 }
218 if (ferror(obuf)) {
219 perror(mbox);
220 fclose(obuf);
221 unlock();
222 return;
223 }
224 fclose(obuf);
225 if (mcount == 1)
226 printf("Saved 1 message in mbox\n");
227 else
228 printf("Saved %d messages in mbox\n", mcount);
229
230 /*
231 * Now we are ready to copy back preserved files to
232 * the system mailbox, if any were requested.
233 */
234
235 if (p != 0) {
236 writeback(rbuf);
237 unlock();
238 return;
239 }
240
241 /*
242 * Finally, remove his /usr/mail file.
243 * If new mail has arrived, copy it back.
244 */
245
246cream:
247 if (rbuf != NULL) {
248 fbuf = fopen(mailname, "w");
249 if (fbuf == NULL)
250 goto newmail;
251 while ((c = getc(rbuf)) != EOF)
252 putc(c, fbuf);
253 fclose(rbuf);
254 fclose(fbuf);
255 alter(mailname);
256 unlock();
257 return;
258 }
259 demail();
260 unlock();
261 return;
262
263newmail:
264 printf("Thou hast new mail.\n");
265 unlock();
266}
267
268/*
269 * Preserve all the appropriate messages back in the system
270 * mailbox, and print a nice message indicated how many were
271 * saved. On any error, just return -1. Else return 0.
272 * Incorporate the any new mail that we found.
273 */
274
275writeback(res)
276 register FILE *res;
277{
278 register struct message *mp;
279 register int p, c;
280 FILE *obuf;
281
282 p = 0;
283 if ((obuf = fopen(mailname, "w")) == NULL) {
284 perror(mailname);
285 return(-1);
286 }
287#ifndef APPEND
288 if (res != NULL)
289 while ((c = getc(res)) != EOF)
290 putc(c, obuf);
291#endif
292 for (mp = &message[0]; mp < &message[msgCount]; mp++)
293 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
294 p++;
295 if (send(mp, obuf) < 0) {
296 perror(mailname);
297 fclose(obuf);
298 return(-1);
299 }
300 }
301#ifdef APPEND
302 if (res != NULL)
303 while ((c = getc(res)) != EOF)
304 putc(c, obuf);
305#endif
306 fflush(obuf);
307 if (ferror(obuf)) {
308 perror(mailname);
309 fclose(obuf);
310 return(-1);
311 }
312 if (res != NULL)
313 fclose(res);
314 fclose(obuf);
315 alter(mailname);
316 if (p == 1)
317 printf("Held 1 message in %s\n", mailname);
318 else
319 printf("Held %d messages in %s\n", p, mailname);
320 return(0);
321}