#include "lib.h"
#include "str.h"
+#include "wildcard-match.h"
#include "array.h"
#include "rfc822-parser.h"
#include "rfc2231-parser.h"
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;
+}
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[];
/*
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
*/