]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: mailbox_list_get_storage() - Add flags, and allow changing vname
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 2 Mar 2022 22:37:50 +0000 (17:37 -0500)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Wed, 6 Jul 2022 20:51:20 +0000 (20:51 +0000)
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).

src/lib-storage/index/shared/shared-list.c
src/lib-storage/list/mailbox-list-fs.c
src/lib-storage/mail-namespace.c
src/lib-storage/mail-storage.c
src/lib-storage/mailbox-list-private.h
src/lib-storage/mailbox-list.c
src/lib-storage/mailbox-list.h
src/plugins/acl/acl-backend-vfile.c
src/plugins/quota/quota-imapc.c
src/plugins/quota/quota-maildir.c
src/plugins/quota/quota.c

index 839ff3963381dbd6f188707789a0e5cae63f660e..ba8eb2c23e08d3432a490537050afdff381c150d 100644 (file)
@@ -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)
index 8dca501f224ea477132b64fb477108b29e4fe3cc..0948dcd367ba1214816a5b08c8652f481dfcdf70 100644 (file)
@@ -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,
index 614aac50f0e04bededd2b3018718cb682b43cfe5..30a936128c76d012d1de4eedcc1d321c6dcad198 100644 (file)
@@ -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);
index 11b9cca6cc22994f0e7bebb6ce6e8cfdcc07cf1d..5b54bf9a725232447d7cbf4336eb2154e23f90ad 100644 (file)
@@ -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);
index 77611b9ba96909f76d7f9f5c9ceb6f595165f9d4..7f85e49c1160f614421e79d277afdafa8ce9cf81 100644 (file)
@@ -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);
index 630cb8c3d1191638c0774b137b56b0826dbe18cd..f6ced9c84400559dbd5dd386f748cee42b4cc9ed 100644 (file)
@@ -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);
index df47dea32edf5634f6ae88e6844b16bee74a164c..7f4a796d5487667f6f3be86aedd67d9a3f2e7d4f 100644 (file)
@@ -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);
index 8f9be9522b52b9939cc2e6ee94e5d001ff9b8500..a2f3b9742f8a506189c612911cc4b534d0c67221 100644 (file)
@@ -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);
 
index 7c9e904cff9eff09a06479a849f292018155d296..9fd89e5e89191f99acb12529a63c31938d2149a2 100644 (file)
@@ -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 &
index d52fca822772b5d24375444ab57a394f1270c132..76ef0867cdbfffd3b6a81a6ae7a482acb40899c9 100644 (file)
@@ -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 &
index d321a238c74d9300503a9d1ad661fb7fc0d153bf..675cedb6bc43f91cd91e505e044557e68538dac2 100644 (file)
@@ -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)