Mercurial > illumos > onarm
comparison usr/src/cmd/mailx/quit.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
1 /* | |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
5 * Common Development and Distribution License, Version 1.0 only | |
6 * (the "License"). You may not use this file except in compliance | |
7 * with the License. | |
8 * | |
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 * or http://www.opensolaris.org/os/licensing. | |
11 * See the License for the specific language governing permissions | |
12 * and limitations under the License. | |
13 * | |
14 * When distributing Covered Code, include this CDDL HEADER in each | |
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 * If applicable, add the following below this CDDL HEADER, with the | |
17 * fields enclosed by brackets "[]" replaced with your own identifying | |
18 * information: Portions Copyright [yyyy] [name of copyright owner] | |
19 * | |
20 * CDDL HEADER END | |
21 */ | |
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ | |
23 /* All Rights Reserved */ | |
24 | |
25 | |
26 /* | |
27 * University Copyright- Copyright (c) 1982, 1986, 1988 | |
28 * The Regents of the University of California | |
29 * All Rights Reserved | |
30 * | |
31 * University Acknowledgment- Portions of this document are derived from | |
32 * software developed by the University of California, Berkeley, and its | |
33 * contributors. | |
34 */ | |
35 | |
36 #pragma ident "@(#)quit.c 1.26 05/06/08 SMI" | |
37 | |
38 #include "rcv.h" | |
39 #include <locale.h> | |
40 | |
41 /* | |
42 * mailx -- a modified version of a University of California at Berkeley | |
43 * mail program | |
44 * | |
45 * Rcv -- receive mail rationally. | |
46 * | |
47 * Termination processing. | |
48 */ | |
49 | |
50 static void writeback(int noremove); | |
51 | |
52 #define PRIV(x) setgid(myegid), (x), setgid(myrgid); | |
53 | |
54 /* | |
55 * Save all of the undetermined messages at the top of "mbox" | |
56 * Save all untouched messages back in the system mailbox. | |
57 * Remove the system mailbox, if none saved there. | |
58 */ | |
59 | |
60 void | |
61 quit( | |
62 int noremove /* don't remove system mailbox, trunc it instead */ | |
63 ) | |
64 { | |
65 int mcount, p, modify, autohold, anystat, holdbit, nohold, fd; | |
66 FILE *ibuf, *obuf, *fbuf, *readstat; | |
67 register struct message *mp; | |
68 register int c; | |
69 char *id; | |
70 int appending; | |
71 char *mbox = Getf("MBOX"); | |
72 | |
73 /* | |
74 * If we are read only, we can't do anything, | |
75 * so just return quickly. | |
76 */ | |
77 | |
78 mcount = 0; | |
79 if (readonly) | |
80 return; | |
81 /* | |
82 * See if there any messages to save in mbox. If no, we | |
83 * can save copying mbox to /tmp and back. | |
84 * | |
85 * Check also to see if any files need to be preserved. | |
86 * Delete all untouched messages to keep them out of mbox. | |
87 * If all the messages are to be preserved, just exit with | |
88 * a message. | |
89 * | |
90 * If the luser has sent mail to himself, refuse to do | |
91 * anything with the mailbox, unless mail locking works. | |
92 */ | |
93 | |
94 #ifndef CANLOCK | |
95 if (selfsent) { | |
96 printf(gettext("You have new mail.\n")); | |
97 return; | |
98 } | |
99 #endif | |
100 | |
101 /* | |
102 * Adjust the message flags in each message. | |
103 */ | |
104 | |
105 anystat = 0; | |
106 autohold = value("hold") != NOSTR; | |
107 appending = value("append") != NOSTR; | |
108 holdbit = autohold ? MPRESERVE : MBOX; | |
109 nohold = MBOXED|MBOX|MSAVED|MDELETED|MPRESERVE; | |
110 if (value("keepsave") != NOSTR) | |
111 nohold &= ~MSAVED; | |
112 for (mp = &message[0]; mp < &message[msgCount]; mp++) { | |
113 if (mp->m_flag & MNEW) { | |
114 receipt(mp); | |
115 mp->m_flag &= ~MNEW; | |
116 mp->m_flag |= MSTATUS; | |
117 } | |
118 if (mp->m_flag & MSTATUS) | |
119 anystat++; | |
120 if ((mp->m_flag & MTOUCH) == 0) | |
121 mp->m_flag |= MPRESERVE; | |
122 if ((mp->m_flag & nohold) == 0) | |
123 mp->m_flag |= holdbit; | |
124 } | |
125 modify = 0; | |
126 if (Tflag != NOSTR) { | |
127 if ((readstat = fopen(Tflag, "w")) == NULL) | |
128 Tflag = NOSTR; | |
129 } | |
130 for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) { | |
131 if (mp->m_flag & MBOX) | |
132 c++; | |
133 if (mp->m_flag & MPRESERVE) | |
134 p++; | |
135 if (mp->m_flag & MODIFY) | |
136 modify++; | |
137 if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) { | |
138 id = hfield("message-id", mp, addone); | |
139 if (id != NOSTR) | |
140 fprintf(readstat, "%s\n", id); | |
141 else { | |
142 id = hfield("article-id", mp, addone); | |
143 if (id != NOSTR) | |
144 fprintf(readstat, "%s\n", id); | |
145 } | |
146 } | |
147 } | |
148 if (Tflag != NOSTR) | |
149 fclose(readstat); | |
150 if (p == msgCount && !modify && !anystat) { | |
151 if (p == 1) | |
152 printf(gettext("Held 1 message in %s\n"), mailname); | |
153 else | |
154 printf(gettext("Held %d messages in %s\n"), p, | |
155 mailname); | |
156 return; | |
157 } | |
158 if (c == 0) { | |
159 writeback(noremove); | |
160 return; | |
161 } | |
162 | |
163 /* | |
164 * Create another temporary file and copy user's mbox file | |
165 * therein. If there is no mbox, copy nothing. | |
166 * If s/he has specified "append" don't copy the mailbox, | |
167 * just copy saveable entries at the end. | |
168 */ | |
169 | |
170 mcount = c; | |
171 if (!appending) { | |
172 if ((fd = open(tempQuit, O_RDWR|O_CREAT|O_EXCL, 0600)) < 0 || | |
173 (obuf = fdopen(fd, "w")) == NULL) { | |
174 perror(tempQuit); | |
175 return; | |
176 } | |
177 if ((ibuf = fopen(tempQuit, "r")) == NULL) { | |
178 perror(tempQuit); | |
179 removefile(tempQuit); | |
180 fclose(obuf); | |
181 return; | |
182 } | |
183 removefile(tempQuit); | |
184 if ((fbuf = fopen(mbox, "r")) != NULL) { | |
185 while ((c = getc(fbuf)) != EOF) | |
186 putc(c, obuf); | |
187 fclose(fbuf); | |
188 } | |
189 fflush(obuf); | |
190 if (fferror(obuf)) { | |
191 perror(tempQuit); | |
192 fclose(ibuf); | |
193 fclose(obuf); | |
194 return; | |
195 } | |
196 fclose(obuf); | |
197 if ((fd = open(mbox, O_RDWR|O_CREAT|O_TRUNC, MBOXPERM)) < 0 || | |
198 (obuf = fdopen(fd, "r+")) == NULL) { | |
199 perror(mbox); | |
200 fclose(ibuf); | |
201 return; | |
202 } | |
203 if (issysmbox) | |
204 touchlock(); | |
205 } else { /* we are appending */ | |
206 if ((fd = open(mbox, O_RDWR|O_CREAT, MBOXPERM)) < 0 || | |
207 (obuf = fdopen(fd, "a")) == NULL) { | |
208 perror(mbox); | |
209 return; | |
210 } | |
211 } | |
212 for (mp = &message[0]; mp < &message[msgCount]; mp++) | |
213 if (mp->m_flag & MBOX) { | |
214 if (msend(mp, obuf, (int)value("alwaysignore") ? | |
215 M_IGNORE|M_SAVING : M_SAVING, fputs) < 0) { | |
216 perror(mbox); | |
217 if (!appending) | |
218 fclose(ibuf); | |
219 fclose(obuf); | |
220 return; | |
221 } | |
222 mp->m_flag &= ~MBOX; | |
223 mp->m_flag |= MBOXED; | |
224 if (issysmbox) | |
225 touchlock(); | |
226 } | |
227 | |
228 /* | |
229 * Copy the user's old mbox contents back | |
230 * to the end of the stuff we just saved. | |
231 * If we are appending, this is unnecessary. | |
232 */ | |
233 | |
234 if (!appending) { | |
235 rewind(ibuf); | |
236 c = getc(ibuf); | |
237 while (c != EOF) { | |
238 putc(c, obuf); | |
239 if (ferror(obuf)) | |
240 break; | |
241 c = getc(ibuf); | |
242 } | |
243 fclose(ibuf); | |
244 fflush(obuf); | |
245 } | |
246 trunc(obuf); | |
247 if (fferror(obuf)) { | |
248 perror(mbox); | |
249 fclose(obuf); | |
250 return; | |
251 } | |
252 fclose(obuf); | |
253 if (mcount == 1) | |
254 printf(gettext("Saved 1 message in %s\n"), mbox); | |
255 else | |
256 printf(gettext("Saved %d messages in %s\n"), mcount, mbox); | |
257 | |
258 /* | |
259 * Now we are ready to copy back preserved files to | |
260 * the system mailbox, if any were requested. | |
261 */ | |
262 writeback(noremove); | |
263 } | |
264 | |
265 /* | |
266 * Preserve all the appropriate messages back in the system | |
267 * mailbox, and print a nice message indicating how many were | |
268 * saved. Incorporate any new mail that we found. | |
269 */ | |
270 static void | |
271 writeback(int noremove) | |
272 { | |
273 register struct message *mp; | |
274 register int p, c; | |
275 struct stat st; | |
276 FILE *obuf = 0, *fbuf = 0, *rbuf = 0; | |
277 void (*fhup)(int), (*fint)(int), (*fquit)(int); | |
278 int fd = -1; | |
279 | |
280 fhup = sigset(SIGHUP, SIG_IGN); | |
281 fint = sigset(SIGINT, SIG_IGN); | |
282 fquit = sigset(SIGQUIT, SIG_IGN); | |
283 | |
284 if (issysmbox) | |
285 lockmail(); | |
286 if ((fbuf = fopen(mailname, "r+")) == NULL) { | |
287 perror(mailname); | |
288 goto die; | |
289 } | |
290 if (!issysmbox) | |
291 lock(fbuf, "r+", 1); | |
292 fstat(fileno(fbuf), &st); | |
293 if (st.st_size > mailsize) { | |
294 printf(gettext("New mail has arrived.\n")); | |
295 snprintf(tempResid, PATHSIZE, "%s/:saved/%s", maildir, myname); | |
296 PRIV(rbuf = fopen(tempResid, "w+")); | |
297 if (rbuf == NULL) { | |
298 snprintf(tempResid, PATHSIZE, "/tmp/Rq%-ld", mypid); | |
299 fd = open(tempResid,O_RDWR|O_CREAT|O_EXCL, 0600); | |
300 PRIV(rbuf = fdopen(fd, "w+")); | |
301 if (rbuf == NULL) { | |
302 snprintf(tempResid, PATHSIZE, | |
303 "%s/:saved/%s", maildir, | |
304 myname); | |
305 perror(tempResid); | |
306 fclose(fbuf); | |
307 goto die; | |
308 } | |
309 } | |
310 #ifdef APPEND | |
311 fseek(fbuf, mailsize, 0); | |
312 while ((c = getc(fbuf)) != EOF) | |
313 putc(c, rbuf); | |
314 #else | |
315 p = st.st_size - mailsize; | |
316 while (p-- > 0) { | |
317 c = getc(fbuf); | |
318 if (c == EOF) { | |
319 perror(mailname); | |
320 fclose(fbuf); | |
321 goto die; | |
322 } | |
323 putc(c, rbuf); | |
324 } | |
325 #endif | |
326 fclose(fbuf); | |
327 fseek(rbuf, 0L, 0); | |
328 if (issysmbox) | |
329 touchlock(); | |
330 } | |
331 | |
332 if ((obuf = fopen(mailname, "r+")) == NULL) { | |
333 perror(mailname); | |
334 goto die; | |
335 } | |
336 #ifndef APPEND | |
337 if (rbuf != NULL) | |
338 while ((c = getc(rbuf)) != EOF) | |
339 putc(c, obuf); | |
340 #endif | |
341 p = 0; | |
342 for (mp = &message[0]; mp < &message[msgCount]; mp++) | |
343 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) { | |
344 p++; | |
345 if (msend(mp, obuf, 0, fputs) < 0) { | |
346 perror(mailname); | |
347 goto die; | |
348 } | |
349 if (issysmbox) | |
350 touchlock(); | |
351 } | |
352 #ifdef APPEND | |
353 if (rbuf != NULL) | |
354 while ((c = getc(rbuf)) != EOF) | |
355 putc(c, obuf); | |
356 #endif | |
357 fflush(obuf); | |
358 trunc(obuf); | |
359 if (fferror(obuf)) { | |
360 perror(mailname); | |
361 goto die; | |
362 } | |
363 alter(mailname); | |
364 if (p) { | |
365 if (p == 1) | |
366 printf(gettext("Held 1 message in %s\n"), mailname); | |
367 else | |
368 printf(gettext("Held %d messages in %s\n"), p, | |
369 mailname); | |
370 } | |
371 | |
372 if (!noremove && (fsize(obuf) == 0) && (value("keep") == NOSTR)) { | |
373 if (stat(mailname, &st) >= 0) | |
374 PRIV(delempty(st.st_mode, mailname)); | |
375 } | |
376 | |
377 die: | |
378 if (rbuf) { | |
379 fclose(rbuf); | |
380 PRIV(removefile(tempResid)); | |
381 } | |
382 if (obuf) | |
383 fclose(obuf); | |
384 if (issysmbox) | |
385 unlockmail(); | |
386 sigset(SIGHUP, fhup); | |
387 sigset(SIGINT, fint); | |
388 sigset(SIGQUIT, fquit); | |
389 } | |
390 | |
391 void | |
392 lockmail(void) | |
393 { | |
394 PRIV(maillock(lockname,10)); | |
395 } | |
396 | |
397 void | |
398 unlockmail(void) | |
399 { | |
400 PRIV(mailunlock()); | |
401 } |