summaryrefslogtreecommitdiffstats
path: root/src/lib-storage/index/dbox-common/dbox-attachment.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib-storage/index/dbox-common/dbox-attachment.c')
-rw-r--r--src/lib-storage/index/dbox-common/dbox-attachment.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/lib-storage/index/dbox-common/dbox-attachment.c b/src/lib-storage/index/dbox-common/dbox-attachment.c
new file mode 100644
index 0000000..cfc3f62
--- /dev/null
+++ b/src/lib-storage/index/dbox-common/dbox-attachment.c
@@ -0,0 +1,77 @@
+/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream.h"
+#include "str.h"
+#include "dbox-file.h"
+#include "dbox-save.h"
+#include "dbox-attachment.h"
+
+void dbox_attachment_save_write_metadata(struct mail_save_context *ctx,
+ string_t *str)
+{
+ const ARRAY_TYPE(mail_attachment_extref) *extrefs;
+
+ extrefs = index_attachment_save_get_extrefs(ctx);
+ if (extrefs == NULL || array_count(extrefs) == 0)
+ return;
+
+ str_append_c(str, DBOX_METADATA_EXT_REF);
+ index_attachment_append_extrefs(str, extrefs);
+ str_append_c(str, '\n');
+}
+
+static int
+dbox_attachment_file_get_stream_from(struct dbox_file *file,
+ const char *ext_refs,
+ struct istream **stream,
+ const char **error_r)
+{
+ const char *path_suffix;
+ uoff_t msg_size;
+
+ if (file->storage->attachment_dir == NULL) {
+ mail_storage_set_critical(&file->storage->storage,
+ "%s contains references to external attachments, "
+ "but mail_attachment_dir is unset", file->cur_path);
+ return -1;
+ }
+
+ msg_size = dbox_file_get_plaintext_size(file);
+ path_suffix = file->storage->v.get_attachment_path_suffix(file);
+ if (index_attachment_stream_get(file->storage->attachment_fs,
+ file->storage->attachment_dir,
+ path_suffix, stream, msg_size,
+ ext_refs, error_r) < 0)
+ return 0;
+ return 1;
+}
+
+int dbox_attachment_file_get_stream(struct dbox_file *file,
+ struct istream **stream)
+{
+ const char *ext_refs, *error;
+ int ret;
+
+ /* need to read metadata in case there are external references */
+ if ((ret = dbox_file_metadata_read(file)) <= 0)
+ return ret;
+
+ i_stream_seek(file->input, file->cur_offset + file->msg_header_size);
+
+ ext_refs = dbox_file_metadata_get(file, DBOX_METADATA_EXT_REF);
+ if (ext_refs == NULL)
+ return 1;
+
+ /* we have external references. */
+ T_BEGIN {
+ ret = dbox_attachment_file_get_stream_from(file, ext_refs,
+ stream, &error);
+ if (ret == 0) {
+ dbox_file_set_corrupted(file,
+ "Corrupted ext-refs metadata %s: %s",
+ ext_refs, error);
+ }
+ } T_END;
+ return ret;
+}