standardize sccs keyword lines
[unix-history] / usr / src / usr.bin / mail / quit.c
CommitLineData
2ae9f53f
SL
1#ifndef lint
2static char sccsid[] = "@(#)quit.c 2.7 (Berkeley) %G%";
3#endif
865dca9a
KS
4
5#include "rcv.h"
6#include <sys/stat.h>
7
8/*
9 * Rcv -- receive mail rationally.
10 *
11 * Termination processing.
12 */
13
865dca9a
KS
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));
b1064dda 180 if ((obuf = fopen(mbox, "r+")) == NULL) {
865dca9a
KS
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)
c2146fa9 195 if (send(mp, obuf, 0) < 0) {
865dca9a
KS
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 }
ed3b895e 221 trunc(obuf);
865dca9a
KS
222 if (ferror(obuf)) {
223 perror(mbox);
224 fclose(obuf);
225 unlock();
226 return;
227 }
228 fclose(obuf);
229 if (mcount == 1)
230 printf("Saved 1 message in mbox\n");
231 else
232 printf("Saved %d messages in mbox\n", mcount);
233
234 /*
235 * Now we are ready to copy back preserved files to
236 * the system mailbox, if any were requested.
237 */
238
239 if (p != 0) {
240 writeback(rbuf);
241 unlock();
242 return;
243 }
244
245 /*
246 * Finally, remove his /usr/mail file.
247 * If new mail has arrived, copy it back.
248 */
249
250cream:
251 if (rbuf != NULL) {
b1064dda 252 fbuf = fopen(mailname, "r+");
865dca9a
KS
253 if (fbuf == NULL)
254 goto newmail;
255 while ((c = getc(rbuf)) != EOF)
256 putc(c, fbuf);
257 fclose(rbuf);
ed3b895e 258 trunc(fbuf);
865dca9a
KS
259 fclose(fbuf);
260 alter(mailname);
261 unlock();
262 return;
263 }
264 demail();
265 unlock();
266 return;
267
268newmail:
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 */
865dca9a
KS
279writeback(res)
280 register FILE *res;
281{
282 register struct message *mp;
283 register int p, c;
284 FILE *obuf;
285
286 p = 0;
b1064dda 287 if ((obuf = fopen(mailname, "r+")) == NULL) {
865dca9a
KS
288 perror(mailname);
289 return(-1);
290 }
291#ifndef APPEND
292 if (res != NULL)
293 while ((c = getc(res)) != EOF)
294 putc(c, obuf);
295#endif
296 for (mp = &message[0]; mp < &message[msgCount]; mp++)
297 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
298 p++;
c2146fa9 299 if (send(mp, obuf, 0) < 0) {
865dca9a
KS
300 perror(mailname);
301 fclose(obuf);
302 return(-1);
303 }
304 }
305#ifdef APPEND
306 if (res != NULL)
307 while ((c = getc(res)) != EOF)
308 putc(c, obuf);
309#endif
310 fflush(obuf);
ed3b895e 311 trunc(obuf);
865dca9a
KS
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}