Skip to content

Commit

Permalink
lib-mail: Add message_part_has_attachment
Browse files Browse the repository at this point in the history
  • Loading branch information
cmouse authored and villesavolainen committed Jan 30, 2018
1 parent c2ece29 commit faf2b76
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
63 changes: 63 additions & 0 deletions src/lib-mail/message-part-data.c
Expand Up @@ -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"
Expand Down Expand Up @@ -498,3 +499,65 @@ void message_part_data_parse_from_header(pool_t pool,
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;
}
30 changes: 30 additions & 0 deletions src/lib-mail/message-part-data.h
Expand Up @@ -38,6 +38,25 @@ struct message_part_data {
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[];

/*
Expand All @@ -54,6 +73,17 @@ bool message_part_data_is_plain_7bit(const struct message_part *part)
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
*/
Expand Down

0 comments on commit faf2b76

Please sign in to comment.