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
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.
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]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
25 * Copyright (c) 2016 by Delphix. All rights reserved.
29 * University Copyright- Copyright (c) 1982, 1986, 1988
30 * The Regents of the University of California
33 * University Acknowledgment- Portions of this document are derived from
34 * software developed by the University of California, Berkeley, and its
38 #pragma ident "%Z%%M% %I% %E% SMI"
44 * mailx -- a modified version of a University of California at Berkeley
47 * Rcv -- receive mail rationally.
49 * Termination processing.
52 static void writeback(int noremove
);
54 #define PRIV(x) setgid(myegid), (x), setgid(myrgid);
57 * Save all of the undetermined messages at the top of "mbox"
58 * Save all untouched messages back in the system mailbox.
59 * Remove the system mailbox, if none saved there.
64 int noremove
/* don't remove system mailbox, trunc it instead */
67 int mcount
, p
, modify
, autohold
, anystat
, holdbit
, nohold
, fd
;
68 FILE *ibuf
, *obuf
, *fbuf
, *readstat
;
69 register struct message
*mp
;
73 char *mbox
= Getf("MBOX");
76 * If we are read only, we can't do anything,
77 * so just return quickly.
84 * See if there any messages to save in mbox. If no, we
85 * can save copying mbox to /tmp and back.
87 * Check also to see if any files need to be preserved.
88 * Delete all untouched messages to keep them out of mbox.
89 * If all the messages are to be preserved, just exit with
92 * If the luser has sent mail to himself, refuse to do
93 * anything with the mailbox, unless mail locking works.
98 printf(gettext("You have new mail.\n"));
104 * Adjust the message flags in each message.
108 autohold
= value("hold") != NOSTR
;
109 appending
= value("append") != NOSTR
;
110 holdbit
= autohold
? MPRESERVE
: MBOX
;
111 nohold
= MBOXED
|MBOX
|MSAVED
|MDELETED
|MPRESERVE
;
112 if (value("keepsave") != NOSTR
)
114 for (mp
= &message
[0]; mp
< &message
[msgCount
]; mp
++) {
115 if (mp
->m_flag
& MNEW
) {
118 mp
->m_flag
|= MSTATUS
;
120 if (mp
->m_flag
& MSTATUS
)
122 if ((mp
->m_flag
& MTOUCH
) == 0)
123 mp
->m_flag
|= MPRESERVE
;
124 if ((mp
->m_flag
& nohold
) == 0)
125 mp
->m_flag
|= holdbit
;
128 if (Tflag
!= NOSTR
) {
129 if ((readstat
= fopen(Tflag
, "w")) == NULL
)
132 for (c
= 0, p
= 0, mp
= &message
[0]; mp
< &message
[msgCount
]; mp
++) {
133 if (mp
->m_flag
& MBOX
)
135 if (mp
->m_flag
& MPRESERVE
)
137 if (mp
->m_flag
& MODIFY
)
139 if (Tflag
!= NOSTR
&& (mp
->m_flag
& (MREAD
|MDELETED
)) != 0) {
140 id
= hfield("message-id", mp
, addone
);
142 fprintf(readstat
, "%s\n", id
);
144 id
= hfield("article-id", mp
, addone
);
146 fprintf(readstat
, "%s\n", id
);
152 if (p
== msgCount
&& !modify
&& !anystat
) {
154 printf(gettext("Held 1 message in %s\n"), mailname
);
156 printf(gettext("Held %d messages in %s\n"), p
,
166 * Create another temporary file and copy user's mbox file
167 * therein. If there is no mbox, copy nothing.
168 * If they have specified "append" don't copy the mailbox,
169 * just copy saveable entries at the end.
174 if ((fd
= open(tempQuit
, O_RDWR
|O_CREAT
|O_EXCL
, 0600)) < 0 ||
175 (obuf
= fdopen(fd
, "w")) == NULL
) {
179 if ((ibuf
= fopen(tempQuit
, "r")) == NULL
) {
181 removefile(tempQuit
);
185 removefile(tempQuit
);
186 if ((fbuf
= fopen(mbox
, "r")) != NULL
) {
187 while ((c
= getc(fbuf
)) != EOF
)
199 if ((fd
= open(mbox
, O_RDWR
|O_CREAT
|O_TRUNC
, MBOXPERM
)) < 0 ||
200 (obuf
= fdopen(fd
, "r+")) == NULL
) {
207 } else { /* we are appending */
208 if ((fd
= open(mbox
, O_RDWR
|O_CREAT
, MBOXPERM
)) < 0 ||
209 (obuf
= fdopen(fd
, "a")) == NULL
) {
214 for (mp
= &message
[0]; mp
< &message
[msgCount
]; mp
++)
215 if (mp
->m_flag
& MBOX
) {
216 if (msend(mp
, obuf
, (int)value("alwaysignore") ?
217 M_IGNORE
|M_SAVING
: M_SAVING
, fputs
) < 0) {
225 mp
->m_flag
|= MBOXED
;
231 * Copy the user's old mbox contents back
232 * to the end of the stuff we just saved.
233 * If we are appending, this is unnecessary.
256 printf(gettext("Saved 1 message in %s\n"), mbox
);
258 printf(gettext("Saved %d messages in %s\n"), mcount
, mbox
);
261 * Now we are ready to copy back preserved files to
262 * the system mailbox, if any were requested.
268 * Preserve all the appropriate messages back in the system
269 * mailbox, and print a nice message indicating how many were
270 * saved. Incorporate any new mail that we found.
273 writeback(int noremove
)
275 register struct message
*mp
;
278 FILE *obuf
= 0, *fbuf
= 0, *rbuf
= 0;
279 void (*fhup
)(int), (*fint
)(int), (*fquit
)(int);
282 fhup
= sigset(SIGHUP
, SIG_IGN
);
283 fint
= sigset(SIGINT
, SIG_IGN
);
284 fquit
= sigset(SIGQUIT
, SIG_IGN
);
288 if ((fbuf
= fopen(mailname
, "r+")) == NULL
) {
294 fstat(fileno(fbuf
), &st
);
295 if (st
.st_size
> mailsize
) {
296 printf(gettext("New mail has arrived.\n"));
297 snprintf(tempResid
, PATHSIZE
, "%s/:saved/%s", maildir
, myname
);
298 PRIV(rbuf
= fopen(tempResid
, "w+"));
300 snprintf(tempResid
, PATHSIZE
, "/tmp/Rq%-ld", mypid
);
301 fd
= open(tempResid
,O_RDWR
|O_CREAT
|O_EXCL
, 0600);
302 PRIV(rbuf
= fdopen(fd
, "w+"));
304 snprintf(tempResid
, PATHSIZE
,
305 "%s/:saved/%s", maildir
,
313 fseek(fbuf
, mailsize
, 0);
314 while ((c
= getc(fbuf
)) != EOF
)
317 p
= st
.st_size
- mailsize
;
334 if ((obuf
= fopen(mailname
, "r+")) == NULL
) {
340 while ((c
= getc(rbuf
)) != EOF
)
344 for (mp
= &message
[0]; mp
< &message
[msgCount
]; mp
++)
345 if ((mp
->m_flag
&MPRESERVE
)||(mp
->m_flag
&MTOUCH
)==0) {
347 if (msend(mp
, obuf
, 0, fputs
) < 0) {
356 while ((c
= getc(rbuf
)) != EOF
)
368 printf(gettext("Held 1 message in %s\n"), mailname
);
370 printf(gettext("Held %d messages in %s\n"), p
,
374 if (!noremove
&& (fsize(obuf
) == 0) && (value("keep") == NOSTR
)) {
375 if (stat(mailname
, &st
) >= 0)
376 PRIV(delempty(st
.st_mode
, mailname
));
382 PRIV(removefile(tempResid
));
388 sigset(SIGHUP
, fhup
);
389 sigset(SIGINT
, fint
);
390 sigset(SIGQUIT
, fquit
);
396 PRIV(maillock(lockname
,10));