diff options
Diffstat (limited to 'camel/camel-disco-diary.c')
-rw-r--r-- | camel/camel-disco-diary.c | 416 |
1 files changed, 0 insertions, 416 deletions
diff --git a/camel/camel-disco-diary.c b/camel/camel-disco-diary.c deleted file mode 100644 index a437f5aa09..0000000000 --- a/camel/camel-disco-diary.c +++ /dev/null @@ -1,416 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-disco-diary.c: class for a disconnected operation log */ - -/* - * Authors: Dan Winship <danw@ximian.com> - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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 "camel-disco-diary.h" -#include "camel-disco-folder.h" -#include "camel-disco-store.h" -#include "camel-exception.h" -#include "camel-file-utils.h" -#include "camel-folder.h" -#include "camel-operation.h" -#include "camel-session.h" -#include "camel-store.h" - -#include <errno.h> - - -static void -camel_disco_diary_class_init (CamelDiscoDiaryClass *camel_disco_diary_class) -{ - /* virtual method definition */ -} - -static void -camel_disco_diary_init (CamelDiscoDiary *diary) -{ - diary->folders = g_hash_table_new (g_str_hash, g_str_equal); - diary->uidmap = g_hash_table_new (g_str_hash, g_str_equal); -} - -static void -unref_folder (gpointer key, gpointer value, gpointer data) -{ - camel_object_unref (value); -} - -static void -free_uid (gpointer key, gpointer value, gpointer data) -{ - g_free (key); - g_free (value); -} - -static void -camel_disco_diary_finalize (CamelDiscoDiary *diary) -{ - if (diary->file) - fclose (diary->file); - if (diary->folders) { - g_hash_table_foreach (diary->folders, unref_folder, NULL); - g_hash_table_destroy (diary->folders); - } - if (diary->uidmap) { - g_hash_table_foreach (diary->uidmap, free_uid, NULL); - g_hash_table_destroy (diary->uidmap); - } -} - -CamelType -camel_disco_diary_get_type (void) -{ - static CamelType camel_disco_diary_type = CAMEL_INVALID_TYPE; - - if (camel_disco_diary_type == CAMEL_INVALID_TYPE) { - camel_disco_diary_type = camel_type_register ( - CAMEL_OBJECT_TYPE, "CamelDiscoDiary", - sizeof (CamelDiscoDiary), - sizeof (CamelDiscoDiaryClass), - (CamelObjectClassInitFunc) camel_disco_diary_class_init, - NULL, - (CamelObjectInitFunc) camel_disco_diary_init, - (CamelObjectFinalizeFunc) camel_disco_diary_finalize); - } - - return camel_disco_diary_type; -} - - -static int -diary_encode_uids (CamelDiscoDiary *diary, GPtrArray *uids) -{ - int i, status; - - status = camel_file_util_encode_uint32 (diary->file, uids->len); - for (i = 0; status != -1 && i < uids->len; i++) - status = camel_file_util_encode_string (diary->file, uids->pdata[i]); - return status; -} - -void -camel_disco_diary_log (CamelDiscoDiary *diary, CamelDiscoDiaryAction action, - ...) -{ - va_list ap; - int status; - - /* You may already be a loser. */ - if (!diary->file) - return; - - status = camel_file_util_encode_uint32 (diary->file, action); - if (status == -1) - goto lose; - - va_start (ap, action); - switch (action) { - case CAMEL_DISCO_DIARY_FOLDER_EXPUNGE: - { - CamelFolder *folder = va_arg (ap, CamelFolder *); - GPtrArray *uids = va_arg (ap, GPtrArray *); - - status = camel_file_util_encode_string (diary->file, folder->full_name); - if (status != -1) - status = diary_encode_uids (diary, uids); - break; - } - - case CAMEL_DISCO_DIARY_FOLDER_APPEND: - { - CamelFolder *folder = va_arg (ap, CamelFolder *); - char *uid = va_arg (ap, char *); - - status = camel_file_util_encode_string (diary->file, folder->full_name); - if (status != -1) - status = camel_file_util_encode_string (diary->file, uid); - break; - } - - case CAMEL_DISCO_DIARY_FOLDER_MOVE: - case CAMEL_DISCO_DIARY_FOLDER_COPY: - { - CamelFolder *source = va_arg (ap, CamelFolder *); - CamelFolder *destination = va_arg (ap, CamelFolder *); - GPtrArray *uids = va_arg (ap, GPtrArray *); - - status = camel_file_util_encode_string (diary->file, source->full_name); - if (status == -1) - break; - status = camel_file_util_encode_string (diary->file, destination->full_name); - if (status == -1) - break; - status = diary_encode_uids (diary, uids); - break; - } - - default: - g_assert_not_reached (); - break; - } - - va_end (ap); - - lose: - if (status == -1) { - char *msg; - - msg = g_strdup_printf (_("Could not write log entry: %s\n" - "Further operations on this server " - "will not be replayed when you\n" - "reconnect to the network."), - g_strerror (errno)); - camel_session_alert_user (camel_service_get_session (CAMEL_SERVICE (diary->store)), - CAMEL_SESSION_ALERT_ERROR, - msg, FALSE); - g_free (msg); - - fclose (diary->file); - diary->file = NULL; - } -} - -static void -free_uids (GPtrArray *array) -{ - while (array->len--) - g_free (array->pdata[array->len]); - g_ptr_array_free (array, TRUE); -} - -static GPtrArray * -diary_decode_uids (CamelDiscoDiary *diary) -{ - GPtrArray *uids; - char *uid; - guint32 i; - - if (camel_file_util_decode_uint32 (diary->file, &i) == -1) - return NULL; - uids = g_ptr_array_new (); - while (i--) { - if (camel_file_util_decode_string (diary->file, &uid) == -1) { - free_uids (uids); - return NULL; - } - g_ptr_array_add (uids, uid); - } - - return uids; -} - -static CamelFolder * -diary_decode_folder (CamelDiscoDiary *diary) -{ - CamelFolder *folder; - char *name; - - if (camel_file_util_decode_string (diary->file, &name) == -1) - return NULL; - folder = g_hash_table_lookup (diary->folders, name); - if (!folder) { - CamelException ex; - char *msg; - - camel_exception_init (&ex); - folder = camel_store_get_folder (CAMEL_STORE (diary->store), - name, 0, &ex); - if (folder) - g_hash_table_insert (diary->folders, name, folder); - else { - msg = g_strdup_printf (_("Could not open `%s':\n%s\nChanges made to this folder will not be resynchronized."), - name, camel_exception_get_description (&ex)); - camel_exception_clear (&ex); - camel_session_alert_user (camel_service_get_session (CAMEL_SERVICE (diary->store)), - CAMEL_SESSION_ALERT_WARNING, - msg, FALSE); - g_free (msg); - g_free (name); - } - } else - g_free (name); - return folder; -} - -static void -close_folder (gpointer name, gpointer folder, gpointer data) -{ - g_free (name); - camel_folder_sync (folder, FALSE, NULL); - camel_object_unref (folder); -} - -void -camel_disco_diary_replay (CamelDiscoDiary *diary, CamelException *ex) -{ - guint32 action; - off_t size; - double pc; - - fseek (diary->file, 0, SEEK_END); - size = ftell (diary->file); - g_return_if_fail (size != 0); - rewind (diary->file); - - camel_operation_start (NULL, _("Resynchronizing with server")); - while (!camel_exception_is_set (ex)) { - pc = ftell (diary->file) / size; - camel_operation_progress (NULL, pc * 100); - - if (camel_file_util_decode_uint32 (diary->file, &action) == -1) - break; - if (action == CAMEL_DISCO_DIARY_END) - break; - - switch (action) { - case CAMEL_DISCO_DIARY_FOLDER_EXPUNGE: - { - CamelFolder *folder; - GPtrArray *uids; - - folder = diary_decode_folder (diary); - uids = diary_decode_uids (diary); - if (!uids) - goto lose; - - if (folder) - camel_disco_folder_expunge_uids (folder, uids, ex); - free_uids (uids); - break; - } - - case CAMEL_DISCO_DIARY_FOLDER_APPEND: - { - CamelFolder *folder; - char *uid; - CamelMimeMessage *message; - CamelMessageInfo *info; - - folder = diary_decode_folder (diary); - if (camel_file_util_decode_string (diary->file, &uid) == -1) - goto lose; - - if (!folder) { - g_free (uid); - continue; - } - - message = camel_folder_get_message (folder, uid, NULL); - if (!message) { - /* The message was appended and then deleted. */ - g_free (uid); - continue; - } - info = camel_folder_get_message_info (folder, uid); - - camel_folder_append_message (folder, message, info, ex); - g_free (uid); - camel_folder_free_message_info (folder, info); - - break; - } - - case CAMEL_DISCO_DIARY_FOLDER_COPY: - case CAMEL_DISCO_DIARY_FOLDER_MOVE: - { - CamelFolder *source, *destination; - GPtrArray *uids; - - source = diary_decode_folder (diary); - destination = diary_decode_folder (diary); - uids = diary_decode_uids (diary); - if (!uids) - goto lose; - - if (!source || !destination) { - free_uids (uids); - continue; - } - - if (action == CAMEL_DISCO_DIARY_FOLDER_COPY) - camel_folder_copy_messages_to (source, uids, destination, ex); - else - camel_folder_move_messages_to (source, uids, destination, ex); - free_uids (uids); - break; - } - - } - } - - lose: - camel_operation_end (NULL); - - /* Close folders */ - g_hash_table_foreach (diary->folders, close_folder, diary); - g_hash_table_destroy (diary->folders); - diary->folders = NULL; - - /* Truncate the log */ - ftruncate (fileno (diary->file), 0); -} - -CamelDiscoDiary * -camel_disco_diary_new (CamelDiscoStore *store, const char *filename, CamelException *ex) -{ - CamelDiscoDiary *diary; - - g_return_val_if_fail (CAMEL_IS_DISCO_STORE (store), NULL); - g_return_val_if_fail (filename != NULL, NULL); - - diary = CAMEL_DISCO_DIARY (camel_object_new (CAMEL_DISCO_DIARY_TYPE)); - diary->store = store; - - diary->file = fopen (filename, "a+"); - if (!diary->file) { - camel_object_unref (CAMEL_OBJECT (diary)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not open journal file: %s", - g_strerror (errno)); - return NULL; - } - - return diary; -} - -gboolean -camel_disco_diary_empty (CamelDiscoDiary *diary) -{ - return ftell (diary->file) == 0; -} - -void -camel_disco_diary_uidmap_add (CamelDiscoDiary *diary, const char *old_uid, - const char *new_uid) -{ - g_hash_table_insert (diary->uidmap, g_strdup (old_uid), - g_strdup (new_uid)); -} - -const char * -camel_disco_diary_uidmap_lookup (CamelDiscoDiary *diary, const char *uid) -{ - return g_hash_table_lookup (diary->uidmap, uid); -} |