|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Heirloom mailx - a mail user agent derived from Berkeley Mail.
|
|
Packit |
272fb1 |
*
|
|
Packit |
272fb1 |
* Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Copyright (c) 1980, 1993
|
|
Packit |
272fb1 |
* The Regents of the University of California. All rights reserved.
|
|
Packit |
272fb1 |
*
|
|
Packit |
272fb1 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
272fb1 |
* modification, are permitted provided that the following conditions
|
|
Packit |
272fb1 |
* are met:
|
|
Packit |
272fb1 |
* 1. Redistributions of source code must retain the above copyright
|
|
Packit |
272fb1 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
272fb1 |
* 2. Redistributions in binary form must reproduce the above copyright
|
|
Packit |
272fb1 |
* notice, this list of conditions and the following disclaimer in the
|
|
Packit |
272fb1 |
* documentation and/or other materials provided with the distribution.
|
|
Packit |
272fb1 |
* 3. All advertising materials mentioning features or use of this software
|
|
Packit |
272fb1 |
* must display the following acknowledgement:
|
|
Packit |
272fb1 |
* This product includes software developed by the University of
|
|
Packit |
272fb1 |
* California, Berkeley and its contributors.
|
|
Packit |
272fb1 |
* 4. Neither the name of the University nor the names of its contributors
|
|
Packit |
272fb1 |
* may be used to endorse or promote products derived from this software
|
|
Packit |
272fb1 |
* without specific prior written permission.
|
|
Packit |
272fb1 |
*
|
|
Packit |
272fb1 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
Packit |
272fb1 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
272fb1 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
272fb1 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
Packit |
272fb1 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit |
272fb1 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
Packit |
272fb1 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
Packit |
272fb1 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
Packit |
272fb1 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
Packit |
272fb1 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
Packit |
272fb1 |
* SUCH DAMAGE.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
#ifndef lint
|
|
Packit |
272fb1 |
#ifdef DOSCCS
|
|
Packit |
272fb1 |
static char sccsid[] = "@(#)quit.c 2.30 (gritter) 11/11/08";
|
|
Packit |
272fb1 |
#endif
|
|
Packit |
272fb1 |
#endif /* not lint */
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
#include "rcv.h"
|
|
Packit |
272fb1 |
#include "extern.h"
|
|
Packit |
272fb1 |
#include <stdio.h>
|
|
Packit |
272fb1 |
#include <errno.h>
|
|
Packit |
272fb1 |
#include <sys/file.h>
|
|
Packit |
272fb1 |
#include <sys/stat.h>
|
|
Packit |
272fb1 |
#include <unistd.h>
|
|
Packit |
272fb1 |
#include <fcntl.h>
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Rcv -- receive mail rationally.
|
|
Packit |
272fb1 |
*
|
|
Packit |
272fb1 |
* Termination processing.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
static int writeback(FILE *res, FILE *obuf);
|
|
Packit |
272fb1 |
static void edstop(void);
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* The "quit" command.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
/*ARGSUSED*/
|
|
Packit |
272fb1 |
int
|
|
Packit |
272fb1 |
quitcmd(void *v)
|
|
Packit |
272fb1 |
{
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* If we are sourcing, then return 1 so execute() can handle it.
|
|
Packit |
272fb1 |
* Otherwise, return -1 to abort command loop.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
if (sourcing)
|
|
Packit |
272fb1 |
return 1;
|
|
Packit |
272fb1 |
return -1;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Preserve all the appropriate messages back in the system
|
|
Packit |
272fb1 |
* mailbox, and print a nice message indicated how many were
|
|
Packit |
272fb1 |
* saved. On any error, just return -1. Else return 0.
|
|
Packit |
272fb1 |
* Incorporate the any new mail that we found.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
static int
|
|
Packit |
272fb1 |
writeback(FILE *res, FILE *obuf)
|
|
Packit |
272fb1 |
{
|
|
Packit |
272fb1 |
struct message *mp;
|
|
Packit |
272fb1 |
int p, c;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
p = 0;
|
|
Packit |
272fb1 |
fseek(obuf, 0L, SEEK_SET);
|
|
Packit |
272fb1 |
#ifndef APPEND
|
|
Packit |
272fb1 |
if (res != NULL)
|
|
Packit |
272fb1 |
while ((c = getc(res)) != EOF)
|
|
Packit |
272fb1 |
putc(c, obuf);
|
|
Packit |
272fb1 |
#endif
|
|
Packit |
272fb1 |
for (mp = &message[0]; mp < &message[msgCount]; mp++)
|
|
Packit |
272fb1 |
if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
|
|
Packit |
272fb1 |
p++;
|
|
Packit |
272fb1 |
if (send(mp, obuf, NULL, NULL, SEND_MBOX, NULL) < 0) {
|
|
Packit |
272fb1 |
perror(mailname);
|
|
Packit |
272fb1 |
fseek(obuf, 0L, SEEK_SET);
|
|
Packit |
272fb1 |
return(-1);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
#ifdef APPEND
|
|
Packit |
272fb1 |
if (res != NULL)
|
|
Packit |
272fb1 |
while ((c = getc(res)) != EOF)
|
|
Packit |
272fb1 |
putc(c, obuf);
|
|
Packit |
272fb1 |
#endif
|
|
Packit |
272fb1 |
fflush(obuf);
|
|
Packit |
272fb1 |
trunc(obuf);
|
|
Packit |
272fb1 |
if (ferror(obuf)) {
|
|
Packit |
272fb1 |
perror(mailname);
|
|
Packit |
272fb1 |
fseek(obuf, 0L, SEEK_SET);
|
|
Packit |
272fb1 |
return(-1);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (res != NULL)
|
|
Packit |
272fb1 |
Fclose(res);
|
|
Packit |
272fb1 |
fseek(obuf, 0L, SEEK_SET);
|
|
Packit |
272fb1 |
alter(mailname);
|
|
Packit |
272fb1 |
if (p == 1)
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 155,
|
|
Packit |
272fb1 |
"Held 1 message in %s\n"), mailname);
|
|
Packit |
272fb1 |
else
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 156,
|
|
Packit |
272fb1 |
"Held %d messages in %s\n"), p, mailname);
|
|
Packit |
272fb1 |
return(0);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Save all of the undetermined messages at the top of "mbox"
|
|
Packit |
272fb1 |
* Save all untouched messages back in the system mailbox.
|
|
Packit |
272fb1 |
* Remove the system mailbox, if none saved there.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
void
|
|
Packit |
272fb1 |
quit(void)
|
|
Packit |
272fb1 |
{
|
|
Packit |
272fb1 |
int p, modify, anystat;
|
|
Packit |
272fb1 |
FILE *fbuf, *rbuf, *readstat = NULL, *abuf;
|
|
Packit |
272fb1 |
struct message *mp;
|
|
Packit |
272fb1 |
int c;
|
|
Packit Service |
b65dad |
char *tempResid;
|
|
Packit |
272fb1 |
struct stat minfo;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* If we are read only, we can't do anything,
|
|
Packit |
272fb1 |
* so just return quickly. IMAP can set some
|
|
Packit |
272fb1 |
* flags (e.g. "\\Seen") so imap_quit must be
|
|
Packit |
272fb1 |
* called even then.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
if (mb.mb_perm == 0 && mb.mb_type != MB_IMAP)
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
switch (mb.mb_type) {
|
|
Packit |
272fb1 |
case MB_FILE:
|
|
Packit |
272fb1 |
break;
|
|
Packit |
272fb1 |
case MB_MAILDIR:
|
|
Packit |
272fb1 |
maildir_quit();
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
case MB_POP3:
|
|
Packit |
272fb1 |
pop3_quit();
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
case MB_IMAP:
|
|
Packit |
272fb1 |
case MB_CACHE:
|
|
Packit |
272fb1 |
imap_quit();
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
case MB_VOID:
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* If editing (not reading system mail box), then do the work
|
|
Packit |
272fb1 |
* in edstop()
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
if (edit) {
|
|
Packit |
272fb1 |
edstop();
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* See if there any messages to save in mbox. If no, we
|
|
Packit |
272fb1 |
* can save copying mbox to /tmp and back.
|
|
Packit |
272fb1 |
*
|
|
Packit |
272fb1 |
* Check also to see if any files need to be preserved.
|
|
Packit |
272fb1 |
* Delete all untouched messages to keep them out of mbox.
|
|
Packit |
272fb1 |
* If all the messages are to be preserved, just exit with
|
|
Packit |
272fb1 |
* a message.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
fbuf = Zopen(mailname, "r+", &mb.mb_compressed);
|
|
Packit |
272fb1 |
if (fbuf == NULL) {
|
|
Packit |
272fb1 |
if (errno == ENOENT)
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
goto newmail;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (fcntl_lock(fileno(fbuf), F_WRLCK) == -1) {
|
|
Packit |
272fb1 |
nolock:
|
|
Packit |
272fb1 |
perror(catgets(catd, CATSET, 157, "Unable to lock mailbox"));
|
|
Packit |
272fb1 |
Fclose(fbuf);
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (dot_lock(mailname, fileno(fbuf), 1, stdout, ".") == -1)
|
|
Packit |
272fb1 |
goto nolock;
|
|
Packit |
272fb1 |
rbuf = NULL;
|
|
Packit |
272fb1 |
if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 158, "New mail has arrived.\n"));
|
|
Packit |
272fb1 |
rbuf = Ftemp(&tempResid, "Rq", "w", 0600, 1);
|
|
Packit |
272fb1 |
if (rbuf == NULL || fbuf == NULL)
|
|
Packit |
272fb1 |
goto newmail;
|
|
Packit |
272fb1 |
#ifdef APPEND
|
|
Packit |
272fb1 |
fseek(fbuf, (long)mailsize, SEEK_SET);
|
|
Packit |
272fb1 |
while ((c = getc(fbuf)) != EOF)
|
|
Packit |
272fb1 |
putc(c, rbuf);
|
|
Packit |
272fb1 |
#else
|
|
Packit |
272fb1 |
p = minfo.st_size - mailsize;
|
|
Packit |
272fb1 |
while (p-- > 0) {
|
|
Packit |
272fb1 |
c = getc(fbuf);
|
|
Packit |
272fb1 |
if (c == EOF)
|
|
Packit |
272fb1 |
goto newmail;
|
|
Packit |
272fb1 |
putc(c, rbuf);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
#endif
|
|
Packit |
272fb1 |
Fclose(rbuf);
|
|
Packit |
272fb1 |
if ((rbuf = Fopen(tempResid, "r")) == NULL)
|
|
Packit |
272fb1 |
goto newmail;
|
|
Packit |
272fb1 |
rm(tempResid);
|
|
Packit |
272fb1 |
Ftfree(&tempResid);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
anystat = holdbits();
|
|
Packit |
272fb1 |
modify = 0;
|
|
Packit |
272fb1 |
if (Tflag != NULL) {
|
|
Packit |
272fb1 |
if ((readstat = Zopen(Tflag, "w", NULL)) == NULL)
|
|
Packit |
272fb1 |
Tflag = NULL;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
|
|
Packit |
272fb1 |
if (mp->m_flag & MBOX)
|
|
Packit |
272fb1 |
c++;
|
|
Packit |
272fb1 |
if (mp->m_flag & MPRESERVE)
|
|
Packit |
272fb1 |
p++;
|
|
Packit |
272fb1 |
if (mp->m_flag & MODIFY)
|
|
Packit |
272fb1 |
modify++;
|
|
Packit |
272fb1 |
if (readstat != NULL && (mp->m_flag & (MREAD|MDELETED)) != 0) {
|
|
Packit |
272fb1 |
char *id;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
if ((id = hfield("message-id", mp)) != NULL ||
|
|
Packit |
272fb1 |
(id = hfield("article-id", mp)) != NULL)
|
|
Packit |
272fb1 |
fprintf(readstat, "%s\n", id);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (readstat != NULL)
|
|
Packit |
272fb1 |
Fclose(readstat);
|
|
Packit |
272fb1 |
if (p == msgCount && !modify && !anystat) {
|
|
Packit |
272fb1 |
if (p == 1)
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 155,
|
|
Packit |
272fb1 |
"Held 1 message in %s\n"), mailname);
|
|
Packit |
272fb1 |
else if (p > 1)
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 156,
|
|
Packit |
272fb1 |
"Held %d messages in %s\n"), p, mailname);
|
|
Packit |
272fb1 |
Fclose(fbuf);
|
|
Packit |
272fb1 |
dot_unlock(mailname);
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (c == 0) {
|
|
Packit |
272fb1 |
if (p != 0) {
|
|
Packit |
272fb1 |
writeback(rbuf, fbuf);
|
|
Packit |
272fb1 |
Fclose(fbuf);
|
|
Packit |
272fb1 |
dot_unlock(mailname);
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
goto cream;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
if (makembox() == STOP) {
|
|
Packit |
272fb1 |
Fclose(fbuf);
|
|
Packit |
272fb1 |
dot_unlock(mailname);
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Now we are ready to copy back preserved files to
|
|
Packit |
272fb1 |
* the system mailbox, if any were requested.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
if (p != 0) {
|
|
Packit |
272fb1 |
writeback(rbuf, fbuf);
|
|
Packit |
272fb1 |
Fclose(fbuf);
|
|
Packit |
272fb1 |
dot_unlock(mailname);
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Finally, remove his /usr/mail file.
|
|
Packit |
272fb1 |
* If new mail has arrived, copy it back.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
cream:
|
|
Packit |
272fb1 |
if (rbuf != NULL) {
|
|
Packit |
272fb1 |
abuf = fbuf;
|
|
Packit |
272fb1 |
fseek(abuf, 0L, SEEK_SET);
|
|
Packit |
272fb1 |
while ((c = getc(rbuf)) != EOF)
|
|
Packit |
272fb1 |
putc(c, abuf);
|
|
Packit |
272fb1 |
Fclose(rbuf);
|
|
Packit |
272fb1 |
trunc(abuf);
|
|
Packit |
272fb1 |
alter(mailname);
|
|
Packit |
272fb1 |
Fclose(fbuf);
|
|
Packit |
272fb1 |
dot_unlock(mailname);
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
demail();
|
|
Packit |
272fb1 |
Fclose(fbuf);
|
|
Packit |
272fb1 |
dot_unlock(mailname);
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
newmail:
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 166, "Thou hast new mail.\n"));
|
|
Packit |
272fb1 |
if (fbuf != NULL) {
|
|
Packit |
272fb1 |
Fclose(fbuf);
|
|
Packit |
272fb1 |
dot_unlock(mailname);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Adjust the message flags in each message.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
int
|
|
Packit |
272fb1 |
holdbits(void)
|
|
Packit |
272fb1 |
{
|
|
Packit |
272fb1 |
struct message *mp;
|
|
Packit |
272fb1 |
int anystat, autohold, holdbit, nohold;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
anystat = 0;
|
|
Packit |
272fb1 |
autohold = value("hold") != NULL;
|
|
Packit |
272fb1 |
holdbit = autohold ? MPRESERVE : MBOX;
|
|
Packit |
272fb1 |
nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
|
|
Packit |
272fb1 |
if (value("keepsave") != NULL)
|
|
Packit |
272fb1 |
nohold &= ~MSAVED;
|
|
Packit |
272fb1 |
for (mp = &message[0]; mp < &message[msgCount]; mp++) {
|
|
Packit |
272fb1 |
if (mp->m_flag & MNEW) {
|
|
Packit |
272fb1 |
mp->m_flag &= ~MNEW;
|
|
Packit |
272fb1 |
mp->m_flag |= MSTATUS;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (mp->m_flag & (MSTATUS|MFLAG|MUNFLAG|MANSWER|MUNANSWER|
|
|
Packit |
272fb1 |
MDRAFT|MUNDRAFT))
|
|
Packit |
272fb1 |
anystat++;
|
|
Packit |
272fb1 |
if ((mp->m_flag & MTOUCH) == 0)
|
|
Packit |
272fb1 |
mp->m_flag |= MPRESERVE;
|
|
Packit |
272fb1 |
if ((mp->m_flag & nohold) == 0)
|
|
Packit |
272fb1 |
mp->m_flag |= holdbit;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
return anystat;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Create another temporary file and copy user's mbox file
|
|
Packit |
272fb1 |
* darin. If there is no mbox, copy nothing.
|
|
Packit |
272fb1 |
* If he has specified "append" don't copy his mailbox,
|
|
Packit |
272fb1 |
* just copy saveable entries at the end.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
enum okay
|
|
Packit |
272fb1 |
makembox(void)
|
|
Packit |
272fb1 |
{
|
|
Packit |
272fb1 |
struct message *mp;
|
|
Packit |
272fb1 |
char *mbox, *tempQuit;
|
|
Packit |
272fb1 |
int mcount, c;
|
|
Packit |
272fb1 |
FILE *ibuf = NULL, *obuf, *abuf;
|
|
Packit |
272fb1 |
enum protocol prot;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
mbox = mboxname;
|
|
Packit |
272fb1 |
mcount = 0;
|
|
Packit |
272fb1 |
if (value("append") == NULL) {
|
|
Packit |
272fb1 |
if ((obuf = Ftemp(&tempQuit, "Rm", "w", 0600, 1)) == NULL) {
|
|
Packit |
272fb1 |
perror(catgets(catd, CATSET, 162,
|
|
Packit |
272fb1 |
"temporary mail quit file"));
|
|
Packit |
272fb1 |
return STOP;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if ((ibuf = Fopen(tempQuit, "r")) == NULL) {
|
|
Packit |
272fb1 |
perror(tempQuit);
|
|
Packit |
272fb1 |
rm(tempQuit);
|
|
Packit |
272fb1 |
Ftfree(&tempQuit);
|
|
Packit |
272fb1 |
Fclose(obuf);
|
|
Packit |
272fb1 |
return STOP;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
rm(tempQuit);
|
|
Packit |
272fb1 |
Ftfree(&tempQuit);
|
|
Packit |
272fb1 |
if ((abuf = Zopen(mbox, "r", NULL)) != NULL) {
|
|
Packit |
272fb1 |
while ((c = getc(abuf)) != EOF)
|
|
Packit |
272fb1 |
putc(c, obuf);
|
|
Packit |
272fb1 |
Fclose(abuf);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (ferror(obuf)) {
|
|
Packit |
272fb1 |
perror(catgets(catd, CATSET, 163,
|
|
Packit |
272fb1 |
"temporary mail quit file"));
|
|
Packit |
272fb1 |
Fclose(ibuf);
|
|
Packit |
272fb1 |
Fclose(obuf);
|
|
Packit |
272fb1 |
return STOP;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
Fclose(obuf);
|
|
Packit |
272fb1 |
close(creat(mbox, 0600));
|
|
Packit |
272fb1 |
if ((obuf = Zopen(mbox, "r+", NULL)) == NULL) {
|
|
Packit |
272fb1 |
perror(mbox);
|
|
Packit |
272fb1 |
Fclose(ibuf);
|
|
Packit |
272fb1 |
return STOP;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
else {
|
|
Packit |
272fb1 |
if ((obuf = Zopen(mbox, "a", NULL)) == NULL) {
|
|
Packit |
272fb1 |
perror(mbox);
|
|
Packit |
272fb1 |
return STOP;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
fchmod(fileno(obuf), 0600);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
prot = which_protocol(mbox);
|
|
Packit |
272fb1 |
for (mp = &message[0]; mp < &message[msgCount]; mp++)
|
|
Packit |
272fb1 |
if (mp->m_flag & MBOX) {
|
|
Packit |
272fb1 |
mcount++;
|
|
Packit |
272fb1 |
if (prot == PROTO_IMAP &&
|
|
Packit |
272fb1 |
saveignore[0].i_count == 0 &&
|
|
Packit |
272fb1 |
saveignore[1].i_count == 0 &&
|
|
Packit |
272fb1 |
imap_thisaccount(mbox)) {
|
|
Packit |
272fb1 |
if (imap_copy(mp, mp-message+1, mbox) == STOP)
|
|
Packit |
272fb1 |
goto err;
|
|
Packit |
272fb1 |
} else if (send(mp, obuf, saveignore,
|
|
Packit |
272fb1 |
NULL, SEND_MBOX, NULL) < 0) {
|
|
Packit |
272fb1 |
perror(mbox);
|
|
Packit |
272fb1 |
err: if (ibuf)
|
|
Packit |
272fb1 |
Fclose(ibuf);
|
|
Packit |
272fb1 |
Fclose(obuf);
|
|
Packit |
272fb1 |
return STOP;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
mp->m_flag |= MBOXED;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Copy the user's old mbox contents back
|
|
Packit |
272fb1 |
* to the end of the stuff we just saved.
|
|
Packit |
272fb1 |
* If we are appending, this is unnecessary.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
if (value("append") == NULL) {
|
|
Packit |
272fb1 |
rewind(ibuf);
|
|
Packit |
272fb1 |
c = getc(ibuf);
|
|
Packit |
272fb1 |
while (c != EOF) {
|
|
Packit |
272fb1 |
putc(c, obuf);
|
|
Packit |
272fb1 |
if (ferror(obuf))
|
|
Packit |
272fb1 |
break;
|
|
Packit |
272fb1 |
c = getc(ibuf);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
Fclose(ibuf);
|
|
Packit |
272fb1 |
fflush(obuf);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
trunc(obuf);
|
|
Packit |
272fb1 |
if (ferror(obuf)) {
|
|
Packit |
272fb1 |
perror(mbox);
|
|
Packit |
272fb1 |
Fclose(obuf);
|
|
Packit |
272fb1 |
return STOP;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (Fclose(obuf) != 0) {
|
|
Packit |
272fb1 |
if (prot != PROTO_IMAP)
|
|
Packit |
272fb1 |
perror(mbox);
|
|
Packit |
272fb1 |
return STOP;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (mcount == 1)
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 164, "Saved 1 message in mbox\n"));
|
|
Packit |
272fb1 |
else
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 165,
|
|
Packit |
272fb1 |
"Saved %d messages in mbox\n"), mcount);
|
|
Packit |
272fb1 |
return OKAY;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
/*
|
|
Packit |
272fb1 |
* Terminate an editing session by attempting to write out the user's
|
|
Packit |
272fb1 |
* file from the temporary. Save any new stuff appended to the file.
|
|
Packit |
272fb1 |
*/
|
|
Packit |
272fb1 |
static void
|
|
Packit |
272fb1 |
edstop(void)
|
|
Packit |
272fb1 |
{
|
|
Packit |
272fb1 |
int gotcha, c;
|
|
Packit |
272fb1 |
struct message *mp;
|
|
Packit |
272fb1 |
FILE *obuf, *ibuf = NULL, *readstat = NULL;
|
|
Packit |
272fb1 |
struct stat statb;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
if (mb.mb_perm == 0)
|
|
Packit |
272fb1 |
return;
|
|
Packit |
272fb1 |
holdsigs();
|
|
Packit |
272fb1 |
if (Tflag != NULL) {
|
|
Packit |
272fb1 |
if ((readstat = Zopen(Tflag, "w", NULL)) == NULL)
|
|
Packit |
272fb1 |
Tflag = NULL;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
|
|
Packit |
272fb1 |
if (mp->m_flag & MNEW) {
|
|
Packit |
272fb1 |
mp->m_flag &= ~MNEW;
|
|
Packit |
272fb1 |
mp->m_flag |= MSTATUS;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (mp->m_flag & (MODIFY|MDELETED|MSTATUS|MFLAG|MUNFLAG|
|
|
Packit |
272fb1 |
MANSWER|MUNANSWER|MDRAFT|MUNDRAFT))
|
|
Packit |
272fb1 |
gotcha++;
|
|
Packit |
272fb1 |
if (readstat != NULL && (mp->m_flag & (MREAD|MDELETED)) != 0) {
|
|
Packit |
272fb1 |
char *id;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
if ((id = hfield("message-id", mp)) != NULL ||
|
|
Packit |
272fb1 |
(id = hfield("article-id", mp)) != NULL)
|
|
Packit |
272fb1 |
fprintf(readstat, "%s\n", id);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if (readstat != NULL)
|
|
Packit |
272fb1 |
Fclose(readstat);
|
|
Packit |
272fb1 |
if (!gotcha || Tflag != NULL)
|
|
Packit |
272fb1 |
goto done;
|
|
Packit |
272fb1 |
ibuf = NULL;
|
|
Packit |
272fb1 |
if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
|
|
Packit |
272fb1 |
char *tempname;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
if ((obuf = Ftemp(&tempname, "mbox.", "w", 0600, 1)) == NULL) {
|
|
Packit |
272fb1 |
perror(catgets(catd, CATSET, 167, "tmpfile"));
|
|
Packit |
272fb1 |
relsesigs();
|
|
Packit |
272fb1 |
reset(0);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
if ((ibuf = Zopen(mailname, "r", &mb.mb_compressed)) == NULL) {
|
|
Packit |
272fb1 |
perror(mailname);
|
|
Packit |
272fb1 |
Fclose(obuf);
|
|
Packit |
272fb1 |
rm(tempname);
|
|
Packit |
272fb1 |
Ftfree(&tempname);
|
|
Packit |
272fb1 |
relsesigs();
|
|
Packit |
272fb1 |
reset(0);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
fseek(ibuf, (long)mailsize, SEEK_SET);
|
|
Packit |
272fb1 |
while ((c = getc(ibuf)) != EOF)
|
|
Packit |
272fb1 |
putc(c, obuf);
|
|
Packit |
272fb1 |
Fclose(ibuf);
|
|
Packit |
272fb1 |
Fclose(obuf);
|
|
Packit |
272fb1 |
if ((ibuf = Fopen(tempname, "r")) == NULL) {
|
|
Packit |
272fb1 |
perror(tempname);
|
|
Packit |
272fb1 |
rm(tempname);
|
|
Packit |
272fb1 |
Ftfree(&tempname);
|
|
Packit |
272fb1 |
relsesigs();
|
|
Packit |
272fb1 |
reset(0);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
rm(tempname);
|
|
Packit |
272fb1 |
Ftfree(&tempname);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
printf(catgets(catd, CATSET, 168, "\"%s\" "), mailname);
|
|
Packit |
272fb1 |
fflush(stdout);
|
|
Packit |
272fb1 |
if ((obuf = Zopen(mailname, "r+", &mb.mb_compressed)) == NULL) {
|
|
Packit |
272fb1 |
perror(mailname);
|
|
Packit |
272fb1 |
relsesigs();
|
|
Packit |
272fb1 |
reset(0);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
trunc(obuf);
|
|
Packit |
272fb1 |
c = 0;
|
|
Packit |
272fb1 |
for (mp = &message[0]; mp < &message[msgCount]; mp++) {
|
|
Packit |
272fb1 |
if ((mp->m_flag & MDELETED) != 0)
|
|
Packit |
272fb1 |
continue;
|
|
Packit |
272fb1 |
c++;
|
|
Packit |
272fb1 |
if (send(mp, obuf, NULL, NULL, SEND_MBOX, NULL) < 0) {
|
|
Packit |
272fb1 |
perror(mailname);
|
|
Packit |
272fb1 |
relsesigs();
|
|
Packit |
272fb1 |
reset(0);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
gotcha = (c == 0 && ibuf == NULL);
|
|
Packit |
272fb1 |
if (ibuf != NULL) {
|
|
Packit |
272fb1 |
while ((c = getc(ibuf)) != EOF)
|
|
Packit |
272fb1 |
putc(c, obuf);
|
|
Packit |
272fb1 |
Fclose(ibuf);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
fflush(obuf);
|
|
Packit |
272fb1 |
if (ferror(obuf)) {
|
|
Packit |
272fb1 |
perror(mailname);
|
|
Packit |
272fb1 |
relsesigs();
|
|
Packit |
272fb1 |
reset(0);
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
Fclose(obuf);
|
|
Packit |
272fb1 |
if (gotcha && value("emptybox") == NULL) {
|
|
Packit |
272fb1 |
rm(mailname);
|
|
Packit |
272fb1 |
printf(value("bsdcompat") || value("bsdmsgs") ?
|
|
Packit |
272fb1 |
catgets(catd, CATSET, 169, "removed\n") :
|
|
Packit |
272fb1 |
catgets(catd, CATSET, 211, "removed.\n"));
|
|
Packit |
272fb1 |
} else
|
|
Packit |
272fb1 |
printf(value("bsdcompat") || value("bsdmsgs") ?
|
|
Packit |
272fb1 |
catgets(catd, CATSET, 170, "complete\n") :
|
|
Packit |
272fb1 |
catgets(catd, CATSET, 212, "updated.\n"));
|
|
Packit |
272fb1 |
fflush(stdout);
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
done:
|
|
Packit |
272fb1 |
relsesigs();
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
enum quitflags {
|
|
Packit |
272fb1 |
QUITFLAG_HOLD = 001,
|
|
Packit |
272fb1 |
QUITFLAG_KEEPSAVE = 002,
|
|
Packit |
272fb1 |
QUITFLAG_APPEND = 004,
|
|
Packit |
272fb1 |
QUITFLAG_EMPTYBOX = 010
|
|
Packit |
272fb1 |
};
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
static const struct quitnames {
|
|
Packit |
272fb1 |
enum quitflags flag;
|
|
Packit |
272fb1 |
const char *name;
|
|
Packit |
272fb1 |
} quitnames[] = {
|
|
Packit |
272fb1 |
{ QUITFLAG_HOLD, "hold" },
|
|
Packit |
272fb1 |
{ QUITFLAG_KEEPSAVE, "keepsave" },
|
|
Packit |
272fb1 |
{ QUITFLAG_APPEND, "append" },
|
|
Packit |
272fb1 |
{ QUITFLAG_EMPTYBOX, "emptybox" },
|
|
Packit |
272fb1 |
{ 0, NULL }
|
|
Packit |
272fb1 |
};
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
int
|
|
Packit |
272fb1 |
savequitflags(void)
|
|
Packit |
272fb1 |
{
|
|
Packit |
272fb1 |
enum quitflags qf = 0;
|
|
Packit |
272fb1 |
int i;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
for (i = 0; quitnames[i].name; i++)
|
|
Packit |
272fb1 |
if (value(quitnames[i].name))
|
|
Packit |
272fb1 |
qf |= quitnames[i].flag;
|
|
Packit |
272fb1 |
return qf;
|
|
Packit |
272fb1 |
}
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
void
|
|
Packit |
272fb1 |
restorequitflags(int qf)
|
|
Packit |
272fb1 |
{
|
|
Packit |
272fb1 |
int i;
|
|
Packit |
272fb1 |
|
|
Packit |
272fb1 |
for (i = 0; quitnames[i].name; i++)
|
|
Packit |
272fb1 |
if (qf & quitnames[i].flag) {
|
|
Packit |
272fb1 |
if (value(quitnames[i].name) == NULL)
|
|
Packit |
272fb1 |
assign(quitnames[i].name, "");
|
|
Packit |
272fb1 |
} else if (value(quitnames[i].name))
|
|
Packit |
272fb1 |
unset_internal(quitnames[i].name);
|
|
Packit |
272fb1 |
}
|