Mercurial > dovecot > core-2.2
changeset 4041:9d7420b0e1ef HEAD
Make life easier for plugins:
- Added MAILBOX_OPEN_SAVEONLY flag for mailbox_open(), which is set when mailbox is opened only for append/copy
- Added a couple of MAIL_STORAGE_ERR_* string defines that should be used when giving visible errors to clients
- Added failed-flag for mailbox_list_context, which plugins can directly set to make mail_storage_mailbox_list_deinit() return failure
- Added mail_storage_get_mailbox_path() and mail_storage_get_mailbox_control_dir() to return locations for mailbox directories
Also be more strict when validating mailbox names.
author | Timo Sirainen <timo.sirainen@movial.fi> |
---|---|
date | Wed, 22 Feb 2006 16:52:11 +0200 |
parents | c0d093d8b8e5 |
children | dabe100f3c38 |
files | src/imap/cmd-append.c src/imap/cmd-copy.c src/lib-storage/index/dbox/dbox-list.c src/lib-storage/index/dbox/dbox-storage.c src/lib-storage/index/maildir/maildir-list.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-list.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/plugins/convert/convert-storage.c src/plugins/quota/quota-plugin.c src/plugins/zlib/zlib-plugin.c |
diffstat | 14 files changed, 208 insertions(+), 71 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/cmd-append.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/imap/cmd-append.c Wed Feb 22 16:52:11 2006 +0200 @@ -365,8 +365,8 @@ mailbox_equals(cmd->client->mailbox, storage, name)) return cmd->client->mailbox; - box = mailbox_open(storage, name, NULL, MAILBOX_OPEN_FAST | - MAILBOX_OPEN_KEEP_RECENT); + box = mailbox_open(storage, name, NULL, MAILBOX_OPEN_SAVEONLY | + MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT); if (box == NULL) { client_send_storage_error(cmd, storage); return NULL;
--- a/src/imap/cmd-copy.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/imap/cmd-copy.c Wed Feb 22 16:52:11 2006 +0200 @@ -81,6 +81,7 @@ destbox = client->mailbox; else { destbox = mailbox_open(storage, mailbox, NULL, + MAILBOX_OPEN_SAVEONLY | MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT); if (destbox == NULL) {
--- a/src/lib-storage/index/dbox/dbox-list.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-list.c Wed Feb 22 16:52:11 2006 +0200 @@ -26,7 +26,7 @@ struct imap_match_glob *glob; struct subsfile_list_context *subsfile_ctx; - bool failed, inbox_found; + bool inbox_found; struct mailbox_list *(*next)(struct dbox_list_context *ctx); @@ -136,7 +136,7 @@ subsfile_list_init(storage, path); if (ctx->subsfile_ctx == NULL) { ctx->next = dbox_list_next; - ctx->failed = TRUE; + ctx->mailbox_ctx.failed = TRUE; return &ctx->mailbox_ctx; } ctx->glob = imap_match_init(default_pool, mask, TRUE, '/'); @@ -178,7 +178,7 @@ int dbox_mailbox_list_deinit(struct mailbox_list_context *_ctx) { struct dbox_list_context *ctx = (struct dbox_list_context *)_ctx; - int ret = ctx->failed ? -1 : 0; + int ret = ctx->mailbox_ctx.failed ? -1 : 0; if (ctx->subsfile_ctx != NULL) { if (subsfile_list_deinit(ctx->subsfile_ctx) < 0) @@ -397,7 +397,7 @@ if (ret > 0) return &ctx->list; if (ret < 0) { - ctx->failed = TRUE; + ctx->mailbox_ctx.failed = TRUE; return NULL; } }
--- a/src/lib-storage/index/dbox/dbox-storage.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-storage.c Wed Feb 22 16:52:11 2006 +0200 @@ -30,7 +30,7 @@ struct mail_storage *storage = &istorage->storage; if (ENOACCESS(errno)) - mail_storage_set_error(storage, "Permission denied"); + mail_storage_set_error(storage, MAIL_STORAGE_ERR_NO_PERMISSION); else if (ENOSPACE(errno)) mail_storage_set_error(storage, "Not enough disk space"); else if (ENOTFOUND(errno)) @@ -158,11 +158,21 @@ if (*mask == '/' || *mask == '~') return FALSE; - /* make sure there's no "../" stuff */ + /* make sure the mailbox name doesn't contain any foolishness: + "../" could give access outside the mailbox directory. + "./" and "//" could fool ACL checks. */ newdir = TRUE; for (p = mask; *p != '\0'; p++) { - if (newdir && p[0] == '.' && p[1] == '.' && p[2] == '/') - return FALSE; + if (newdir) { + if (p[0] == '/') + return FALSE; /* // */ + if (p[0] == '.') { + if (p[1] == '/') + return FALSE; /* ./ */ + if (p[1] == '.' && p[2] == '/') + return FALSE; /* ../ */ + } + } newdir = p[0] == '/'; } @@ -266,6 +276,28 @@ "/", name, "/"DBOX_MAILDIR_NAME, NULL); } +static const char * +dbox_get_mailbox_path(struct mail_storage *_storage, + const char *name, bool *is_file_r) +{ + struct dbox_storage *storage = (struct dbox_storage *)_storage; + struct index_storage *istorage = INDEX_STORAGE(storage); + + *is_file_r = FALSE; + if (*name == '\0') + return istorage->dir; + return dbox_get_path(istorage, name); +} + +static const char * +dbox_get_mailbox_control_dir(struct mail_storage *_storage, const char *name) +{ + struct dbox_storage *storage = (struct dbox_storage *)_storage; + struct index_storage *istorage = INDEX_STORAGE(storage); + + return dbox_get_path(istorage, name); +} + static struct mailbox * dbox_open(struct dbox_storage *storage, const char *name, enum mailbox_open_flags flags) @@ -358,8 +390,8 @@ if (stat(path, &st) == 0) { return dbox_open(storage, name, flags); } else if (errno == ENOENT) { - mail_storage_set_error(_storage, "Mailbox doesn't exist: %s", - name); + mail_storage_set_error(_storage, + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name); return NULL; } else { mail_storage_set_critical(_storage, "stat(%s) failed: %m", @@ -421,7 +453,7 @@ if (stat(mail_path, &st) < 0 && ENOTFOUND(errno)) { if (stat(path, &st) < 0) { mail_storage_set_error(_storage, - "Mailbox doesn't exist: %s", name); + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name); return -1; } @@ -517,7 +549,7 @@ if (rename(oldpath, newpath) < 0) { if (ENOTFOUND(errno)) { mail_storage_set_error(_storage, - "Mailbox doesn't exist: %s", oldname); + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, oldname); } else if (!dbox_handle_errors(storage)) { mail_storage_set_critical(_storage, "rename(%s, %s) failed: %m", oldpath, newpath); @@ -614,6 +646,8 @@ dbox_free, dbox_autodetect, index_storage_set_callbacks, + dbox_get_mailbox_path, + dbox_get_mailbox_control_dir, dbox_mailbox_open, dbox_mailbox_create, dbox_mailbox_delete,
--- a/src/lib-storage/index/maildir/maildir-list.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/index/maildir/maildir-list.c Wed Feb 22 16:52:11 2006 +0200 @@ -29,7 +29,6 @@ size_t parent_pos; struct mailbox_node *root, *next_node; struct mailbox_list list; - bool failed; }; static void maildir_nodes_fix(struct mailbox_node *node, bool is_subs) @@ -289,7 +288,7 @@ if ((flags & MAILBOX_LIST_SUBSCRIBED) != 0) { if (!maildir_fill_subscribed(ctx, glob)) { - ctx->failed = TRUE; + ctx->mailbox_ctx.failed = TRUE; return &ctx->mailbox_ctx; } } else if ((storage->flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && @@ -306,7 +305,7 @@ (ctx->flags & MAILBOX_LIST_FAST_FLAGS) == 0) { bool update_only = (flags & MAILBOX_LIST_SUBSCRIBED) != 0; if (!maildir_fill_readdir(ctx, glob, update_only)) { - ctx->failed = TRUE; + ctx->mailbox_ctx.failed = TRUE; return &ctx->mailbox_ctx; } } @@ -320,7 +319,7 @@ int maildir_mailbox_list_deinit(struct mailbox_list_context *_ctx) { struct maildir_list_context *ctx = (struct maildir_list_context *)_ctx; - int ret = ctx->failed ? -1 : 0; + int ret = ctx->mailbox_ctx.failed ? -1 : 0; mailbox_tree_deinit(ctx->tree_ctx); pool_unref(ctx->pool);
--- a/src/lib-storage/index/maildir/maildir-storage.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/index/maildir/maildir-storage.c Wed Feb 22 16:52:11 2006 +0200 @@ -182,7 +182,13 @@ { size_t len; - len = strlen(name); + /* check that there are no adjacent hierarchy separators */ + for (len = 0; name[len] != '\0'; len++) { + if (name[len] == MAILDIR_FS_SEP && + name[len+1] == MAILDIR_FS_SEP) + return FALSE; + } + if (len == 0 || len > MAILDIR_MAX_MAILBOX_NAME_LENGTH || name[0] == MAILDIR_FS_SEP || name[len-1] == MAILDIR_FS_SEP) return FALSE; @@ -464,6 +470,27 @@ return &mbox->ibox.box; } +static const char * +maildir_get_mailbox_path(struct mail_storage *_storage, + const char *name, bool *is_file_r) +{ + struct maildir_storage *storage = (struct maildir_storage *)_storage; + struct index_storage *istorage = INDEX_STORAGE(storage); + + *is_file_r = FALSE; + if (*name == '\0') + return istorage->dir; + return maildir_get_path(istorage, name); +} + +static const char * +maildir_get_mailbox_control_dir(struct mail_storage *_storage, const char *name) +{ + struct maildir_storage *storage = (struct maildir_storage *)_storage; + + return maildir_get_control_path(storage, name); +} + static struct mailbox * maildir_mailbox_open(struct mail_storage *_storage, const char *name, struct istream *input, enum mailbox_open_flags flags) @@ -506,8 +533,8 @@ return maildir_open(storage, name, flags); } else if (errno == ENOENT) { - mail_storage_set_error(_storage, "Mailbox doesn't exist: %s", - name); + mail_storage_set_error(_storage, + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name); return NULL; } else { mail_storage_set_critical(_storage, "stat(%s) failed: %m", @@ -601,8 +628,8 @@ src = maildir_get_path(storage, name); dest = maildir_get_unlink_path(storage, name); if (stat(src, &st) != 0 && errno == ENOENT) { - mail_storage_set_error(_storage, "Mailbox doesn't exist: %s", - name); + mail_storage_set_error(_storage, + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name); return -1; } @@ -765,7 +792,7 @@ return -1; if (!found && ret == 0) { mail_storage_set_error(_storage, - "Mailbox doesn't exist"); + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, oldname); return -1; } @@ -873,13 +900,15 @@ struct mail_storage maildir_storage = { MEMBER(name) "maildir", - MEMBER(hierarchy_sep) '.', + MEMBER(hierarchy_sep) MAILDIR_FS_SEP, { maildir_create, maildir_free, maildir_autodetect, index_storage_set_callbacks, + maildir_get_mailbox_path, + maildir_get_mailbox_control_dir, maildir_mailbox_open, maildir_mailbox_create, maildir_mailbox_delete,
--- a/src/lib-storage/index/mbox/mbox-list.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/index/mbox/mbox-list.c Wed Feb 22 16:52:11 2006 +0200 @@ -32,7 +32,7 @@ struct imap_match_glob *glob; struct subsfile_list_context *subsfile_ctx; - bool failed, inbox_found; + bool inbox_found; struct mailbox_list *(*next)(struct mbox_list_context *ctx); @@ -142,7 +142,7 @@ subsfile_list_init(storage, path); if (ctx->subsfile_ctx == NULL) { ctx->next = mbox_list_next; - ctx->failed = TRUE; + ctx->mailbox_ctx.failed = TRUE; return &ctx->mailbox_ctx; } ctx->glob = imap_match_init(default_pool, mask, TRUE, '/'); @@ -184,7 +184,7 @@ int mbox_mailbox_list_deinit(struct mailbox_list_context *_ctx) { struct mbox_list_context *ctx = (struct mbox_list_context *)_ctx; - int ret = ctx->failed ? -1 : 0; + int ret = ctx->mailbox_ctx.failed ? -1 : 0; if (ctx->subsfile_ctx != NULL) { if (subsfile_list_deinit(ctx->subsfile_ctx) < 0) @@ -387,7 +387,7 @@ else { mail_storage_set_critical(ctx->mailbox_ctx.storage, "stat(%s) failed: %m", ctx->istorage->inbox_path); - ctx->failed = TRUE; + ctx->mailbox_ctx.failed = TRUE; return NULL; } @@ -412,7 +412,7 @@ if (ret > 0) return &ctx->list; if (ret < 0) { - ctx->failed = TRUE; + ctx->mailbox_ctx.failed = TRUE; return NULL; } }
--- a/src/lib-storage/index/mbox/mbox-storage.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Wed Feb 22 16:52:11 2006 +0200 @@ -59,7 +59,7 @@ struct mail_storage *storage = &istorage->storage; if (ENOACCESS(errno)) - mail_storage_set_error(storage, "Permission denied"); + mail_storage_set_error(storage, MAIL_STORAGE_ERR_NO_PERMISSION); else if (ENOSPACE(errno)) mail_storage_set_error(storage, "Not enough disk space"); else if (ENOTFOUND(errno)) @@ -370,11 +370,21 @@ if (*mask == '/' || *mask == '~') return FALSE; - /* make sure there's no "../" stuff */ + /* make sure the mailbox name doesn't contain any foolishness: + "../" could give access outside the mailbox directory. + "./" and "//" could fool ACL checks. */ newdir = TRUE; for (p = mask; *p != '\0'; p++) { - if (newdir && p[0] == '.' && p[1] == '.' && p[2] == '/') - return FALSE; + if (newdir) { + if (p[0] == '/') + return FALSE; /* // */ + if (p[0] == '.') { + if (p[1] == '/') + return FALSE; /* ./ */ + if (p[1] == '.' && p[2] == '/') + return FALSE; /* ../ */ + } + } newdir = p[0] == '/'; } @@ -633,6 +643,31 @@ return &mbox->ibox.box; } +static const char * +mbox_get_mailbox_path(struct mail_storage *_storage, + const char *name, bool *is_file_r) +{ + struct mbox_storage *storage = (struct mbox_storage *)_storage; + struct index_storage *istorage = INDEX_STORAGE(storage); + + if (*name == '\0') { + *is_file_r = FALSE; + return istorage->dir; + } + + *is_file_r = TRUE; + return mbox_get_path(istorage, name); +} + +static const char * +mbox_get_mailbox_control_dir(struct mail_storage *_storage, const char *name) +{ + struct mbox_storage *storage = (struct mbox_storage *)_storage; + struct index_storage *istorage = INDEX_STORAGE(storage); + + return mbox_get_index_dir(istorage, name); +} + static struct mailbox * mbox_mailbox_open(struct mail_storage *_storage, const char *name, struct istream *input, enum mailbox_open_flags flags) @@ -671,8 +706,8 @@ } if (ENOTFOUND(errno)) { - mail_storage_set_error(_storage, "Mailbox doesn't exist: %s", - name); + mail_storage_set_error(_storage, + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name); } else if (!mbox_handle_errors(istorage)) { mail_storage_set_critical(_storage, "stat(%s) failed: %m", path); @@ -783,7 +818,7 @@ if (lstat(path, &st) < 0) { if (ENOTFOUND(errno)) { mail_storage_set_error(_storage, - "Mailbox doesn't exist: %s", name); + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name); } else if (!mbox_handle_errors(storage)) { mail_storage_set_critical(_storage, "lstat() failed for %s: %m", path); @@ -811,7 +846,7 @@ if (ENOTFOUND(errno)) { mail_storage_set_error(_storage, - "Mailbox doesn't exist: %s", name); + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name); } else if (errno == ENOTEMPTY) { mail_storage_set_error(_storage, "Folder %s isn't empty, can't delete it.", @@ -827,7 +862,7 @@ if (unlink(path) < 0) { if (ENOTFOUND(errno)) { mail_storage_set_error(_storage, - "Mailbox doesn't exist: %s", name); + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name); } else if (!mbox_handle_errors(storage)) { mail_storage_set_critical(_storage, "unlink() failed for %s: %m", path); @@ -914,7 +949,7 @@ if (rename(oldpath, newpath) < 0) { if (ENOTFOUND(errno)) { mail_storage_set_error(_storage, - "Mailbox doesn't exist: %s", oldname); + MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, oldname); } else if (!mbox_handle_errors(storage)) { mail_storage_set_critical(_storage, "rename(%s, %s) failed: %m", oldpath, newpath); @@ -1035,6 +1070,8 @@ mbox_free, mbox_autodetect, index_storage_set_callbacks, + mbox_get_mailbox_path, + mbox_get_mailbox_control_dir, mbox_mailbox_open, mbox_mailbox_create, mbox_mailbox_delete,
--- a/src/lib-storage/mail-storage-private.h Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/mail-storage-private.h Wed Feb 22 16:52:11 2006 +0200 @@ -3,6 +3,11 @@ #include "mail-storage.h" +/* Some error strings that should be used everywhere to avoid + permissions checks from revealing mailbox's existence */ +#define MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND "Mailbox doesn't exist: %s" +#define MAIL_STORAGE_ERR_NO_PERMISSION "Permission denied" + /* Modules should use do "my_id = mail_storage_module_id++" and use objects' module_contexts[id] for their own purposes. */ extern unsigned int mail_storage_module_id; @@ -20,6 +25,11 @@ struct mail_storage_callbacks *callbacks, void *context); + const char *(*get_mailbox_path)(struct mail_storage *storage, + const char *name, bool *is_file_r); + const char *(*get_mailbox_control_dir)(struct mail_storage *storage, + const char *name); + struct mailbox *(*mailbox_open)(struct mail_storage *storage, const char *name, struct istream *input, @@ -204,6 +214,7 @@ struct mailbox_list_context { struct mail_storage *storage; + bool failed; }; struct mailbox_transaction_context {
--- a/src/lib-storage/mail-storage.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/mail-storage.c Wed Feb 22 16:52:11 2006 +0200 @@ -327,6 +327,18 @@ temporary_error_r); } +const char *mail_storage_get_mailbox_path(struct mail_storage *storage, + const char *name, bool *is_file_r) +{ + return storage->v.get_mailbox_path(storage, name, is_file_r); +} + +const char *mail_storage_get_mailbox_control_dir(struct mail_storage *storage, + const char *name) +{ + return storage->v.get_mailbox_control_dir(storage, name); +} + struct mailbox *mailbox_open(struct mail_storage *storage, const char *name, struct istream *input, enum mailbox_open_flags flags)
--- a/src/lib-storage/mail-storage.h Wed Feb 22 15:58:43 2006 +0200 +++ b/src/lib-storage/mail-storage.h Wed Feb 22 16:52:11 2006 +0200 @@ -33,13 +33,15 @@ enum mailbox_open_flags { /* Mailbox must not be modified even if asked */ MAILBOX_OPEN_READONLY = 0x01, + /* Only saving/copying mails to mailbox works. */ + MAILBOX_OPEN_SAVEONLY = 0x02, /* Any extra time consuming operations shouldn't be performed (eg. when opening mailbox just for STATUS). */ - MAILBOX_OPEN_FAST = 0x02, + MAILBOX_OPEN_FAST = 0x04, /* Don't reset MAIL_RECENT flags when syncing */ - MAILBOX_OPEN_KEEP_RECENT = 0x04, + MAILBOX_OPEN_KEEP_RECENT = 0x08, /* Don't create index files for the mailbox */ - MAILBOX_OPEN_NO_INDEX_FILES = 0x08 + MAILBOX_OPEN_NO_INDEX_FILES = 0x10 }; enum mailbox_list_flags { @@ -293,6 +295,17 @@ bool *syntax_error_r, bool *temporary_error_r); +/* Returns path to the given mailbox, or NULL if mailbox doesn't exist in + filesystem. is_file_r is set to TRUE if returned path points to a file, + and FALSE if it points to a directory. If name is "", the root storage + directory is returned. */ +const char *mail_storage_get_mailbox_path(struct mail_storage *storage, + const char *name, bool *is_file_r); +/* Returns path to the control directory of the mailbox, or NULL if mailbox + doesn't exist in filesystem. */ +const char *mail_storage_get_mailbox_control_dir(struct mail_storage *storage, + const char *name); + /* Open a mailbox. If input stream is given, mailbox is opened read-only using it as a backend. If storage doesn't support stream backends and its tried to be used, NULL is returned.
--- a/src/plugins/convert/convert-storage.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/plugins/convert/convert-storage.c Wed Feb 22 16:52:11 2006 +0200 @@ -229,17 +229,19 @@ if (ret == 0) { /* all finished. rename the source directory to mark the - move as finished. FIXME: kind of kludgy way to get the - directory.. */ - struct index_storage *index_storage = - (struct index_storage *)source_storage; - const char *dest; + move as finished. */ + const char *src, *dest; + bool is_file; - dest = t_strconcat(index_storage->dir, "-converted", NULL); - if (rename(index_storage->dir, dest) < 0) { - i_error("Mailbox conversion: rename(%s, %s) failed: %m", - index_storage->dir, dest); - /* return success anyway */ + src = mail_storage_get_mailbox_path(source_storage, "", + &is_file); + if (src != NULL) { + dest = t_strconcat(src, "-converted", NULL); + if (rename(src, dest) < 0) { + i_error("Mailbox conversion: " + "rename(%s, %s) failed: %m", src, dest); + /* return success anyway */ + } } ret = 1; }
--- a/src/plugins/quota/quota-plugin.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/plugins/quota/quota-plugin.c Wed Feb 22 16:52:11 2006 +0200 @@ -1,7 +1,6 @@ /* Copyright (C) 2005 Timo Sirainen */ #include "lib.h" -#include "str.h" #include "mail-storage.h" #include "quota.h" #include "quota-plugin.h"
--- a/src/plugins/zlib/zlib-plugin.c Wed Feb 22 15:58:43 2006 +0200 +++ b/src/plugins/zlib/zlib-plugin.c Wed Feb 22 16:52:11 2006 +0200 @@ -6,9 +6,10 @@ #include "home-expand.h" #include "istream.h" #include "mail-storage-private.h" -#include "index-storage.h" #include "zlib-plugin.h" +#include <fcntl.h> + struct zlib_mail_storage { struct mail_storage_vfuncs super; }; @@ -26,31 +27,30 @@ static unsigned int zlib_storage_module_id = 0; static bool zlib_storage_module_id_set = FALSE; -static const char * -mbox_get_path(struct index_storage *storage, const char *name) -{ - if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && - (*name == '/' || *name == '~')) - return home_expand(name); - return t_strconcat(storage->dir, "/", name, NULL); -} - static struct mailbox * zlib_mailbox_open(struct mail_storage *storage, const char *name, struct istream *input, enum mailbox_open_flags flags) { - struct index_storage *istorage = (struct index_storage *)storage; struct zlib_mail_storage *qstorage = ZLIB_CONTEXT(storage); struct mailbox *box; struct istream *zlib_input = NULL; size_t len = strlen(name); - if (input == NULL && strcmp(storage->name, "mbox") == 0 && - len > 3 && strcmp(name + len - 3, ".gz") == 0) { - int fd = open(mbox_get_path(istorage, name), O_RDONLY); - if (fd != -1) { - input = zlib_input = - i_stream_create_zlib(fd, default_pool); + if (input == NULL && len > 3 && strcmp(name + len - 3, ".gz") == 0) { + /* Looks like a .gz file */ + const char *path; + bool is_file; + + path = mail_storage_get_mailbox_path(storage, name, &is_file); + if (is_file && path != NULL) { + /* it's a single file mailbox. we can handle this. */ + int fd; + + fd = open(path, O_RDONLY); + if (fd != -1) { + input = zlib_input = + i_stream_create_zlib(fd, default_pool); + } } }