]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Fixes to rename error handling.
authorTimo Sirainen <tss@iki.fi>
Mon, 15 Feb 2010 02:08:46 +0000 (04:08 +0200)
committerTimo Sirainen <tss@iki.fi>
Mon, 15 Feb 2010 02:08:46 +0000 (04:08 +0200)
--HG--
branch : HEAD

src/lib-storage/index/index-storage.c
src/lib-storage/list/mailbox-list-fs.c
src/lib-storage/mail-storage.c

index f06f997644550db6091be0de8609d9e723253d59..3245ac64f4ba017cee9e016854a673a72e99429d 100644 (file)
@@ -490,8 +490,10 @@ int index_storage_mailbox_rename(struct mailbox *src, struct mailbox *dest,
 
        if (src->list->v.rename_mailbox(src->list, src->name,
                                        dest->list, dest->name,
-                                       rename_children) < 0)
+                                       rename_children) < 0) {
+               mail_storage_copy_list_error(src->storage, src->list);
                return -1;
+       }
 
        /* we'll track mailbox names, instead of GUIDs. We may be renaming a
           non-selectable mailbox (directory), which doesn't even have a GUID */
index 33763b8092047beb9f220fea384d3253930d11ee..8c6811ce01d6fdcc6ce099ab4878cc76097864a4 100644 (file)
@@ -571,16 +571,6 @@ static int fs_list_rename_mailbox(struct mailbox_list *oldlist,
                return -1;
        }
 
-       if ((alt_newpath != NULL && alt_oldpath == NULL) ||
-           (alt_newpath == NULL && alt_oldpath != NULL)) {
-               /* both or neither source/dest must to have alt path defined.
-                  otherwise we'd have to do the merging ourself, which would
-                  be possible but a bit too much trouble for now */
-               mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
-                       "Can't rename mailboxes across specified storages.");
-               return -1;
-       }
-
        if (alt_newpath != NULL) {
                if (stat(alt_newpath, &st) == 0) {
                        /* race condition or a directory left there lying around?
index f5895512214da4895708f2d564b580055d271263..c1d3476d710326d44ff9ed5761f138e4975d3587 100644 (file)
@@ -666,35 +666,53 @@ int mailbox_delete(struct mailbox *box)
        return ret;
 }
 
+static bool
+mail_storages_rename_compatible(struct mail_storage *storage1,
+                               struct mail_storage *storage2)
+{
+       if (storage1 == storage2)
+               return TRUE;
+
+       if (strcmp(storage1->name, storage2->name) != 0)
+               return FALSE;
+       if ((storage1->class_flags & MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT) != 0)
+               return FALSE;
+       return TRUE;
+}
+
 static bool nullequals(const void *p1, const void *p2)
 {
        return (p1 == NULL && p2 == NULL) || (p1 != NULL && p2 != NULL);
 }
 
+static bool
+mailbox_lists_rename_compatible(struct mailbox_list *list1,
+                               struct mailbox_list *list2)
+{
+       return nullequals(list1->set.alt_dir, list2->set.alt_dir) &&
+               nullequals(list1->set.index_dir, list2->set.index_dir) &&
+               nullequals(list1->set.control_dir, list2->set.control_dir);
+}
+
 int mailbox_rename(struct mailbox *src, struct mailbox *dest,
                   bool rename_children)
 {
        if (!mailbox_list_is_valid_existing_name(src->list, src->name) ||
            *src->name == '\0' ||
            !mailbox_list_is_valid_create_name(dest->list, dest->name)) {
-               mailbox_list_set_error(src->list, MAIL_ERROR_PARAMS,
+               mail_storage_set_error(src->storage, MAIL_ERROR_PARAMS,
                                       "Invalid mailbox name");
                return -1;
        }
-       if (strcmp(src->storage->name, dest->storage->name) != 0) {
-               mailbox_list_set_error(src->list, MAIL_ERROR_NOTPOSSIBLE,
-                       "Can't rename mailbox to another storage type.");
-               return -1;
-       }
-       if (!nullequals(src->list->set.index_dir, dest->list->set.index_dir) ||
-           !nullequals(src->list->set.control_dir, dest->list->set.control_dir)) {
-               mailbox_list_set_error(src->list, MAIL_ERROR_NOTPOSSIBLE,
+       if (!mail_storages_rename_compatible(src->storage, dest->storage) ||
+           !mailbox_lists_rename_compatible(src->list, dest->list)) {
+               mail_storage_set_error(src->storage, MAIL_ERROR_NOTPOSSIBLE,
                        "Can't rename mailboxes across specified storages.");
                return -1;
        }
        if (src->list->ns->type != NAMESPACE_PRIVATE ||
            dest->list->ns->type != NAMESPACE_PRIVATE) {
-               mailbox_list_set_error(src->list, MAIL_ERROR_NOTPOSSIBLE,
+               mail_storage_set_error(src->storage, MAIL_ERROR_NOTPOSSIBLE,
                        "Renaming not supported across non-private namespaces.");
                return -1;
        }