Gracefully handle empty mailboxes in mu_msgset_parse_imap
* libmailutils/msgset/parse.c (MU_MSGSET_EMPTY): New constant. (parse_msgrange): Don't add any ranges if mode is set to MU_MSGSET_EMPTY. (mu_msgset_parse_imap): Force MU_MSGSET_EMPTY mode if the mailbox is empty. * libmailutils/msgset/print.c (mu_msgset_print): Handle empty message sets. * libmailutils/msgset/trans.c (_mu_msgset_translate_pair): Initialize variable. * libmailutils/tests/Makefile.am (msgset_LDADD): New variable. * libmailutils/tests/msgset.c (parse_msgset): Take mailbox as first argument. (main): New option -mailbox
Showing
5 changed files
with
33 additions
and
11 deletions
... | @@ -26,6 +26,9 @@ | ... | @@ -26,6 +26,9 @@ |
26 | #include <mailutils/msgset.h> | 26 | #include <mailutils/msgset.h> |
27 | #include <mailutils/sys/msgset.h> | 27 | #include <mailutils/sys/msgset.h> |
28 | 28 | ||
29 | /* Special translation mode, indicating that the mailbox is empty */ | ||
30 | #define MU_MSGSET_EMPTY -1 | ||
31 | |||
29 | /* This structure keeps parser state while parsing message set. */ | 32 | /* This structure keeps parser state while parsing message set. */ |
30 | struct parse_msgnum_env | 33 | struct parse_msgnum_env |
31 | { | 34 | { |
... | @@ -33,7 +36,7 @@ struct parse_msgnum_env | ... | @@ -33,7 +36,7 @@ struct parse_msgnum_env |
33 | size_t minval; /* Min. sequence number or UID */ | 36 | size_t minval; /* Min. sequence number or UID */ |
34 | size_t maxval; /* Max. sequence number or UID */ | 37 | size_t maxval; /* Max. sequence number or UID */ |
35 | mu_msgset_t msgset; /* Message set being built. */ | 38 | mu_msgset_t msgset; /* Message set being built. */ |
36 | int mode; /* Operation mode (num/uid) */ | 39 | int mode; /* Operation mode (num/uid/dry_run) */ |
37 | }; | 40 | }; |
38 | 41 | ||
39 | /* Get a single message number/UID from env->s and store it into *PN. | 42 | /* Get a single message number/UID from env->s and store it into *PN. |
... | @@ -96,6 +99,8 @@ parse_msgrange (struct parse_msgnum_env *env) | ... | @@ -96,6 +99,8 @@ parse_msgrange (struct parse_msgnum_env *env) |
96 | msgrange.msg_beg = tmp; | 99 | msgrange.msg_beg = tmp; |
97 | } | 100 | } |
98 | 101 | ||
102 | if (env->mode == MU_MSGSET_EMPTY) | ||
103 | return 0; | ||
99 | return mu_msgset_add_range (env->msgset, msgrange.msg_beg, msgrange.msg_end, | 104 | return mu_msgset_add_range (env->msgset, msgrange.msg_beg, msgrange.msg_end, |
100 | env->mode); | 105 | env->mode); |
101 | } | 106 | } |
... | @@ -131,7 +136,11 @@ mu_msgset_parse_imap (mu_msgset_t mset, int mode, const char *s, char **end) | ... | @@ -131,7 +136,11 @@ mu_msgset_parse_imap (mu_msgset_t mset, int mode, const char *s, char **end) |
131 | rc = mu_mailbox_messages_count (mset->mbox, &lastmsgno); | 136 | rc = mu_mailbox_messages_count (mset->mbox, &lastmsgno); |
132 | if (rc == 0) | 137 | if (rc == 0) |
133 | { | 138 | { |
134 | if (mode == MU_MSGSET_UID) | 139 | if (lastmsgno == 0) |
140 | { | ||
141 | env.mode = MU_MSGSET_EMPTY; | ||
142 | } | ||
143 | else if (mode == MU_MSGSET_UID) | ||
135 | { | 144 | { |
136 | rc = mu_mailbox_translate (mset->mbox, MU_MAILBOX_MSGNO_TO_UID, | 145 | rc = mu_mailbox_translate (mset->mbox, MU_MAILBOX_MSGNO_TO_UID, |
137 | lastmsgno, &env.maxval); | 146 | lastmsgno, &env.maxval); | ... | ... |
... | @@ -64,7 +64,7 @@ mu_msgset_print (mu_stream_t str, mu_msgset_t mset) | ... | @@ -64,7 +64,7 @@ mu_msgset_print (mu_stream_t str, mu_msgset_t mset) |
64 | int rc; | 64 | int rc; |
65 | 65 | ||
66 | if (mu_list_is_empty (mset->list)) | 66 | if (mu_list_is_empty (mset->list)) |
67 | return MU_ERR_NOENT; | 67 | return mu_stream_printf (str, "%s", "nil"); |
68 | rc = mu_msgset_aggregate (mset); | 68 | rc = mu_msgset_aggregate (mset); |
69 | if (rc) | 69 | if (rc) |
70 | return rc; | 70 | return rc; | ... | ... |
... | @@ -30,7 +30,7 @@ _mu_msgset_translate_pair (mu_msgset_t mset, int mode, | ... | @@ -30,7 +30,7 @@ _mu_msgset_translate_pair (mu_msgset_t mset, int mode, |
30 | if (mode != _MU_MSGSET_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 = 1; |
34 | size_t beg = *pbeg; | 34 | size_t beg = *pbeg; |
35 | size_t end = *pend; | 35 | size_t end = *pend; |
36 | 36 | ... | ... |
... | @@ -69,6 +69,12 @@ noinst_PROGRAMS = \ | ... | @@ -69,6 +69,12 @@ noinst_PROGRAMS = \ |
69 | 69 | ||
70 | LDADD = ${MU_LIB_MAILUTILS} | 70 | LDADD = ${MU_LIB_MAILUTILS} |
71 | 71 | ||
72 | msgset_LDADD = \ | ||
73 | ${MU_LIB_MBOX}\ | ||
74 | ${MU_LIB_MH}\ | ||
75 | ${MU_LIB_MAILDIR}\ | ||
76 | ${MU_LIB_MAILUTILS} | ||
77 | |||
72 | EXTRA_DIST += Encode Decode Wicketfile | 78 | EXTRA_DIST += Encode Decode Wicketfile |
73 | 79 | ||
74 | ## ------------ ## | 80 | ## ------------ ## | ... | ... |
... | @@ -53,16 +53,16 @@ parse_msgrange (char *arg, struct mu_msgrange *range) | ... | @@ -53,16 +53,16 @@ parse_msgrange (char *arg, struct mu_msgrange *range) |
53 | } | 53 | } |
54 | 54 | ||
55 | mu_msgset_t | 55 | mu_msgset_t |
56 | parse_msgset (const char *arg) | 56 | parse_msgset (mu_mailbox_t mbox, const char *arg) |
57 | { | 57 | { |
58 | int rc; | 58 | int rc; |
59 | mu_msgset_t msgset; | 59 | mu_msgset_t msgset; |
60 | char *end; | 60 | char *end; |
61 | 61 | ||
62 | MU_ASSERT (mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM)); | 62 | MU_ASSERT (mu_msgset_create (&msgset, mbox, MU_MSGSET_NUM)); |
63 | if (arg) | 63 | if (arg) |
64 | { | 64 | { |
65 | rc = mu_msgset_parse_imap (msgset, MU_MSGSET_NUM, arg, &end); | 65 | rc = mu_msgset_parse_imap (msgset, MU_MSGSET_UID, arg, &end); |
66 | if (rc) | 66 | if (rc) |
67 | { | 67 | { |
68 | mu_error ("mu_msgset_parse_imap: %s near %s", | 68 | mu_error ("mu_msgset_parse_imap: %s near %s", |
... | @@ -79,26 +79,33 @@ main (int argc, char **argv) | ... | @@ -79,26 +79,33 @@ main (int argc, char **argv) |
79 | int i; | 79 | int i; |
80 | char *msgset_string = NULL; | 80 | char *msgset_string = NULL; |
81 | mu_msgset_t msgset; | 81 | mu_msgset_t msgset; |
82 | mu_mailbox_t mbox = NULL; | ||
82 | 83 | ||
83 | mu_set_program_name (argv[0]); | 84 | mu_set_program_name (argv[0]); |
85 | mu_register_local_mbox_formats (); | ||
84 | for (i = 1; i < argc; i++) | 86 | for (i = 1; i < argc; i++) |
85 | { | 87 | { |
86 | char *arg = argv[i]; | 88 | char *arg = argv[i]; |
87 | 89 | ||
88 | if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0) | 90 | if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0) |
89 | { | 91 | { |
90 | mu_printf ("usage: %s [-msgset=SET] [-add=X[:Y]] [-del=X[:Y]] " | 92 | mu_printf ("usage: %s [-mailbox=PATH] [-msgset=SET] [-add=X[:Y]] [-del=X[:Y]] " |
91 | "[-addset=SET] [-delset=SET] ...\n", | 93 | "[-addset=SET] [-delset=SET] ...\n", |
92 | mu_program_name); | 94 | mu_program_name); |
93 | return 0; | 95 | return 0; |
94 | } | 96 | } |
95 | else if (strncmp (arg, "-msgset=", 8) == 0) | 97 | else if (strncmp (arg, "-msgset=", 8) == 0) |
96 | msgset_string = arg + 8; | 98 | msgset_string = arg + 8; |
99 | else if (strncmp (arg, "-mailbox=", 9) == 0) | ||
100 | { | ||
101 | MU_ASSERT (mu_mailbox_create_default (&mbox, arg + 9)); | ||
102 | MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_READ)); | ||
103 | } | ||
97 | else | 104 | else |
98 | break; | 105 | break; |
99 | } | 106 | } |
100 | 107 | ||
101 | msgset = parse_msgset (msgset_string); | 108 | msgset = parse_msgset (mbox, msgset_string); |
102 | 109 | ||
103 | for (; i < argc; i++) | 110 | for (; i < argc; i++) |
104 | { | 111 | { |
... | @@ -119,7 +126,7 @@ main (int argc, char **argv) | ... | @@ -119,7 +126,7 @@ main (int argc, char **argv) |
119 | } | 126 | } |
120 | else if (strncmp (arg, "-addset=", 8) == 0) | 127 | else if (strncmp (arg, "-addset=", 8) == 0) |
121 | { | 128 | { |
122 | mu_msgset_t tset = parse_msgset (arg + 8); | 129 | mu_msgset_t tset = parse_msgset (mbox, arg + 8); |
123 | if (!msgset) | 130 | if (!msgset) |
124 | msgset = tset; | 131 | msgset = tset; |
125 | else | 132 | else |
... | @@ -130,7 +137,7 @@ main (int argc, char **argv) | ... | @@ -130,7 +137,7 @@ main (int argc, char **argv) |
130 | } | 137 | } |
131 | else if (strncmp (arg, "-subset=", 8) == 0) | 138 | else if (strncmp (arg, "-subset=", 8) == 0) |
132 | { | 139 | { |
133 | mu_msgset_t tset = parse_msgset (arg + 8); | 140 | mu_msgset_t tset = parse_msgset (mbox, arg + 8); |
134 | if (!msgset) | 141 | if (!msgset) |
135 | { | 142 | { |
136 | mu_error ("no initial message set"); | 143 | mu_error ("no initial message set"); | ... | ... |
-
Please register or sign in to post a comment