/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999-2021 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see . */
#include "mail.h"
/*
* q[uit]
*
*/
int
mail_quit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
{
if (mail_mbox_close ())
return 1;
exit (0);
}
int
mail_mbox_close (void)
{
mu_url_t url = NULL;
size_t held_count = 0;
if (!mbox)
return 0;
if (!mailvar_is_true (mailvar_name_readonly))
{
if (mail_mbox_commit ())
return 1;
mu_mailbox_flush (mbox, 1);
}
mu_mailbox_get_url (mbox, &url);
mu_mailbox_messages_count (mbox, &held_count);
mu_printf (
ngettext ("Held %lu message in %s\n",
"Held %lu messages in %s\n",
held_count),
(unsigned long) held_count, util_url_to_string (url));
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
return 0;
}
enum mailbox_class
{
MBX_SYSTEM,
MBX_MBOX,
MBX_USER
};
static enum mailbox_class
mailbox_classify (void)
{
mu_url_t url;
mu_mailbox_get_url (mbox, &url);
if (strcmp (util_url_to_string (url), getenv ("MBOX")) == 0)
return MBX_MBOX;
else
{
mu_mailbox_t mb;
mu_url_t u;
mu_mailbox_create_default (&mb, NULL);
mu_mailbox_get_url (mb, &u);
if (strcmp (mu_url_to_string (u), mu_url_to_string (url)) == 0)
return MBX_SYSTEM;
}
return MBX_USER;
}
int
mail_mbox_commit (void)
{
unsigned int i;
mu_mailbox_t dest_mbox = NULL;
int saved_count = 0;
mu_message_t msg;
mu_attribute_t attr;
int keepsave = mailvar_is_true (mailvar_name_keepsave);
int hold = mailvar_is_true (mailvar_name_hold);
enum mailbox_class class = mailbox_classify ();
if (class != MBX_SYSTEM)
{
/* The mailbox we are closing is not a system one (%). Stay on the
safe side: retain both read and saved messages in the mailbox. */
hold = 1;
keepsave = 1;
}
for (i = 1; i <= total; i++)
{
int status;
enum { ACT_KEEP, ACT_MBOX, ACT_DELETE } action = ACT_KEEP;
if (util_get_message (mbox, i, &msg))
return 1;
mu_message_get_attribute (msg, &attr);
if (mu_attribute_is_deleted (attr))
continue;
if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED))
action = ACT_KEEP;
else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_MBOXED))
action = ACT_MBOX;
else if (class == MBX_SYSTEM)
{
if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SHOWN
| MAIL_ATTRIBUTE_TOUCHED))
action = hold ? ACT_KEEP : ACT_MBOX;
else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED))
{
if (keepsave)
action = hold ? ACT_KEEP : ACT_MBOX;
else
action = ACT_DELETE;
}
}
switch (action)
{
case ACT_KEEP:
if (mu_attribute_is_read (attr))
mu_attribute_set_seen (attr);
break;
case ACT_MBOX:
if (!dest_mbox)
{
char *name = getenv ("MBOX");
if ((status = mu_mailbox_create_default (&dest_mbox, name)) != 0)
{
mu_error (_("Cannot create mailbox %s: %s"), name,
mu_strerror (status));
return 1;
}
if ((status = mu_mailbox_open (dest_mbox,
MU_STREAM_WRITE | MU_STREAM_CREAT))
!= 0)
{
mu_error (_("Cannot open mailbox %s: %s"), name,
mu_strerror (status));
return 1;
}
}
status = mu_mailbox_append_message (dest_mbox, msg);
if (status)
{
mu_url_t url = NULL;
mu_mailbox_get_url (dest_mbox, &url);
mu_error (_("Cannot append message to %s: %s"),
util_url_to_string (url),
mu_strerror (status));
}
else
{
mu_attribute_set_deleted (attr);
saved_count++;
}
break;
case ACT_DELETE:
mu_attribute_set_deleted (attr);
break;
}
}
if (saved_count)
{
mu_url_t u = NULL;
mu_mailbox_get_url (dest_mbox, &u);
mu_printf (
ngettext ("Saved %d message in %s\n",
"Saved %d messages in %s\n",
saved_count),
saved_count, util_url_to_string (u));
mu_mailbox_close (dest_mbox);
mu_mailbox_destroy (&dest_mbox);
}
return 0;
}