Commit d9ddd27a d9ddd27acef16ebbb44a0fc096fe86fedab5399d by Sergey Poznyakoff

MH: Synchronize sequences after removal of messages.

* include/mailutils/msgset.h (mu_msgset_sget_mailbox): New proto.
* include/mailutils/sys/msgset.h (_MU_MSGSET_MODE): New macro.
* libmailutils/msgset/Makefile.am: Add getmbox.c
* libmailutils/msgset/getmbox.c: New file.
* libmailutils/msgset/addset.c: Use _MU_MSGSET_MODE.
* libmailutils/msgset/create.c: Likewise.
* libmailutils/msgset/foreachmsg.c: Likewise.
* libmailutils/msgset/foreachnum.c: Likewise.
* libmailutils/msgset/negate.c: Likewise.
* libmailutils/msgset/subset.c: Likewise.
* libmailutils/msgset/trans.c: Likewise.

* mh/mh.h (mh_private_sequences_iterate): New proto.
* mh/mh_sequence.c (format_closure) <delim>: New member.
(format_sequence): Use delim to avoid outputting leading space.
(save_sequence): Initialize delim.
(mh_private_sequences_iterate): New function.
* mh/rmm.c (main): Remove message numbers from sequences.
* mh/tests/rmm.at: Update.
1 parent 796d9aef
......@@ -43,6 +43,8 @@ int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int mode);
int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist);
int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr);
int mu_msgset_sget_mailbox (mu_msgset_t mset, mu_mailbox_t *mbox);
int mu_msgset_add_range (mu_msgset_t set, size_t beg, size_t end, int mode);
int mu_msgset_sub_range (mu_msgset_t set, size_t beg, size_t end, int mode);
int mu_msgset_add (mu_msgset_t a, mu_msgset_t b);
......
......@@ -20,6 +20,7 @@
#define _MU_MSGSET_AGGREGATED 0x10
#define _MU_MSGSET_USERFLAG_MASK 0x0f
#define _MU_MSGSET_MODE(c) ((c) & _MU_MSGSET_USERFLAG_MASK)
struct _mu_msgset
{
......
......@@ -26,6 +26,7 @@ libmsgset_la_SOURCES = \
count.c\
getitr.c\
getlist.c\
getmbox.c\
foreachnum.c\
foreachmsgno.c\
foreachuid.c\
......
......@@ -44,7 +44,7 @@ mu_msgset_add (mu_msgset_t a, mu_msgset_t b)
return EINVAL;
if (!b)
return 0;
closure.mode = b->flags;
closure.mode = _MU_MSGSET_MODE (b->flags);
closure.dest = a;
return mu_list_foreach (b->list, add_range, &closure);
}
......
......@@ -54,7 +54,7 @@ mu_msgset_create (mu_msgset_t *pres, mu_mailbox_t mbox, int flags)
mu_list_set_destroy_item (msgset->list, mu_list_free_item);
mu_list_set_comparator (msgset->list, compare_msgnum);
msgset->mbox = mbox;
msgset->flags = flags & _MU_MSGSET_USERFLAG_MASK;
msgset->flags = _MU_MSGSET_MODE (flags);
*pres = msgset;
return 0;
}
......
......@@ -38,7 +38,7 @@ call_action (struct action_closure *clos, size_t i)
mu_message_t msg = NULL;
size_t n;
if (clos->msgset->flags == MU_MSGSET_UID)
if (_MU_MSGSET_MODE (clos->msgset->flags) == MU_MSGSET_UID)
{
rc = mu_mailbox_translate (clos->msgset->mbox, MU_MAILBOX_UID_TO_MSGNO,
i, &n);
......
......@@ -37,11 +37,11 @@ call_action (struct action_closure *clos, size_t i)
size_t n;
int cmd;
if (clos->msgset->flags != (clos->flags & MU_MSGSET_MODE_MASK))
if (_MU_MSGSET_MODE (clos->msgset->flags) != _MU_MSGSET_MODE (clos->flags))
{
int rc;
switch (clos->flags & MU_MSGSET_MODE_MASK)
switch (_MU_MSGSET_MODE (clos->flags))
{
case MU_MSGSET_NUM:
cmd = MU_MAILBOX_UID_TO_MSGNO;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011-2013 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 <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/msgset.h>
#include <mailutils/sys/msgset.h>
int
mu_msgset_sget_mailbox (mu_msgset_t mset, mu_mailbox_t *mbox)
{
if (!mset)
return EINVAL;
if (!mbox)
return MU_ERR_OUT_PTR_NULL;
*mbox = mset->mbox;
return 0;
}
......@@ -40,7 +40,7 @@ _invert_range (void *item, void *data)
{
rc = mu_msgset_add_range (clos->nset,
clos->next_num, range->msg_beg - 1,
clos->nset->flags);
_MU_MSGSET_MODE (clos->nset->flags));
if (rc)
return rc;
}
......@@ -68,7 +68,7 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
rc = mu_mailbox_messages_count (msgset->mbox, &total);
if (rc)
return rc;
if (msgset->flags == MU_MSGSET_UID)
if (_MU_MSGSET_MODE (msgset->flags))
{
rc = mu_mailbox_translate (msgset->mbox,
MU_MAILBOX_MSGNO_TO_UID,
......@@ -76,7 +76,8 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
if (rc)
return rc;
}
rc = mu_msgset_create (&clos.nset, msgset->mbox, msgset->flags);
rc = mu_msgset_create (&clos.nset, msgset->mbox,
_MU_MSGSET_MODE (msgset->flags));
if (rc)
return rc;
clos.next_num = 1;
......@@ -85,7 +86,7 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
{
if (clos.next_num < total)
rc = mu_msgset_add_range (clos.nset, clos.next_num, total,
clos.nset->flags);
_MU_MSGSET_MODE (clos.nset->flags));
}
if (rc)
......
......@@ -44,7 +44,7 @@ mu_msgset_sub (mu_msgset_t a, mu_msgset_t b)
return EINVAL;
if (!b)
return 0;
closure.mode = b->flags;
closure.mode = _MU_MSGSET_MODE (b->flags);
closure.dest = a;
return mu_list_foreach (b->list, sub_range, &closure);
}
......
......@@ -27,14 +27,14 @@ int
_mu_msgset_translate_pair (mu_msgset_t mset, int mode,
size_t *pbeg, size_t *pend)
{
if (mode != mset->flags && mset->mbox)
if (mode != _MU_MSGSET_MODE (mset->flags) && mset->mbox)
{
int cmd, rc;
size_t n;
size_t beg = *pbeg;
size_t end = *pend;
switch (mset->flags)
switch (_MU_MSGSET_MODE (mset->flags))
{
case MU_MSGSET_NUM:
cmd = MU_MAILBOX_UID_TO_MSGNO;
......
......@@ -266,6 +266,9 @@ void mh_global_sequences_drop (mu_mailbox_t mbox);
void mh_global_save_state (void);
int mh_private_sequences_iterate (mu_mailbox_t mbox, mu_mhprop_iterator_t fp,
void *data);
int mh_interactive_mode_p (void);
int mh_getyn (const char *fmt, ...) MU_PRINTFLIKE(1,2);
int mh_getyn_interactive (const char *fmt, ...) MU_PRINTFLIKE(1,2);
......
......@@ -67,6 +67,7 @@ struct format_closure
{
mu_stream_t stream;
mu_mailbox_t mailbox;
int delim;
};
static int
......@@ -87,8 +88,10 @@ format_sequence (void *item, void *data)
}
else
beg = r->msg_beg;
if (clos->delim)
mu_stream_write (clos->stream, " ", 1, NULL);
if (r->msg_beg == r->msg_end)
rc = mu_stream_printf (clos->stream, " %lu", (unsigned long) beg);
rc = mu_stream_printf (clos->stream, "%lu", (unsigned long) beg);
else
{
if (clos->mailbox)
......@@ -102,14 +105,15 @@ format_sequence (void *item, void *data)
else
end = r->msg_end;
if (beg + 1 == end)
rc = mu_stream_printf (clos->stream, " %lu %lu",
rc = mu_stream_printf (clos->stream, "%lu %lu",
(unsigned long) beg,
(unsigned long) end);
else
rc = mu_stream_printf (clos->stream, " %lu-%lu",
rc = mu_stream_printf (clos->stream, "%lu-%lu",
(unsigned long) beg,
(unsigned long) end);
}
clos->delim = 1;
return rc;
}
......@@ -136,6 +140,7 @@ save_sequence (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
}
clos.mailbox = mset->mbox;
clos.delim = 0;
rc = mu_list_foreach (list, format_sequence, &clos);
if (rc)
{
......@@ -184,3 +189,66 @@ mh_seq_delete (mu_mailbox_t mbox, const char *name,
return 0;
}
struct privseq_closure
{
const char *mbox_dir;
mu_mhprop_iterator_t fun;
void *data;
char *namebuf;
size_t namelen;
};
static int
privseq_handler (const char *name, const char *value, void *data)
{
struct privseq_closure *pclos = data;
if (strncmp (name, "atr-", 4) == 0)
{
char *p = strchr (name + 4, '-');
if (p && strcmp (p + 1, pclos->mbox_dir) == 0)
{
size_t len = p - name - 4;
if (pclos->namelen < len + 1)
{
pclos->namelen = len + 1;
pclos->namebuf = mu_realloc (pclos->namebuf, pclos->namelen);
}
memcpy (pclos->namebuf, name + 4, len);
pclos->namebuf[len] = 0;
}
return pclos->fun (pclos->namebuf, value, pclos->data);
}
return 0;
}
int
mh_private_sequences_iterate (mu_mailbox_t mbox,
mu_mhprop_iterator_t fp, void *data)
{
int rc;
struct privseq_closure clos;
mu_url_t url;
rc = mu_mailbox_get_url (mbox, &url);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_url", NULL, rc);
exit (1);
}
rc = mu_url_sget_path (url, &clos.mbox_dir);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_url_sget_path",
mu_url_to_string (url), rc);
exit (1);
}
clos.fun = fp;
clos.data = data;
clos.namebuf = NULL;
clos.namelen = 0;
rc = mu_mhprop_iterate (mu_mh_context, privseq_handler, &clos);
free (clos.namebuf);
return rc;
}
......
......@@ -58,6 +58,23 @@ rmm (size_t num, mu_message_t msg, void *data)
return 0;
}
struct seq_closure
{
mu_msgset_t rmset;
int rmflag;
};
static int
rmseq (const char *name, const char *value, void *data)
{
struct seq_closure *s = data;
mu_mailbox_t mbox;
mu_msgset_sget_mailbox (s->rmset, &mbox);
mh_seq_delete (mbox, name, s->rmset, s->rmflag);
return 0;
}
int
main (int argc, char **argv)
{
......@@ -65,7 +82,8 @@ main (int argc, char **argv)
mu_mailbox_t mbox;
mu_msgset_t msgset;
int status;
struct seq_closure clos;
/* Native Language Support */
MU_APP_INIT_NLS ();
......@@ -78,6 +96,12 @@ main (int argc, char **argv)
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
status = mu_msgset_foreach_message (msgset, rmm, NULL);
clos.rmset = msgset;
clos.rmflag = 0;
mh_global_sequences_iterate (mbox, rmseq, &clos);
clos.rmflag = SEQ_PRIVATE;
mh_private_sequences_iterate (mbox, rmseq, &clos);
mu_mailbox_expunge (mbox);
mu_mailbox_close (mbox);
......
......@@ -45,7 +45,6 @@ sed '/^$/d' Mail/inbox/.mh_sequences
[0],
[Mail/inbox/1
Mail/inbox/4
test: 2 3 5
cur: 1
])
......