aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/local/camel-maildir-folder.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/local/camel-maildir-folder.c')
-rw-r--r--camel/providers/local/camel-maildir-folder.c229
1 files changed, 0 insertions, 229 deletions
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
deleted file mode 100644
index 198e4ebc00..0000000000
--- a/camel/providers/local/camel-maildir-folder.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Authors: Michael Zucchi <notzed@helixcode.com>
- *
- * Copyright (C) 1999, 2000 Helix Code Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include "camel-maildir-folder.h"
-#include "camel-maildir-store.h"
-#include "string-utils.h"
-#include "camel-stream-fs.h"
-#include "camel-maildir-summary.h"
-#include "camel-data-wrapper.h"
-#include "camel-mime-message.h"
-#include "camel-exception.h"
-
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-static CamelLocalFolderClass *parent_class = NULL;
-
-/* Returns the class for a CamelMaildirFolder */
-#define CMAILDIRF_CLASS(so) CAMEL_MAILDIR_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CMAILDIRS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static CamelLocalSummary *maildir_create_summary(const char *path, const char *folder, ibex *index);
-
-static void maildir_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, CamelException * ex);
-static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex);
-
-static void maildir_finalize(CamelObject * object);
-
-static void camel_maildir_folder_class_init(CamelObjectClass * camel_maildir_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_maildir_folder_class);
- CamelLocalFolderClass *lclass = (CamelLocalFolderClass *)camel_maildir_folder_class;
-
- parent_class = CAMEL_LOCAL_FOLDER_CLASS (camel_type_get_global_classfuncs(camel_local_folder_get_type()));
-
- /* virtual method definition */
-
- /* virtual method overload */
- camel_folder_class->append_message = maildir_append_message;
- camel_folder_class->get_message = maildir_get_message;
-
- lclass->create_summary = maildir_create_summary;
-}
-
-static void maildir_init(gpointer object, gpointer klass)
-{
- /*CamelFolder *folder = object;
- CamelMaildirFolder *maildir_folder = object;*/
-}
-
-static void maildir_finalize(CamelObject * object)
-{
- /*CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER(object);*/
-}
-
-CamelType camel_maildir_folder_get_type(void)
-{
- static CamelType camel_maildir_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_maildir_folder_type == CAMEL_INVALID_TYPE) {
- camel_maildir_folder_type = camel_type_register(CAMEL_LOCAL_FOLDER_TYPE, "CamelMaildirFolder",
- sizeof(CamelMaildirFolder),
- sizeof(CamelMaildirFolderClass),
- (CamelObjectClassInitFunc) camel_maildir_folder_class_init,
- NULL,
- (CamelObjectInitFunc) maildir_init,
- (CamelObjectFinalizeFunc) maildir_finalize);
- }
-
- return camel_maildir_folder_type;
-}
-
-CamelFolder *
-camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex)
-{
- CamelFolder *folder;
-
- d(printf("Creating maildir folder: %s\n", full_name));
-
- folder = (CamelFolder *)camel_object_new(CAMEL_MAILDIR_FOLDER_TYPE);
- folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder,
- parent_store, full_name, flags, ex);
-
- return folder;
-}
-
-static CamelLocalSummary *maildir_create_summary(const char *path, const char *folder, ibex *index)
-{
- return (CamelLocalSummary *)camel_maildir_summary_new(path, folder, index);
-}
-
-static void maildir_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, CamelException * ex)
-{
- CamelMaildirFolder *maildir_folder = (CamelMaildirFolder *)folder;
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- CamelStream *output_stream;
- CamelMessageInfo *mi;
- CamelMaildirMessageInfo *mdi;
- char *name, *dest;
-
- d(printf("Appending message\n"));
-
- /* add it to the summary/assign the uid, etc */
- mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex);
- if (camel_exception_is_set(ex)) {
- return;
- }
-
- mdi = (CamelMaildirMessageInfo *)mi;
-
- d(printf("Appending message: uid is %s filename is %s\n", camel_message_info_uid(mi), mdi->filename));
-
- /* write it out to tmp, use the uid we got from the summary */
- name = g_strdup_printf("%s/tmp/%s", lf->folder_path, camel_message_info_uid(mi));
- output_stream = camel_stream_fs_new_with_name(name, O_WRONLY|O_CREAT, 0600);
- if (output_stream == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to maildir folder: %s: %s"), name, g_strerror(errno));
- g_free(name);
- return;
- }
-
- if (camel_data_wrapper_write_to_stream((CamelDataWrapper *)message, output_stream) == -1
- || camel_stream_close(output_stream) == -1) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to maildir folder: %s: %s"), name, g_strerror(errno));
- camel_object_unref((CamelObject *)output_stream);
- unlink(name);
- g_free(name);
- return;
- }
-
- /* now move from tmp to cur (bypass new, does it matter?) */
- dest = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi));
- if (rename(name, dest) == 1) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to maildir folder: %s: %s"), name, g_strerror(errno));
- camel_object_unref((CamelObject *)output_stream);
- unlink(name);
- g_free(name);
- g_free(dest);
- return;
- }
-
- g_free(dest);
- g_free(name);
-
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", ((CamelLocalFolder *)maildir_folder)->changes);
- camel_folder_change_info_clear(((CamelLocalFolder *)maildir_folder)->changes);
-}
-
-static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex)
-{
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- CamelStream *message_stream = NULL;
- CamelMimeMessage *message = NULL;
- CamelMessageInfo *info;
- char *name;
- CamelMaildirMessageInfo *mdi;
-
- d(printf("getting message: %s\n", uid));
-
- /* get the message summary info */
- if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), uid, _("No such message"));
- return NULL;
- }
-
- mdi = (CamelMaildirMessageInfo *)info;
-
- /* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */
- name = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi));
-
- camel_folder_summary_info_free(folder->summary, info);
-
- if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"),
- name, g_strerror(errno));
- g_free(name);
- return NULL;
- }
-
- message = camel_mime_message_new();
- if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"),
- name, _("Invalid message contents"));
- g_free(name);
- camel_object_unref((CamelObject *)message_stream);
- camel_object_unref((CamelObject *)message);
- return NULL;
-
- }
- camel_object_unref((CamelObject *)message_stream);
- g_free(name);
-
- return message;
-}
mentation for the folder operations. */
-
-static EStorageResult
-create_folder_directory (ELocalStorage *local_storage,
- const char *path,
- const char *type,
- const char *description,
- char **physical_path_return)
-{
- EStorage *storage;
- ELocalStoragePrivate *priv;
- const char *folder_name;
- char *physical_path;
-
- storage = E_STORAGE (local_storage);
- priv = local_storage->priv;
-
- *physical_path_return = NULL;
- g_assert (g_path_is_absolute (path));
-
- folder_name = g_basename (path);
-
- if (folder_name != path + 1) {
- char *subfolders_directory_physical_path;
- char *parent_path;
-
- /* Create the `subfolders' subdirectory under the parent. */
-
- parent_path = g_strndup (path, folder_name - path);
- subfolders_directory_physical_path = e_path_to_physical (priv->base_path, parent_path);
- g_free (parent_path);
-
- if (! g_file_exists (subfolders_directory_physical_path)) {
- if (mkdir (subfolders_directory_physical_path, 0700) == -1) {
- g_free (subfolders_directory_physical_path);
- return errno_to_storage_result ();
- }
- }
- g_free (subfolders_directory_physical_path);
- }
-
- physical_path = e_path_to_physical (priv->base_path, path);
-
- /* Create the directory that holds the folder. */
-
- *physical_path_return = physical_path;
- if (mkdir (physical_path, 0700) == -1) {
- return errno_to_storage_result ();
- }
-
- return E_STORAGE_OK;
-}
-
-static EStorageResult
-create_folder (ELocalStorage *local_storage,
- const char *path,
- const char *type,
- const char *description,
- EStorageResultCallback callback,
- void *data)
-{
- EStorage *storage;
- ELocalStoragePrivate *priv;
- EvolutionShellComponentClient *component_client;
- AsyncCreateFolderCallbackData *callback_data;
- EStorageResult result;
- const char *folder_name;
- char *physical_path;
- char *physical_uri;
-
- storage = E_STORAGE (local_storage);
- priv = local_storage->priv;
- component_client = e_folder_type_registry_get_handler_for_type (priv->folder_type_registry,
- type);
- if (component_client == NULL) {
- if (callback != NULL)
- (* callback) (storage, E_STORAGE_INVALIDTYPE, data);
- return E_STORAGE_INVALIDTYPE;
- }
-
- g_assert (g_path_is_absolute (path));
-
- result = create_folder_directory (local_storage, path, type, description, &physical_path);
- if (result != E_STORAGE_OK) {
- g_warning ("physical_path: %s", physical_path);
- if (callback != NULL)
- (* callback) (storage, result, data);
- g_free (physical_path);
- return result;
- }
-
- folder_name = g_basename (path);
-
- /* Finally tell the component to do the job of creating the physical files in it. */
-
- /* FIXME: We should put the operations on a queue so that we can cancel them when
- the ELocalStorage is destroyed. */
-
- physical_uri = g_strconcat ("file://", physical_path, NULL);
-
- callback_data = g_new (AsyncCreateFolderCallbackData, 1);
- callback_data->storage = E_STORAGE (local_storage);
- callback_data->path = g_strdup (path);
- callback_data->display_name = g_strdup (folder_name);
- callback_data->type = g_strdup (type);
- callback_data->description = g_strdup (description);
- callback_data->physical_uri = physical_uri;
- callback_data->physical_path = physical_path;
- callback_data->callback = callback;
- callback_data->callback_data = data;
-
- bonobo_object_ref (BONOBO_OBJECT (component_client));
-
- evolution_shell_component_client_async_create_folder (component_client,
- physical_uri,
- type,
- component_async_create_folder_callback,
- callback_data);
-
- return result;
-}
-
-struct _AsyncRemoveFolderCallbackData {
- EStorage *storage;
-
- char *path;
- char *physical_path;
-};
-typedef struct _AsyncRemoveFolderCallbackData AsyncRemoveFolderCallbackData;
-
-static void
-component_async_remove_folder_callback (EvolutionShellComponentClient *shell_component_client,
- EvolutionShellComponentResult result,
- void *data)
-{
- AsyncRemoveFolderCallbackData *callback_data;
- EStorageResult storage_result;
-
- callback_data = (AsyncRemoveFolderCallbackData *) data;
-
- storage_result = shell_component_result_to_storage_result (result);
-
- /* If result == HASSUBFOLDERS then recurse delete the subfolders dir? */
-
- /* FIXME: Handle errors */
- if (result == EVOLUTION_SHELL_COMPONENT_OK) {
- ELocalStoragePrivate *priv;
-
- priv = E_LOCAL_STORAGE (callback_data->storage)->priv;
-
- e_storage_removed_folder (E_STORAGE (callback_data->storage),
- callback_data->path);
-
- evolution_storage_removed_folder (EVOLUTION_STORAGE (priv->bonobo_interface),
- callback_data->path);
- }
-
- bonobo_object_unref (BONOBO_OBJECT (shell_component_client));
-
- g_free (callback_data->path);
- g_free (callback_data->physical_path);
- g_free (callback_data);
-}
-
-static EStorageResult
-remove_folder_directory (ELocalStorage *local_storage,
- const char *path)
-{
- EStorage *storage;
- ELocalStoragePrivate *priv;
- const char *folder_name;
- char *file_name;
- char *physical_path;
-
- priv = local_storage->priv;
-
- storage = E_STORAGE (local_storage);
- folder_name = g_basename (path);
-
- /* Delete the metadata file associated with this folder. */
- physical_path = e_path_to_physical (priv->base_path, path);
- file_name = g_concat_dir_and_file (physical_path, E_LOCAL_FOLDER_METADATA_FILE_NAME);
- unlink (file_name);
- g_free (file_name);
-
- /* Delete the physical directory. */
- if (rmdir (physical_path) == -1) {
- g_free (physical_path);
- return E_STORAGE_GENERICERROR;
- }
-
- g_free (physical_path);
-
- /* Delete the 'subfolders' directory that this folder lies in */
- if (folder_name != path + 1) {
- char *subfolders_directory_physical_path;
- char *parent_path;
-
- parent_path = g_strndup (path, folder_name - path);
- subfolders_directory_physical_path = e_path_to_physical (priv->base_path, parent_path);
- g_free (parent_path);
-
- rmdir (subfolders_directory_physical_path);
- g_free (subfolders_directory_physical_path);
- }
-
- return E_STORAGE_OK;
-}
-
-static EStorageResult
-remove_folder (ELocalStorage *local_storage,
- const char *path,
- const char *physical_uri)
-{
- ELocalStoragePrivate *priv;
- EStorage *storage;
- AsyncRemoveFolderCallbackData *callback_data;
- EvolutionShellComponentClient *component_client;
- EStorageResult result;
- EFolder *folder;
- char *physical_path;
- GList *subfolder_paths;
- GList *p;
-
- priv = local_storage->priv;
-
- storage = E_STORAGE (local_storage);
- folder = e_storage_get_folder (storage, path);
-
- if (e_folder_get_is_stock (folder))
- return E_STORAGE_CANTCHANGESTOCKFOLDER;
-
- component_client = e_folder_type_registry_get_handler_for_type (priv->folder_type_registry,
- e_folder_get_type_string (folder));
- if (component_client == NULL)
- return E_STORAGE_INVALIDTYPE;
-
- physical_path = e_path_to_physical (priv->base_path, path);
-
- if (!physical_uri)
- physical_uri = g_strconcat ("file://", physical_path, NULL);
-
- /* Recursively remove the subfolders */
- subfolder_paths = e_storage_get_subfolder_paths (storage, path);
-
- for (p = subfolder_paths; p; p = p->next)
- remove_folder (local_storage, p->data, NULL);
-
- callback_data = g_new (AsyncRemoveFolderCallbackData, 1);
- callback_data->storage = E_STORAGE (local_storage);
- callback_data->path = g_strdup (path);
- callback_data->physical_path = physical_path;
-
- bonobo_object_ref (BONOBO_OBJECT (component_client));
-
- evolution_shell_component_client_async_remove_folder (component_client,
- physical_uri,
- e_folder_get_type_string (folder),
- component_async_remove_folder_callback,
- callback_data);
-
- result = remove_folder_directory (E_LOCAL_STORAGE (local_storage), path);
-
- return result;
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_destroy (GtkObject *object)
-{
- ELocalStorage *local_storage;
- ELocalStoragePrivate *priv;
- CORBA_Environment ev;
-
- local_storage = E_LOCAL_STORAGE (object);
- priv = local_storage->priv;
-
- CORBA_exception_init (&ev);
-
- g_free (priv->base_path);
-
- if (priv->folder_type_registry != NULL)
- gtk_object_unref (GTK_OBJECT (priv->folder_type_registry));
-
- if (priv->bonobo_interface != NULL)
- bonobo_object_unref (BONOBO_OBJECT (priv->bonobo_interface));
-
- g_free (priv);
-
- CORBA_exception_free (&ev);
-
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-/* EStorage methods. */
-
-static const char *
-impl_get_name (EStorage *storage)
-{
- return E_LOCAL_STORAGE_NAME;
-}
-
-static const char *
-impl_get_display_name (EStorage *storage)
-{
- return _("Local Folders");
-}
-
-
-/* Creating folders. */
-
-static void
-impl_async_create_folder (EStorage *storage,
- const char *path,
- const char *type,
- const char *description,
- EStorageResultCallback callback,
- void *data)
-{
- ELocalStorage *local_storage;
-
- local_storage = E_LOCAL_STORAGE (storage);
-
- create_folder (local_storage, path, type, description, callback, data);
-}
-
-
-/* Removing folders. */
-
-static void
-impl_async_remove_folder (EStorage *storage,
- const char *path,
- EStorageResultCallback callback,
- void *data)
-{
- ELocalStorage *local_storage;
- EStorageResult result;
-
- local_storage = E_LOCAL_STORAGE (storage);
-
- result = remove_folder (local_storage, path, NULL);
-
- if (callback != NULL)
- (* callback) (E_STORAGE (local_storage), result, data);
-}
-
-
-
-/* Transferring folders. */
-
-struct _XferItem {
- char *source_path;
- char *destination_path;
-};
-typedef struct _XferItem XferItem;
-
-static XferItem *
-xfer_item_new (char *source_path,
- char *destination_path)
-{
- XferItem *new;
-
- new = g_new (XferItem, 1);
- new->source_path = source_path;
- new->destination_path = destination_path;
-
- return new;
-}
-
-static void
-xfer_item_free (XferItem *item)
-{
- g_free (item->source_path);
- g_free (item->destination_path);
- g_free (item);
-}
-
-static void
-append_xfer_item_list (EStorage *storage,
- char *source_path,
- char *destination_path,
- GList **list)
-{
- GList *subfolders;
- GList *p;
-
- *list = g_list_prepend (*list, xfer_item_new (source_path, destination_path));
-
- subfolders = e_storage_get_subfolder_paths (storage, source_path);
- for (p = subfolders; p != NULL; p = p->next) {
- char *source_subpath;
- char *destination_subpath;
-
- source_subpath = g_strdup ((const char *) p->data);
- destination_subpath = g_concat_dir_and_file (destination_path,
- g_basename (source_subpath));
-
- append_xfer_item_list (storage, source_subpath, destination_subpath, list);
- }
-
- e_free_string_list (subfolders);
-}
-
-struct _XferData {
- /* The storage on which we are performing the xfer operation. */
- ELocalStorage *local_storage;
-
- /* List of source/destination path couples to copy, in the right
- order. */
- GList *folder_items;
-
- /* Pointer into `folder_items'. The folder item pointed by this is the
- one handled by the previous CORBA invocation. */
- GList *current_folder_item;
-
- /* Whether we want to remove the source too. */
- gboolean remove_source;
-
- /* The callback, with its data. */
- EStorageResultCallback callback;
- void *callback_data;
-};
-typedef struct _XferData XferData;
-
-static void
-async_xfer_folder_step (ELocalStorage *local_storage,
- const char *source_path,
- const char *destination_path,
- gboolean remove_source,
- EvolutionShellComponentClientCallback component_client_callback,
- void *component_client_callback_data)
-{
- ELocalStoragePrivate *priv;
- EFolder *source_folder;
- EvolutionShellComponentClient *component_client;
- char *physical_path;
- char *physical_uri;
-
- priv = local_storage->priv;
-
- g_print ("async_xfer_folder_step %s -> %s\n", source_path, destination_path);
-
- source_folder = e_storage_get_folder (E_STORAGE (local_storage), source_path);
- g_assert (source_folder != NULL);
-
- create_folder_directory (local_storage, destination_path,
- e_folder_get_type_string (source_folder),
- e_folder_get_description (source_folder),
- &physical_path);
-
- physical_uri = g_strconcat ("file://", physical_path, NULL);
- g_free (physical_path);
-
- component_client = e_folder_type_registry_get_handler_for_type (priv->folder_type_registry,
- e_folder_get_type_string (source_folder));
- g_assert (component_client != NULL);
-
- evolution_shell_component_client_async_xfer_folder (component_client,
- e_folder_get_physical_uri (source_folder),
- physical_uri,
- e_folder_get_type_string (source_folder),
- remove_source,
- component_client_callback,
- component_client_callback_data);
-
- g_free (physical_uri);
-}
-
-static void
-async_xfer_folder_complete (XferData *xfer_data)
-{
- ELocalStorage *local_storage;
- GList *p;
-
- local_storage = xfer_data->local_storage;
-
-#if 0
- if (xfer_data->remove_source) {
- EStorageResult result;
-
- /* Remove all the source physical directories, and also the
- corresponding folders from the folder tree. */
-
- for (p = g_list_last (xfer_data->folder_items); p != NULL; p = p->prev) {
- XferItem *item;
-
- item = (XferItem *) p->data;
-
- result = remove_folder_directory (local_storage, item->source_path);
-
- /* FIXME handle failure differently? This should be n
- unlikely situation. */
- if (result == E_STORAGE_OK)
- e_storage_removed_folder (E_STORAGE (local_storage), item->source_path);
- }
- }
-#endif
-
- /* Free the data. */
-
- for (p = xfer_data->folder_items; p != NULL; p = p->next) {
- XferItem *item;
-
- item = (XferItem *) p->data;
- xfer_item_free (item);
- }
- g_list_free (xfer_data->folder_items);
-
- g_free (xfer_data);
-}
-
-static void
-async_xfer_folder_callback (EvolutionShellComponentClient *shell_component_client,
- EvolutionShellComponentResult result,
- void *callback_data)
-{
- XferData *xfer_data;
- XferItem *item;
- EFolder *source_folder;
- EFolder *destination_folder;
- char *new_physical_uri;
-
- /* FIXME handle errors. */
-
- xfer_data = (XferData *) callback_data;
-
- item = (XferItem *) xfer_data->current_folder_item->data;
-
- source_folder = e_storage_get_folder (E_STORAGE (xfer_data->local_storage), item->source_path);
- destination_folder = e_local_folder_new (e_folder_get_name (source_folder),
- e_folder_get_type_string (source_folder),
- e_folder_get_description (source_folder));
-
- new_physical_uri = g_strconcat ("file:///", item->destination_path, NULL);
- e_folder_set_physical_uri (destination_folder, new_physical_uri);
- g_free (new_physical_uri);
-
- e_local_folder_save (E_LOCAL_FOLDER (destination_folder)); /* FIXME check for errors */
- new_folder (xfer_data->local_storage, item->destination_path, destination_folder);
-
- xfer_data->current_folder_item = xfer_data->current_folder_item->next;
- if (xfer_data->current_folder_item == NULL) {
- async_xfer_folder_complete (xfer_data);
- return;
- }
-
- item = (XferItem *) xfer_data->current_folder_item->data;
-
- async_xfer_folder_step (xfer_data->local_storage,
- item->source_path,
- item->destination_path,
- xfer_data->remove_source,
- async_xfer_folder_callback,
- xfer_data);
-}
-
-static void
-impl_async_xfer_folder (EStorage *storage,
- const char *source_path,
- const char *destination_path,
- gboolean remove_source,
- EStorageResultCallback callback,
- void *callback_data)
-{
- ELocalStorage *local_storage;
- ELocalStoragePrivate *priv;
- XferData *xfer_data;
- GList *folder_items; /* <XferItem> */
- XferItem *first_item;
-
- local_storage = E_LOCAL_STORAGE (storage);
- priv = local_storage->priv;
-
- if (remove_source && e_folder_get_is_stock (e_storage_get_folder (storage, source_path)))
- (* callback) (storage, E_STORAGE_CANTCHANGESTOCKFOLDER, callback_data);
-
- folder_items = NULL;
- append_xfer_item_list (storage, g_strdup (source_path), g_strdup (destination_path), &folder_items);
- folder_items = g_list_reverse (folder_items); /* lame */
-
- xfer_data = g_new (XferData, 1);
- xfer_data->local_storage = local_storage;
- xfer_data->folder_items = folder_items;
- xfer_data->current_folder_item = folder_items;
- xfer_data->remove_source = remove_source;
- xfer_data->callback = callback;
- xfer_data->callback_data = callback_data;
-
- first_item = (XferItem *) xfer_data->folder_items->data;
-
- async_xfer_folder_step (E_LOCAL_STORAGE (storage),
- first_item->source_path,
- first_item->destination_path,
- remove_source,
- async_xfer_folder_callback,
- xfer_data);
-}
-
-
-/* Callbacks for the `Evolution::Storage' interface we are exposing to the outside world. */
-static int
-bonobo_interface_create_folder_cb (EvolutionStorage *storage,
- const char *path,
- const char *type,
- const char *description,
- const char *parent_path,
- void *data)
-{
- ELocalStorage *local_storage;
-
- local_storage = E_LOCAL_STORAGE (data);
-
- return create_folder (local_storage, path, type, description, NULL, NULL);
-}
-
-static int
-bonobo_interface_remove_folder_cb (EvolutionStorage *storage,
- const char *path,
- const char *physical_uri,
- void *data)
-{
- ELocalStorage *local_storage;
-
- local_storage = E_LOCAL_STORAGE (data);
-
- return remove_folder (local_storage, path, physical_uri);
-}
-
-static void
-bonobo_interface_update_folder_cb (EvolutionStorage *storage,
- const char *path,
- const char *display_name,
- int unread_count,
- void *data)
-{
- ELocalStorage *local_storage;
- EFolder *folder;
-
- local_storage = E_LOCAL_STORAGE (data);
-
- folder = e_storage_get_folder (E_STORAGE (local_storage), path);
- if (folder == NULL)
- return;
-
- /* e_folder_set_name (folder, display_name); */
- e_folder_set_unread_count (folder, unread_count);
-
- return;
-}
-
-
-/* Initialization. */
-
-static void
-class_init (ELocalStorageClass *class)
-{
- EStorageClass *storage_class;
- GtkObjectClass *object_class;
-
- parent_class = gtk_type_class (e_storage_get_type ());
- object_class = GTK_OBJECT_CLASS (class);
- storage_class = E_STORAGE_CLASS (class);
-
- object_class->destroy = impl_destroy;
-
- storage_class->get_name = impl_get_name;
- storage_class->get_display_name = impl_get_display_name;
- storage_class->async_create_folder = impl_async_create_folder;
- storage_class->async_remove_folder = impl_async_remove_folder;
- storage_class->async_xfer_folder = impl_async_xfer_folder;
-}
-
-static void
-init (ELocalStorage *local_storage)
-{
- ELocalStoragePrivate *priv;
-
- priv = g_new (ELocalStoragePrivate, 1);
-
- priv->base_path = NULL;
- priv->folder_type_registry = NULL;
- priv->bonobo_interface = NULL;
-
- local_storage->priv = priv;
-}
-
-
-static gboolean
-construct (ELocalStorage *local_storage,
- EFolderTypeRegistry *folder_type_registry,
- const char *base_path)
-{
- ELocalStoragePrivate *priv;
- int base_path_len;
-
- e_storage_construct (E_STORAGE (local_storage), NULL, NULL);
-
- priv = local_storage->priv;
-
- base_path_len = strlen (base_path);
- while (base_path_len > 0 && base_path[base_path_len - 1] == G_DIR_SEPARATOR)
- base_path_len--;
-
- g_return_val_if_fail (base_path_len != 0, FALSE);
-
- g_assert (priv->folder_type_registry == NULL);
- gtk_object_ref (GTK_OBJECT (folder_type_registry));
- priv->folder_type_registry = folder_type_registry;
-
- g_assert (priv->base_path == NULL);
- priv->base_path = g_strndup (base_path, base_path_len);
-
- g_assert (priv->bonobo_interface == NULL);
- priv->bonobo_interface = evolution_storage_new (E_LOCAL_STORAGE_NAME,
- NULL, NULL);
-
- gtk_signal_connect (GTK_OBJECT (priv->bonobo_interface), "create_folder",
- GTK_SIGNAL_FUNC (bonobo_interface_create_folder_cb),
- local_storage);
- gtk_signal_connect (GTK_OBJECT (priv->bonobo_interface), "remove_folder",
- GTK_SIGNAL_FUNC (bonobo_interface_remove_folder_cb),
- local_storage);
- gtk_signal_connect (GTK_OBJECT (priv->bonobo_interface), "update_folder",
- GTK_SIGNAL_FUNC (bonobo_interface_update_folder_cb),
- local_storage);
-
- return load_all_folders (local_storage);
-}
-
-EStorage *
-e_local_storage_open (EFolderTypeRegistry *folder_type_registry,
- const char *base_path)
-{
- EStorage *new;
-
- g_return_val_if_fail (folder_type_registry != NULL, NULL);
- g_return_val_if_fail (E_IS_FOLDER_TYPE_REGISTRY (folder_type_registry), NULL);
- g_return_val_if_fail (base_path != NULL, NULL);
-
- new = gtk_type_new (e_local_storage_get_type ());
-
- if (! construct (E_LOCAL_STORAGE (new), folder_type_registry, base_path)) {
- gtk_object_unref (GTK_OBJECT (new));
- return NULL;
- }
-
- return new;
-}
-
-const char *
-e_local_storage_get_base_path (ELocalStorage *local_storage)
-{
- g_return_val_if_fail (local_storage != NULL, NULL);
- g_return_val_if_fail (E_IS_LOCAL_STORAGE (local_storage), NULL);
-
- return local_storage->priv->base_path;
-}
-
-
-const GNOME_Evolution_Storage
-e_local_storage_get_corba_interface (ELocalStorage *local_storage)
-{
- ELocalStoragePrivate *priv;
- GNOME_Evolution_Storage corba_interface;
-
- g_return_val_if_fail (local_storage != NULL, NULL);
- g_return_val_if_fail (E_IS_LOCAL_STORAGE (local_storage), NULL);
-
- priv = local_storage->priv;
- corba_interface = bonobo_object_corba_objref (BONOBO_OBJECT (priv->bonobo_interface));
-
- return corba_interface;
-}
-
-
-E_MAKE_TYPE (e_local_storage, "ELocalStorage", ELocalStorage, class_init, init, PARENT_TYPE)