diff options
Diffstat (limited to 'camel/providers/mbox/camel-mbox-folder.c')
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 945 |
1 files changed, 0 insertions, 945 deletions
diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c deleted file mode 100644 index 7e55610cf8..0000000000 --- a/camel/providers/mbox/camel-mbox-folder.c +++ /dev/null @@ -1,945 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-folder.c : Abstract class for an email folder */ - -/* - * Authors: Bertrand Guiheneuf <bertrand@helixcode.com> - * 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 - */ - - -#include <config.h> - -#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-mbox-folder.h" -#include "camel-mbox-store.h" -#include "string-utils.h" -#include "camel-stream-fs.h" -#include "camel-mbox-summary.h" -#include "gmime-utils.h" -#include "camel-mbox-search.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" - -#include "camel-exception.h" - -#define d(x) - -static CamelFolderClass *parent_class=NULL; - -/* Returns the class for a CamelMboxFolder */ -#define CMBOXF_CLASS(so) CAMEL_MBOX_FOLDER_CLASS (GTK_OBJECT(so)->klass) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (GTK_OBJECT(so)->klass) -#define CMBOXS_CLASS(so) CAMEL_STORE_CLASS (GTK_OBJECT(so)->klass) - - -static void mbox_init (CamelFolder *folder, CamelStore *parent_store, - CamelFolder *parent_folder, const gchar *name, - gchar separator, CamelException *ex); - -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 GList *mbox_list_subfolders (CamelFolder *folder, CamelException *ex); -static CamelMimeMessage *mbox_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex); -static gint mbox_get_message_count (CamelFolder *folder, CamelException *ex); -static void mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex); -static GList *mbox_get_uid_list (CamelFolder *folder, CamelException *ex); -static CamelMimeMessage *mbox_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex); - -static void mbox_expunge (CamelFolder *folder, CamelException *ex); -#if 0 -static void _copy_message_to (CamelFolder *folder, CamelMimeMessage *message, CamelFolder *dest_folder, CamelException *ex); -static const gchar *_get_message_uid (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex); -#endif - -GPtrArray *summary_get_message_info (CamelFolder *folder, int first, int count); -static const CamelMessageInfo *mbox_summary_get_by_uid(CamelFolder *f, const char *uid); - -static void mbox_finalize (GtkObject *object); - -static void -camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class) -{ - CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_mbox_folder_class); - GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_folder_class); - - parent_class = gtk_type_class (camel_folder_get_type ()); - - /* virtual method definition */ - - /* virtual method overload */ - 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->list_subfolders = mbox_list_subfolders; - camel_folder_class->get_message_by_number = mbox_get_message_by_number; - camel_folder_class->get_message_count = mbox_get_message_count; - camel_folder_class->append_message = mbox_append_message; - camel_folder_class->get_uid_list = mbox_get_uid_list; - camel_folder_class->expunge = mbox_expunge; -#if 0 - camel_folder_class->copy_message_to = _copy_message_to; - camel_folder_class->get_message_uid = _get_message_uid; -#endif - camel_folder_class->get_message_by_uid = mbox_get_message_by_uid; - - camel_folder_class->search_by_expression = camel_mbox_folder_search_by_expression; - - camel_folder_class->get_message_info = summary_get_message_info; - camel_folder_class->summary_get_by_uid = mbox_summary_get_by_uid; - - gtk_object_class->finalize = mbox_finalize; - -} - -static void -mbox_finalize (GtkObject *object) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (object); - - g_free (mbox_folder->folder_file_path); - g_free (mbox_folder->folder_dir_path); - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - -GtkType -camel_mbox_folder_get_type (void) -{ - static GtkType camel_mbox_folder_type = 0; - - if (!camel_mbox_folder_type) { - GtkTypeInfo camel_mbox_folder_info = - { - "CamelMboxFolder", - sizeof (CamelMboxFolder), - sizeof (CamelMboxFolderClass), - (GtkClassInitFunc) camel_mbox_folder_class_init, - (GtkObjectInitFunc) NULL, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - camel_mbox_folder_type = gtk_type_unique (CAMEL_FOLDER_TYPE, &camel_mbox_folder_info); - } - - return camel_mbox_folder_type; -} - -static void -mbox_init (CamelFolder *folder, CamelStore *parent_store, - CamelFolder *parent_folder, const gchar *name, gchar separator, - CamelException *ex) -{ - CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder; - const gchar *root_dir_path; - - /* call parent method */ - parent_class->init (folder, parent_store, parent_folder, - name, separator, ex); - if (camel_exception_get_id (ex)) - return; - - /* we assume that the parent init - method checks for the existance of @folder */ - folder->can_hold_messages = TRUE; - folder->can_hold_folders = TRUE; - folder->has_summary_capability = TRUE; - folder->has_uid_capability = TRUE; - folder->has_search_capability = TRUE; - - folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | - CAMEL_MESSAGE_DELETED | - CAMEL_MESSAGE_DRAFT | - CAMEL_MESSAGE_FLAGGED | - CAMEL_MESSAGE_SEEN; - - mbox_folder->summary = NULL; - - /* now set the name info */ - g_free (mbox_folder->folder_file_path); - g_free (mbox_folder->folder_dir_path); - g_free (mbox_folder->index_file_path); - - root_dir_path = camel_mbox_store_get_toplevel_dir (CAMEL_MBOX_STORE(folder->parent_store)); - - mbox_folder->folder_file_path = g_strdup_printf ("%s/%s", root_dir_path, folder->full_name); - mbox_folder->summary_file_path = g_strdup_printf ("%s/%s-ev-summary", root_dir_path, folder->full_name); - mbox_folder->folder_dir_path = g_strdup_printf ("%s/%s.sdb", root_dir_path, folder->full_name); - mbox_folder->index_file_path = g_strdup_printf ("%s/%s.ibex", root_dir_path, folder->full_name); -} - -static void -mbox_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - - /* call parent class */ - parent_class->open (folder, mode, ex); - if (camel_exception_get_id(ex)) - return; - - mbox_folder->index = ibex_open(mbox_folder->index_file_path, O_CREAT|O_RDWR, 0600); - if (mbox_folder->index == NULL) { - g_warning("Could not open/create index file: %s: indexing will not function", - strerror(errno)); - } - - mbox_folder->summary = camel_mbox_summary_new(mbox_folder->summary_file_path, mbox_folder->folder_file_path, mbox_folder->index); - if (mbox_folder->summary == NULL) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, /* FIXME: right error code */ - "Could not create summary"); - return; - } - camel_mbox_summary_load(mbox_folder->summary); -} - -static void -mbox_close (CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - - /* call parent implementation */ - parent_class->close (folder, expunge, ex); - - if (expunge) { - mbox_expunge(folder, ex); - } - - /* save index */ - if (mbox_folder->index) { - ibex_close(mbox_folder->index); - mbox_folder->index = NULL; - } - camel_mbox_summary_save (mbox_folder->summary); - camel_mbox_summary_unref (mbox_folder->summary); - mbox_folder->summary = NULL; -} - - -static void -mbox_expunge (CamelFolder *folder, CamelException *ex) -{ - CamelMboxFolder *mbox = (CamelMboxFolder *)folder; - - if (camel_mbox_summary_expunge(mbox->summary) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID, /* FIXME: right error code */ - "Could not expunge: %s", strerror(errno)); - } -} - - -/* 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; - } - - -} - -/* FIXME: cleanup */ -static GList * -mbox_list_subfolders (CamelFolder *folder, CamelException *ex) -{ - GList *subfolder_name_list = NULL; - - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - const gchar *folder_dir_path; - gboolean folder_exists; - - struct stat stat_buf; - gint stat_error = 0; - gchar *entry_name; - gchar *full_entry_name; - gchar *real_folder_name; - struct dirent *dir_entry; - DIR *dir_handle; - gboolean folder_suffix_found; - - - /* check if the folder object exists */ - if (!folder) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_NULL, - "folder object is NULL"); - return FALSE; - } - - - /* in the case the folder does not exist, - raise an exception */ - folder_exists = camel_folder_exists (folder, ex); - if (camel_exception_get_id (ex)) return FALSE; - - if (!folder_exists) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, - "Inexistant folder."); - return FALSE; - } - - - /* get the mbox subfolders directories */ - folder_dir_path = mbox_folder->folder_file_path; - if (!folder_dir_path) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, - "Invalid folder path. Use set_name ?"); - return FALSE; - } - - - dir_handle = opendir (folder_dir_path); - - /* read the first entry in the directory */ - dir_entry = readdir (dir_handle); - while ((stat_error != -1) && (dir_entry != NULL)) { - - /* get the name of the next entry in the dir */ - entry_name = dir_entry->d_name; - full_entry_name = g_strdup_printf ("%s/%s", folder_dir_path, entry_name); - stat_error = stat (full_entry_name, &stat_buf); - g_free (full_entry_name); - - /* is it a directory ? */ - if ((stat_error != -1) && S_ISDIR (stat_buf.st_mode)) { - /* yes, add it to the list */ - if (entry_name[0] != '.') { - /* if the folder is a netscape folder, remove the - ".sdb" from the name */ - real_folder_name = string_prefix (entry_name, ".sdb", &folder_suffix_found); - /* stick here the tests for other folder suffixes if any */ - - if (!folder_suffix_found) real_folder_name = g_strdup (entry_name); - - /* add the folder name to the list */ - subfolder_name_list = g_list_append (subfolder_name_list, - real_folder_name); - } - } - /* read next entry */ - dir_entry = readdir (dir_handle); - } - - closedir (dir_handle); - - return subfolder_name_list; - - - - /* io exception handling */ - switch (errno) { - case EACCES : - - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "Unable to list the directory. Full Error text is : %s ", - strerror (errno)); - break; - - case ENOENT : - case ENOTDIR : - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_PATH, - "Invalid mbox folder path. Full Error text is : %s ", - strerror (errno)); - break; - - default : - camel_exception_set (ex, - CAMEL_EXCEPTION_SYSTEM, - "Unable to delete the mbox folder."); - - } - - g_list_free (subfolder_name_list); - return NULL; -} - -static gint -mbox_get_message_count (CamelFolder *folder, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder; - - g_assert (folder); - g_assert (mbox_folder->summary); - - return camel_mbox_summary_message_count(mbox_folder->summary); -} - -/* - This is a lazy append. - - Basically, messages are appended to the end of the mbox, and probably assigned - a new uid (they wont be if copying from a source folder which doesn't have - a uid - which wont happen with the current summariser). - - Indexing/summarising happens when the mbox is next queried. - - Should this set a flag up for subsequent updating?? -*/ - -/* FIXME: this may need some tweaking for performance? */ -/* FIXME: MUST check all sytem call return codes MUST MUST */ -static void -mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder), *source_folder; - CamelStream *output_stream; - struct stat st; - off_t seek; - char *xev; - guint32 uid; - - if (stat(mbox_folder->folder_file_path, &st) != 0) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */ - "Cannot append to mbox file: %s", strerror (errno)); - return; - } - - /* are we coming from an mbox folder? then we can optimise somewhat ... */ - if (message->folder && IS_CAMEL_MBOX_FOLDER(message->folder)) { - CamelMboxMessageInfo *info; - int sfd, dfd; - off_t pos; - - /* FIXME: this is pretty ugly - we lookup the message info in the source folder, copy it, - then go back and paste in its real uid. */ - source_folder = (CamelMboxFolder *)message->folder; - info = camel_mbox_summary_uid(source_folder->summary, message->message_uid); - - d(printf("Copying message directly from %s to %s\n", source_folder->folder_file_path, mbox_folder->folder_file_path)); - d(printf("start = %d, xev = %d\n", ((CamelMboxMessageContentInfo *)info->info.content)->pos, info->xev_offset)); - - sfd = open(source_folder->folder_file_path, O_RDONLY); - dfd = open(mbox_folder->folder_file_path, O_RDWR|O_CREAT, 0600); - if (lseek(dfd, st.st_size, SEEK_SET) != st.st_size) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */ - "Cannot append to mbox file: %s", strerror (errno)); - close(sfd); - close(dfd); - return; - } - write(dfd, "From - \n", strlen("From - \n")); - camel_mbox_summary_copy_block - (sfd, dfd, ((CamelMboxMessageContentInfo *)info->info.content)->pos, - ((CamelMboxMessageContentInfo *)info->info.content)->endpos - ((CamelMboxMessageContentInfo *)info->info.content)->pos); - if (info->xev_offset != -1) { - pos = st.st_size + (info->xev_offset - ((CamelMboxMessageContentInfo *)info->info.content)->pos) + strlen("From - \n"); - d(printf("Inserting new uid at %d\n", (int)pos)); - if (pos != lseek(dfd, pos, SEEK_SET)) { - ftruncate(dfd, st.st_size); - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */ - "Cannot append to mbox file: %s", strerror (errno)); - close(sfd); - close(dfd); - return; - } - uid = camel_mbox_summary_next_uid(mbox_folder->summary); - xev = g_strdup_printf("X-Evolution: %08x-%04x", uid, 0); - write(dfd, xev, strlen(xev)); /* FIXME: check return */ - d(printf("header = %s\n", xev)); - g_free(xev); - } - close(sfd); - close(dfd); - return; - } - - /* its not an mbox folder, so lets do it the slow way ... */ - output_stream = camel_stream_fs_new_with_name (mbox_folder->folder_file_path, O_CREAT|O_RDWR, 0600); - if (output_stream == NULL) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */ - "Cannot append to mbox file: %s", strerror (errno)); - return; - } - - seek = camel_seekable_stream_seek((CamelSeekableStream *)output_stream, st.st_size, SEEK_SET); - if (seek != st.st_size) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */ - "Cannot seek to position in mbox file: %s", strerror (errno)); - gtk_object_unref ((GtkObject *)output_stream); - return; - } - - /* assign a new x-evolution header */ - /* FIXME: save flags? */ - camel_medium_remove_header((CamelMedium *)message, "X-Evolution"); - uid = camel_mbox_summary_next_uid(mbox_folder->summary); - xev = g_strdup_printf("%08x-%04x", uid, 0); - camel_medium_add_header((CamelMedium *)message, "X-Evolution", xev); - g_free(xev); - - camel_stream_write_string (output_stream, "From - \n"); - /* FIXME: does this return an error? IT HAS TO FOR THIS TO BE RELIABLE */ - camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), output_stream); - camel_stream_close (output_stream); - - /* TODO: update the summary so it knows a new message is there to summarise/index */ - /* This is only a performance improvement, the summary is *only* a cache */ - - gtk_object_unref (GTK_OBJECT (output_stream)); -} - - - - -static GList * -mbox_get_uid_list (CamelFolder *folder, CamelException *ex) -{ - GList *uid_list = NULL; - CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder; - int i, count; - - /* FIXME: how are these allocated strings ever free'd? */ - count = camel_mbox_summary_message_count(mbox_folder->summary); - for (i=0;i<count;i++) { - CamelMboxMessageInfo *info = camel_mbox_summary_index(mbox_folder->summary, i); - uid_list = g_list_prepend(uid_list, g_strdup(info->info.uid)); - } - - return uid_list; -} - -static CamelMimeMessage * -mbox_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder; - CamelMboxMessageInfo *info; - - g_warning("YOUR CODE SHOULD NOT BE GETTING MESSAGES BY NUMBER, CHANGE IT"); - - info = camel_mbox_summary_index(mbox_folder->summary, number); - if (info == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID, - "No such message %d in folder `%s'.", - number, folder->name); - return NULL; - } - - return mbox_get_message_by_uid (folder, info->info.uid, ex); -} - -/* track flag changes in the summary */ -static void -message_changed(CamelMimeMessage *m, int type, CamelMboxFolder *mf) -{ - printf("Message changed: %s: %d\n", m->message_uid, type); - switch (type) { - case MESSAGE_FLAGS_CHANGED: - camel_mbox_summary_set_flags_by_uid(mf->summary, m->message_uid, m->flags); - break; - default: - printf("Unhandled message change event: %d\n", type); - break; - } -} - - -static CamelMimeMessage * -mbox_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - CamelStream *message_stream; - CamelMimeMessage *message = NULL; - CamelStore *parent_store; - CamelMboxMessageInfo *info; - - /* get the parent store */ - parent_store = camel_folder_get_parent_store (folder, ex); - if (camel_exception_get_id (ex)) { - return NULL; - } - - /* get the message summary info */ - info = camel_mbox_summary_uid(mbox_folder->summary, uid); - - if (info == NULL) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_UID, - "uid %s not found in the folder", - uid); - return NULL; - } - - /* if this has no content, its an error in the library */ - g_assert(info->info.content); - - /* FIXME: more checks below */ - /* create a stream bound to the message position/size */ - message_stream = camel_stream_fs_new_with_name_and_bounds (mbox_folder->folder_file_path, O_RDONLY, 0, - ((CamelMboxMessageContentInfo *)info->info.content)->pos, - ((CamelMboxMessageContentInfo *)info->info.content)->endpos); - gtk_object_ref((GtkObject *)message_stream); - gtk_object_sink((GtkObject *)message_stream); - message = camel_mime_message_new(); - if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) { - gtk_object_unref((GtkObject *)message); - gtk_object_unref((GtkObject *)message_stream); - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_UID, /* FIXME: code */ - "Could not create message for uid %s: %s", uid, strerror(errno)); - return NULL; - } - gtk_object_unref((GtkObject *)message_stream); - - /* init other fields? */ - message->folder = folder; - gtk_object_ref((GtkObject *)folder); - message->message_uid = g_strdup(uid); - message->flags = info->info.flags; - printf("%p flags = %x = %x\n", message, info->info.flags, message->flags); - - gtk_signal_connect((GtkObject *)message, "message_changed", message_changed, folder); - - return message; -} - -/* get message info for a range of messages */ -GPtrArray *summary_get_message_info (CamelFolder *folder, int first, int count) -{ - GPtrArray *array = g_ptr_array_new(); - int i, maxcount; - CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder; - - maxcount = camel_mbox_summary_message_count(mbox_folder->summary); - maxcount = MAX(count, maxcount); - for (i=first;i<maxcount;i++) - g_ptr_array_add(array, g_ptr_array_index(mbox_folder->summary->messages, i)); - - return array; -} - -/* get a single message info, by uid */ -static const CamelMessageInfo * -mbox_summary_get_by_uid(CamelFolder *f, const char *uid) -{ - CamelMboxFolder *mbox_folder = (CamelMboxFolder *)f; - - return (CamelMessageInfo *)camel_mbox_summary_uid(mbox_folder->summary, uid); -} - |