From 4d5427769cfec587d9b8f727bd57ac1a1d2ae340 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 7 Jun 2000 00:06:29 +0000 Subject: Remove exists, create, delete. A CamelFolder now always references an * camel-folder.c: Remove exists, create, delete. A CamelFolder now always references an existing folder. Remove delete_messages too since it wasn't being used. Add a "create" flag to get_subfolder saying whether or not to create the subfolder if it doesn't yet exist. * camel-store.c (camel_store_get_folder): Add a "create" flag to say whether or not to create the folder if it doesn't yet exist. (camel_store_delete_folder): New method, moved from CamelFolder. (cache_folder, uncache_folder): Fix up a bit. (get_folder_name): Explain what this is for. * providers/mbox/camel-mbox-folder.c: * providers/mbox/camel-mbox-store.c: Update. Remove support for hierarchical folders to simplify this for now, since we're not using it, and it's not completely clear how they should work in an ELocalStorage world. Needs to be revisited. * providers/pop3/camel-pop3-folder.c (delete_messages): Remove. * providers/pop3/camel-pop3-store.c (get_folder): Update. * providers/vee/camel-vee-folder.c (exists): Remove. * providers/vee/camel-vee-store.c (vee_get_folder): Update. svn path=/trunk/; revision=3453 --- camel/ChangeLog | 27 ++- camel/camel-exception-list.def | 1 + camel/camel-folder.c | 232 +----------------------- camel/camel-folder.h | 24 +-- camel/camel-store.c | 94 +++++++--- camel/camel-store.h | 10 + camel/providers/mbox/camel-mbox-folder.c | 301 ------------------------------- camel/providers/mbox/camel-mbox-store.c | 128 +++++++++++-- camel/providers/pop3/camel-pop3-folder.c | 28 --- camel/providers/pop3/camel-pop3-store.c | 6 +- camel/providers/vee/camel-vee-folder.c | 8 - camel/providers/vee/camel-vee-store.c | 5 +- 12 files changed, 236 insertions(+), 628 deletions(-) (limited to 'camel') diff --git a/camel/ChangeLog b/camel/ChangeLog index d55f24814c..cd68f9a008 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,29 @@ +2000-06-06 Dan Winship + + * camel-folder.c: Remove exists, create, delete. A CamelFolder + now always references an existing folder. Remove delete_messages + too since it wasn't being used. Add a "create" flag to + get_subfolder saying whether or not to create the subfolder if it + doesn't yet exist. + + * camel-store.c (camel_store_get_folder): Add a "create" flag to + say whether or not to create the folder if it doesn't yet exist. + (camel_store_delete_folder): New method, moved from CamelFolder. + (cache_folder, uncache_folder): Fix up a bit. + (get_folder_name): Explain what this is for. + + * providers/mbox/camel-mbox-folder.c: + * providers/mbox/camel-mbox-store.c: Update. Remove support for + hierarchical folders to simplify this for now, since we're not + using it, and it's not completely clear how they should work in an + ELocalStorage world. Needs to be revisited. + + * providers/pop3/camel-pop3-folder.c (delete_messages): Remove. + * providers/pop3/camel-pop3-store.c (get_folder): Update. + + * providers/vee/camel-vee-folder.c (exists): Remove. + * providers/vee/camel-vee-store.c (vee_get_folder): Update. + 2000-06-06 Jeffrey Stedfast * providers/imap/camel-imap-*.[c,h]: Started on getting @@ -94,7 +120,6 @@ * camel-data-wrapper.c (finalize): unref the stream, if it exists. 2000-06-01 Not Zed ->>>>>>> 1.212 * camel-mime-part.c (construct_from_parser): For a message part, set the default content-type to message/rfc822. Maybe needs to be diff --git a/camel/camel-exception-list.def b/camel/camel-exception-list.def index fcb99e5a52..cdb95b1a81 100644 --- a/camel/camel-exception-list.def +++ b/camel/camel-exception-list.def @@ -26,6 +26,7 @@ CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID, /* CamelStoreException */ CAMEL_EXCEPTION_STORE_NULL = 200, CAMEL_EXCEPTION_STORE_INVALID, +CAMEL_EXCEPTION_STORE_NO_FOLDER, /* CamelServiceException */ CAMEL_EXCEPTION_SERVICE_NULL = 300, diff --git a/camel/camel-folder.c b/camel/camel-folder.c index c4f06a55c4..a3e50f163d 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -62,21 +62,16 @@ static const gchar *get_full_name (CamelFolder *folder); static gboolean can_hold_folders (CamelFolder *folder); static gboolean can_hold_messages (CamelFolder *folder); -static gboolean exists (CamelFolder *folder, CamelException *ex); static gboolean is_open (CamelFolder *folder); static guint32 get_permanent_flags (CamelFolder *folder, CamelException *ex); static CamelFolderOpenMode get_mode (CamelFolder *folder, CamelException *ex); -static gboolean create (CamelFolder *folder, CamelException *ex); -static gboolean delete (CamelFolder *folder, gboolean recurse, - CamelException *ex); - - static GPtrArray *get_subfolder_names (CamelFolder *folder, CamelException *ex); static CamelFolder *get_subfolder (CamelFolder *folder, const gchar *folder_name, + gboolean create, CamelException *ex); static CamelFolder *get_parent_folder (CamelFolder *folder, CamelException *ex); @@ -87,8 +82,6 @@ static CamelStore *get_parent_store (CamelFolder *folder, static gint get_message_count (CamelFolder *folder, CamelException *ex); -static gboolean delete_messages (CamelFolder *folder, - CamelException *ex); static void expunge (CamelFolder *folder, CamelException *ex); @@ -137,12 +130,8 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) camel_folder_class->get_full_name = get_full_name; camel_folder_class->can_hold_folders = can_hold_folders; camel_folder_class->can_hold_messages = can_hold_messages; - camel_folder_class->exists = exists; camel_folder_class->is_open = is_open; camel_folder_class->get_subfolder = get_subfolder; - camel_folder_class->create = create; - camel_folder_class->delete = delete; - camel_folder_class->delete_messages = delete_messages; camel_folder_class->get_parent_folder = get_parent_folder; camel_folder_class->get_parent_store = get_parent_store; camel_folder_class->get_mode = get_mode; @@ -401,32 +390,6 @@ can_hold_messages (CamelFolder *folder) } -static gboolean -exists (CamelFolder *folder, CamelException *ex) -{ - return FALSE; -} - -/** - * camel_folder_exists: - * @folder: folder object - * @ex: a CamelException - * - * Test if a folder exists in a store. A CamelFolder can be created - * without physically existing in a store. In that case, use - * CamelFolder::create to create it. - * - * Return value: whether or not the folder exists - **/ -gboolean -camel_folder_exists (CamelFolder *folder, CamelException *ex) -{ - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - - return CF_CLASS (folder)->exists (folder, ex); -} - - static gboolean is_open (CamelFolder *folder) { @@ -453,7 +416,7 @@ camel_folder_is_open (CamelFolder *folder) static CamelFolder * get_subfolder (CamelFolder *folder, const gchar *folder_name, - CamelException *ex) + gboolean create, CamelException *ex) { CamelFolder *new_folder; gchar *full_name; @@ -466,7 +429,7 @@ get_subfolder (CamelFolder *folder, const gchar *folder_name, full_name = g_strdup_printf ("%s%c%s", current_folder_full_name, folder->separator, folder_name); new_folder = camel_store_get_folder (folder->parent_store, - full_name, ex); + full_name, create, ex); g_free (full_name); return new_folder; @@ -476,6 +439,7 @@ get_subfolder (CamelFolder *folder, const gchar *folder_name, * camel_folder_get_subfolder: * @folder: a folder * @folder_name: subfolder path + * @create: whether or not to create the folder if it doesn't exist * @ex: a CamelException * * This method returns a folder object. This folder is a subfolder of @@ -487,196 +451,14 @@ get_subfolder (CamelFolder *folder, const gchar *folder_name, **/ CamelFolder * camel_folder_get_subfolder (CamelFolder *folder, const gchar *folder_name, - CamelException *ex) + gboolean create, CamelException *ex) { g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); g_return_val_if_fail (camel_folder_is_open (folder), NULL); g_return_val_if_fail (folder_name != NULL, NULL); - return CF_CLASS (folder)->get_subfolder (folder, folder_name, ex); -} - - -/** - * create: creates a folder on its store - * @folder: a CamelFolder object. - * - * this routine handles the recursion mechanism. - * Children classes have to implement the actual - * creation mechanism. They must call this method - * before physically creating the folder in order - * to be sure the parent folder exists. - * Calling this routine on an existing folder is - * not an error, and returns %TRUE. - * - * Return value: %TRUE if the folder exists, %FALSE otherwise - **/ -static gboolean -create (CamelFolder *folder, CamelException *ex) -{ - CamelFolder *parent; - - g_return_val_if_fail (folder->parent_store != NULL, FALSE); - g_return_val_if_fail (folder->name != NULL, FALSE); - - /* if the folder already exists on the store, do nothing and return true */ - if (CF_CLASS (folder)->exists (folder, ex)) - return TRUE; - - if (folder->parent_folder) { - camel_folder_create (folder->parent_folder, ex); - if (camel_exception_get_id (ex)) - return FALSE; - } else if (folder->full_name) { - char *slash, *prefix; - - slash = strrchr(folder->full_name, folder->separator); - if (slash && slash != folder->full_name) { - prefix = g_strndup(folder->full_name, slash-folder->full_name); - parent = camel_store_get_folder (folder->parent_store, prefix, ex); - camel_folder_create (parent, ex); - if (camel_exception_get_id (ex)) - return FALSE; - } - } - return TRUE; -} - - -/** - * camel_folder_create: create the folder object on the physical store - * @folder: folder object to create - * @ex: a CamelException - * - * This routine physically creates the folder on the store. Having - * created the object does not mean the folder physically exists. If - * it does not exist, this routine will create it. If the folder full - * name contains more than one level of hierarchy, all folders between - * the current folder and the last folder name will be created if not - * existing. - * - * Return value: whether or not the operation succeeded - **/ -gboolean -camel_folder_create (CamelFolder *folder, CamelException *ex) -{ - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - g_return_val_if_fail (!camel_folder_is_open (folder), FALSE); - - return CF_CLASS (folder)->create (folder, ex); -} - - -/** - * delete: delete folder - * @folder: folder to delete - * @recurse: true is subfolders must also be deleted - * - * Delete a folder and its subfolders (if recurse is TRUE). - * The scheme is the following: - * 1) delete all messages in the folder - * 2) if recurse is FALSE, and if there are subfolders - * return FALSE, else delete current folder and return TRUE - * if recurse is TRUE, delete subfolders, delete - * current folder and return TRUE - * - * subclasses implementing a protocol with a different - * deletion behaviour must emulate this one or implement - * empty folders deletion and call this routine which - * will do all the works for them. - * Opertions must be done in the folllowing order: - * - call this routine - * - delete empty folder - * - * Return value: true if the folder has been deleted - **/ -static gboolean -delete (CamelFolder *folder, gboolean recurse, CamelException *ex) -{ - GPtrArray *subfolders; - int i; - gboolean ok; - - /* delete all messages in the folder */ - CF_CLASS (folder)->delete_messages (folder, ex); - if (camel_exception_get_id (ex)) - return FALSE; - - subfolders = camel_folder_get_subfolder_names (folder, ex); - if (camel_exception_get_id (ex)) - return FALSE; - - ok = TRUE; - if (recurse) { /* delete subfolders */ - if (subfolders) { - for (i = 0; ok && i < subfolders->len; i++) { - CamelFolder *sf; - - sf = camel_folder_get_subfolder (folder, subfolders->pdata[i], ex); - camel_folder_delete (sf, TRUE, ex); - if (camel_exception_get_id (ex)) - ok = FALSE; - } - } - } else if (subfolders) { - camel_exception_set (ex, CAMEL_EXCEPTION_FOLDER_NON_EMPTY, - "folder has subfolders"); - ok = FALSE; - } - - if (subfolders) - camel_folder_free_subfolder_names (folder, subfolders); - - return ok; -} - -/** - * camel_folder_delete: delete a folder - * @folder: folder to delete - * @recurse: %TRUE if subfolders must be deleted - * @ex: a CamelException - * - * Delete a folder. All messages in the folder are deleted before the - * folder is deleted. When @recurse is %TRUE, all subfolders are - * deleted too. When @recurse is %FALSE and folder contains - * subfolders, all messages are deleted, but folder deletion fails. - * - * Return value: whether or not deletion was successful - **/ -gboolean -camel_folder_delete (CamelFolder *folder, gboolean recurse, CamelException *ex) -{ - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - g_return_val_if_fail (!camel_folder_is_open (folder), FALSE); - - return CF_CLASS (folder)->delete (folder, recurse, ex); -} - - -static gboolean -delete_messages (CamelFolder *folder, CamelException *ex) -{ - g_warning ("CamelFolder::delete_messages not implemented for `%s'", - gtk_type_name (GTK_OBJECT_TYPE (folder))); - return FALSE; -} - -/** - * camel_folder_delete_messages: delete all messages in the folder - * @folder: folder - * @ex: a CamelException - * - * Delete all messages stored in a folder. - * - * Return value: whether or not the messages could be deleted - **/ -gboolean -camel_folder_delete_messages (CamelFolder *folder, CamelException *ex) -{ - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - g_return_val_if_fail (!camel_folder_is_open (folder), FALSE); - - return CF_CLASS (folder)->delete_messages (folder, ex); + return CF_CLASS (folder)->get_subfolder (folder, folder_name, + create, ex); } diff --git a/camel/camel-folder.h b/camel/camel-folder.h index c90802c6c2..7297f00cc6 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -99,25 +99,13 @@ typedef struct { gboolean (*can_hold_messages) (CamelFolder *folder); - gboolean (*exists) (CamelFolder *folder, - CamelException *ex); - gboolean (*is_open) (CamelFolder *folder); CamelFolder * (*get_subfolder) (CamelFolder *folder, const gchar *folder_name, + gboolean create, CamelException *ex); - gboolean (*create) (CamelFolder *folder, - CamelException *ex); - - gboolean (*delete) (CamelFolder *folder, - gboolean recurse, - CamelException *ex); - - gboolean (*delete_messages) (CamelFolder *folder, - CamelException *ex); - CamelFolder * (*get_parent_folder) (CamelFolder *folder, CamelException *ex); @@ -186,6 +174,7 @@ GtkType camel_folder_get_type (void); CamelFolder * camel_folder_get_subfolder (CamelFolder *folder, const gchar *folder_name, + gboolean create, CamelException *ex); void camel_folder_open (CamelFolder *folder, @@ -197,8 +186,6 @@ void camel_folder_close (CamelFolder *folder, gboolean expunge, CamelException *ex); -gboolean camel_folder_create (CamelFolder *folder, - CamelException *ex); CamelFolder * camel_folder_get_parent_folder (CamelFolder *folder, CamelException *ex); CamelStore * camel_folder_get_parent_store (CamelFolder *folder, @@ -208,11 +195,6 @@ GList * camel_folder_list_subfolders (CamelFolder *folder, /* delete operations */ -gboolean camel_folder_delete (CamelFolder *folder, - gboolean recurse, - CamelException *ex); -gboolean camel_folder_delete_messages (CamelFolder *folder, - CamelException *ex); void camel_folder_expunge (CamelFolder *folder, CamelException *ex); @@ -223,8 +205,6 @@ const gchar * camel_folder_get_full_name (CamelFolder *folder); /* various properties accessors */ -gboolean camel_folder_exists (CamelFolder *folder, - CamelException *ex); guint32 camel_folder_get_permanent_flags (CamelFolder *folder, CamelException *ex); diff --git a/camel/camel-store.c b/camel/camel-store.c index ab0c4241f7..d729bf10e7 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -35,7 +35,9 @@ static CamelServiceClass *parent_class = NULL; #define CS_CLASS(so) CAMEL_STORE_CLASS (GTK_OBJECT(so)->klass) static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - CamelException *ex); + gboolean create, CamelException *ex); +static void delete_folder (CamelStore *store, const char *folder_name, + CamelException *ex); static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); @@ -59,6 +61,7 @@ camel_store_class_init (CamelStoreClass *camel_store_class) /* virtual method definition */ camel_store_class->get_folder = get_folder; + camel_store_class->delete_folder = delete_folder; camel_store_class->get_folder_name = get_folder_name; camel_store_class->get_root_folder_name = get_root_folder_name; camel_store_class->get_default_folder_name = get_default_folder_name; @@ -120,13 +123,29 @@ finalize (GtkObject *object) static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, CamelException *ex) +get_folder (CamelStore *store, const char *folder_name, + gboolean create, CamelException *ex) { g_warning ("CamelStore::get_folder not implemented for `%s'", gtk_type_name (GTK_OBJECT_TYPE (store))); return NULL; } +static void +delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) +{ + g_warning ("CamelStore::delete_folder not implemented for `%s'", + gtk_type_name (GTK_OBJECT_TYPE (store))); +} + + +/* CamelStore::get_folder_name should: + * a) make sure that the provided name is valid + * b) return it in canonical form, in allocated memory. + * + * This is used to make sure that duplicate names for the same folder + * don't result in duplicate cache entries. + */ static char * get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) @@ -170,43 +189,44 @@ cache_folder (CamelStore *store, const char *folder_name, CamelFolder *folder) g_warning ("Caching folder %s that already exists.", folder_name); } - g_hash_table_insert (store->folders, camel_folder_get_full_name (folder), folder); + g_hash_table_insert (store->folders, g_strdup (folder_name), folder); gtk_signal_connect_object (GTK_OBJECT (folder), "destroy", GTK_SIGNAL_FUNC (CS_CLASS (store)->uncache_folder), GTK_OBJECT (store)); } +static gboolean +folder_matches (gpointer key, gpointer value, gpointer user_data) +{ + if (value == user_data) { + g_free (key); + return TRUE; + } else + return FALSE; +} + static void uncache_folder (CamelStore *store, CamelFolder *folder) { - /* FIXME: free name index */ - g_hash_table_remove (store->folders, - camel_folder_get_full_name (folder)); + g_hash_table_foreach_remove (store->folders, folder_matches, folder); } static CamelFolder * get_folder_internal (CamelStore *store, const char *folder_name, - CamelException *ex) + gboolean create, CamelException *ex) { CamelFolder *folder = NULL; - printf("Getting folder %p '%s'\n", store, folder_name); /* Try cache first. */ folder = CS_CLASS (store)->lookup_folder (store, folder_name); - if (folder) { - printf("Folder cached!\n"); - } else { - printf("Folder not cached!\n"); - } - if (!folder) { - folder = CS_CLASS (store)->get_folder (store, folder_name, ex); + folder = CS_CLASS (store)->get_folder (store, folder_name, + create, ex); if (!folder) return NULL; - printf("storing folder in cache: %p '%s'\n", store, folder_name); CS_CLASS (store)->cache_folder (store, folder_name, folder); } @@ -219,33 +239,55 @@ get_folder_internal (CamelStore *store, const char *folder_name, * camel_store_get_folder: Return the folder corresponding to a path. * @store: a CamelStore * @folder_name: name of the folder to get + * @create: whether or not to create the folder if it doesn't already exist * @ex: a CamelException * - * Returns the folder corresponding to the path "name". If the path - * begins with the separator character, it is relative to the root - * folder. Otherwise, it is relative to the default folder. The folder - * does not necessarily already exist on the store. To test if it - * already exists, use its "exists" method. If it does not exist, you - * can create it with its "create" method. + * Returns the folder corresponding to the path @folder_name. If the + * path begins with the separator character, it is relative to the + * root folder. Otherwise, it is relative to the default folder. If + * @create is %TRUE and the named folder does not already exist, it will + * be created. * * Return value: the folder **/ CamelFolder * camel_store_get_folder (CamelStore *store, const char *folder_name, - CamelException *ex) + gboolean create, CamelException *ex) { char *name; CamelFolder *folder = NULL; name = CS_CLASS (store)->get_folder_name (store, folder_name, ex); if (name) { - folder = get_folder_internal (store, name, ex); + folder = get_folder_internal (store, name, create, ex); g_free (name); } return folder; } +/** + * camel_store_delete_folder: Delete the folder corresponding to a path. + * @store: a CamelStore + * @folder_name: name of the folder to delete + * @ex: a CamelException + * + * Deletes the named folder. The folder must be empty. + **/ +void +camel_store_delete_folder (CamelStore *store, const char *folder_name, + CamelException *ex) +{ + char *name; + + name = CS_CLASS (store)->get_folder_name (store, folder_name, ex); + if (name) { + CS_CLASS (store)->delete_folder (store, name, ex); + g_free (name); + } +} + + /** * camel_store_get_root_folder: return the top-level folder * @@ -262,7 +304,7 @@ camel_store_get_root_folder (CamelStore *store, CamelException *ex) name = CS_CLASS (store)->get_root_folder_name (store, ex); if (name) { - folder = get_folder_internal (store, name, ex); + folder = get_folder_internal (store, name, TRUE, ex); g_free (name); } return folder; @@ -285,7 +327,7 @@ camel_store_get_default_folder (CamelStore *store, CamelException *ex) name = CS_CLASS (store)->get_default_folder_name (store, ex); if (name) { - folder = get_folder_internal (store, name, ex); + folder = get_folder_internal (store, name, TRUE, ex); g_free (name); } return folder; diff --git a/camel/camel-store.h b/camel/camel-store.h index 7f1aa89d59..6d2d9e53e9 100644 --- a/camel/camel-store.h +++ b/camel/camel-store.h @@ -56,6 +56,11 @@ typedef struct { CamelServiceClass parent_class; CamelFolder * (*get_folder) (CamelStore *store, + const char *folder_name, + gboolean create, + CamelException *ex); + + void (*delete_folder) (CamelStore *store, const char *folder_name, CamelException *ex); @@ -84,12 +89,17 @@ GtkType camel_store_get_type (void); /* public methods */ CamelFolder * camel_store_get_folder (CamelStore *store, const char *folder_name, + gboolean create, CamelException *ex); CamelFolder * camel_store_get_root_folder (CamelStore *store, CamelException *ex); CamelFolder * camel_store_get_default_folder (CamelStore *store, CamelException *ex); +void camel_store_delete_folder (CamelStore *store, + const char *folder_name, + CamelException *ex); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index 56af83a98b..305935fcdd 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -62,10 +62,6 @@ static void mbox_init (CamelFolder *folder, CamelStore *parent_store, static void mbox_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex); static void mbox_close (CamelFolder *folder, gboolean expunge, CamelException *ex); -static gboolean mbox_exists (CamelFolder *folder, CamelException *ex); -static gboolean mbox_create(CamelFolder *folder, CamelException *ex); -static gboolean mbox_delete (CamelFolder *folder, gboolean recurse, CamelException *ex); -static gboolean mbox_delete_messages (CamelFolder *folder, CamelException *ex); static gint mbox_get_message_count (CamelFolder *folder, CamelException *ex); static void mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex); static GPtrArray *mbox_get_uids (CamelFolder *folder, CamelException *ex); @@ -102,10 +98,6 @@ camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class) camel_folder_class->init = mbox_init; camel_folder_class->open = mbox_open; camel_folder_class->close = mbox_close; - camel_folder_class->exists = mbox_exists; - camel_folder_class->create = mbox_create; - camel_folder_class->delete = mbox_delete; - camel_folder_class->delete_messages = mbox_delete_messages; camel_folder_class->get_message_count = mbox_get_message_count; camel_folder_class->append_message = mbox_append_message; camel_folder_class->get_uids = mbox_get_uids; @@ -285,299 +277,6 @@ mbox_expunge (CamelFolder *folder, CamelException *ex) gtk_signal_emit_by_name((GtkObject *)folder, "folder_changed", 0); } -/* FIXME: clean up this snot */ -static gboolean -mbox_exists (CamelFolder *folder, CamelException *ex) -{ - CamelMboxFolder *mbox_folder; - struct stat stat_buf; - gint stat_error; - gboolean exists; - - g_assert(folder != NULL); - - mbox_folder = CAMEL_MBOX_FOLDER (folder); - - /* check if the mbox file path is determined */ - if (!mbox_folder->folder_file_path) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, - "undetermined folder file path. Maybe use set_name ?"); - return FALSE; - } - - /* check if the mbox dir path is determined */ - if (!mbox_folder->folder_dir_path) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, - "undetermined folder directory path. Maybe use set_name ?"); - return FALSE; - } - - - /* we should not check for that here */ -#if 0 - /* check if the mbox directory exists */ - access_result = access (mbox_folder->folder_dir_path, F_OK); - if (access_result < 0) { - camel_exception_set (ex, - CAMEL_EXCEPTION_SYSTEM, - strerror(errno)); - return FALSE; - } - stat_error = stat (mbox_folder->folder_dir_path, &stat_buf); - if (stat_error == -1) { - camel_exception_set (ex, - CAMEL_EXCEPTION_SYSTEM, - strerror(errno)); - return FALSE; - } - exists = S_ISDIR (stat_buf.st_mode); - if (!exists) return FALSE; -#endif - - - /* check if the mbox file exists */ - stat_error = stat (mbox_folder->folder_file_path, &stat_buf); - if (stat_error == -1) - return FALSE; - - exists = S_ISREG (stat_buf.st_mode); - /* we should check the rights here */ - - return exists; -} - -/* FIXME: clean up this snot */ -static gboolean -mbox_create (CamelFolder *folder, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - const gchar *folder_file_path, *folder_dir_path; - mode_t dir_mode = S_IRWXU; - gint mkdir_error; - gboolean folder_already_exists; - int creat_fd; - - g_assert(folder != NULL); - - /* call default implementation */ - parent_class->create (folder, ex); - - /* get the paths of what we need to create */ - folder_file_path = mbox_folder->folder_file_path; - folder_dir_path = mbox_folder->folder_dir_path; - - if (!(folder_file_path || folder_dir_path)) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, - "invalid folder path. Use set_name ?"); - return FALSE; - } - - - /* if the folder already exists, simply return */ - folder_already_exists = camel_folder_exists (folder,ex); - if (camel_exception_get_id (ex)) - return FALSE; - - if (folder_already_exists) - return TRUE; - - - /* create the directory for the subfolders */ - mkdir_error = mkdir (folder_dir_path, dir_mode); - if (mkdir_error == -1) - goto io_error; - - - /* create the mbox file */ - /* it must be rw for the user and none for the others */ - creat_fd = open (folder_file_path, - O_WRONLY | O_CREAT | O_APPEND, - 0600); - if (creat_fd == -1) - goto io_error; - - close (creat_fd); - - return TRUE; - - /* exception handling for io errors */ - io_error : - if (errno == EACCES) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "You don't have the permission to create the mbox file."); - return FALSE; - } else { - camel_exception_set (ex, - CAMEL_EXCEPTION_SYSTEM, - "Unable to create the mbox file."); - return FALSE; - } -} - - -/* FIXME: cleanup */ -static gboolean -mbox_delete (CamelFolder *folder, gboolean recurse, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - const gchar *folder_file_path, *folder_dir_path; - gint rmdir_error = 0; - gint unlink_error = 0; - gboolean folder_already_exists; - - g_assert(folder != NULL); - - /* check if the folder object exists */ - - /* in the case where the folder does not exist, - return immediatly */ - folder_already_exists = camel_folder_exists (folder, ex); - if (camel_exception_get_id (ex)) - return FALSE; - - if (!folder_already_exists) - return TRUE; - - - /* call default implementation. - It should delete the messages in the folder - and recurse the operation to subfolders */ - parent_class->delete (folder, recurse, ex); - - - /* get the paths of what we need to be deleted */ - folder_file_path = mbox_folder->folder_file_path; - folder_dir_path = mbox_folder->folder_file_path; - - if (!(folder_file_path || folder_dir_path)) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, - "invalid folder path. Use set_name ?"); - return FALSE; - } - - - /* physically delete the directory */ - rmdir_error = rmdir (folder_dir_path); - if (rmdir_error == -1) - switch (errno) { - case EACCES : - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "Not enough permission to delete the mbox folder"); - return FALSE; - break; - - case ENOTEMPTY : - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_NON_EMPTY, - "mbox folder not empty. Cannot delete it. Maybe use recurse flag ?"); - return FALSE; - break; - default : - camel_exception_set (ex, - CAMEL_EXCEPTION_SYSTEM, - "Unable to delete the mbox folder."); - return FALSE; - } - - /* physically delete the file */ - unlink_error = unlink (folder_dir_path); - if (unlink_error == -1) - switch (errno) { - case EACCES : - case EPERM : - case EROFS : - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "Not enough permission to delete the mbox file"); - return FALSE; - break; - - case EFAULT : - case ENOENT : - case ENOTDIR : - case EISDIR : - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_PATH, - "Invalid mbox file"); - return FALSE; - break; - - default : - camel_exception_set (ex, - CAMEL_EXCEPTION_SYSTEM, - "Unable to delete the mbox folder."); - return FALSE; - } - - - return TRUE; -} - -/* TODO: remove this */ -gboolean -mbox_delete_messages (CamelFolder *folder, CamelException *ex) -{ - - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - const gchar *folder_file_path; - gboolean folder_already_exists; - int creat_fd; - g_assert(folder!=NULL); - - /* in the case where the folder does not exist, - return immediatly */ - folder_already_exists = camel_folder_exists (folder, ex); - if (camel_exception_get_id (ex)) return FALSE; - - if (!folder_already_exists) return TRUE; - - - - /* get the paths of the mbox file we need to delete */ - folder_file_path = mbox_folder->folder_file_path; - - if (!folder_file_path) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, - "invalid folder path. Use set_name ?"); - return FALSE; - } - - - /* create the mbox file */ - /* it must be rw for the user and none for the others */ - creat_fd = open (folder_file_path, - O_WRONLY | O_TRUNC, - 0600); - if (creat_fd == -1) - goto io_error; - close (creat_fd); - - return TRUE; - - /* exception handling for io errors */ - io_error : - if (errno == EACCES) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "You don't have the permission to write in the mbox file."); - return FALSE; - } else { - camel_exception_set (ex, - CAMEL_EXCEPTION_SYSTEM, - "Unable to write in the mbox file."); - return FALSE; - } - - -} - static gint mbox_get_message_count (CamelFolder *folder, CamelException *ex) { diff --git a/camel/providers/mbox/camel-mbox-store.c b/camel/providers/mbox/camel-mbox-store.c index 8db2f9338e..6a2b826f9b 100644 --- a/camel/providers/mbox/camel-mbox-store.c +++ b/camel/providers/mbox/camel-mbox-store.c @@ -24,6 +24,11 @@ #include +#include +#include +#include +#include + #include "camel-mbox-store.h" #include "camel-mbox-folder.h" #include "camel-exception.h" @@ -35,7 +40,9 @@ #define CMBOXF_CLASS(so) CAMEL_MBOX_FOLDER_CLASS (GTK_OBJECT(so)->klass) static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - CamelException *ex); + gboolean create, CamelException *ex); +static void delete_folder (CamelStore *store, const char *folder_name, + CamelException *ex); static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); @@ -46,6 +53,7 @@ camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class) /* virtual method overload */ camel_store_class->get_folder = get_folder; + camel_store_class->delete_folder = delete_folder; camel_store_class->get_folder_name = get_folder_name; } @@ -101,29 +109,127 @@ camel_mbox_store_get_toplevel_dir (CamelMboxStore *store) } - static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, CamelException *ex) +get_folder (CamelStore *store, const char *folder_name, gboolean create, + CamelException *ex) { - CamelMboxFolder *new_mbox_folder; CamelFolder *new_folder; + char *name; + struct stat st; + + name = g_strdup_printf ("%s%s", CAMEL_SERVICE (store)->url->path, + folder_name); + + if (stat (name, &st) == -1) { + int fd; + + if (errno != ENOENT) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Could not open folder `%s':" + "\n%s", folder_name, + g_strerror (errno)); + g_free (name); + return NULL; + } + if (!create) { + camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, + "Folder `%s' does not exist.", + folder_name); + g_free (name); + return NULL; + } + + fd = open (name, O_WRONLY | O_CREAT | O_APPEND, + S_IRUSR | S_IWUSR); + g_free (name); + if (fd == -1) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Could not create folder `%s':" + "\n%s", folder_name, + g_strerror (errno)); + return NULL; + } + close (fd); + } else if (!S_ISREG (st.st_mode)) { + camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, + "`%s' is not a regular file.", + name); + g_free (name); + return NULL; + } - new_mbox_folder = gtk_type_new (CAMEL_MBOX_FOLDER_TYPE); - new_folder = CAMEL_FOLDER (new_mbox_folder); + new_folder = gtk_type_new (CAMEL_MBOX_FOLDER_TYPE); - /* XXX We shouldn't be passing NULL here, but it's equivalent to - * what was there before, and there's no - * CamelMboxFolder::get_subfolder yet anyway... - */ CF_CLASS (new_folder)->init (new_folder, store, NULL, folder_name, '/', ex); return new_folder; } +static void +delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) +{ + char *name, *name2; + struct stat st; + int status; + + name = g_strdup_printf ("%s%s", CAMEL_SERVICE (store)->url->path, + folder_name); + if (stat (name, &st) == -1) { + if (errno == ENOENT) + return; + + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Could not delete folder `%s':\n%s", + folder_name, g_strerror (errno)); + g_free (name); + return; + } + if (!S_ISREG (st.st_mode)) { + camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, + "`%s' is not a regular file.", name); + g_free (name); + return; + } + if (st.st_size != 0) { + camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_NON_EMPTY, + "Folder `%s' is not empty. Not deleted.", + folder_name); + g_free (name); + return; + } + + /* Delete index and summary first, then the main file. */ + name2 = g_strdup_printf ("%s.ibex", name); + status = unlink (name2); + g_free (name2); + if (status == 0 || errno == ENOENT) { + name2 = g_strdup_printf ("%s-ev-summary", name); + status = unlink (name2); + g_free (name2); + } + if (status == 0 || errno == ENOENT) + status = unlink (name); + g_free (name); + + if (status == -1 && errno != ENOENT) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Could not delete folder `%s':\n%s", + folder_name, g_strerror (errno)); + } +} + static char * get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) { - return g_strdup (folder_name); + /* For now, we don't allow hieararchy. FIXME. */ + if (strchr (folder_name + 1, '/')) { + camel_exception_set (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, + "Mbox folders may not be nested."); + return NULL; + } + + return *folder_name == '/' ? g_strdup (folder_name) : + g_strdup_printf ("/%s", folder_name); } diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c index 396bbc04f6..7355bd048b 100644 --- a/camel/providers/pop3/camel-pop3-folder.c +++ b/camel/providers/pop3/camel-pop3-folder.c @@ -39,7 +39,6 @@ static void pop3_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex); static void pop3_close (CamelFolder *folder, gboolean expunge, CamelException *ex); -static gboolean delete_messages (CamelFolder *folder, CamelException *ex); static gint get_message_count (CamelFolder *folder, CamelException *ex); static GPtrArray *get_uids (CamelFolder *folder, CamelException *ex); @@ -61,7 +60,6 @@ camel_pop3_folder_class_init (CamelPop3FolderClass *camel_pop3_folder_class) /* virtual method overload */ camel_folder_class->open = pop3_open; camel_folder_class->close = pop3_close; - camel_folder_class->delete_messages = delete_messages; camel_folder_class->get_message_count = get_message_count; camel_folder_class->get_uids = get_uids; @@ -138,32 +136,6 @@ pop3_close (CamelFolder *folder, gboolean expunge, CamelException *ex) parent_class->close (folder, expunge, ex); } -static gboolean -delete_messages (CamelFolder *folder, CamelException *ex) -{ - int msgs; - gboolean status; - - msgs = get_message_count (folder, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) - return FALSE; - - status = TRUE; - for (; msgs > 0; msgs--) { - status = status && - (camel_pop3_command (CAMEL_POP3_STORE (folder->parent_store), - NULL, "DELE %d", msgs) == - CAMEL_POP3_OK); - } - - if (!status) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Unable to delete all messages."); - } - - return status; -} - static CamelMimeMessage * get_message_by_uid (CamelFolder *folder, const char *uid, CamelException *ex) diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index 813ab6eaf7..9607d6723f 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -64,7 +64,7 @@ static GList *query_auth_types (CamelService *service, CamelException *ex); static void free_auth_types (CamelService *service, GList *authtypes); static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - CamelException *ex); + gboolean create, CamelException *ex); static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); static char *get_root_folder_name (CamelStore *store, CamelException *ex); @@ -101,7 +101,6 @@ static void camel_pop3_store_init (gpointer object, gpointer klass) { CamelService *service = CAMEL_SERVICE (object); - CamelStore *store = CAMEL_STORE (object); service->url_flags = ( CAMEL_SERVICE_URL_NEED_USER | CAMEL_SERVICE_URL_NEED_HOST ); @@ -486,7 +485,8 @@ pop3_disconnect (CamelService *service, CamelException *ex) } static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, CamelException *ex) +get_folder (CamelStore *store, const char *folder_name, + gboolean create, CamelException *ex) { return camel_pop3_folder_new (store, ex); } diff --git a/camel/providers/vee/camel-vee-folder.c b/camel/providers/vee/camel-vee-folder.c index 0d6abf17d2..af316a0d6f 100644 --- a/camel/providers/vee/camel-vee-folder.c +++ b/camel/providers/vee/camel-vee-folder.c @@ -44,7 +44,6 @@ static void vee_init (CamelFolder *folder, CamelStore *parent_store, static void vee_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex); static void vee_close (CamelFolder *folder, gboolean expunge, CamelException *ex); -static gboolean vee_exists (CamelFolder *folder, CamelException *ex); static GPtrArray *vee_get_uids (CamelFolder *folder, CamelException *ex); GPtrArray *vee_get_summary (CamelFolder *folder, CamelException *ex); @@ -109,7 +108,6 @@ camel_vee_folder_class_init (CamelVeeFolderClass *klass) folder_class->init = vee_init; folder_class->open = vee_open; folder_class->close = vee_close; - folder_class->exists = vee_exists; folder_class->get_uids = vee_get_uids; folder_class->get_summary = vee_get_summary; @@ -267,12 +265,6 @@ static void vee_close (CamelFolder *folder, gboolean expunge, CamelException *ex /* FIXME: close vfolder? */ } -/* vfolders always exist? */ -static gboolean vee_exists (CamelFolder *folder, CamelException *ex) -{ - return TRUE; -} - static void vee_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex) { CamelVeeFolder *vf = (CamelVeeFolder *)folder; diff --git a/camel/providers/vee/camel-vee-store.c b/camel/providers/vee/camel-vee-store.c index b62a6b9fab..177fc0a371 100644 --- a/camel/providers/vee/camel-vee-store.c +++ b/camel/providers/vee/camel-vee-store.c @@ -22,7 +22,7 @@ #include "camel-vee-store.h" #include "camel-vee-folder.h" -static CamelFolder *vee_get_folder (CamelStore *store, const char *folder_name, CamelException *ex); +static CamelFolder *vee_get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex); static char *vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); struct _CamelVeeStorePrivate { @@ -111,7 +111,7 @@ camel_vee_store_new (void) } static CamelFolder * -vee_get_folder (CamelStore *store, const char *folder_name, CamelException *ex) +vee_get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex) { CamelFolder *folder; @@ -126,7 +126,6 @@ vee_get_folder (CamelStore *store, const char *folder_name, CamelException *ex) static char * vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) { -#warning "What purpose does this function serve?" return g_strdup(folder_name); } -- cgit