From: Timo Sirainen Date: Wed, 2 Mar 2022 22:37:50 +0000 (-0500) Subject: lib-storage: mailbox_list_get_storage() - Add flags, and allow changing vname X-Git-Tag: 2.4.0~3797 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c83c6b656cdc01519d28bc5d99b11222b9fa3fc8;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: mailbox_list_get_storage() - Add flags, and allow changing vname The previous API allowed changing the mailbox_list, but not the vname string. Now it's possible to change both. The flags allows the implementation more flexibility. It will be used by following commits to determine whether opening a virtual mailbox should actually be opening the backend mailbox (for saving mails). --- diff --git a/src/lib-storage/index/shared/shared-list.c b/src/lib-storage/index/shared/shared-list.c index 839ff39633..ba8eb2c23e 100644 --- a/src/lib-storage/index/shared/shared-list.c +++ b/src/lib-storage/index/shared/shared-list.c @@ -37,13 +37,14 @@ static void shared_list_copy_error(struct mailbox_list *shared_list, } static int -shared_get_storage(struct mailbox_list **list, const char *vname, +shared_get_storage(struct mailbox_list **list, const char **vname, + enum mailbox_list_get_storage_flags flags, struct mail_storage **storage_r) { struct mail_namespace *ns = (*list)->ns; const char *name; - name = mailbox_list_get_storage_name(*list, vname); + name = mailbox_list_get_storage_name(*list, *vname); if (*name == '\0' && (ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) { /* trying to access the shared/ prefix itself */ *storage_r = ns->storage; @@ -53,7 +54,7 @@ shared_get_storage(struct mailbox_list **list, const char *vname, if (shared_storage_get_namespace(&ns, &name) < 0) return -1; *list = ns->list; - return mailbox_list_get_storage(list, vname, storage_r); + return mailbox_list_get_storage(list, vname, flags, storage_r); } static char shared_list_get_hierarchy_sep(struct mailbox_list *list ATTR_UNUSED) diff --git a/src/lib-storage/list/mailbox-list-fs.c b/src/lib-storage/list/mailbox-list-fs.c index 8dca501f22..0948dcd367 100644 --- a/src/lib-storage/list/mailbox-list-fs.c +++ b/src/lib-storage/list/mailbox-list-fs.c @@ -437,7 +437,7 @@ static int fs_list_rename_mailbox(struct mailbox_list *oldlist, bool rmdir_parent = FALSE; oldvname = mailbox_list_get_vname(oldlist, oldname); - if (mailbox_list_get_storage(&oldlist, oldvname, &oldstorage) < 0) + if (mailbox_list_get_storage(&oldlist, &oldvname, 0, &oldstorage) < 0) return -1; if (mailbox_list_get_path(oldlist, oldname, diff --git a/src/lib-storage/mail-namespace.c b/src/lib-storage/mail-namespace.c index 614aac50f0..30a936128c 100644 --- a/src/lib-storage/mail-namespace.c +++ b/src/lib-storage/mail-namespace.c @@ -740,7 +740,7 @@ mail_namespace_find_shared(struct mail_namespace *ns, const char *mailbox) struct mailbox_list *list = ns->list; struct mail_storage *storage; - if (mailbox_list_get_storage(&list, mailbox, &storage) < 0) + if (mailbox_list_get_storage(&list, &mailbox, 0, &storage) < 0) return ns; return mailbox_list_get_namespace(list); diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 11b9cca6cc..5b54bf9a72 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -871,7 +871,11 @@ struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname, } T_BEGIN { - if (mailbox_list_get_storage(&new_list, vname, &storage) < 0) { + enum mailbox_list_get_storage_flags storage_flags = 0; + if ((flags & MAILBOX_FLAG_SAVEONLY) != 0) + storage_flags |= MAILBOX_LIST_GET_STORAGE_FLAG_SAVEONLY; + if (mailbox_list_get_storage(&new_list, &vname, + storage_flags, &storage) < 0) { /* do a delayed failure at mailbox_open() */ storage = mail_namespace_get_default_storage(list->ns); errstr = mailbox_list_get_last_error(new_list, &open_error); diff --git a/src/lib-storage/mailbox-list-private.h b/src/lib-storage/mailbox-list-private.h index 77611b9ba9..7f85e49c11 100644 --- a/src/lib-storage/mailbox-list-private.h +++ b/src/lib-storage/mailbox-list-private.h @@ -38,7 +38,8 @@ struct mailbox_list_vfuncs { int (*init)(struct mailbox_list *list, const char **error_r); void (*deinit)(struct mailbox_list *list); - int (*get_storage)(struct mailbox_list **list, const char *vname, + int (*get_storage)(struct mailbox_list **list, const char **vname, + enum mailbox_list_get_storage_flags flags, struct mail_storage **storage_r); char (*get_hierarchy_sep)(struct mailbox_list *list); diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index 630cb8c3d1..f6ced9c844 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -889,15 +889,16 @@ mailbox_list_get_storage_driver(struct mailbox_list *list, const char *driver, return 0; } -int mailbox_list_get_storage(struct mailbox_list **list, const char *vname, +int mailbox_list_get_storage(struct mailbox_list **list, const char **vname, + enum mailbox_list_get_storage_flags flags, struct mail_storage **storage_r) { const struct mailbox_settings *set; if ((*list)->v.get_storage != NULL) - return (*list)->v.get_storage(list, vname, storage_r); + return (*list)->v.get_storage(list, vname, flags, storage_r); - set = mailbox_settings_find((*list)->ns, vname); + set = mailbox_settings_find((*list)->ns, *vname); if (set != NULL && set->driver != NULL && set->driver[0] != '\0') { return mailbox_list_get_storage_driver(*list, set->driver, storage_r); diff --git a/src/lib-storage/mailbox-list.h b/src/lib-storage/mailbox-list.h index df47dea32e..7f4a796d54 100644 --- a/src/lib-storage/mailbox-list.h +++ b/src/lib-storage/mailbox-list.h @@ -105,6 +105,10 @@ enum mailbox_list_file_type { MAILBOX_LIST_FILE_TYPE_OTHER }; +enum mailbox_list_get_storage_flags { + MAILBOX_LIST_GET_STORAGE_FLAG_SAVEONLY = BIT(0), +}; + struct mailbox_list_settings { const char *layout; /* FIXME: shouldn't be here */ const char *root_dir; @@ -222,7 +226,12 @@ struct mail_namespace * mailbox_list_get_namespace(const struct mailbox_list *list) ATTR_PURE; struct mail_user * mailbox_list_get_user(const struct mailbox_list *list) ATTR_PURE; -int mailbox_list_get_storage(struct mailbox_list **list, const char *vname, +/* Get a mail_storage for the given mailbox_list/vname combination. This might + result in mailbox_list and/or vname becoming changed. For example shared + folders will change the mailbox_list and saving to a virtual folder changes + both. */ +int mailbox_list_get_storage(struct mailbox_list **list, const char **vname, + enum mailbox_list_get_storage_flags flags, struct mail_storage **storage_r); void mailbox_list_get_default_storage(struct mailbox_list *list, struct mail_storage **storage); diff --git a/src/plugins/acl/acl-backend-vfile.c b/src/plugins/acl/acl-backend-vfile.c index 8f9be9522b..a2f3b9742f 100644 --- a/src/plugins/acl/acl-backend-vfile.c +++ b/src/plugins/acl/acl-backend-vfile.c @@ -117,7 +117,7 @@ acl_backend_vfile_get_local_dir(struct acl_backend *backend, /* ACL files are very important. try to keep them among the main mail files. that's not possible though with a) if the mailbox is a file or b) if the mailbox path doesn't point to filesystem. */ - if (mailbox_list_get_storage(&list, vname, &storage) < 0) + if (mailbox_list_get_storage(&list, &vname, 0, &storage) < 0) return NULL; i_assert(list == ns->list); diff --git a/src/plugins/quota/quota-imapc.c b/src/plugins/quota/quota-imapc.c index 7c9e904cff..9fd89e5e89 100644 --- a/src/plugins/quota/quota-imapc.c +++ b/src/plugins/quota/quota-imapc.c @@ -218,7 +218,8 @@ static bool imapc_quota_client_init(struct imapc_quota_root *root) root->initialized = TRUE; list = root->imapc_ns->list; - if (mailbox_list_get_storage(&list, "", &storage) == 0 && + const char *vname = ""; + if (mailbox_list_get_storage(&list, &vname, 0, &storage) == 0 && strcmp(storage->name, IMAPC_STORAGE_NAME) != 0) { /* non-imapc namespace, skip */ if ((storage->class_flags & diff --git a/src/plugins/quota/quota-maildir.c b/src/plugins/quota/quota-maildir.c index d52fca8227..76ef0867cd 100644 --- a/src/plugins/quota/quota-maildir.c +++ b/src/plugins/quota/quota-maildir.c @@ -662,7 +662,8 @@ static bool maildirquota_limits_init(struct maildir_quota_root *root) } list = root->maildirsize_ns->list; - if (mailbox_list_get_storage(&list, "", &storage) == 0 && + const char *vname = ""; + if (mailbox_list_get_storage(&list, &vname, 0, &storage) == 0 && strcmp(storage->name, MAILDIR_STORAGE_NAME) != 0) { /* non-maildir namespace, skip */ if ((storage->class_flags & diff --git a/src/plugins/quota/quota.c b/src/plugins/quota/quota.c index d321a238c7..675cedb6bc 100644 --- a/src/plugins/quota/quota.c +++ b/src/plugins/quota/quota.c @@ -679,7 +679,8 @@ bool quota_root_is_namespace_visible(struct quota_root *root, struct mail_storage *storage; /* this check works as long as there is only one storage per list */ - if (mailbox_list_get_storage(&list, "", &storage) == 0 && + const char *vname = ""; + if (mailbox_list_get_storage(&list, &vname, 0, &storage) == 0 && (storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NOQUOTA) != 0) return FALSE; if (root->quota->unwanted_ns == ns)