Mercurial > dovecot > core-2.2
changeset 22780:a982d52a740b
lib-mail: Add message_part_has_attachment
author | Aki Tuomi <aki.tuomi@dovecot.fi> |
---|---|
date | Fri, 10 Nov 2017 14:32:44 +0200 |
parents | ecbd87187f4f |
children | 4b60d9bdc1a7 |
files | src/lib-mail/message-part-data.c src/lib-mail/message-part-data.h |
diffstat | 2 files changed, 93 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-mail/message-part-data.c Mon Jan 22 13:33:29 2018 +0200 +++ b/src/lib-mail/message-part-data.c Fri Nov 10 14:32:44 2017 +0200 @@ -2,6 +2,7 @@ #include "lib.h" #include "str.h" +#include "wildcard-match.h" #include "array.h" #include "rfc822-parser.h" #include "rfc2231-parser.h" @@ -498,3 +499,65 @@ message_part_envelope_parse_from_header(pool, &part_data->envelope, hdr); } } + +bool message_part_has_content_types(struct message_part *part, + const char *const *types) +{ + struct message_part_data *data = part->data; + bool ret = TRUE; + const char *const *ptr; + const char *content_type; + + if (data->content_type == NULL) + return FALSE; + else if (data->content_subtype == NULL) + content_type = t_strdup_printf("%s/", data->content_type); + else + content_type = t_strdup_printf("%s/%s", data->content_type, + data->content_subtype); + for(ptr = types; *ptr != NULL; ptr++) { + bool exclude = (**ptr == '!'); + if (wildcard_match_icase(content_type, (*ptr)+(exclude?1:0))) + ret = !exclude; + } + + return ret; +} + +bool message_part_has_parameter(struct message_part *part, const char *parameter, + bool has_value) +{ + struct message_part_data *data = part->data; + + for (unsigned int i = 0; i < data->content_disposition_params_count; i++) { + const struct message_part_param *param = + &data->content_disposition_params[i]; + if (strcasecmp(param->name, parameter) == 0 && + (!has_value || *param->value != '\0')) { + return TRUE; + } + } + return FALSE; +} + +bool message_part_is_attachment(struct message_part *part, + const struct message_part_attachment_settings *set) +{ + struct message_part_data *data = part->data; + + i_assert(data != NULL); + + /* see if the content-type is excluded */ + if (set->content_type_filter != NULL && + !message_part_has_content_types(part, set->content_type_filter)) + return FALSE; + + /* accept any attachment, or any inlined attachment with filename, + unless inlined ones are excluded */ + if (null_strcasecmp(data->content_disposition, "attachment") == 0 || + (!set->exclude_inlined && + null_strcasecmp(data->content_disposition, "inline") == 0 && + message_part_has_parameter(part, "filename", FALSE))) + return TRUE; + return FALSE; +}
--- a/src/lib-mail/message-part-data.h Mon Jan 22 13:33:29 2018 +0200 +++ b/src/lib-mail/message-part-data.h Fri Nov 10 14:32:44 2017 +0200 @@ -38,6 +38,25 @@ struct message_part_envelope *envelope; }; +struct message_part_attachment_settings { + /* By default, all attachments with content-disposition=attachment + or content-disposition=inline;filename=... are consired as an + attachment. + + If content_type_filter is set to an array of masks, then + anything starting with ! is excluded, and anything without + is considered negating exclusion. Setting foo/bar alone will */ +// not do anything, but setting !foo/*, foo/bar, will exclude + /* all attachments with foo/anything content type, but will + accept foo/bar. + + Setting exclude_inlined, will exclude **any** inlined attachment + regardless of what content_type_filter is. + */ + const char *const *content_type_filter; + bool exclude_inlined; +}; + extern const char *message_part_envelope_headers[]; /* @@ -54,6 +73,17 @@ bool message_part_data_get_filename(const struct message_part *part, const char **filename_r); +/* See message_part_attachment_settings */ +bool message_part_has_content_types(struct message_part *part, const char *const *types); + +/* Returns TRUE if message part has given parameter, and has non-empty + value if has_value is TRUE. */ +bool message_part_has_parameter(struct message_part *part, const char *parameter, + bool has_value); + +/* Check if part is attachment according to given settings */ +bool message_part_is_attachment(struct message_part *part, + const struct message_part_attachment_settings *set); /* * Header parsing */