diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-01-26 00:30:28 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-01-26 01:05:52 +0200 |
commit | 3798a0f09da7fcaa6daa12e9ae483ebf99f7c46a (patch) | |
tree | 97c80866168b24c3c45f2d1961311d80b6ff1823 | |
parent | bc4d023a3810a7da6ede2cc522cdc34fa3129378 (diff) | |
download | mailutils-3798a0f09da7fcaa6daa12e9ae483ebf99f7c46a.tar.gz mailutils-3798a0f09da7fcaa6daa12e9ae483ebf99f7c46a.tar.bz2 |
imap4d: implement SEARCH CHARSET; fix BODY and TEXT searches.
* imap4d/search.c: Implement proper BODY searches. Implement CHARSET.
* imap4d/util.c (util_strcasestr): Remove. Use mu_c_strcasestr instead.
* imap4d/imap4d.h: Likewise.
* NEWS: Document changes.
-rw-r--r-- | NEWS | 11 | ||||
-rw-r--r-- | imap4d/imap4d.h | 1 | ||||
-rw-r--r-- | imap4d/search.c | 458 | ||||
-rw-r--r-- | imap4d/util.c | 8 | ||||
-rw-r--r-- | libmailutils/mailbox/header.c | 4 |
5 files changed, 341 insertions, 141 deletions
@@ -1,14 +1,23 @@ | |||
1 | GNU mailutils NEWS -- history of user-visible changes. 2019-01-23 | 1 | GNU mailutils NEWS -- history of user-visible changes. 2019-01-26 |
2 | Copyright (C) 2002-2019 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2019 Free Software Foundation, Inc. |
3 | See the end of file for copying conditions. | 3 | See the end of file for copying conditions. |
4 | 4 | ||
5 | Please send mailutils bug reports to <bug-mailutils@gnu.org>. | 5 | Please send mailutils bug reports to <bug-mailutils@gnu.org>. |
6 | 6 | ||
7 | Version 3.5.90 (git) | 7 | Version 3.5.90 (git) |
8 | 8 | ||
9 | * imap4d: SEARCH command | ||
10 | |||
11 | ** Implemented SEARCH CHARSET | ||
12 | |||
13 | ** Improved SEARCH BODY and SEARCH TEXT commands | ||
14 | |||
15 | Both commands now properly descend into multipart message parts and | ||
16 | decode messages, if necessary | ||
17 | |||
9 | * Fixes in the 'mail' utility | 18 | * Fixes in the 'mail' utility |
10 | 19 | ||
11 | ** New mailbox notation @ | 20 | ** New mailbox notation @ |
12 | 21 | ||
13 | @ can be used with any command requring a mailbox name to refer to the | 22 | @ can be used with any command requring a mailbox name to refer to the |
14 | file given with the -f option. | 23 | file given with the -f option. |
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h index 2ad339a30..b90d653a0 100644 --- a/imap4d/imap4d.h +++ b/imap4d/imap4d.h | |||
@@ -451,13 +451,12 @@ enum datetime_parse_mode /* how to parse date/time strings */ | |||
451 | extern int util_parse_internal_date (char *date, time_t *timep, | 451 | extern int util_parse_internal_date (char *date, time_t *timep, |
452 | enum datetime_parse_mode flag); | 452 | enum datetime_parse_mode flag); |
453 | extern int util_parse_822_date (const char *date, time_t *timep, | 453 | extern int util_parse_822_date (const char *date, time_t *timep, |
454 | enum datetime_parse_mode flag); | 454 | enum datetime_parse_mode flag); |
455 | extern int util_parse_ctime_date (const char *date, time_t *timep, | 455 | extern int util_parse_ctime_date (const char *date, time_t *timep, |
456 | enum datetime_parse_mode flag); | 456 | enum datetime_parse_mode flag); |
457 | extern char *util_strcasestr (const char *haystack, const char *needle); | ||
458 | extern char *util_localname (void); | 457 | extern char *util_localname (void); |
459 | 458 | ||
460 | void util_print_flags (mu_attribute_t attr); | 459 | void util_print_flags (mu_attribute_t attr); |
461 | int util_attribute_matches_flag (mu_attribute_t attr, const char *item); | 460 | int util_attribute_matches_flag (mu_attribute_t attr, const char *item); |
462 | int util_uidvalidity (mu_mailbox_t smbox, unsigned long *uidvp); | 461 | int util_uidvalidity (mu_mailbox_t smbox, unsigned long *uidvp); |
463 | 462 | ||
diff --git a/imap4d/search.c b/imap4d/search.c index 1d28b570f..3c243eddf 100644 --- a/imap4d/search.c +++ b/imap4d/search.c | |||
@@ -12,12 +12,13 @@ | |||
12 | GNU General Public License for more details. | 12 | GNU General Public License for more details. |
13 | 13 | ||
14 | You should have received a copy of the GNU General Public License | 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/>. */ | 15 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ |
16 | 16 | ||
17 | #include "imap4d.h" | 17 | #include "imap4d.h" |
18 | #include <mailutils/assoc.h> | ||
18 | 19 | ||
19 | /* | 20 | /* |
20 | * This will be a royal pain in the arse to implement | 21 | * This will be a royal pain in the arse to implement |
21 | * Alain: True, but the new lib mailbox should coming handy with | 22 | * Alain: True, but the new lib mailbox should coming handy with |
22 | * some sort of query interface. | 23 | * some sort of query interface. |
23 | * Sergey: It was, indeed. | 24 | * Sergey: It was, indeed. |
@@ -87,61 +88,61 @@ struct search_node | |||
87 | struct search_node *arg[2]; /* Binary operation */ | 88 | struct search_node *arg[2]; /* Binary operation */ |
88 | struct value value; | 89 | struct value value; |
89 | } v; | 90 | } v; |
90 | }; | 91 | }; |
91 | 92 | ||
92 | static void cond_msgset (struct parsebuf *, struct search_node *, | 93 | static void cond_msgset (struct parsebuf *, struct search_node *, |
93 | struct value *, struct value *); | 94 | struct value *, struct value *); |
94 | static void cond_bcc (struct parsebuf *, struct search_node *, | 95 | static void cond_bcc (struct parsebuf *, struct search_node *, |
95 | struct value *, struct value *); | 96 | struct value *, struct value *); |
96 | static void cond_before (struct parsebuf *, struct search_node *, | 97 | static void cond_before (struct parsebuf *, struct search_node *, |
97 | struct value *, struct value *); | 98 | struct value *, struct value *); |
98 | static void cond_body (struct parsebuf *, struct search_node *, | 99 | static void cond_body (struct parsebuf *, struct search_node *, |
99 | struct value *, struct value *); | 100 | struct value *, struct value *); |
100 | static void cond_cc (struct parsebuf *, struct search_node *, | 101 | static void cond_cc (struct parsebuf *, struct search_node *, |
101 | struct value *, struct value *); | 102 | struct value *, struct value *); |
102 | static void cond_from (struct parsebuf *, struct search_node *, | 103 | static void cond_from (struct parsebuf *, struct search_node *, |
103 | struct value *, struct value *); | 104 | struct value *, struct value *); |
104 | static void cond_header (struct parsebuf *, struct search_node *, | 105 | static void cond_header (struct parsebuf *, struct search_node *, |
105 | struct value *, struct value *); | 106 | struct value *, struct value *); |
106 | static void cond_keyword (struct parsebuf *, struct search_node *, | 107 | static void cond_keyword (struct parsebuf *, struct search_node *, |
107 | struct value *, struct value *); | 108 | struct value *, struct value *); |
108 | static void cond_larger (struct parsebuf *, struct search_node *, | 109 | static void cond_larger (struct parsebuf *, struct search_node *, |
109 | struct value *, struct value *); | 110 | struct value *, struct value *); |
110 | static void cond_on (struct parsebuf *, struct search_node *, | 111 | static void cond_on (struct parsebuf *, struct search_node *, |
111 | struct value *, struct value *); | 112 | struct value *, struct value *); |
112 | static void cond_sentbefore (struct parsebuf *, struct search_node *, | 113 | static void cond_sentbefore (struct parsebuf *, struct search_node *, |
113 | struct value *, struct value *); | 114 | struct value *, struct value *); |
114 | static void cond_senton (struct parsebuf *, struct search_node *, | 115 | static void cond_senton (struct parsebuf *, struct search_node *, |
115 | struct value *, struct value *); | 116 | struct value *, struct value *); |
116 | static void cond_sentsince (struct parsebuf *, struct search_node *, | 117 | static void cond_sentsince (struct parsebuf *, struct search_node *, |
117 | struct value *, struct value *); | 118 | struct value *, struct value *); |
118 | static void cond_since (struct parsebuf *, struct search_node *, | 119 | static void cond_since (struct parsebuf *, struct search_node *, |
119 | struct value *, struct value *); | 120 | struct value *, struct value *); |
120 | static void cond_smaller (struct parsebuf *, struct search_node *, | 121 | static void cond_smaller (struct parsebuf *, struct search_node *, |
121 | struct value *, struct value *); | 122 | struct value *, struct value *); |
122 | static void cond_subject (struct parsebuf *, struct search_node *, | 123 | static void cond_subject (struct parsebuf *, struct search_node *, |
123 | struct value *, struct value *); | 124 | struct value *, struct value *); |
124 | static void cond_text (struct parsebuf *, struct search_node *, | 125 | static void cond_text (struct parsebuf *, struct search_node *, |
125 | struct value *, struct value *); | 126 | struct value *, struct value *); |
126 | static void cond_to (struct parsebuf *, struct search_node *, | 127 | static void cond_to (struct parsebuf *, struct search_node *, |
127 | struct value *, struct value *); | 128 | struct value *, struct value *); |
128 | static void cond_uid (struct parsebuf *, struct search_node *, | 129 | static void cond_uid (struct parsebuf *, struct search_node *, |
129 | struct value *, struct value *); | 130 | struct value *, struct value *); |
130 | 131 | ||
131 | /* A basic condition structure */ | 132 | /* A basic condition structure */ |
132 | struct cond | 133 | struct cond |
133 | { | 134 | { |
134 | char *name; /* Condition name */ | 135 | char *name; /* Condition name */ |
135 | char *argtypes; /* String of argument types or NULL if it takes no | 136 | char *argtypes; /* String of argument types or NULL if it takes no |
136 | args */ | 137 | args */ |
137 | instr_fn inst; /* Corresponding instruction function */ | 138 | instr_fn inst; /* Corresponding instruction function */ |
138 | }; | 139 | }; |
139 | 140 | ||
140 | /* Types are: s -- string | 141 | /* Types are: s -- string |
141 | n -- number | 142 | n -- number |
142 | d -- date | 143 | d -- date |
143 | m -- message set | 144 | m -- message set |
144 | */ | 145 | */ |
145 | 146 | ||
146 | /* List of basic conditions. "ALL" and <message set> is handled separately */ | 147 | /* List of basic conditions. "ALL" and <message set> is handled separately */ |
147 | struct cond condlist[] = | 148 | struct cond condlist[] = |
@@ -210,105 +211,112 @@ struct mem_chain | |||
210 | #define CODEINCR 16 | 211 | #define CODEINCR 16 |
211 | #define STACKSIZE 64 | 212 | #define STACKSIZE 64 |
212 | #define STACKINCR 16 | 213 | #define STACKINCR 16 |
213 | 214 | ||
214 | /* Maximum length of a token. Tokens longer than that are accepted, provided | 215 | /* Maximum length of a token. Tokens longer than that are accepted, provided |
215 | that they are enclosed in doublequotes */ | 216 | that they are enclosed in doublequotes */ |
216 | #define MAXTOKEN 64 | 217 | #define MAXTOKEN 64 |
217 | 218 | ||
218 | /* Parse buffer structure */ | 219 | /* Parse buffer structure */ |
219 | struct parsebuf | 220 | struct parsebuf |
220 | { | 221 | { |
221 | imap4d_tokbuf_t tok; /* Token buffer */ | 222 | imap4d_tokbuf_t tok; /* Token buffer */ |
222 | int arg; /* Argument number */ | 223 | int arg; /* Argument number */ |
223 | char *token; /* Current token */ | 224 | char *token; /* Current token */ |
224 | int isuid; /* UIDs instead of msgnos are required */ | 225 | int isuid; /* UIDs instead of msgnos are required */ |
225 | char *err_mesg; /* Error message if a parse error occured */ | 226 | char *err_mesg; /* Error message if a parse error occured */ |
226 | struct mem_chain *alloc; /* Chain of objects allocated during parsing */ | 227 | struct mem_chain *alloc; /* Chain of objects allocated during parsing */ |
227 | 228 | char *charset; /* Charset, other than US-ASCII requested */ | |
229 | |||
228 | struct search_node *tree; /* Parse tree */ | 230 | struct search_node *tree; /* Parse tree */ |
229 | 231 | ||
230 | /* Execution time only: */ | 232 | /* Execution time only: */ |
231 | size_t msgno; /* Number of current message */ | 233 | size_t msgno; /* Number of current message */ |
232 | mu_message_t msg; /* Current message */ | 234 | mu_message_t msg; /* Current message */ |
233 | }; | 235 | }; |
234 | 236 | ||
235 | static void parse_free_mem (struct parsebuf *pb); | 237 | static void parse_free_mem (struct parsebuf *pb); |
236 | static void *parse_regmem (struct parsebuf *pb, void *mem, void (*f)(void*)); | 238 | static void *parse_regmem (struct parsebuf *pb, void *mem, void (*f)(void*)); |
237 | static char *parse_strdup (struct parsebuf *pb, char *s); | 239 | static char *parse_strdup (struct parsebuf *pb, char *s); |
238 | static void *parse_alloc (struct parsebuf *pb, size_t size); |