]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-fs: Added support for giving a hash of the written data to be verified by storage.
authorTimo Sirainen <tss@iki.fi>
Mon, 9 Sep 2013 21:27:12 +0000 (00:27 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 9 Sep 2013 21:27:12 +0000 (00:27 +0300)
src/lib-fs/fs-api-private.h
src/lib-fs/fs-api.c
src/lib-fs/fs-api.h

index f88a2d8c9993c0b4094fb611ff7c8d3269ce6828..d1acff6b9485bf59a5346f2b1f385cbc29035fef 100644 (file)
@@ -75,6 +75,9 @@ struct fs_file {
        struct istream *pending_read_input;
        bool write_pending;
 
+       const struct hash_method *write_digest_method;
+       void *write_digest;
+
        pool_t metadata_pool;
        ARRAY_TYPE(fs_metadata) metadata;
 
index a9fe3aab0cc5355eb6ef9daa442db0a27710feef..3554e6d32fb8a0910c6ae4c69fe2d060fc7782b3 100644 (file)
@@ -4,6 +4,7 @@
 #include "array.h"
 #include "module-dir.h"
 #include "str.h"
+#include "hash-method.h"
 #include "istream.h"
 #include "istream-seekable.h"
 #include "ostream.h"
@@ -199,6 +200,7 @@ void fs_file_close(struct fs_file *file)
                i_stream_unref(&file->copy_input);
                (void)fs_write_stream_abort(file, &file->copy_output);
        }
+       i_free_and_null(file->write_digest);
        if (file->fs->v.file_close != NULL) T_BEGIN {
                file->fs->v.file_close(file);
        } T_END;
@@ -251,6 +253,11 @@ const char *fs_file_path(struct fs_file *file)
                file->fs->v.get_path(file);
 }
 
+struct fs *fs_file_fs(struct fs_file *file)
+{
+       return file->fs;
+}
+
 static void ATTR_FORMAT(2, 0)
 fs_set_verror(struct fs *fs, const char *fmt, va_list args)
 {
@@ -475,6 +482,16 @@ void fs_write_stream_abort(struct fs_file *file, struct ostream **output)
        } T_END;
 }
 
+void fs_write_set_hash(struct fs_file *file, const struct hash_method *method,
+                      const void *digest)
+{
+       file->write_digest_method = method;
+
+       i_free(file->write_digest);
+       file->write_digest = i_malloc(method->digest_size);
+       memcpy(file->write_digest, digest, method->digest_size);
+}
+
 void fs_file_set_async_callback(struct fs_file *file,
                                fs_file_async_callback_t *callback,
                                void *context)
index d2d9a1dd6122bfe7de3387d7d3f87efdbb67257c..228bb6f39c10bb7d5e4594ed4d29abb159b9328c 100644 (file)
@@ -5,6 +5,7 @@ struct stat;
 struct fs;
 struct fs_file;
 struct fs_lock;
+struct hash_method;
 
 enum fs_properties {
        FS_PROPERTY_METADATA    = 0x01,
@@ -19,7 +20,9 @@ enum fs_properties {
        FS_PROPERTY_RELIABLEITER= 0x40,
        /* Backend uses directories, which aren't automatically deleted
           when its children are deleted. */
-       FS_PROPERTY_DIRECTORIES = 0x80
+       FS_PROPERTY_DIRECTORIES = 0x80,
+       FS_PROPERTY_WRITE_HASH_MD5      = 0x100,
+       FS_PROPERTY_WRITE_HASH_SHA256   = 0x200
 };
 
 enum fs_open_mode {
@@ -115,6 +118,8 @@ int fs_get_metadata(struct fs_file *file,
    FS_OPEN_MODE_CREATE_UNIQUE_128 and the write has already finished,
    return the path including the generated filename. */
 const char *fs_file_path(struct fs_file *file);
+/* Returns the file's fs. */
+struct fs *fs_file_fs(struct fs_file *file);
 
 /* Return the error message for the last failed operation. */
 const char *fs_last_error(struct fs *fs);
@@ -151,6 +156,12 @@ int fs_write_stream_finish_async(struct fs_file *file);
 /* Abort writing via stream. Anything written to the stream is discarded. */
 void fs_write_stream_abort(struct fs_file *file, struct ostream **output);
 
+/* Set a hash to the following write. The storage can then verify that the
+   input data matches the specified hash, or fail if it doesn't. Typically
+   implemented by Content-MD5 header. */
+void fs_write_set_hash(struct fs_file *file, const struct hash_method *method,
+                      const void *digest);
+
 /* Call the specified callback whenever the file can be read/written to.
    May call the callback immediately. */
 void fs_file_set_async_callback(struct fs_file *file,