# HG changeset patch # User Timo Sirainen # Date 1476691174 -10800 # Node ID 59a3ab804bcc595012d6de72f611cce8152547c9 # Parent c9e32ef49048c0773496c4137171d5055422caa9 lib-fs: Added FS_METADATA_WRITE_FNAME to allow renaming a file being written. diff -r c9e32ef49048 -r 59a3ab804bcc src/lib-fs/fs-api.h --- a/src/lib-fs/fs-api.h Tue Oct 11 01:04:39 2016 +0300 +++ b/src/lib-fs/fs-api.h Mon Oct 17 10:59:34 2016 +0300 @@ -13,6 +13,10 @@ This can be later on used to optimize reads by setting it before reading the file. */ #define FS_METADATA_OBJECTID FS_METADATA_INTERNAL_PREFIX"ObjectID" +/* Calling this before fs_write_stream_finish() allows renaming the filename. + This can be useful if you don't know the final filename before writing it + (e.g. filename contains the file size). */ +#define FS_METADATA_WRITE_FNAME FS_METADATA_INTERNAL_PREFIX"WriteFilename" enum fs_properties { FS_PROPERTY_METADATA = 0x01, diff -r c9e32ef49048 -r 59a3ab804bcc src/lib-fs/fs-dict.c --- a/src/lib-fs/fs-dict.c Tue Oct 11 01:04:39 2016 +0300 +++ b/src/lib-fs/fs-dict.c Mon Oct 17 10:59:34 2016 +0300 @@ -185,6 +185,20 @@ o_stream_set_name(_file->output, file->key); } +static void fs_dict_write_rename_if_needed(struct dict_fs_file *file) +{ + struct dict_fs *fs = (struct dict_fs *)file->file.fs; + const char *new_fname; + + new_fname = fs_metadata_find(&file->file.metadata, FS_METADATA_WRITE_FNAME); + if (new_fname == NULL) + return; + + file->file.path = p_strdup(file->pool, new_fname); + file->key = fs->path_prefix == NULL ? p_strdup(file->pool, new_fname) : + p_strconcat(file->pool, fs->path_prefix, new_fname, NULL); +} + static int fs_dict_write_stream_finish(struct fs_file *_file, bool success) { struct dict_fs_file *file = (struct dict_fs_file *)_file; @@ -195,6 +209,7 @@ if (!success) return -1; + fs_dict_write_rename_if_needed(file); trans = dict_transaction_begin(fs->dict); switch (fs->encoding) { case FS_DICT_VALUE_ENCODING_RAW: @@ -302,7 +317,8 @@ NULL, NULL, NULL, NULL, - NULL, NULL, + fs_default_set_metadata, + NULL, fs_dict_prefetch, NULL, fs_dict_read_stream, diff -r c9e32ef49048 -r 59a3ab804bcc src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Tue Oct 11 01:04:39 2016 +0300 +++ b/src/lib-fs/fs-posix.c Mon Oct 17 10:59:34 2016 +0300 @@ -443,6 +443,23 @@ return input; } +static void fs_posix_write_rename_if_needed(struct posix_fs_file *file) +{ + struct posix_fs *fs = (struct posix_fs *)file->file.fs; + const char *new_fname; + + new_fname = fs_metadata_find(&file->file.metadata, FS_METADATA_WRITE_FNAME); + if (new_fname == NULL) + return; + + i_free(file->file.path); + file->file.path = i_strdup(new_fname); + + i_free(file->full_path); + file->full_path = fs->path_prefix == NULL ? i_strdup(new_fname) : + i_strconcat(fs->path_prefix, new_fname, NULL); +} + static int fs_posix_write_finish(struct posix_fs_file *file) { int ret, old_errno; @@ -455,6 +472,7 @@ } } + fs_posix_write_rename_if_needed(file); switch (file->open_mode) { case FS_OPEN_MODE_CREATE_UNIQUE_128: case FS_OPEN_MODE_CREATE: @@ -872,7 +890,8 @@ fs_posix_file_close, NULL, NULL, NULL, - NULL, NULL, + fs_default_set_metadata, + NULL, fs_posix_prefetch, fs_posix_read, fs_posix_read_stream,