/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2003-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
static char prog_doc[] = N_("Manipulate message sequences");
static char args_doc[] = N_("[MSGLIST]");
enum action_type
{
action_undef,
action_list,
action_add,
action_delete
};
static enum action_type action = action_undef; /* Action to perform */
static int seq_flags = 0; /* Create public sequences;
Do not zero the sequence before addition */
static mu_list_t seq_list; /* List of sequence names to operate upon */
static const char *mbox_dir;
static int public_option = -1;
static int zero_option = -1;
static void
set_action_add (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
action = action_add;
}
static void
set_action_delete (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
action = action_delete;
}
static void
set_action_list (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
action = action_list;
}
static void
add_sequence (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
if (!seq_list && mu_list_create (&seq_list))
{
mu_error (_("cannot create sequence list"));
exit (1);
}
mu_list_append (seq_list, mu_strdup (arg));
}
static struct mu_option options[] = {
{ "sequence", 0, N_("NAME"), MU_OPTION_DEFAULT,
N_("specify sequence name to operate upon"),
mu_c_string, NULL, add_sequence },
{ "add", 0, NULL, MU_OPTION_DEFAULT,
N_("add messages to the sequence"),
mu_c_string, NULL, set_action_add },
{ "delete", 0, NULL, MU_OPTION_DEFAULT,
N_("delete messages from the sequence"),
mu_c_string, NULL, set_action_delete },
{ "list", 0, NULL, MU_OPTION_DEFAULT,
N_("list the sequences"),
mu_c_string, NULL, set_action_list },
{ "public", 0, NULL, MU_OPTION_DEFAULT,
N_("create public sequence"),
mu_c_bool, &public_option },
{ "zero", 0, NULL, MU_OPTION_DEFAULT,
N_("empty the sequence before adding messages"),
mu_c_bool, &zero_option },
MU_OPTION_END
};
struct mark_closure
{
mu_mailbox_t mbox;
mu_msgset_t msgset;
};
static int
do_add (void *item, void *data)
{
struct mark_closure *clos = data;
mh_seq_add (clos->mbox, (char *)item, clos->msgset, seq_flags);
return 0;
}
static int
do_delete (void *item, void *data)
{
struct mark_closure *clos = data;
mh_seq_delete (clos->mbox, (char *)item, clos->msgset, seq_flags);
return 0;
}
static int
do_list (void *item, void *data)
{
struct mark_closure *clos = data;
char *name = item;
const char *val;
val = mh_seq_read (clos->mbox, name, 0);
if (val)
printf ("%s: %s\n", name, val);
else if ((val = mh_seq_read (clos->mbox, name, SEQ_PRIVATE)))
printf ("%s (%s): %s\n", name, _("private"), val);
return 0;
}
static int
list_private (const char *name, const char *value, void *data)
{
int nlen;
if (memcmp (name, "atr-", 4))
return 0;
name += 4;
nlen = strlen (name) - strlen (mbox_dir);
if (nlen > 0 && strcmp (name + nlen, mbox_dir) == 0)
{
nlen--;
printf ("%*.*s (%s): %s\n", nlen, nlen, name, _("private"), value);
}
return 0;
}
static int
list_public (const char *name, const char *value, void *data)
{
printf ("%s: %s\n", name, value);
return 0;
}
static void
list_all (mu_mailbox_t mbox)
{
mh_global_sequences_iterate (mbox, list_public, NULL);
mh_global_context_iterate (list_private, NULL);
}
int
main (int argc, char **argv)
{
mu_msgset_t msgset;
mu_mailbox_t mbox;
mu_url_t url;
struct mark_closure clos;
mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
if (public_option == -1)
/* use default */;
else if (public_option)
seq_flags &= ~SEQ_PRIVATE;
else
seq_flags |= SEQ_PRIVATE;
if (zero_option == -1)
/* use default */;
else if (zero_option)
seq_flags |= SEQ_ZERO;
else
seq_flags &= ~SEQ_ZERO;
if (action == action_undef)
{
/* If no explicit action is given, assume -add if a sequence
was specified, and -list otherwise. */
if (mu_list_is_empty (seq_list))
action = action_list;
else
action = action_add;
}
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mu_mailbox_get_url (mbox, &url);
mbox_dir = mu_url_to_string (url);
if (memcmp (mbox_dir, "mh:", 3) == 0)
mbox_dir += 3;
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
clos.mbox = mbox;
clos.msgset = msgset;
//FIXME: msgset operates on UIDs but there's no way to inform it about that.
switch (action)
{
case action_add:
if (!seq_list)
{
mu_error (_("--add requires at least one --sequence argument"));
return 1;
}
mu_list_foreach (seq_list, do_add, (void *) &clos);
mh_global_save_state ();
break;
case action_delete:
if (!seq_list)
{
mu_error (_("--delete requires at least one --sequence argument"));
return 1;
}
mu_list_foreach (seq_list, do_delete, (void *) &clos);
mh_global_save_state ();
break;
case action_list:
if (!seq_list)
list_all (mbox);
else
mu_list_foreach (seq_list, do_list, &clos);
break;
default:
abort ();
}
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
return 0;
}