diff options
-rw-r--r-- | camel/ChangeLog | 27 | ||||
-rw-r--r-- | camel/camel-exception-list.def | 1 | ||||
-rw-r--r-- | camel/camel-folder.c | 232 | ||||
-rw-r--r-- | camel/camel-folder.h | 24 | ||||
-rw-r--r-- | camel/camel-store.c | 94 | ||||
-rw-r--r-- | camel/camel-store.h | 10 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 301 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-store.c | 128 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-folder.c | 28 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-store.c | 6 | ||||
-rw-r--r-- | camel/providers/vee/camel-vee-folder.c | 8 | ||||
-rw-r--r-- | camel/providers/vee/camel-vee-store.c | 5 |
12 files changed, 236 insertions, 628 deletions
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 <danw@helixcode.com> + + * 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 <fejj@helixcode.com> * 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 <NotZed@HelixCode.com> ->>>>>>> 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; @@ -402,32 +391,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) { return folder->open_state == FOLDER_OPEN; @@ -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 @@ -57,6 +57,11 @@ typedef struct { CamelFolder * (*get_folder) (CamelStore *store, const char *folder_name, + gboolean create, + CamelException *ex); + + void (*delete_folder) (CamelStore *store, + const char *folder_name, CamelException *ex); char * (*get_folder_name) (CamelStore *store, @@ -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 <config.h> +#include <sys/stat.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + #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); } |