/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011-2019 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
#include
#include
static void
parse_msgrange (char *arg, struct mu_msgrange *range)
{
size_t msgnum;
char *p;
errno = 0;
msgnum = strtoul (arg, &p, 10);
range->msg_beg = msgnum;
if (*p == ':')
{
if (*++p == '*')
msgnum = 0;
else
{
msgnum = strtoul (p, &p, 10);
if (*p)
{
mu_error ("error in message range near %s", p);
exit (1);
}
}
}
else if (*p == '*')
msgnum = 0;
else if (*p)
{
mu_error ("error in message range near %s", p);
exit (1);
}
range->msg_end = msgnum;
}
mu_msgset_t
parse_msgset (const char *arg, mu_mailbox_t mbox,
int create_mode, int parse_mode)
{
int rc;
mu_msgset_t msgset;
char *end;
MU_ASSERT (mu_msgset_create (&msgset, mbox, create_mode));
if (arg)
{
rc = mu_msgset_parse_imap (msgset, parse_mode, arg, &end);
if (rc)
{
mu_error ("mu_msgset_parse_imap: %s near %s",
mu_strerror (rc), end);
exit (1);
}
}
return msgset;
}
int
main (int argc, char **argv)
{
int i;
char *msgset_string = NULL;
mu_msgset_t msgset, outset;
int create_mode = MU_MSGSET_NUM;
int parse_mode = MU_MSGSET_NUM;
int output_mode = MU_MSGSET_NUM;
int output_flags = 0;
mu_msgset_format_t format = mu_msgset_fmt_imap;
mu_mailbox_t mbox = NULL;
mu_set_program_name (argv[0]);
mu_register_local_mbox_formats ();
for (i = 1; i < argc; i++)
{
char *arg = argv[i];
if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
{
mu_printf ("usage: %s [-msgset[uid]=SET] [-uid] [-add[uid]=X[:Y]] [-del[uid]=X[:Y]] "
"[-addset[uid]=SET] [-delset[uid]=SET] ...\n",
mu_program_name);
return 0;
}
else if (strncmp (arg, "-msgset=", 8) == 0)
{
parse_mode = MU_MSGSET_NUM;
msgset_string = arg + 8;
}
else if (strncmp (arg, "-msgsetuid=", 11) == 0)
{
parse_mode = MU_MSGSET_UID;
msgset_string = arg + 11;
}
else if (strcmp (arg, "-uid") == 0)
create_mode = MU_MSGSET_UID;
else if (strncmp (arg, "-mailbox=", 9) == 0)
{
MU_ASSERT (mu_mailbox_create (&mbox, arg + 9));
MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_READ));
}
else if (strcmp (arg, "-mh") == 0)
format = mu_msgset_fmt_mh;
else if (strcmp (arg, "-printuid") == 0)
output_mode = MU_MSGSET_UID;
else if (strcmp (arg, "-printnum") == 0)
output_mode = MU_MSGSET_NUM;
else if (strcmp (arg, "-ignore-error") == 0)
output_flags = MU_MSGSET_IGNORE_TRANSERR;
else
break;
}
msgset = parse_msgset (msgset_string, mbox, create_mode, parse_mode);
for (; i < argc; i++)
{
char *arg = argv[i];
struct mu_msgrange range;
if (strncmp (arg, "-add=", 5) == 0)
{
parse_msgrange (arg + 5, &range);
MU_ASSERT (mu_msgset_add_range (msgset,
range.msg_beg, range.msg_end,
MU_MSGSET_NUM));
}
else if (strncmp (arg, "-sub=", 5) == 0)
{
parse_msgrange (arg + 5, &range);
MU_ASSERT (mu_msgset_sub_range (msgset,
range.msg_beg, range.msg_end,
MU_MSGSET_NUM));
}
else if (strncmp (arg, "-adduid=", 8) == 0)
{
parse_msgrange (arg + 8, &range);
MU_ASSERT (mu_msgset_add_range (msgset,
range.msg_beg, range.msg_end,
MU_MSGSET_UID));
}
else if (strncmp (arg, "-subuid=", 8) == 0)
{
parse_msgrange (arg + 8, &range);
MU_ASSERT (mu_msgset_sub_range (msgset,
range.msg_beg, range.msg_end,
MU_MSGSET_UID));
}
else if (strncmp (arg, "-addset", 7) == 0)
{
mu_msgset_t tset;
int m;
arg += 7;
if (strncmp (arg, "uid", 3) == 0)
{
m = MU_MSGSET_UID;
arg += 3;
}
else
m = MU_MSGSET_NUM;
if (*arg == '=')
arg++;
else
{
mu_error ("unknown option %s", argv[i]);
return 1;
}
tset = parse_msgset (arg, mbox, m, m);
if (!msgset)
msgset = tset;
else
{
MU_ASSERT (mu_msgset_add (msgset, tset));
mu_msgset_free (tset);
}
}
else if (strncmp (arg, "-subset=", 8) == 0)
{
mu_msgset_t tset;
int m;
arg += 7;
if (strncmp (arg, "uid", 3) == 0)
{
m = MU_MSGSET_UID;
arg += 3;
}
else
m = MU_MSGSET_NUM;
if (*arg == '=')
arg++;
else
{
mu_error ("unknown option %s", argv[i]);
return 1;
}
tset = parse_msgset (arg, mbox, m, m);
if (!msgset)
{
mu_error ("no initial message set");
exit (1);
}
else
{
MU_ASSERT (mu_msgset_sub (msgset, tset));
mu_msgset_free (tset);
}
}
else if (strcmp (arg, "-neg") == 0)
{
mu_msgset_t negated_set;
MU_ASSERT (mu_msgset_negate (msgset, &negated_set));
mu_msgset_free (msgset);
msgset = negated_set;
}
else
{
mu_error ("unknown option %s", arg);
return 1;
}
}
MU_ASSERT (mu_msgset_translate (&outset, msgset, output_mode|output_flags));
MU_ASSERT (mu_stream_msgset_format (mu_strout, format, outset));
mu_printf ("\n");
mu_msgset_free (outset);
mu_msgset_free (msgset);
return 0;
}