diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-01-23 10:42:35 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-01-23 10:51:00 +0200 |
commit | 5fbfaa6b81685e91a4407344ed7b2b221ce878f3 (patch) | |
tree | aa4a5e103996fbb6faa639ca745c0fef938e65b6 | |
parent | 6ea2ea5259553f5d8437e7fd8c7d4c15e7facfb0 (diff) | |
download | mailutils-5fbfaa6b81685e91a4407344ed7b2b221ce878f3.tar.gz mailutils-5fbfaa6b81685e91a4407344ed7b2b221ce878f3.tar.bz2 |
mail: improve message set parser
* mail/from.c (sender_string): New function.
* mail/mail.h: Likewise.
* mail/msgset.y: Fix memory management and error reporting.
Implement sender address matching.
* mail/util.c (util_outfolder_name): Always return allocated value.
* mail/copy.c (mail_copy0): Add typecast.
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | mail/copy.c | 2 | ||||
-rw-r--r-- | mail/from.c | 16 | ||||
-rw-r--r-- | mail/mail.h | 1 | ||||
-rw-r--r-- | mail/msgset.y | 100 | ||||
-rw-r--r-- | mail/util.c | 2 |
6 files changed, 90 insertions, 37 deletions
@@ -13,6 +13,12 @@ Version 3.5.90 (git) @ can be used with any command requring a mailbox name to refer to the file given with the -f option. +** Sender addresses in message sets + +Arbitrary string in message set is treated as sender address. It +expands to all messages whose sender addresses as displayed in a header +summary match the string. + ** showenvelope With the showenvelope variable set, mail incorrectly displayed diff --git a/mail/copy.c b/mail/copy.c index 967a0db1a..9732dbeb5 100644 --- a/mail/copy.c +++ b/mail/copy.c @@ -239,7 +239,7 @@ mail_copy0 (int argc, char **argv, int mark) if (mail_expand_name (filename, &url)) return 1; - filename = mu_url_to_string (url); + filename = (char*) mu_url_to_string (url); if (mu_url_is_scheme (url, "file") || mu_url_is_scheme (url, "mbox")) rc = append_to_file (filename, msglist, mark, &totals); else diff --git a/mail/from.c b/mail/from.c index 2fc3bbb48..a9ee08f94 100644 --- a/mail/from.c +++ b/mail/from.c @@ -219,9 +219,8 @@ hdr_date (struct header_call_args *args, void *data) return header_buf_string (args, date); } -/* %f */ -static char * -hdr_from (struct header_call_args *args, void *data) +char * +sender_string (mu_message_t msg) { char *from = NULL; @@ -229,7 +228,7 @@ hdr_from (struct header_call_args *args, void *data) { mu_header_t hdr; - if (mu_message_get_header (args->msg, &hdr) == 0 + if (mu_message_get_header (msg, &hdr) == 0 && mu_header_aget_value_unfold (hdr, MU_HEADER_FROM, &from) == 0) { mu_address_t address = NULL; @@ -276,11 +275,18 @@ hdr_from (struct header_call_args *args, void *data) mu_envelope_t env = NULL; const char *sender = ""; - if (mu_message_get_envelope (args->msg, &env) == 0) + if (mu_message_get_envelope (msg, &env) == 0) mu_envelope_sget_sender (env, &sender); from = mu_strdup (sender); } + return from; +} +/* %f */ +static char * +hdr_from (struct header_call_args *args, void *data) +{ + char *from = sender_string (args->msg); header_buf_string (args, from); free (from); return args->buf; diff --git a/mail/mail.h b/mail/mail.h index ec48f9e32..ee634c8ef 100644 --- a/mail/mail.h +++ b/mail/mail.h @@ -430,6 +430,7 @@ const char *util_url_to_string (mu_url_t url); mu_stream_t open_pager (size_t lines); void format_msgset (mu_stream_t str, const msgset_t *msgset, size_t *count); +char *sender_string (mu_message_t msg); int is_address_field (const char *name); diff --git a/mail/msgset.y b/mail/msgset.y index 4f41a85cc..8011dc779 100644 --- a/mail/msgset.y +++ b/mail/msgset.y @@ -44,12 +44,14 @@ static int select_type (mu_message_t msg, void *closure); static int select_sender (mu_message_t msg, void *closure); static int select_deleted (mu_message_t msg, void *closure); static int check_set (msgset_t **pset); - + int yyerror (const char *); int yylex (void); static int msgset_flags = MSG_NODELETED; +static size_t message_count; static msgset_t *result; +static mu_opool_t tokpool; %} %union { @@ -144,13 +146,23 @@ msg : header REGEXP /* /.../ */ hd.header = $1; hd.expr = $2; $$ = msgset_select (select_header, &hd, 0, 0); - if ($1) - free ($1); - free ($2); + if (!$$) + { + if ($1) + mu_error (_("No applicable messages from {%s:/%s}"), $1, $2); + else + mu_error (_("No applicable messages from {/%s}"), $2); + YYERROR; + } } | BODY { $$ = msgset_select (select_body, $1, 0, 0); + if (!$$) + { + mu_error (_("No applicable messages from {:/%s}"), $1); + YYERROR; + } } | TYPE /* :n, :d, etc */ { @@ -160,11 +172,20 @@ msg : header REGEXP /* /.../ */ YYERROR; } $$ = msgset_select (select_type, (void *)&$1, 0, 0); + if (!$$) + { + mu_error (_("No messages satisfy :%c"), $1); + YYERROR; + } } | IDENT /* Sender name */ { $$ = msgset_select (select_sender, (void *)$1, 0, 0); - free ($1); + if (!$$) + { + mu_error (_("No applicable messages from {%s}"), $1); + YYERROR; + } } ; @@ -211,6 +232,8 @@ range : number ; number : partno + { + } | partno '[' rangeset ']' { $$ = msgset_expand ($1, $3); @@ -221,6 +244,12 @@ number : partno partno : NUMBER { + if ($1 > message_count) + { + util_error_range ($1); + YYERROR; + } + $$ = msgset_make_1 ($1); } | '(' rangeset ')' @@ -279,14 +308,12 @@ yylex (void) if (mu_isalpha (*cur_p)) { char *p = cur_p; - int len; while (*cur_p && *cur_p != ',' && *cur_p != ':') cur_p++; - len = cur_p - p + 1; - yylval.string = mu_alloc (len); - memcpy (yylval.string, p, len-1); - yylval.string[len-1] = 0; + mu_opool_append (tokpool, p, cur_p - p); + mu_opool_append_char (tokpool, 0); + yylval.string = mu_opool_finish (tokpool, NULL); if (*cur_p == ':') { ++cur_p; @@ -298,16 +325,17 @@ yylex (void) if (*cur_p == '/') { char *p = ++cur_p; - int len; while (*cur_p && *cur_p != '/') cur_p++; - len = cur_p - p + 1; + + mu_opool_append (tokpool, p, cur_p - p); + mu_opool_append_char (tokpool, 0); + yylval.string = mu_opool_finish (tokpool, NULL); + if (*cur_p) cur_p++; - yylval.string = mu_alloc (len); - memcpy (yylval.string, p, len-1); - yylval.string[len-1] = 0; + return REGEXP; } @@ -317,16 +345,17 @@ yylex (void) if (*cur_p == '/') { char *p = ++cur_p; - int len; - + while (*cur_p && *cur_p != '/') cur_p++; - len = cur_p - p + 1; + + mu_opool_append (tokpool, p, cur_p - p); + mu_opool_append_char (tokpool, 0); + yylval.string = mu_opool_finish (tokpool, NULL); + if (*cur_p) cur_p++; - yylval.string = mu_alloc (len); - memcpy (yylval.string, p, len-1); - yylval.string[len-1] = 0; + return BODY; } if (*cur_p == 0) @@ -348,10 +377,13 @@ msgset_parse (const int argc, char **argv, int flags, msgset_t **mset) cur_ind = 1; cur_p = NULL; result = NULL; + + mu_opool_create (&tokpool, MU_OPOOL_ENOMEMABRT); + mu_mailbox_messages_count (mbox, &message_count); rc = yyparse (); if (rc == 0) { - if (result == NULL) + if (!result) { util_noapp (); rc = 1; @@ -359,6 +391,7 @@ msgset_parse (const int argc, char **argv, int flags, msgset_t **mset) else *mset = result; } + mu_opool_destroy (&tokpool); return rc; } @@ -555,7 +588,7 @@ msgset_select (int (*sel) (mu_message_t, void *), void *closure, int rev, for (i = total; i > 0; i--) { mu_mailbox_get_message (mbox, i, &msg); - if ((*sel)(msg, closure)) + if ((*sel) (msg, closure)) { mp = msgset_make_1 (i); if (!first) @@ -573,7 +606,7 @@ msgset_select (int (*sel) (mu_message_t, void *), void *closure, int rev, for (i = 1; i <= total; i++) { mu_mailbox_get_message (mbox, i, &msg); - if ((*sel)(msg, closure)) + if ((*sel) (msg, closure)) { mp = msgset_make_1 (i); if (!first) @@ -686,13 +719,13 @@ select_body (mu_message_t msg, void *closure) } int -select_sender (mu_message_t msg MU_ARG_UNUSED, void *closure MU_ARG_UNUSED) +select_sender (mu_message_t msg, void *closure) { - /* char *sender = (char*) closure; */ - /* FIXME: all messages from sender argv[i] */ - /* Annoying we can use mu_address_create() for that - but to compare against what? The email ? */ - return 0; + char *needle = (char*) closure; + char *sender = sender_string (msg); + int status = strcmp (sender, needle) == 0; + free (sender); + return status; } int @@ -739,7 +772,12 @@ check_set (msgset_t **pset) { int flags = msgset_flags; int rc = 0; - + + if (!*pset) + { + util_noapp (); + return 1; + } if (msgset_count (*pset) == 1) flags ^= MSG_SILENT; if (flags & MSG_NODELETED) diff --git a/mail/util.c b/mail/util.c index f5471e77b..5611b84a3 100644 --- a/mail/util.c +++ b/mail/util.c @@ -677,6 +677,8 @@ util_outfolder_name (char *str) } free (s); } + else + exp = mu_strdup (str); break; } |