summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-01-26 00:30:28 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-01-26 01:05:52 +0200
commit3798a0f09da7fcaa6daa12e9ae483ebf99f7c46a (patch)
tree97c80866168b24c3c45f2d1961311d80b6ff1823
parentbc4d023a3810a7da6ede2cc522cdc34fa3129378 (diff)
downloadmailutils-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--NEWS11
-rw-r--r--imap4d/imap4d.h1
-rw-r--r--imap4d/search.c458
-rw-r--r--imap4d/util.c8
-rw-r--r--libmailutils/mailbox/header.c4
5 files changed, 341 insertions, 141 deletions
diff --git a/NEWS b/NEWS
index 84d36010c..4f5c0dec9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,2 +1,2 @@
1GNU mailutils NEWS -- history of user-visible changes. 2019-01-23 1GNU mailutils NEWS -- history of user-visible changes. 2019-01-26
2Copyright (C) 2002-2019 Free Software Foundation, Inc. 2Copyright (C) 2002-2019 Free Software Foundation, Inc.
@@ -8,2 +8,11 @@ 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
15Both commands now properly descend into multipart message parts and
16decode messages, if necessary
17
9* Fixes in the 'mail' utility 18* Fixes in the 'mail' utility
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index 2ad339a30..b90d653a0 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -456,3 +456,2 @@ extern int util_parse_ctime_date (const char *date, time_t *timep,
456 enum datetime_parse_mode flag); 456 enum datetime_parse_mode flag);
457extern char *util_strcasestr (const char *haystack, const char *needle);
458extern char *util_localname (void); 457extern char *util_localname (void);
diff --git a/imap4d/search.c b/imap4d/search.c
index 1d28b570f..3c243eddf 100644
--- a/imap4d/search.c
+++ b/imap4d/search.c
@@ -17,2 +17,3 @@
17#include "imap4d.h" 17#include "imap4d.h"
18#include <mailutils/assoc.h>
18 19
@@ -92,3 +93,3 @@ struct search_node
92static void cond_msgset (struct parsebuf *, struct search_node *, 93static void cond_msgset (struct parsebuf *, struct search_node *,
93 struct value *, struct value *); 94 struct value *, struct value *);
94static void cond_bcc (struct parsebuf *, struct search_node *, 95static void cond_bcc (struct parsebuf *, struct search_node *,
@@ -96,21 +97,21 @@ static void cond_bcc (struct parsebuf *, struct search_node *,
96static void cond_before (struct parsebuf *, struct search_node *, 97static void cond_before (struct parsebuf *, struct search_node *,
97 struct value *, struct value *); 98 struct value *, struct value *);
98static void cond_body (struct parsebuf *, struct search_node *, 99static void cond_body (struct parsebuf *, struct search_node *,
99 struct value *, struct value *); 100 struct value *, struct value *);
100static void cond_cc (struct parsebuf *, struct search_node *, 101static void cond_cc (struct parsebuf *, struct search_node *,
101 struct value *, struct value *); 102 struct value *, struct value *);
102static void cond_from (struct parsebuf *, struct search_node *, 103static void cond_from (struct parsebuf *, struct search_node *,
103 struct value *, struct value *); 104 struct value *, struct value *);
104static void cond_header (struct parsebuf *, struct search_node *, 105static void cond_header (struct parsebuf *, struct search_node *,
105 struct value *, struct value *); 106 struct value *, struct value *);
106static void cond_keyword (struct parsebuf *, struct search_node *, 107static void cond_keyword (struct parsebuf *, struct search_node *,
107 struct value *, struct value *); 108 struct value *, struct value *);
108static void cond_larger (struct parsebuf *, struct search_node *, 109static void cond_larger (struct parsebuf *, struct search_node *,
109 struct value *, struct value *); 110 struct value *, struct value *);
110static void cond_on (struct parsebuf *, struct search_node *, 111static void cond_on (struct parsebuf *, struct search_node *,
111 struct value *, struct value *); 112 struct value *, struct value *);
112static void cond_sentbefore (struct parsebuf *, struct search_node *, 113static void cond_sentbefore (struct parsebuf *, struct search_node *,
113 struct value *, struct value *); 114 struct value *, struct value *);
114static void cond_senton (struct parsebuf *, struct search_node *, 115static void cond_senton (struct parsebuf *, struct search_node *,
115 struct value *, struct value *); 116 struct value *, struct value *);
116static void cond_sentsince (struct parsebuf *, struct search_node *, 117static void cond_sentsince (struct parsebuf *, struct search_node *,
@@ -118,13 +119,13 @@ static void cond_sentsince (struct parsebuf *, struct search_node *,
118static void cond_since (struct parsebuf *, struct search_node *, 119static void cond_since (struct parsebuf *, struct search_node *,
119 struct value *, struct value *); 120 struct value *, struct value *);
120static void cond_smaller (struct parsebuf *, struct search_node *, 121static void cond_smaller (struct parsebuf *, struct search_node *,
121 struct value *, struct value *); 122 struct value *, struct value *);
122static void cond_subject (struct parsebuf *, struct search_node *, 123static void cond_subject (struct parsebuf *, struct search_node *,
123 struct value *, struct value *); 124 struct value *, struct value *);
124static void cond_text (struct parsebuf *, struct search_node *, 125static void cond_text (struct parsebuf *, struct search_node *,
125 struct value *, struct value *); 126 struct value *, struct value *);
126static void cond_to (struct parsebuf *, struct search_node *, 127static void cond_to (struct parsebuf *, struct search_node *,
127 struct value *, struct value *); 128 struct value *, struct value *);
128static void cond_uid (struct parsebuf *, struct search_node *, 129static void cond_uid (struct parsebuf *, struct search_node *,
129 struct value *, struct value *); 130 struct value *, struct value *);
130 131
@@ -140,3 +141,3 @@ struct cond
140/* Types are: s -- string 141/* Types are: s -- string
141 n -- number 142 n -- number
142 d -- date 143 d -- date
@@ -215,3 +216,3 @@ struct mem_chain
215 that they are enclosed in doublequotes */ 216 that they are enclosed in doublequotes */
216#define MAXTOKEN 64 217#define MAXTOKEN 64
217 218
@@ -220,14 +221,15 @@ 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};
@@ -243,2 +245,3 @@ static int search_run (struct parsebuf *pb);
243static void do_search (struct parsebuf *pb); 245static void do_search (struct parsebuf *pb);
246static int available_charset (const char *charset);
244 247
@@ -248,3 +251,3 @@ static void do_search (struct parsebuf *pb);
248 Arguments: OPTIONAL [CHARSET] specification 251 Arguments: OPTIONAL [CHARSET] specification
249 searching criteria (one or more) 252 searching criteria (one or more)
250 253
@@ -253,5 +256,5 @@ static void do_search (struct parsebuf *pb);
253 Result: OK - search completed 256 Result: OK - search completed
254 NO - search error: can't search that [CHARSET] or 257 NO - search error: can't search that [CHARSET] or
255 criteria 258 criteria
256 BAD - command unknown or arguments invalid 259 BAD - command unknown or arguments invalid
257*/ 260*/
@@ -260,3 +263,3 @@ int
260imap4d_search (struct imap4d_session *session, 263imap4d_search (struct imap4d_session *session,
261 struct imap4d_command *command, imap4d_tokbuf_t tok) 264 struct imap4d_command *command, imap4d_tokbuf_t tok)
262{ 265{
@@ -264,3 +267,3 @@ imap4d_search (struct imap4d_session *session,
264 char *err_text= ""; 267 char *err_text= "";
265 268
266 rc = imap4d_search0 (tok, 0, &err_text); 269 rc = imap4d_search0 (tok, 0, &err_text);
@@ -268,3 +271,3 @@ imap4d_search (struct imap4d_session *session,
268} 271}
269 272
270int 273int
@@ -273,3 +276,3 @@ imap4d_search0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
273 struct parsebuf parsebuf; 276 struct parsebuf parsebuf;
274 277
275 memset (&parsebuf, 0, sizeof(parsebuf)); 278 memset (&parsebuf, 0, sizeof(parsebuf));
@@ -286,3 +289,3 @@ imap4d_search0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
286 } 289 }
287 290
288 if (mu_c_strcasecmp (parsebuf.token, "CHARSET") == 0) 291 if (mu_c_strcasecmp (parsebuf.token, "CHARSET") == 0)
@@ -298,5 +301,11 @@ imap4d_search0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
298 { 301 {
299 *err_text = "Charset not supported"; 302 parsebuf.charset = parse_strdup (&parsebuf, parsebuf.token);
300 return RESP_NO; 303 if (!available_charset (parsebuf.charset))
304 {
305 *err_text = "[BADCHARSET] Charset not supported";
306 return RESP_NO;
307 }
301 } 308 }
309 else
310 parsebuf.charset = NULL;
302 311
@@ -307,3 +316,2 @@ imap4d_search0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
307 } 316 }
308
309 } 317 }
@@ -325,8 +333,8 @@ imap4d_search0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
325 } 333 }
326 334
327 /* Execute compiled expression */ 335 /* Execute compiled expression */
328 do_search (&parsebuf); 336 do_search (&parsebuf);
329 337
330 parse_free_mem (&parsebuf); 338 parse_free_mem (&parsebuf);
331 339
332 *err_text = "Completed"; 340 *err_text = "Completed";
@@ -341,3 +349,3 @@ do_search (struct parsebuf *pb)
341 size_t count = 0; 349 size_t count = 0;
342 350
343 mu_mailbox_messages_count (mbox, &count); 351 mu_mailbox_messages_count (mbox, &count);
@@ -419,3 +427,3 @@ parse_alloc (struct parsebuf *pb, size_t size)
419 427
420/* Create a copy of the string. */ 428/* Create a copy of the string. */
421char * 429char *
@@ -447,3 +455,3 @@ parse_msgset_create (struct parsebuf *pb, mu_mailbox_t mbox, int flags)
447 search_key_list : search_key 455 search_key_list : search_key
448 | search_key_list search_key 456 | search_key_list search_key
449 ; 457 ;
@@ -451,3 +459,3 @@ parse_msgset_create (struct parsebuf *pb, mu_mailbox_t mbox, int flags)
451 search_key : simple_key 459 search_key : simple_key
452 | NOT simple_key 460 | NOT simple_key
453 | OR simple_key simple_key 461 | OR simple_key simple_key
@@ -488,3 +496,3 @@ parse_search_key (struct parsebuf *pb)
488 struct search_node *node;