In-line expanded calls on readline/putline in setptr() for speed
[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
63e83a9b 12static char *SccsId = "@(#)quit.c 1.4 %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{
63e83a9b 22 int mcount, p, modify, autohold, anystat;
865dca9a
KS
23 FILE *ibuf, *obuf, *fbuf, *rbuf;
24 register struct message *mp;
25 register int c;
26 extern char tempQuit[], tempResid[];
27 struct stat minfo;
28
3ecebc0f
KS
29 /*
30 * If we are read only, we can't do anything,
31 * so just return quickly.
32 */
33
34 if (readonly)
35 return;
865dca9a
KS
36 /*
37 * See if there any messages to save in mbox. If no, we
38 * can save copying mbox to /tmp and back.
39 *
40 * Check also to see if any files need to be preserved.
41 * Delete all untouched messages to keep them out of mbox.
42 * If all the messages are to be preserved, just exit with
43 * a message.
44 *
45 * If the luser has sent mail to himself, refuse to do
46 * anything with the mailbox, unless mail locking works.
47 */
48
49 lock(mailname);
50#ifndef CANLOCK
51 if (selfsent) {
52 printf("You have new mail.\n");
53 unlock();
54 return;
55 }
56#endif
57 rbuf = NULL;
58 if (stat(mailname, &minfo) >= 0 && minfo.st_size > mailsize) {
59 printf("New mail has arrived.\n");
60 rbuf = fopen(tempResid, "w");
61 fbuf = fopen(mailname, "r");
62 if (rbuf == NULL || fbuf == NULL)
63 goto newmail;
64#ifdef APPEND
65 fseek(fbuf, mailsize, 0);
66 while ((c = getc(fbuf)) != EOF)
67 putc(c, rbuf);
68#else
69 p = minfo.st_size - mailsize;
70 while (p-- > 0) {
71 c = getc(fbuf);
72 if (c == EOF)
73 goto newmail;
74 putc(c, rbuf);
75 }
76#endif
77 fclose(fbuf);
78 fclose(rbuf);
79 if ((rbuf = fopen(tempResid, "r")) == NULL)
80 goto newmail;
81 remove(tempResid);
82 }
63e83a9b
KS
83
84 /*
85 * Adjust the message flags in each message.
86 */
87
88 anystat = 0;
865dca9a 89 for (mp = &message[0]; mp < &message[msgCount]; mp++) {
63e83a9b
KS
90 if (mp->m_flag & MNEW) {
91 mp->m_flag &= ~MNEW;
92 mp->m_flag |= MSTATUS;
93 }
94 if (mp->m_flag & MSTATUS)
95 anystat++;
865dca9a
KS
96 if (mp->m_flag & MDELETED)
97 mp->m_flag = MDELETED|MTOUCH;
98 if ((mp->m_flag & MTOUCH) == 0)
99 mp->m_flag |= MDELETED;
100 }
a333d502 101 autohold = value("hold") != NOSTR;
865dca9a
KS
102 modify = 0;
103 for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
a333d502
KS
104 if ((mp->m_flag & (MSAVED|MDELETED)) == 0 && autohold)
105 mp->m_flag |= MPRESERVE;
865dca9a
KS
106 if ((mp->m_flag & (MSAVED|MDELETED|MPRESERVE)) == 0)
107 c++;
108 if ((mp->m_flag & MPRESERVE) || (mp->m_flag & MTOUCH) == 0)
109 p++;
110 if (mp->m_flag & MODIFY)
111 modify++;
112 }
63e83a9b 113 if (p == msgCount && !modify && !anystat) {
865dca9a
KS
114 if (p == 1)
115 printf("Held 1 message in %s\n", mailname);
116 else
117 printf("Held %2d messages in %s\n", p, mailname);
118 unlock();
119 return;
120 }
121 if (c == 0) {
122 if (p != 0) {
123 writeback(rbuf);
124 unlock();
125 return;
126 }
127 goto cream;
128 }
129
130 /*
131 * Create another temporary file and copy user's mbox file
132 * darin. If there is no mbox, copy nothing.
133 * If he has specified "append" don't copy his mailbox,
134 * just copy saveable entries at the end.
135 */
136
137 mcount = c;
138 if (value("append") == NOSTR) {
139 if ((obuf = fopen(tempQuit, "w")) == NULL) {
140 perror(tempQuit);
141 unlock();
142 return;
143 }
144 if ((ibuf = fopen(tempQuit, "r")) == NULL) {
145 perror(tempQuit);
146 remove(tempQuit);
147 fclose(obuf);
148 unlock();
149 return;
150 }
151 remove(tempQuit);
152 if ((fbuf = fopen(mbox, "r")) != NULL) {
153 while ((c = getc(fbuf)) != EOF)
154 putc(c, obuf);
155 fclose(fbuf);
156 }
157 if (ferror(obuf)) {
158 perror(tempQuit);
159 fclose(ibuf);
160 fclose(obuf);
161 unlock();
162 return;
163 }
164 fclose(obuf);
165 close(creat(mbox, 0600));
166 if ((obuf = fopen(mbox, "w")) == NULL) {
167 perror(mbox);
168 fclose(ibuf);
169 unlock();
170 return;
171 }
172 }
173 if (value("append") != NOSTR)
174 if ((obuf = fopen(mbox, "a")) == NULL) {
175 perror(mbox);
176 unlock();
177 return;
178 }
179 for (mp = &message[0]; mp < &message[msgCount]; mp++)
180 if ((mp->m_flag & (MDELETED|MSAVED|MPRESERVE)) == 0)
181 if (send(mp, obuf) < 0) {
182 perror(mbox);
183 fclose(ibuf);
184 fclose(obuf);
185 unlock();
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 (value("append") == NOSTR) {
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 unlock();
211 return;
212 }
213 fclose(obuf);
214 if (mcount == 1)
215 printf("Saved 1 message in mbox\n");
216 else
217 printf("Saved %d messages in mbox\n", mcount);
218
219 /*
220 * Now we are ready to copy back preserved files to
221 * the system mailbox, if any were requested.
222 */
223
224 if (p != 0) {
225 writeback(rbuf);
226 unlock();
227 return;
228 }
229
230 /*
231 * Finally, remove his /usr/mail file.
232 * If new mail has arrived, copy it back.
233 */
234
235cream:
236 if (rbuf != NULL) {
237 fbuf = fopen(mailname, "w");
238 if (fbuf == NULL)
239 goto newmail;
240 while ((c = getc(rbuf)) != EOF)
241 putc(c, fbuf);
242 fclose(rbuf);
243 fclose(fbuf);
244 alter(mailname);
245 unlock();
246 return;
247 }
248 demail();
249 unlock();
250 return;
251
252newmail:
253 printf("Thou hast new mail.\n");
254 unlock();
255}
256
257/*
258 * Preserve all the appropriate messages back in the system
259 * mailbox, and print a nice message indicated how many were
260 * saved. On any error, just return -1. Else return 0.
261 * Incorporate the any new mail that we found.
262 */
263
264writeback(res)
265 register FILE *res;
266{
267 register struct message *mp;
268 register int p, c;
269 FILE *obuf;
270
271 p = 0;
272 if ((obuf = fopen(mailname, "w")) == NULL) {
273 perror(mailname);
274 return(-1);
275 }
276#ifndef APPEND
277 if (res != NULL)
278 while ((c = getc(res)) != EOF)
279 putc(c, obuf);
280#endif
281 for (mp = &message[0]; mp < &message[msgCount]; mp++)
282 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
283 p++;
284 if (send(mp, obuf) < 0) {
285 perror(mailname);
286 fclose(obuf);
287 return(-1);
288 }
289 }
290#ifdef APPEND
291 if (res != NULL)
292 while ((c = getc(res)) != EOF)
293 putc(c, obuf);
294#endif
295 fflush(obuf);
296 if (ferror(obuf)) {
297 perror(mailname);
298 fclose(obuf);
299 return(-1);
300 }
301 if (res != NULL)
302 fclose(res);
303 fclose(obuf);
304 alter(mailname);
305 if (p == 1)
306 printf("Held 1 message in %s\n", mailname);
307 else
308 printf("Held %d messages in %s\n", p, mailname);
309 return(0);
310}