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); ...@@ -43,6 +43,8 @@ int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int mode);
43 int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist); 43 int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist);
44 int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr); 44 int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr);
45 45
46 int mu_msgset_sget_mailbox (mu_msgset_t mset, mu_mailbox_t *mbox);
47
46 int mu_msgset_add_range (mu_msgset_t set, size_t beg, size_t end, int mode); 48 int mu_msgset_add_range (mu_msgset_t set, size_t beg, size_t end, int mode);
47 int mu_msgset_sub_range (mu_msgset_t set, size_t beg, size_t end, int mode); 49 int mu_msgset_sub_range (mu_msgset_t set, size_t beg, size_t end, int mode);
48 int mu_msgset_add (mu_msgset_t a, mu_msgset_t b); 50 int mu_msgset_add (mu_msgset_t a, mu_msgset_t b);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 20
21 #define _MU_MSGSET_AGGREGATED 0x10 21 #define _MU_MSGSET_AGGREGATED 0x10
22 #define _MU_MSGSET_USERFLAG_MASK 0x0f 22 #define _MU_MSGSET_USERFLAG_MASK 0x0f
23 #define _MU_MSGSET_MODE(c) ((c) & _MU_MSGSET_USERFLAG_MASK)
23 24
24 struct _mu_msgset 25 struct _mu_msgset
25 { 26 {
......
...@@ -26,6 +26,7 @@ libmsgset_la_SOURCES = \ ...@@ -26,6 +26,7 @@ libmsgset_la_SOURCES = \
26 count.c\ 26 count.c\
27 getitr.c\ 27 getitr.c\
28 getlist.c\ 28 getlist.c\
29 getmbox.c\
29 foreachnum.c\ 30 foreachnum.c\
30 foreachmsgno.c\ 31 foreachmsgno.c\
31 foreachuid.c\ 32 foreachuid.c\
......
...@@ -44,7 +44,7 @@ mu_msgset_add (mu_msgset_t a, mu_msgset_t b) ...@@ -44,7 +44,7 @@ mu_msgset_add (mu_msgset_t a, mu_msgset_t b)
44 return EINVAL; 44 return EINVAL;
45 if (!b) 45 if (!b)
46 return 0; 46 return 0;
47 closure.mode = b->flags; 47 closure.mode = _MU_MSGSET_MODE (b->flags);
48 closure.dest = a; 48 closure.dest = a;
49 return mu_list_foreach (b->list, add_range, &closure); 49 return mu_list_foreach (b->list, add_range, &closure);
50 } 50 }
......
...@@ -54,7 +54,7 @@ mu_msgset_create (mu_msgset_t *pres, mu_mailbox_t mbox, int flags) ...@@ -54,7 +54,7 @@ mu_msgset_create (mu_msgset_t *pres, mu_mailbox_t mbox, int flags)
54 mu_list_set_destroy_item (msgset->list, mu_list_free_item); 54 mu_list_set_destroy_item (msgset->list, mu_list_free_item);
55 mu_list_set_comparator (msgset->list, compare_msgnum); 55 mu_list_set_comparator (msgset->list, compare_msgnum);
56 msgset->mbox = mbox; 56 msgset->mbox = mbox;
57 msgset->flags = flags & _MU_MSGSET_USERFLAG_MASK; 57 msgset->flags = _MU_MSGSET_MODE (flags);
58 *pres = msgset; 58 *pres = msgset;
59 return 0; 59 return 0;
60 } 60 }
......
...@@ -38,7 +38,7 @@ call_action (struct action_closure *clos, size_t i) ...@@ -38,7 +38,7 @@ call_action (struct action_closure *clos, size_t i)
38 mu_message_t msg = NULL; 38 mu_message_t msg = NULL;
39 size_t n; 39 size_t n;
40 40
41 if (clos->msgset->flags == MU_MSGSET_UID) 41 if (_MU_MSGSET_MODE (clos->msgset->flags) == MU_MSGSET_UID)
42 { 42 {
43 rc = mu_mailbox_translate (clos->msgset->mbox, MU_MAILBOX_UID_TO_MSGNO, 43 rc = mu_mailbox_translate (clos->msgset->mbox, MU_MAILBOX_UID_TO_MSGNO,
44 i, &n); 44 i, &n);
......
...@@ -37,11 +37,11 @@ call_action (struct action_closure *clos, size_t i) ...@@ -37,11 +37,11 @@ call_action (struct action_closure *clos, size_t i)
37 size_t n; 37 size_t n;
38 int cmd; 38 int cmd;
39 39
40 if (clos->msgset->flags != (clos->flags & MU_MSGSET_MODE_MASK)) 40 if (_MU_MSGSET_MODE (clos->msgset->flags) != _MU_MSGSET_MODE (clos->flags))
41 { 41 {
42 int rc; 42 int rc;
43 43
44 switch (clos->flags & MU_MSGSET_MODE_MASK) 44 switch (_MU_MSGSET_MODE (clos->flags))
45 { 45 {
46 case MU_MSGSET_NUM: 46 case MU_MSGSET_NUM:
47 cmd = MU_MAILBOX_UID_TO_MSGNO; 47 cmd = MU_MAILBOX_UID_TO_MSGNO;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011-2013 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <mailutils/types.h>
19 #include <mailutils/errno.h>
20 #include <mailutils/msgset.h>
21 #include <mailutils/sys/msgset.h>
22
23 int
24 mu_msgset_sget_mailbox (mu_msgset_t mset, mu_mailbox_t *mbox)
25 {
26 if (!mset)
27 return EINVAL;
28 if (!mbox)
29 return MU_ERR_OUT_PTR_NULL;
30 *mbox = mset->mbox;
31 return 0;
32 }
...@@ -40,7 +40,7 @@ _invert_range (void *item, void *data) ...@@ -40,7 +40,7 @@ _invert_range (void *item, void *data)
40 { 40 {
41 rc = mu_msgset_add_range (clos->nset, 41 rc = mu_msgset_add_range (clos->nset,
42 clos->next_num, range->msg_beg - 1, 42 clos->next_num, range->msg_beg - 1,
43 clos->nset->flags); 43 _MU_MSGSET_MODE (clos->nset->flags));
44 if (rc) 44 if (rc)
45 return rc; 45 return rc;
46 } 46 }
...@@ -68,7 +68,7 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset) ...@@ -68,7 +68,7 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
68 rc = mu_mailbox_messages_count (msgset->mbox, &total); 68 rc = mu_mailbox_messages_count (msgset->mbox, &total);
69 if (rc) 69 if (rc)
70 return rc; 70 return rc;
71 if (msgset->flags == MU_MSGSET_UID) 71 if (_MU_MSGSET_MODE (msgset->flags))
72 { 72 {
73 rc = mu_mailbox_translate (msgset->mbox, 73 rc = mu_mailbox_translate (msgset->mbox,
74 MU_MAILBOX_MSGNO_TO_UID, 74 MU_MAILBOX_MSGNO_TO_UID,
...@@ -76,7 +76,8 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset) ...@@ -76,7 +76,8 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
76 if (rc) 76 if (rc)
77 return rc; 77 return rc;
78 } 78 }
79 rc = mu_msgset_create (&clos.nset, msgset->mbox, msgset->flags); 79 rc = mu_msgset_create (&clos.nset, msgset->mbox,
80 _MU_MSGSET_MODE (msgset->flags));
80 if (rc) 81 if (rc)
81 return rc; 82 return rc;
82 clos.next_num = 1; 83 clos.next_num = 1;
...@@ -85,7 +86,7 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset) ...@@ -85,7 +86,7 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
85 { 86 {
86 if (clos.next_num < total) 87 if (clos.next_num < total)
87 rc = mu_msgset_add_range (clos.nset, clos.next_num, total, 88 rc = mu_msgset_add_range (clos.nset, clos.next_num, total,
88 clos.nset->flags); 89 _MU_MSGSET_MODE (clos.nset->flags));
89 } 90 }
90 91
91 if (rc) 92 if (rc)
......
...@@ -44,7 +44,7 @@ mu_msgset_sub (mu_msgset_t a, mu_msgset_t b) ...@@ -44,7 +44,7 @@ mu_msgset_sub (mu_msgset_t a, mu_msgset_t b)
44 return EINVAL; 44 return EINVAL;
45 if (!b) 45 if (!b)
46 return 0; 46 return 0;
47 closure.mode = b->flags; 47 closure.mode = _MU_MSGSET_MODE (b->flags);
48 closure.dest = a; 48 closure.dest = a;
49 return mu_list_foreach (b->list, sub_range, &closure); 49 return mu_list_foreach (b->list, sub_range, &closure);
50 } 50 }
......
...@@ -27,14 +27,14 @@ int ...@@ -27,14 +27,14 @@ int
27 _mu_msgset_translate_pair (mu_msgset_t mset, int mode, 27 _mu_msgset_translate_pair (mu_msgset_t mset, int mode,
28 size_t *pbeg, size_t *pend) 28 size_t *pbeg, size_t *pend)
29 { 29 {
30 if (mode != mset->flags && mset->mbox) 30 if (mode != _MU_MSGSET_MODE (mset->flags) && mset->mbox)
31 { 31 {
32 int cmd, rc; 32 int cmd, rc;
33 size_t n; 33 size_t n;
34 size_t beg = *pbeg; 34 size_t beg = *pbeg;
35 size_t end = *pend; 35 size_t end = *pend;
36 36
37 switch (mset->flags) 37 switch (_MU_MSGSET_MODE (mset->flags))
38 { 38 {
39 case MU_MSGSET_NUM: 39 case MU_MSGSET_NUM:
40 cmd = MU_MAILBOX_UID_TO_MSGNO; 40 cmd = MU_MAILBOX_UID_TO_MSGNO;
......
...@@ -266,6 +266,9 @@ void mh_global_sequences_drop (mu_mailbox_t mbox); ...@@ -266,6 +266,9 @@ void mh_global_sequences_drop (mu_mailbox_t mbox);
266 266
267 void mh_global_save_state (void); 267 void mh_global_save_state (void);
268 268
269 int mh_private_sequences_iterate (mu_mailbox_t mbox, mu_mhprop_iterator_t fp,
270 void *data);
271
269 int mh_interactive_mode_p (void); 272 int mh_interactive_mode_p (void);
270 int mh_getyn (const char *fmt, ...) MU_PRINTFLIKE(1,2); 273 int mh_getyn (const char *fmt, ...) MU_PRINTFLIKE(1,2);
271 int mh_getyn_interactive (const char *fmt, ...) MU_PRINTFLIKE(1,2); 274 int mh_getyn_interactive (const char *fmt, ...) MU_PRINTFLIKE(1,2);
......
...@@ -67,6 +67,7 @@ struct format_closure ...@@ -67,6 +67,7 @@ struct format_closure
67 { 67 {
68 mu_stream_t stream; 68 mu_stream_t stream;
69 mu_mailbox_t mailbox; 69 mu_mailbox_t mailbox;
70 int delim;
70 }; 71 };
71 72
72 static int 73 static int
...@@ -87,8 +88,10 @@ format_sequence (void *item, void *data) ...@@ -87,8 +88,10 @@ format_sequence (void *item, void *data)
87 } 88 }
88 else 89 else
89 beg = r->msg_beg; 90 beg = r->msg_beg;
91 if (clos->delim)
92 mu_stream_write (clos->stream, " ", 1, NULL);
90 if (r->msg_beg == r->msg_end) 93 if (r->msg_beg == r->msg_end)
91 rc = mu_stream_printf (clos->stream, " %lu", (unsigned long) beg); 94 rc = mu_stream_printf (clos->stream, "%lu", (unsigned long) beg);
92 else 95 else
93 { 96 {
94 if (clos->mailbox) 97 if (clos->mailbox)
...@@ -102,14 +105,15 @@ format_sequence (void *item, void *data) ...@@ -102,14 +105,15 @@ format_sequence (void *item, void *data)
102 else 105 else
103 end = r->msg_end; 106 end = r->msg_end;
104 if (beg + 1 == end) 107 if (beg + 1 == end)
105 rc = mu_stream_printf (clos->stream, " %lu %lu", 108 rc = mu_stream_printf (clos->stream, "%lu %lu",
106 (unsigned long) beg, 109 (unsigned long) beg,
107 (unsigned long) end); 110 (unsigned long) end);
108 else 111 else
109 rc = mu_stream_printf (clos->stream, " %lu-%lu", 112 rc = mu_stream_printf (clos->stream, "%lu-%lu",
110 (unsigned long) beg, 113 (unsigned long) beg,
111 (unsigned long) end); 114 (unsigned long) end);
112 } 115 }
116 clos->delim = 1;
113 return rc; 117 return rc;
114 } 118 }
115 119
...@@ -136,6 +140,7 @@ save_sequence (mu_mailbox_t mbox, const char *name, mu_msgset_t mset, ...@@ -136,6 +140,7 @@ save_sequence (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
136 } 140 }
137 141
138 clos.mailbox = mset->mbox; 142 clos.mailbox = mset->mbox;
143 clos.delim = 0;
139 rc = mu_list_foreach (list, format_sequence, &clos); 144 rc = mu_list_foreach (list, format_sequence, &clos);
140 if (rc) 145 if (rc)
141 { 146 {
...@@ -184,3 +189,66 @@ mh_seq_delete (mu_mailbox_t mbox, const char *name, ...@@ -184,3 +189,66 @@ mh_seq_delete (mu_mailbox_t mbox, const char *name,
184 return 0; 189 return 0;
185 } 190 }
186 191
192 struct privseq_closure
193 {
194 const char *mbox_dir;
195 mu_mhprop_iterator_t fun;
196 void *data;
197 char *namebuf;
198 size_t namelen;
199 };
200
201 static int
202 privseq_handler (const char *name, const char *value, void *data)
203 {
204 struct privseq_closure *pclos = data;
205
206 if (strncmp (name, "atr-", 4) == 0)
207 {
208 char *p = strchr (name + 4, '-');
209 if (p && strcmp (p + 1, pclos->mbox_dir) == 0)
210 {
211 size_t len = p - name - 4;
212 if (pclos->namelen < len + 1)
213 {
214 pclos->namelen = len + 1;
215 pclos->namebuf = mu_realloc (pclos->namebuf, pclos->namelen);
216 }
217 memcpy (pclos->namebuf, name + 4, len);
218 pclos->namebuf[len] = 0;
219 }
220 return pclos->fun (pclos->namebuf, value, pclos->data);
221 }
222 return 0;
223 }
224
225 int
226 mh_private_sequences_iterate (mu_mailbox_t mbox,
227 mu_mhprop_iterator_t fp, void *data)
228 {
229 int rc;
230 struct privseq_closure clos;
231 mu_url_t url;
232
233 rc = mu_mailbox_get_url (mbox, &url);
234 if (rc)
235 {
236 mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_url", NULL, rc);
237 exit (1);
238 }
239 rc = mu_url_sget_path (url, &clos.mbox_dir);
240 if (rc)
241 {
242 mu_diag_funcall (MU_DIAG_ERROR, "mu_url_sget_path",
243 mu_url_to_string (url), rc);
244 exit (1);
245 }
246
247 clos.fun = fp;
248 clos.data = data;
249 clos.namebuf = NULL;
250 clos.namelen = 0;
251 rc = mu_mhprop_iterate (mu_mh_context, privseq_handler, &clos);
252 free (clos.namebuf);
253 return rc;
254 }
......
...@@ -58,6 +58,23 @@ rmm (size_t num, mu_message_t msg, void *data) ...@@ -58,6 +58,23 @@ rmm (size_t num, mu_message_t msg, void *data)
58 return 0; 58 return 0;
59 } 59 }
60 60
61 struct seq_closure
62 {
63 mu_msgset_t rmset;
64 int rmflag;
65 };
66
67 static int
68 rmseq (const char *name, const char *value, void *data)
69 {
70 struct seq_closure *s = data;
71 mu_mailbox_t mbox;
72
73 mu_msgset_sget_mailbox (s->rmset, &mbox);
74 mh_seq_delete (mbox, name, s->rmset, s->rmflag);
75 return 0;
76 }
77
61 int 78 int
62 main (int argc, char **argv) 79 main (int argc, char **argv)
63 { 80 {
...@@ -65,6 +82,7 @@ main (int argc, char **argv) ...@@ -65,6 +82,7 @@ main (int argc, char **argv)
65 mu_mailbox_t mbox; 82 mu_mailbox_t mbox;
66 mu_msgset_t msgset; 83 mu_msgset_t msgset;
67 int status; 84 int status;
85 struct seq_closure clos;
68 86
69 /* Native Language Support */ 87 /* Native Language Support */
70 MU_APP_INIT_NLS (); 88 MU_APP_INIT_NLS ();
...@@ -79,6 +97,12 @@ main (int argc, char **argv) ...@@ -79,6 +97,12 @@ main (int argc, char **argv)
79 97
80 status = mu_msgset_foreach_message (msgset, rmm, NULL); 98 status = mu_msgset_foreach_message (msgset, rmm, NULL);
81 99
100 clos.rmset = msgset;
101 clos.rmflag = 0;
102 mh_global_sequences_iterate (mbox, rmseq, &clos);
103 clos.rmflag = SEQ_PRIVATE;
104 mh_private_sequences_iterate (mbox, rmseq, &clos);
105
82 mu_mailbox_expunge (mbox); 106 mu_mailbox_expunge (mbox);
83 mu_mailbox_close (mbox); 107 mu_mailbox_close (mbox);
84 mu_mailbox_destroy (&mbox); 108 mu_mailbox_destroy (&mbox);
......
...@@ -45,7 +45,6 @@ sed '/^$/d' Mail/inbox/.mh_sequences ...@@ -45,7 +45,6 @@ sed '/^$/d' Mail/inbox/.mh_sequences
45 [0], 45 [0],
46 [Mail/inbox/1 46 [Mail/inbox/1
47 Mail/inbox/4 47 Mail/inbox/4
48 test: 2 3 5
49 cur: 1 48 cur: 1
50 ]) 49 ])
51 50
......