API for formatting message sets on output
* libmailutils/msgset/print.c (mu_msgset_formats): New global. (mu_stream_msgset_format): New function. * include/mailutils/msgset.h (mu_msgset_format): New struct. (mu_msgset_fmt_imap, mu_msgset_fmt_mh): New defines. (MU_MSGSET_IGNORE_TRANSERR): New flag (mu_msgset_copy, mu_msgset_translate): New protos. (mu_stream_msgset_format, mu_msgset_imap_print): New protos. (mu_msgset_print): Deprecate. * libmailutils/imapio/sendmsgset.c: Use mu_msgset_imap_print instead of mu_msgset_print. * mu/libexec/imap.c: Likewise. * libmailutils/msgset/Makefile.am: Add copy.c * libmailutils/msgset/add.c (mu_msgset_add_range): Translate if message set mode doesn't match the requested one. * libmailutils/msgset/sub.c (mu_msgset_sub_range): Likewise. * libmailutils/msgset/trans.c (_mu_msgset_translate_pair): Act according to the mode argument. (mu_msgset_translate): New function. * libmailutils/tests/msgset.c: New option -mh * mh/mh_sequence.c (write_sequence): Rewrite. * testsuite/msgset.c: Optionally translate uids to msgnums and vice-versa.
Showing
14 changed files
with
213 additions
and
98 deletions
... | @@ -30,6 +30,25 @@ struct mu_msgrange | ... | @@ -30,6 +30,25 @@ struct mu_msgrange |
30 | size_t msg_end; | 30 | size_t msg_end; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | struct mu_msgset_format | ||
34 | { | ||
35 | char *range; /* range separator (e.g., ":" for IMAP, "-" for MH) */ | ||
36 | char *delim; /* delimiter (e.g., "," for IMAP, " " for MH) */ | ||
37 | char *last; /* last message marker (e.g., "*" for IMAP, "last" for MH) */ | ||
38 | char *empty; /* empty list representation ( "NIL", for IMAP, NULL for MH */ | ||
39 | }; | ||
40 | |||
41 | enum | ||
42 | { | ||
43 | MU_MSGSET_FMT_IMAP, | ||
44 | MU_MSGSET_FMT_MH | ||
45 | }; | ||
46 | |||
47 | extern struct mu_msgset_format const mu_msgset_formats[]; | ||
48 | typedef struct mu_msgset_format const *mu_msgset_format_t; | ||
49 | #define mu_msgset_fmt_imap (&mu_msgset_formats[MU_MSGSET_FMT_IMAP]) | ||
50 | #define mu_msgset_fmt_mh (&mu_msgset_formats[MU_MSGSET_FMT_MH]) | ||
51 | |||
33 | /* Message numbers start with 1. MU_MSGNO_LAST denotes the last | 52 | /* Message numbers start with 1. MU_MSGNO_LAST denotes the last |
34 | message. */ | 53 | message. */ |
35 | #define MU_MSGNO_LAST 0 | 54 | #define MU_MSGNO_LAST 0 |
... | @@ -37,9 +56,15 @@ struct mu_msgrange | ... | @@ -37,9 +56,15 @@ struct mu_msgrange |
37 | #define MU_MSGSET_NUM 0 /* Message set operates on sequence numbers */ | 56 | #define MU_MSGSET_NUM 0 /* Message set operates on sequence numbers */ |
38 | #define MU_MSGSET_UID 1 /* Message set operates on UIDs */ | 57 | #define MU_MSGSET_UID 1 /* Message set operates on UIDs */ |
39 | 58 | ||
59 | #define MU_MSGSET_IGNORE_TRANSERR 0x10 | ||
60 | |||
40 | #define MU_MSGSET_MODE_MASK 0x0f | 61 | #define MU_MSGSET_MODE_MASK 0x0f |
41 | 62 | ||
42 | int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int mode); | 63 | int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int mode); |
64 | |||
65 | int mu_msgset_copy (mu_msgset_t src, mu_msgset_t dst); | ||
66 | int mu_msgset_translate (mu_msgset_t *dst, mu_msgset_t src, int flags); | ||
67 | |||
43 | int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist); | 68 | 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); | 69 | int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr); |
45 | 70 | ||
... | @@ -54,9 +79,21 @@ int mu_msgset_clear (mu_msgset_t set); | ... | @@ -54,9 +79,21 @@ int mu_msgset_clear (mu_msgset_t set); |
54 | void mu_msgset_free (mu_msgset_t set); | 79 | void mu_msgset_free (mu_msgset_t set); |
55 | void mu_msgset_destroy (mu_msgset_t *set); | 80 | void mu_msgset_destroy (mu_msgset_t *set); |
56 | 81 | ||
57 | int mu_msgset_parse_imap (mu_msgset_t set, int mode, const char *s, char **end); | 82 | int mu_msgset_parse_imap (mu_msgset_t set, int mode, const char *s, |
83 | char **end); | ||
84 | |||
85 | int mu_stream_msgset_format (mu_stream_t str, | ||
86 | struct mu_msgset_format const *fmt, | ||
87 | mu_msgset_t mset); | ||
88 | int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset) | ||
89 | MU_DEPRECATED; | ||
90 | |||
91 | static inline int | ||
92 | mu_msgset_imap_print (mu_stream_t str, mu_msgset_t mset) | ||
93 | { | ||
94 | return mu_stream_msgset_format (str, mu_msgset_fmt_imap, mset); | ||
95 | } | ||
58 | 96 | ||
59 | int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset); | ||
60 | 97 | ||
61 | int mu_msgset_locate (mu_msgset_t msgset, size_t n, | 98 | int mu_msgset_locate (mu_msgset_t msgset, size_t n, |
62 | struct mu_msgrange const **prange); | 99 | struct mu_msgrange const **prange); | ... | ... |
... | @@ -27,6 +27,7 @@ struct _mu_msgset | ... | @@ -27,6 +27,7 @@ struct _mu_msgset |
27 | mu_list_t list; /* List of mu_msgrange structures */ | 27 | mu_list_t list; /* List of mu_msgrange structures */ |
28 | mu_mailbox_t mbox; /* Associated mailbox */ | 28 | mu_mailbox_t mbox; /* Associated mailbox */ |
29 | int flags; /* Message set flags */ | 29 | int flags; /* Message set flags */ |
30 | size_t format; /* Format index */ | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | int _mu_msgset_translate_pair (mu_msgset_t mset, int mode, | 33 | int _mu_msgset_translate_pair (mu_msgset_t mset, int mode, | ... | ... |
... | @@ -25,5 +25,5 @@ | ... | @@ -25,5 +25,5 @@ |
25 | int | 25 | int |
26 | mu_imapio_send_msgset (mu_imapio_t io, mu_msgset_t msgset) | 26 | mu_imapio_send_msgset (mu_imapio_t io, mu_msgset_t msgset) |
27 | { | 27 | { |
28 | return mu_msgset_print (io->_imap_stream, msgset); | 28 | return mu_msgset_imap_print (io->_imap_stream, msgset); |
29 | } | 29 | } | ... | ... |
... | @@ -41,12 +41,16 @@ mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end, int mode) | ... | @@ -41,12 +41,16 @@ mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end, int mode) |
41 | return ENOMEM; | 41 | return ENOMEM; |
42 | range->msg_beg = beg; | 42 | range->msg_beg = beg; |
43 | range->msg_end = end; | 43 | range->msg_end = end; |
44 | rc = _mu_msgset_translate_range (mset, mode, range); | 44 | if (mode != _MU_MSGSET_MODE (mset->flags)) |
45 | { | ||
46 | rc = _mu_msgset_translate_range (mset, _MU_MSGSET_MODE (mset->flags), | ||
47 | range); | ||
45 | if (rc) | 48 | if (rc) |
46 | { | 49 | { |
47 | free (range); | 50 | free (range); |
48 | return rc; | 51 | return rc; |
49 | } | 52 | } |
53 | } | ||
50 | rc = mu_list_append (mset->list, range); | 54 | rc = mu_list_append (mset->list, range); |
51 | if (rc) | 55 | if (rc) |
52 | free (range); | 56 | free (range); | ... | ... |
... | @@ -24,10 +24,26 @@ | ... | @@ -24,10 +24,26 @@ |
24 | #include <mailutils/msgset.h> | 24 | #include <mailutils/msgset.h> |
25 | #include <mailutils/sys/msgset.h> | 25 | #include <mailutils/sys/msgset.h> |
26 | 26 | ||
27 | struct mu_msgset_format const mu_msgset_formats[] = { | ||
28 | [MU_MSGSET_FMT_IMAP] = { | ||
29 | .delim = ",", | ||
30 | .range = ":", | ||
31 | .last = "*", | ||
32 | .empty = "NIL" | ||
33 | }, | ||
34 | [MU_MSGSET_FMT_MH] = { | ||
35 | .delim = " ", | ||
36 | .range = "-", | ||
37 | .last = "last" | ||
38 | } | ||
39 | }; | ||
40 | |||
41 | |||
27 | struct print_env | 42 | struct print_env |
28 | { | 43 | { |
29 | mu_stream_t stream; | 44 | mu_stream_t stream; |
30 | int cont; | 45 | int cont; |
46 | struct mu_msgset_format const *fmt; | ||
31 | }; | 47 | }; |
32 | 48 | ||
33 | static int | 49 | static int |
... | @@ -39,36 +55,59 @@ _msgrange_printer (void *item, void *data) | ... | @@ -39,36 +55,59 @@ _msgrange_printer (void *item, void *data) |
39 | 55 | ||
40 | if (env->cont) | 56 | if (env->cont) |
41 | { | 57 | { |
42 | rc = mu_stream_write (env->stream, ",", 1, NULL); | 58 | rc = mu_stream_printf (env->stream, "%s", env->fmt->delim); |
43 | if (rc) | 59 | if (rc) |
44 | return rc; | 60 | return rc; |
45 | } | 61 | } |
46 | else | 62 | else |
47 | env->cont = 1; | 63 | env->cont = 1; |
64 | |||
48 | if (range->msg_beg == range->msg_end) | 65 | if (range->msg_beg == range->msg_end) |
49 | rc = mu_stream_printf (env->stream, "%lu", (unsigned long) range->msg_beg); | 66 | rc = mu_stream_printf (env->stream, "%lu", (unsigned long) range->msg_beg); |
50 | else if (range->msg_end == 0) | 67 | else if (range->msg_end == 0) |
51 | rc = mu_stream_printf (env->stream, "%lu:*", | 68 | rc = mu_stream_printf (env->stream, "%lu%s%s", |
52 | (unsigned long) range->msg_beg); | 69 | (unsigned long) range->msg_beg, |
70 | env->fmt->range, | ||
71 | env->fmt->last); | ||
72 | else if (range->msg_end == range->msg_beg + 1) | ||
73 | rc = mu_stream_printf (env->stream, "%lu%s%lu", | ||
74 | (unsigned long) range->msg_beg, | ||
75 | env->fmt->delim, | ||
76 | (unsigned long) range->msg_end); | ||
53 | else | 77 | else |
54 | rc = mu_stream_printf (env->stream, "%lu:%lu", | 78 | rc = mu_stream_printf (env->stream, "%lu%s%lu", |
55 | (unsigned long) range->msg_beg, | 79 | (unsigned long) range->msg_beg, |
80 | env->fmt->range, | ||
56 | (unsigned long) range->msg_end); | 81 | (unsigned long) range->msg_end); |
57 | return rc; | 82 | return rc; |
58 | } | 83 | } |
59 | 84 | ||
60 | int | 85 | int |
61 | mu_msgset_print (mu_stream_t str, mu_msgset_t mset) | 86 | mu_stream_msgset_format (mu_stream_t str, struct mu_msgset_format const *fmt, |
87 | mu_msgset_t mset) | ||
62 | { | 88 | { |
63 | struct print_env env; | 89 | struct print_env env; |
64 | int rc; | 90 | int rc; |
65 | 91 | ||
92 | env.stream = str; | ||
93 | env.cont = 0; | ||
94 | env.fmt = fmt; | ||
95 | |||
66 | if (mu_list_is_empty (mset->list)) | 96 | if (mu_list_is_empty (mset->list)) |
67 | return mu_stream_printf (str, "%s", "nil"); | 97 | { |
98 | if (env.fmt->empty) | ||
99 | return mu_stream_printf (str, "%s", env.fmt->empty); | ||
100 | return 0; | ||
101 | } | ||
68 | rc = mu_msgset_aggregate (mset); | 102 | rc = mu_msgset_aggregate (mset); |
69 | if (rc) | 103 | if (rc) |
70 | return rc; | 104 | return rc; |
71 | env.stream = str; | ||
72 | env.cont = 0; | ||
73 | return mu_list_foreach (mset->list, _msgrange_printer, &env); | 105 | return mu_list_foreach (mset->list, _msgrange_printer, &env); |
74 | } | 106 | } |
107 | |||
108 | int | ||
109 | mu_msgset_print (mu_stream_t str, mu_msgset_t mset) | ||
110 | { | ||
111 | return mu_stream_msgset_format (str, mu_msgset_fmt_imap, mset); | ||
112 | } | ||
113 | ... | ... |
... | @@ -129,11 +129,15 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end, int mode) | ... | @@ -129,11 +129,15 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end, int mode) |
129 | beg = t; | 129 | beg = t; |
130 | } | 130 | } |
131 | 131 | ||
132 | rc = _mu_msgset_translate_pair (mset, mode, &beg, &end); | 132 | if (mode != _MU_MSGSET_MODE (mset->flags)) |
133 | { | ||
134 | rc = _mu_msgset_translate_pair (mset, _MU_MSGSET_MODE (mset->flags), | ||
135 | &beg, &end); | ||
133 | if (rc == MU_ERR_NOENT) | 136 | if (rc == MU_ERR_NOENT) |
134 | return 0; | 137 | return 0; |
135 | else if (rc) | 138 | else if (rc) |
136 | return rc; | 139 | return rc; |
140 | } | ||
137 | 141 | ||
138 | rc = mu_msgset_aggregate (mset); | 142 | rc = mu_msgset_aggregate (mset); |
139 | if (rc) | 143 | if (rc) | ... | ... |
... | @@ -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 != _MU_MSGSET_MODE (mset->flags) && mset->mbox) | 30 | if (mset->mbox) |
31 | { | 31 | { |
32 | int cmd, rc; | 32 | int cmd, rc; |
33 | size_t n = 1; | 33 | size_t n = 1; |
34 | size_t beg = *pbeg; | 34 | size_t beg = *pbeg; |
35 | size_t end = *pend; | 35 | size_t end = *pend; |
36 | 36 | ||
37 | switch (_MU_MSGSET_MODE (mset->flags)) | 37 | switch (mode) |
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; |
... | @@ -97,3 +97,74 @@ _mu_msgset_translate_range (mu_msgset_t mset, int mode, struct mu_msgrange *r) | ... | @@ -97,3 +97,74 @@ _mu_msgset_translate_range (mu_msgset_t mset, int mode, struct mu_msgrange *r) |
97 | return _mu_msgset_translate_pair (mset, mode, &r->msg_beg, &r->msg_end); | 97 | return _mu_msgset_translate_pair (mset, mode, &r->msg_beg, &r->msg_end); |
98 | } | 98 | } |
99 | 99 | ||
100 | struct trans_closure | ||
101 | { | ||
102 | mu_msgset_t mset; | ||
103 | int flags; | ||
104 | }; | ||
105 | |||
106 | static int | ||
107 | trans_range (void *item, void *data) | ||
108 | { | ||
109 | struct mu_msgrange const *range = item; | ||
110 | struct trans_closure *clos = data; | ||
111 | struct mu_msgrange *copy; | ||
112 | int rc; | ||
113 | |||
114 | copy = malloc (sizeof *copy); | ||
115 | if (!copy) | ||
116 | return errno; | ||
117 | *copy = *range; | ||
118 | rc = _mu_msgset_translate_range (clos->mset, _MU_MSGSET_MODE (clos->flags), | ||
119 | copy); | ||
120 | switch (rc) | ||
121 | { | ||
122 | case 0: | ||
123 | rc = mu_list_append (clos->mset->list, copy); | ||
124 | break; | ||
125 | |||
126 | case MU_ERR_NOENT: | ||
127 | if (clos->flags & MU_MSGSET_IGNORE_TRANSERR) | ||
128 | rc = 0; | ||
129 | /* fallthrough */ | ||
130 | |||
131 | default: | ||
132 | free (copy); | ||
133 | } | ||
134 | |||
135 | return rc; | ||
136 | } | ||
137 | |||
138 | int | ||
139 | mu_msgset_translate (mu_msgset_t *dst, mu_msgset_t src, int flags) | ||
140 | { | ||
141 | int rc; | ||
142 | mu_msgset_t tmp; | ||
143 | |||
144 | rc = mu_msgset_create (&tmp, src->mbox, src->flags); | ||
145 | if (rc) | ||
146 | return rc; | ||
147 | |||
148 | tmp->format = src->format; | ||
149 | |||
150 | if (_MU_MSGSET_MODE (flags) == src->flags) | ||
151 | { | ||
152 | rc = mu_msgset_copy (src, tmp); | ||
153 | } | ||
154 | else | ||
155 | { | ||
156 | struct trans_closure tc; | ||
157 | tc.mset = tmp; | ||
158 | tc.flags = flags; | ||
159 | rc = mu_list_foreach (src->list, trans_range, &tc); | ||
160 | } | ||
161 | |||
162 | if (rc) | ||
163 | mu_msgset_destroy (&tmp); | ||
164 | else | ||
165 | *dst = tmp; | ||
166 | |||
167 | return rc; | ||
168 | } | ||
169 | |||
170 | ... | ... |
... | @@ -18,6 +18,8 @@ | ... | @@ -18,6 +18,8 @@ |
18 | #include <stdlib.h> | 18 | #include <stdlib.h> |
19 | #include <mailutils/mailutils.h> | 19 | #include <mailutils/mailutils.h> |
20 | 20 | ||
21 | mu_msgset_format_t format = mu_msgset_fmt_imap; | ||
22 | |||
21 | static void | 23 | static void |
22 | parse_msgrange (char *arg, struct mu_msgrange *range) | 24 | parse_msgrange (char *arg, struct mu_msgrange *range) |
23 | { | 25 | { |
... | @@ -76,7 +78,7 @@ parse_msgset (const char *arg) | ... | @@ -76,7 +78,7 @@ parse_msgset (const char *arg) |
76 | static void | 78 | static void |
77 | print_all (mu_msgset_t msgset) | 79 | print_all (mu_msgset_t msgset) |
78 | { | 80 | { |
79 | MU_ASSERT (mu_msgset_print (mu_strout, msgset)); | 81 | MU_ASSERT (mu_stream_msgset_format (mu_strout, format, msgset)); |
80 | mu_printf ("\n"); | 82 | mu_printf ("\n"); |
81 | } | 83 | } |
82 | 84 | ||
... | @@ -111,13 +113,15 @@ main (int argc, char **argv) | ... | @@ -111,13 +113,15 @@ main (int argc, char **argv) |
111 | 113 | ||
112 | if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0) | 114 | if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0) |
113 | { | 115 | { |
114 | mu_printf ("usage: %s [-msgset=SET] [-add=X[:Y]] [-del=X[:Y]] " | 116 | mu_printf ("usage: %s [-mh] [-msgset=SET] [-add=X[:Y]] [-del=X[:Y]] " |
115 | "[-addset=SET] [-delset=SET] [-first] [-last]...\n", | 117 | "[-addset=SET] [-delset=SET] [-first] [-last] ...\n", |
116 | mu_program_name); | 118 | mu_program_name); |
117 | return 0; | 119 | return 0; |
118 | } | 120 | } |
119 | else if (strncmp (arg, "-msgset=", 8) == 0) | 121 | else if (strncmp (arg, "-msgset=", 8) == 0) |
120 | msgset_string = arg + 8; | 122 | msgset_string = arg + 8; |
123 | else if (strcmp (arg, "-mh") == 0) | ||
124 | format = mu_msgset_fmt_mh; | ||
121 | else | 125 | else |
122 | break; | 126 | break; |
123 | } | 127 | } | ... | ... |
... | @@ -440,9 +440,7 @@ main (int argc, char **argv) | ... | @@ -440,9 +440,7 @@ main (int argc, char **argv) |
440 | 440 | ||
441 | mu_msgset_create (&unseen, NULL, MU_MSGSET_NUM); | 441 | mu_msgset_create (&unseen, NULL, MU_MSGSET_NUM); |
442 | mu_msgset_add_range (unseen, lastseen, incdat.lastmsg, MU_MSGSET_NUM); | 442 | mu_msgset_add_range (unseen, lastseen, incdat.lastmsg, MU_MSGSET_NUM); |
443 | mh_seq_add (incdat.output, | 443 | mh_seq_add (incdat.output, unseen_seq, unseen, 0); |
444 | unseen_seq, | ||
445 | unseen, 0); | ||
446 | mu_msgset_free (unseen); | 444 | mu_msgset_free (unseen); |
447 | } | 445 | } |
448 | 446 | ... | ... |
... | @@ -119,6 +119,7 @@ msgset_parser_init (struct msgset_parser *parser, mu_mailbox_t mbox, | ... | @@ -119,6 +119,7 @@ msgset_parser_init (struct msgset_parser *parser, mu_mailbox_t mbox, |
119 | mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, rc); | 119 | mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, rc); |
120 | exit (1); | 120 | exit (1); |
121 | } | 121 | } |
122 | |||
122 | parser->argc = argc; | 123 | parser->argc = argc; |
123 | parser->argv = argv; | 124 | parser->argv = argv; |
124 | parser->curp = ""; | 125 | parser->curp = ""; | ... | ... |
... | @@ -47,6 +47,8 @@ mh_seq_read (mu_mailbox_t mbox, const char *name, int flags) | ... | @@ -47,6 +47,8 @@ mh_seq_read (mu_mailbox_t mbox, const char *name, int flags) |
47 | static void | 47 | static void |
48 | write_sequence (mu_mailbox_t mbox, const char *name, char *value, int private) | 48 | write_sequence (mu_mailbox_t mbox, const char *name, char *value, int private) |
49 | { | 49 | { |
50 | if (value && value[0] == 0) | ||
51 | value = NULL; | ||
50 | if (private) | 52 | if (private) |
51 | { | 53 | { |
52 | char *p = private_sequence_name (name); | 54 | char *p = private_sequence_name (name); |
... | @@ -63,96 +65,35 @@ delete_sequence (mu_mailbox_t mbox, const char *name, int private) | ... | @@ -63,96 +65,35 @@ delete_sequence (mu_mailbox_t mbox, const char *name, int private) |
63 | write_sequence (mbox, name, NULL, private); | 65 | write_sequence (mbox, name, NULL, private); |
64 | } | 66 | } |
65 | 67 | ||
66 | struct format_closure | ||
67 | { | ||
68 | mu_stream_t stream; | ||
69 | mu_mailbox_t mailbox; | ||
70 | int delim; | ||
71 | }; | ||
72 | |||
73 | static int | ||
74 | format_sequence (void *item, void *data) | ||
75 | { | ||
76 | struct mu_msgrange *r = item; | ||
77 | struct format_closure *clos = data; | ||
78 | int rc; | ||
79 | size_t beg, end; | ||
80 | |||
81 | if (clos->mailbox) | ||
82 | { | ||
83 | rc = mu_mailbox_translate (clos->mailbox, | ||
84 | MU_MAILBOX_MSGNO_TO_UID, | ||
85 | r->msg_beg, &beg); | ||
86 | if (rc) | ||
87 | return rc; | ||
88 | } | ||
89 | else | ||
90 | beg = r->msg_beg; | ||
91 | if (clos->delim) | ||
92 | mu_stream_write (clos->stream, " ", 1, NULL); | ||
93 | if (r->msg_beg == r->msg_end) | ||
94 | rc = mu_stream_printf (clos->stream, "%lu", (unsigned long) beg); | ||
95 | else | ||
96 | { | ||
97 | if (clos->mailbox) | ||
98 | { | ||
99 | rc = mu_mailbox_translate (clos->mailbox, | ||
100 | MU_MAILBOX_MSGNO_TO_UID, | ||
101 | r->msg_end, &end); | ||
102 | if (rc) | ||
103 | return rc; | ||
104 | } | ||
105 | else | ||
106 | end = r->msg_end; | ||
107 | if (beg + 1 == end) | ||
108 | rc = mu_stream_printf (clos->stream, "%lu %lu", | ||
109 | (unsigned long) beg, | ||
110 | (unsigned long) end); | ||
111 | else | ||
112 | rc = mu_stream_printf (clos->stream, "%lu-%lu", | ||
113 | (unsigned long) beg, | ||
114 | (unsigned long) end); | ||
115 | } | ||
116 | clos->delim = 1; | ||
117 | return rc; | ||
118 | } | ||
119 | |||
120 | static void | 68 | static void |
121 | save_sequence (mu_mailbox_t mbox, const char *name, mu_msgset_t mset, | 69 | save_sequence (mu_mailbox_t mbox, const char *name, mu_msgset_t mset, |
122 | int flags) | 70 | int flags) |
123 | { | 71 | { |
124 | mu_list_t list; | ||
125 | |||
126 | mu_msgset_get_list (mset, &list); | ||
127 | if (mu_list_is_empty (list)) | ||
128 | write_sequence (mset->mbox, name, NULL, flags & SEQ_PRIVATE); | ||
129 | else | ||
130 | { | ||
131 | struct format_closure clos; | ||
132 | int rc; | 72 | int rc; |
73 | mu_stream_t mstr; | ||
74 | mu_msgset_t outset; | ||
133 | mu_transport_t trans[2]; | 75 | mu_transport_t trans[2]; |
134 | 76 | ||
135 | rc = mu_memory_stream_create (&clos.stream, MU_STREAM_RDWR); | 77 | rc = mu_msgset_translate (&outset, mset, |
78 | MU_MSGSET_UID|MU_MSGSET_IGNORE_TRANSERR); | ||
136 | if (rc) | 79 | if (rc) |
137 | { | 80 | { |
138 | mu_diag_funcall (MU_DIAG_ERROR, "mu_memory_stream_create", NULL, rc); | 81 | mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_translate", NULL, rc); |
139 | exit (1); | 82 | exit (1); |
140 | } | 83 | } |
141 | 84 | ||
142 | clos.mailbox = mset->mbox; | 85 | rc = mu_memory_stream_create (&mstr, MU_STREAM_RDWR); |
143 | clos.delim = 0; | ||
144 | rc = mu_list_foreach (list, format_sequence, &clos); | ||
145 | if (rc) | 86 | if (rc) |
146 | { | 87 | { |
147 | mu_diag_funcall (MU_DIAG_ERROR, "mu_list_foreach", NULL, rc); | 88 | mu_diag_funcall (MU_DIAG_ERROR, "mu_memory_stream_create", NULL, rc); |
148 | exit (1); | 89 | exit (1); |
149 | } | 90 | } |
150 | mu_stream_write (clos.stream, "", 1, NULL); | 91 | mu_stream_msgset_format (mstr, mu_msgset_fmt_mh, outset); |
151 | mu_stream_ioctl (clos.stream, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, | 92 | mu_stream_write (mstr, "", 1, NULL); |
152 | trans); | 93 | mu_stream_ioctl (mstr, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans); |
153 | write_sequence (mbox, name, (char*)trans[0], flags & SEQ_PRIVATE); | 94 | write_sequence (mbox, name, (char*)trans[0], flags & SEQ_PRIVATE); |
154 | mu_stream_unref (clos.stream); | 95 | mu_stream_unref (mstr); |
155 | } | 96 | mu_msgset_free (outset); |
156 | } | 97 | } |
157 | 98 | ||
158 | void | 99 | void | ... | ... |
... | @@ -1100,7 +1100,7 @@ com_search (int argc, char **argv) | ... | @@ -1100,7 +1100,7 @@ com_search (int argc, char **argv) |
1100 | return 0; | 1100 | return 0; |
1101 | } | 1101 | } |
1102 | mu_printf ("%lu matches:", (unsigned long) count); | 1102 | mu_printf ("%lu matches:", (unsigned long) count); |
1103 | mu_msgset_print (mu_strout, mset); | 1103 | mu_msgset_imap_print (mu_strout, mset); |
1104 | mu_printf ("\n"); | 1104 | mu_printf ("\n"); |
1105 | mu_msgset_free (mset); | 1105 | mu_msgset_free (mset); |
1106 | 1106 | ... | ... |
... | @@ -79,13 +79,16 @@ main (int argc, char **argv) | ... | @@ -79,13 +79,16 @@ main (int argc, char **argv) |
79 | { | 79 | { |
80 | int i; | 80 | int i; |
81 | char *msgset_string = NULL; | 81 | char *msgset_string = NULL; |
82 | mu_msgset_t msgset; | 82 | mu_msgset_t msgset, outset; |
83 | int create_mode = MU_MSGSET_NUM; | 83 | int create_mode = MU_MSGSET_NUM; |
84 | int parse_mode = MU_MSGSET_NUM; | 84 | int parse_mode = MU_MSGSET_NUM; |
85 | int output_mode = MU_MSGSET_NUM; | ||
86 | int output_flags = 0; | ||
87 | mu_msgset_format_t format = mu_msgset_fmt_imap; | ||
85 | mu_mailbox_t mbox = NULL; | 88 | mu_mailbox_t mbox = NULL; |
86 | 89 | ||
87 | mu_set_program_name (argv[0]); | 90 | mu_set_program_name (argv[0]); |
88 | mu_registrar_record (mu_mbox_record); | 91 | mu_register_local_mbox_formats (); |
89 | for (i = 1; i < argc; i++) | 92 | for (i = 1; i < argc; i++) |
90 | { | 93 | { |
91 | char *arg = argv[i]; | 94 | char *arg = argv[i]; |
... | @@ -114,6 +117,14 @@ main (int argc, char **argv) | ... | @@ -114,6 +117,14 @@ main (int argc, char **argv) |
114 | MU_ASSERT (mu_mailbox_create (&mbox, arg + 9)); | 117 | MU_ASSERT (mu_mailbox_create (&mbox, arg + 9)); |
115 | MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_READ)); | 118 | MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_READ)); |
116 | } | 119 | } |
120 | else if (strcmp (arg, "-mh") == 0) | ||
121 | format = mu_msgset_fmt_mh; | ||
122 | else if (strcmp (arg, "-printuid") == 0) | ||
123 | output_mode = MU_MSGSET_UID; | ||
124 | else if (strcmp (arg, "-printnum") == 0) | ||
125 | output_mode = MU_MSGSET_NUM; | ||
126 | else if (strcmp (arg, "-ignore-error") == 0) | ||
127 | output_flags = MU_MSGSET_IGNORE_TRANSERR; | ||
117 | else | 128 | else |
118 | break; | 129 | break; |
119 | } | 130 | } |
... | @@ -230,8 +241,11 @@ main (int argc, char **argv) | ... | @@ -230,8 +241,11 @@ main (int argc, char **argv) |
230 | return 1; | 241 | return 1; |
231 | } | 242 | } |
232 | } | 243 | } |
233 | MU_ASSERT (mu_msgset_print (mu_strout, msgset)); | 244 | |
245 | MU_ASSERT (mu_msgset_translate (&outset, msgset, output_mode|output_flags)); | ||
246 | MU_ASSERT (mu_stream_msgset_format (mu_strout, format, outset)); | ||
234 | mu_printf ("\n"); | 247 | mu_printf ("\n"); |
248 | mu_msgset_free (outset); | ||
235 | mu_msgset_free (msgset); | 249 | mu_msgset_free (msgset); |
236 | 250 | ||
237 | return 0; | 251 | return 0; | ... | ... |
-
Please register or sign in to post a comment