From 3998a03ae925f47cd1ffcf31fca0a4701f8c75da Mon Sep 17 00:00:00 2001 From: Not Zed Date: Tue, 28 Nov 2000 13:13:23 +0000 Subject: Set the info size's properly, oops! 2000-11-28 Not Zed * providers/local/camel-maildir-summary.c (camel_maildir_summary_init): Set the info size's properly, oops! * tests/lib/folders.[ch]: Folder testing helpers. * tests/folder/test2.c: Test basic message ops on folders. * tests/folder/test1.c (main): Test basic folder ops on (local) stores. * providers/local/camel-local-provider.c (camel_provider_module_init): Removed some debug. * providers/local/camel-maildir-folder.c (camel_maildir_folder_class_init): fix parent class. * providers/local/camel-mh-folder.c (camel_mh_folder_class_init): Fix parent class (damn cut & paste). * providers/local/camel-maildir-store.c (get_folder): Call parent impl. (camel_maildir_store_class_init): Fix parent class setup. (delete_folder): Check the folder exists before trying to delete it. (delete_folder): Try and make the delete operation atomic/rollback failures. e.g. if one directory isn't empty, then create the other empty ones back. Also clear the tmp directory fully first. * providers/local/camel-mbox-store.c (get_folder): Call parent impl. (camel_mbox_store_class_init): parent class is camel_local_store, not camel_folder, oops. (delete_folder): Return an error if it doesn't exist, rather than covering it up. * providers/local/camel-mh-store.c (get_folder): Call parent impl. (camel_mh_store_class_init): fix parent class setup. (delete_folder): Error if it doesn't exist now. * camel-folder.c (camel_folder_move_message_to): (camel_folder_copy_message_to): Added warnings as these functions are going to be removed later. * camel-store.c (camel_store_get_root_folder): Fix for an early api change. We want CAMEL_STORE_FOLDER_CREATE, not TRUE, since its a flag. (camel_store_get_default_folder): And here too. * providers/local/camel-local-store.c (xrename): Handle renaming folders differently to renaming files. (get_default_folder_name): local stores dont have a default folder, so make it so. Or at least, it doesn't seem to make sense to have one. (get_root_folder_name): Same for root. (get_folder): Added parent implementation, that makes sure the service path exists, if we are creating a new folder (but doesn't create the folder). 2000-11-27 Not Zed * providers/local/camel-local-store.c (xrename): Fixed races. Use link/unlink, rather than rename, to properly detect overwriting another file. And allow some files to be missing. * providers/Makefile.am: Removed mh, mbox, added local, to the default. svn path=/trunk/; revision=6693 --- camel/providers/local/camel-maildir-store.c | 66 +++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 12 deletions(-) (limited to 'camel/providers/local/camel-maildir-store.c') diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c index 0601307449..f5bd353b6f 100644 --- a/camel/providers/local/camel-maildir-store.c +++ b/camel/providers/local/camel-maildir-store.c @@ -27,6 +27,8 @@ #include #include +#include + #include "camel-maildir-store.h" #include "camel-maildir-folder.h" #include "camel-exception.h" @@ -47,7 +49,7 @@ static void camel_maildir_store_class_init(CamelObjectClass * camel_maildir_stor CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS(camel_maildir_store_class); /*CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_maildir_store_class);*/ - parent_class = (CamelLocalStoreClass *)camel_type_get_global_classfuncs(camel_folder_get_type()); + parent_class = (CamelLocalStoreClass *)camel_type_get_global_classfuncs(camel_local_store_get_type()); /* virtual method overload, use defaults for most */ camel_store_class->get_folder = get_folder; @@ -85,6 +87,10 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guin struct stat st; CamelFolder *folder = NULL; + (void) ((CamelStoreClass *)parent_class)->get_folder(store, folder_name, flags, ex); + if (camel_exception_is_set(ex)) + return NULL; + name = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, folder_name); tmp = g_strdup_printf("%s/tmp", name); cur = g_strdup_printf("%s/cur", name); @@ -99,8 +105,6 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guin camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, _("Folder `%s' does not exist."), folder_name); } else { - printf("creating ...\n"); - if (mkdir(name, 0700) != 0 || mkdir(tmp, 0700) != 0 || mkdir(cur, 0700) != 0 @@ -113,7 +117,6 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guin rmdir(new); rmdir(name); } else { - printf("created ok?\n"); folder = camel_maildir_folder_new(store, folder_name, flags, ex); } } @@ -138,23 +141,62 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guin static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex) { char *name, *tmp, *cur, *new; + struct stat st; name = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, folder_name); + tmp = g_strdup_printf("%s/tmp", name); cur = g_strdup_printf("%s/cur", name); new = g_strdup_printf("%s/new", name); - /* remove subdirs first - will fail if not empty */ - if ((rmdir(tmp) == -1 && errno != ENOENT) - || (rmdir(new) == -1 && errno != ENOENT) - || (rmdir(cur) == -1 && errno != ENOENT) - || (rmdir(name) == -1 && errno != ENOENT)) { + if (stat(name, &st) == -1 || !S_ISDIR(st.st_mode) + || stat(tmp, &st) == -1 || !S_ISDIR(st.st_mode) + || stat(cur, &st) == -1 || !S_ISDIR(st.st_mode) + || stat(new, &st) == -1 || !S_ISDIR(st.st_mode)) { camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Could not delete folder `%s': %s"), - folder_name, strerror(errno)); + folder_name, errno?strerror(errno):_("not a maildir directory")); } else { - /* and remove metadata */ - ((CamelStoreClass *)parent_class)->delete_folder(store, folder_name, ex); + int err = 0; + + /* remove subdirs first - will fail if not empty */ + if (rmdir(cur) == -1 || rmdir(new) == -1) { + err = errno; + } else { + DIR *dir; + struct dirent *d; + + /* for tmp (only), its contents is irrelevant */ + dir = opendir(tmp); + if (dir) { + while ( (d=readdir(dir)) ) { + char *name = d->d_name, *file; + + if (!strcmp(name, ".") || !strcmp(name, "..")) + continue; + file = g_strdup_printf("%s/%s", tmp, name); + unlink(file); + g_free(file); + } + closedir(dir); + } + if (rmdir(tmp) == -1 || rmdir(name) == -1) + err = errno; + } + + if (err != 0) { + /* easier just to mkdir all (and let them fail), than remember what we got to */ + mkdir(name, 0700); + mkdir(cur, 0700); + mkdir(new, 0700); + mkdir(tmp, 0700); + camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, + _("Could not delete folder `%s': %s"), + folder_name, strerror(err)); + } else { + /* and remove metadata */ + ((CamelStoreClass *)parent_class)->delete_folder(store, folder_name, ex); + } } g_free(name); -- cgit v1.2.3