diff options
author | nobody <nobody@localhost> | 2000-04-19 17:50:35 +0800 |
---|---|---|
committer | nobody <nobody@localhost> | 2000-04-19 17:50:35 +0800 |
commit | 17c0e71bc773de276bd37d1f17c467bfbb0ca198 (patch) | |
tree | 0bded5f4fdc715c91225d3c94fdb9e5cf5eef453 /camel/providers/mbox | |
parent | f3a84bec06a82e86b7903d01e13589d0fcf4a2bc (diff) | |
download | gsoc2013-evolution-EOG_0_3.tar gsoc2013-evolution-EOG_0_3.tar.gz gsoc2013-evolution-EOG_0_3.tar.bz2 gsoc2013-evolution-EOG_0_3.tar.lz gsoc2013-evolution-EOG_0_3.tar.xz gsoc2013-evolution-EOG_0_3.tar.zst gsoc2013-evolution-EOG_0_3.zip |
This commit was manufactured by cvs2svn to create tag 'EOG_0_3'.EOG_0_3
svn path=/tags/EOG_0_3/; revision=2496
Diffstat (limited to 'camel/providers/mbox')
-rw-r--r-- | camel/providers/mbox/.cvsignore | 7 | ||||
-rw-r--r-- | camel/providers/mbox/Makefile.am | 45 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 1034 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.h | 83 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-parser.c | 865 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-parser.h | 65 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-provider.c | 57 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-search.c | 413 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-search.h | 14 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-store.c | 129 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-store.h | 69 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-summary.c | 420 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-summary.h | 85 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-utils.c | 574 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-utils.h | 71 |
15 files changed, 0 insertions, 3931 deletions
diff --git a/camel/providers/mbox/.cvsignore b/camel/providers/mbox/.cvsignore deleted file mode 100644 index fd6b811c68..0000000000 --- a/camel/providers/mbox/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la diff --git a/camel/providers/mbox/Makefile.am b/camel/providers/mbox/Makefile.am deleted file mode 100644 index e3234ce228..0000000000 --- a/camel/providers/mbox/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ -## Process this file with automake to produce Makefile.in - -SUBDIRS = - -libcamelmboxincludedir = $(includedir)/camel - - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelmbox.la - -INCLUDES = -I.. \ - -I$(srcdir)/.. \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/libibex \ - -I$(top_srcdir)/e-util \ - -I$(top_srcdir) \ - -I$(includedir) \ - $(GTK_INCLUDEDIR) - -libcamelmbox_la_SOURCES = \ - camel-mbox-folder.c \ - camel-mbox-parser.c \ - camel-mbox-provider.c \ - camel-mbox-store.c \ - camel-mbox-summary.c \ - camel-mbox-search.c \ - camel-mbox-utils.c - -libcamelmboxinclude_HEADERS = \ - camel-mbox-folder.h \ - camel-mbox-parser.h \ - camel-mbox-store.h \ - camel-mbox-summary.h \ - camel-mbox-search.h \ - camel-mbox-utils.h - - -libcamelmbox_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir) - -libcamelmbox_la_LIBADD = $(top_builddir)/e-util/libeutil.la $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) -#libcamelmbox_la_LIBADD = $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) - -EXTRA_DIST = diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c deleted file mode 100644 index 9cd055a658..0000000000 --- a/camel/providers/mbox/camel-mbox-folder.c +++ /dev/null @@ -1,1034 +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 */ - -/* - * Author : Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 Helix Code . - * - * 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 "camel-mbox-parser.h" -#include "camel-mbox-utils.h" -#include "gmime-utils.h" -#include "camel-mbox-search.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" - -#include "camel-exception.h" - -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 _init (CamelFolder *folder, CamelStore *parent_store, - CamelFolder *parent_folder, const gchar *name, - gchar separator, CamelException *ex); -static void _set_name(CamelFolder *folder, const gchar *name, CamelException *ex); - - -static void _open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex); -static void _close (CamelFolder *folder, gboolean expunge, CamelException *ex); -static gboolean _exists (CamelFolder *folder, CamelException *ex); -static gboolean _create(CamelFolder *folder, CamelException *ex); -static gboolean _delete (CamelFolder *folder, gboolean recurse, CamelException *ex); -static gboolean _delete_messages (CamelFolder *folder, CamelException *ex); -static GList *_list_subfolders (CamelFolder *folder, CamelException *ex); -static CamelMimeMessage *_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex); -static gint _get_message_count (CamelFolder *folder, CamelException *ex); -static void _append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex); -static GList *_get_uid_list (CamelFolder *folder, CamelException *ex); -static CamelMimeMessage *_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex); -#if 0 -static void _expunge (CamelFolder *folder, CamelException *ex); -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 - -static void _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 = _init; - camel_folder_class->set_name = _set_name; - camel_folder_class->open = _open; - camel_folder_class->close = _close; - camel_folder_class->exists = _exists; - camel_folder_class->create = _create; - camel_folder_class->delete = _delete; - camel_folder_class->delete_messages = _delete_messages; - camel_folder_class->list_subfolders = _list_subfolders; - camel_folder_class->get_message_by_number = _get_message_by_number; - camel_folder_class->get_message_count = _get_message_count; - camel_folder_class->append_message = _append_message; - camel_folder_class->get_uid_list = _get_uid_list; -#if 0 - camel_folder_class->expunge = _expunge; - 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 = _get_message_by_uid; - - camel_folder_class->search_by_expression = camel_mbox_folder_search_by_expression; - camel_folder_class->search_complete = camel_mbox_folder_search_complete; - camel_folder_class->search_cancel = camel_mbox_folder_search_cancel; - - gtk_object_class->finalize = _finalize; - -} - - - -static void -_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 -_init (CamelFolder *folder, CamelStore *parent_store, - CamelFolder *parent_folder, const gchar *name, gchar separator, - CamelException *ex) -{ - /* 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->summary = NULL; -} - - - -/* internal method used to : - - test for the existence of a summary file - - test the sync between the summary and the mbox file - - load the summary or create it if necessary -*/ -static void -_check_get_or_maybe_generate_summary_file (CamelMboxFolder *mbox_folder, - CamelException *ex) -{ - CamelFolder *folder = CAMEL_FOLDER (mbox_folder); - CamelMboxSummary *summ; - GArray *message_info_array; - gint mbox_file_fd; - guint32 next_uid; - guint32 file_size; - struct stat st; - - folder->summary = NULL; - - /* Test for the existence and up-to-dateness of the summary file. */ - if (access (mbox_folder->summary_file_path, F_OK) == 0) { - summ = camel_mbox_summary_load (mbox_folder->summary_file_path, - ex); - if (summ) { - if (stat (mbox_folder->folder_file_path, &st) == 0 && - summ->mbox_file_size == st.st_size && - summ->mbox_modtime == st.st_mtime) - folder->summary = CAMEL_FOLDER_SUMMARY (summ); - else - gtk_object_destroy (GTK_OBJECT (summ)); - } else { - /* Bad summary file */ - if (camel_exception_get_id (ex) != - CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID) - return; - camel_exception_clear (ex); - } - } - - /* In the case where the summary does not exist (or was the - * wrong version), or is not in sync with the mbox file, - * regenerate it. - */ - if (folder->summary == NULL) { - /* Parse the mbox folder and get some information - * about the messages. - */ - mbox_file_fd = open (mbox_folder->folder_file_path, O_RDONLY); - if (mbox_file_fd != -1) { - message_info_array = - camel_mbox_parse_file (mbox_file_fd, "From ", - 0, &file_size, - &next_uid, TRUE, - NULL, 0, ex); - close (mbox_file_fd); - if (camel_exception_get_id (ex)) - return; - - next_uid = camel_mbox_write_xev (mbox_folder, - mbox_folder->folder_file_path, - message_info_array, - &file_size, - next_uid, ex); - if (camel_exception_get_id (ex)) { - /* ** FIXME : free the preparsed information */ - return; - } - - summ = CAMEL_MBOX_SUMMARY (gtk_object_new (camel_mbox_summary_get_type (), NULL)); - summ->message_info = parsed_information_to_mbox_summary (message_info_array); - summ->nb_message = summ->message_info->len; - summ->next_uid = next_uid; - summ->mbox_file_size = file_size; - /* **FIXME : Free the parsed information structure */ - } else { - summ = CAMEL_MBOX_SUMMARY (gtk_object_new (camel_mbox_summary_get_type (), NULL)); - summ->message_info = g_array_new (FALSE, FALSE, sizeof (CamelMboxSummaryInformation)); - summ->nb_message = 0; - summ->next_uid = 0; - summ->mbox_file_size = 0; - } - - folder->summary = CAMEL_FOLDER_SUMMARY (summ); - } -} - - - -static void -_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - - 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)); - } - - /* call parent class */ - parent_class->open (folder, mode, ex); - if (camel_exception_get_id(ex)) - return; - -#if 0 - /* get (or create) uid list */ - if (!(mbox_load_uid_list (mbox_folder) > 0)) - mbox_generate_uid_list (mbox_folder); -#endif - - _check_get_or_maybe_generate_summary_file (mbox_folder, ex); -} - - -static void -_close (CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - CamelMboxSummary *mbox_summary = CAMEL_MBOX_SUMMARY (folder->summary); - struct stat st; - - /* call parent implementation */ - parent_class->close (folder, expunge, ex); - - /* save index */ - if (mbox_folder->index) { - ibex_close(mbox_folder->index); - } - - /* Update the summary and save it to disk */ - if (stat (mbox_folder->folder_file_path, &st) == 0) { - mbox_summary->mbox_file_size = st.st_size; - mbox_summary->mbox_modtime = st.st_mtime; - } - camel_mbox_summary_save (mbox_summary, - mbox_folder->summary_file_path, ex); -} - - - - -static void -_set_name (CamelFolder *folder, const gchar *name, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - const gchar *root_dir_path; - - /* call default implementation */ - parent_class->set_name (folder, name, ex); - if (camel_exception_get_id (ex)) return; - - 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 gboolean -_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; -} - - - - - - - - -static gboolean -_create (CamelFolder *folder, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - CamelMboxSummary *summary; - 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); - - /* create the summary object */ - summary = CAMEL_MBOX_SUMMARY (gtk_object_new (camel_mbox_summary_get_type (), NULL)); - summary->nb_message = 0; - summary->next_uid = 1; - summary->mbox_file_size = 0; - summary->message_info = g_array_new (FALSE, FALSE, sizeof (CamelMboxSummaryInformation)); - - 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; - } -} - - - -static gboolean -_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; -} - - - - -gboolean -_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 GList * -_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 -_get_message_count (CamelFolder *folder, CamelException *ex) -{ - gint message_count; - - g_assert (folder); - g_assert (folder->summary); - - message_count = CAMEL_MBOX_SUMMARY (folder->summary)->nb_message; - - return message_count; -} - - -static void -_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - CamelMboxSummary *summary = CAMEL_MBOX_SUMMARY (folder->summary); - CamelStream *output_stream; - guint32 tmp_file_size; - guint32 next_uid; - gint tmp_file_fd; - GArray *message_info_array; - GArray *mbox_summary_info; - gchar *tmp_message_filename; - gint fd1, fd2; - int i; - - tmp_message_filename = g_strdup_printf ("%s.tmp", - mbox_folder->folder_file_path); - - /* write the message itself */ - output_stream = camel_stream_fs_new_with_name (tmp_message_filename, - CAMEL_STREAM_FS_WRITE); - if (output_stream != NULL) { - camel_stream_write_string (output_stream, "From - \n"); - camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), output_stream); - } - camel_stream_close (output_stream); - gtk_object_unref (GTK_OBJECT (output_stream)); - - /* at this point we have saved the message to a - temporary file, now, we have to add the x-evolution - field and also update the main summary */ - - /* - First : parse the mbox file, but only from the - position where the message has been added, - wich happens to be the last postion in the - mbox file before we added the message. - This position is still stored in the summary - for the moment - */ - next_uid = summary->next_uid; - tmp_file_fd = open (tmp_message_filename, O_RDONLY); - message_info_array = - camel_mbox_parse_file (tmp_file_fd, "From - ", 0, - &tmp_file_size, &next_uid, TRUE, - NULL, 0, ex); - - close (tmp_file_fd); - - /* get the value of the last available UID - as saved in the summary file, again */ - next_uid = summary->next_uid; - - /* make sure all our of message info's have 0 uid - ignore any - set elsewhere */ - for (i=0;i<message_info_array->len;i++) { - g_array_index(message_info_array, CamelMboxParserMessageInfo, i).uid = 0; - } - - /* - OK, this is not very efficient, we should not use the same - method as for parsing an entire mail file, - but I have no time to write a simpler parser - */ - next_uid = camel_mbox_write_xev (mbox_folder, tmp_message_filename, - message_info_array, &tmp_file_size, next_uid, ex); - - if (camel_exception_get_id (ex)) { - /* ** FIXME : free the preparsed information */ - return; - } - - mbox_summary_info = - parsed_information_to_mbox_summary (message_info_array); - - /* store the number of messages as well as the summary array */ - summary->nb_message += 1; - summary->next_uid = next_uid; - - ((CamelMboxSummaryInformation *)(mbox_summary_info->data))->position += - summary->mbox_file_size; - summary->mbox_file_size += tmp_file_size; - - camel_mbox_summary_append_entries (summary, mbox_summary_info); - g_array_free (mbox_summary_info, TRUE); - - - /* append the temporary file message to the mbox file */ - fd1 = open (tmp_message_filename, O_RDONLY); - fd2 = open (mbox_folder->folder_file_path, - O_WRONLY | O_CREAT | O_APPEND, - 0600); - - if (fd2 == -1) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not open the mbox folder file for appending the message\n" - "\t%s\n" - "Full error is : %s\n", - mbox_folder->folder_file_path, - strerror (errno)); - return; - } - - camel_mbox_copy_file_chunk (fd1, - fd2, - tmp_file_size, - ex); - close (fd1); - close (fd2); - - /* remove the temporary file */ - unlink (tmp_message_filename); - - g_free (tmp_message_filename); -} - - - - -static GList * -_get_uid_list (CamelFolder *folder, CamelException *ex) -{ - GArray *message_info_array; - CamelMboxSummaryInformation *message_info; - GList *uid_list = NULL; - int i; - - message_info_array = - CAMEL_MBOX_SUMMARY (folder->summary)->message_info; - - for (i=0; i<message_info_array->len; i++) { - message_info = (CamelMboxSummaryInformation *)(message_info_array->data) + i; - uid_list = g_list_prepend (uid_list, g_strdup_printf ("%u", message_info->uid)); - } - - return uid_list; -} - - - - -static CamelMimeMessage * -_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex) -{ - GArray *message_info_array; - CamelMboxSummaryInformation *message_info; - char uidbuf[20]; - - message_info_array = - CAMEL_MBOX_SUMMARY (folder->summary)->message_info; - - if (number > message_info_array->len) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID, - "No such message %d in folder `%s'.", - number, folder->name); - return NULL; - } - - message_info = - (CamelMboxSummaryInformation *)(message_info_array->data) + - (number - 1); - sprintf (uidbuf, "%lu", message_info->uid); - - return _get_message_by_uid (folder, uidbuf, ex); -} - - -static CamelMimeMessage * -_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) -{ - - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder); - GArray *message_info_array; - CamelMboxSummaryInformation *message_info = NULL; - guint32 searched_uid; - int i; - gboolean uid_found; - CamelStream *message_stream; - CamelMimeMessage *message = NULL; - CamelStore *parent_store; - - searched_uid = strtoul (uid, NULL, 10); - - message_info_array = - CAMEL_MBOX_SUMMARY (folder->summary)->message_info; - i=0; - uid_found = FALSE; - - /* first, look for the message that has the searched uid */ - while ((i<message_info_array->len) && (!uid_found)) { - message_info = (CamelMboxSummaryInformation *)(message_info_array->data) + i; - uid_found = (message_info->uid == searched_uid); - i++; - } - - /* if the uid was not found, raise an exception and return */ - if (!uid_found) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_UID, - "uid %s not found in the folder", - uid); - return NULL; - } - - /* at this point, the message_info structure - contains the informations concerning the - message that was searched for */ - - /* create a stream bound to the message */ - message_stream = camel_stream_fs_new_with_name_and_bounds (mbox_folder->folder_file_path, - CAMEL_STREAM_FS_READ, - message_info->position, - message_info->position + message_info->size); - - - /* get the parent store */ - parent_store = camel_folder_get_parent_store (folder, ex); - if (camel_exception_get_id (ex)) { - gtk_object_unref (GTK_OBJECT (message_stream)); - return NULL; - } - - - message = camel_mime_message_new (); - camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (message), message_stream); - - return message; -} diff --git a/camel/providers/mbox/camel-mbox-folder.h b/camel/providers/mbox/camel-mbox-folder.h deleted file mode 100644 index 52d3fa6e70..0000000000 --- a/camel/providers/mbox/camel-mbox-folder.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-folder.h : Abstract class for an email folder */ - -/* - * - * Author : Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 Helix Code . - * - * 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 - */ - - -#ifndef CAMEL_MBOX_FOLDER_H -#define CAMEL_MBOX_FOLDER_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <gtk/gtk.h> -#include "camel-folder.h" -#include "camel-mbox-summary.h" -#include "libibex/ibex.h" - -/* #include "camel-store.h" */ - -#define CAMEL_MBOX_FOLDER_TYPE (camel_mbox_folder_get_type ()) -#define CAMEL_MBOX_FOLDER(obj) (GTK_CHECK_CAST((obj), CAMEL_MBOX_FOLDER_TYPE, CamelMboxFolder)) -#define CAMEL_MBOX_FOLDER_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MBOX_FOLDER_TYPE, CamelMboxFolderClass)) -#define IS_CAMEL_MBOX_FOLDER(o) (GTK_CHECK_TYPE((o), CAMEL_MBOX_FOLDER_TYPE)) - - -typedef struct { - CamelFolder parent_object; - - gchar *folder_file_path; /* contains the messages */ - gchar *summary_file_path; /* contains the messages summary */ - gchar *folder_dir_path; /* contains the subfolders */ - gchar *index_file_path; /* index of body contents */ - - GList *uid_array; - - ibex *index; /* index for this folder */ - int search_id; /* next search id */ - GList *searches; /* current searches */ -} CamelMboxFolder; - - - -typedef struct { - CamelFolderClass parent_class; - - /* Virtual methods */ - -} CamelMboxFolderClass; - - -/* public methods */ - -/* Standard Gtk function */ -GtkType camel_mbox_folder_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_MBOX_FOLDER_H */ diff --git a/camel/providers/mbox/camel-mbox-parser.c b/camel/providers/mbox/camel-mbox-parser.c deleted file mode 100644 index b9091278fb..0000000000 --- a/camel/providers/mbox/camel-mbox-parser.c +++ /dev/null @@ -1,865 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-parser.c : mbox folder parser */ - -/* - * - * Author : Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 Helix Code . - * - * 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 "camel-mbox-parser.h" -#include "camel-mbox-utils.h" -#include "camel-exception.h" -#include <sys/types.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <sys/stat.h> -#include <fcntl.h> - - - -#define MBOX_PARSER_BUF_SIZE 10000 - -#define MBOX_PARSER_FROM_KW "from:" -#define MBOX_PARSER_FROM_KW_SZ 5 - -#define MBOX_PARSER_DATE_KW "date:" -#define MBOX_PARSER_DATE_KW_SZ 5 - -#define MBOX_PARSER_SUBJECT_KW "subject:" -#define MBOX_PARSER_SUBJECT_KW_SZ 8 - -#define MBOX_PARSER_TO_KW "to:" -#define MBOX_PARSER_TO_KW_SZ 3 - -#define MBOX_PARSER_X_EVOLUTION_KW "x-evolution:" -#define MBOX_PARSER_X_EVOLUTION_KW_SZ 12 - -/* the maximum lentgh of all the previous keywords */ -#define MBOX_PARSER_MAX_KW_SIZE 12 - - -#define MBOX_PARSER_SUMMARY_SIZE 150 - - - - - - -typedef struct { - - int fd; /* file descriptor of the mbox file */ - glong real_position; /* real position in the file */ - - - gchar *message_delimiter; /* message delimiter string */ - guint message_delimiter_length; - - guint message_summary_size; /* how many characters from the begining of the - mail to put into the message summary */ - - GArray *preparsed_messages; /* array of MessagePreParsingInfo */ - CamelMboxParserMessageInfo current_message_info; /* used to store curent info */ - gboolean is_pending_message; /* is there some message information pending ? */ - - /* buffer info */ - gchar *buffer; /* temporary buffer */ - guint left_chunk_size; /* size of the left chunk in the temp buffer */ - guint last_position; /* last position that can be compared to a keyword */ - guint current_position; /* current position in the temp buffer */ - - /* other */ - GString *tmp_string; /* temporary string to fill the headers in */ - - - -} CamelMboxPreParser; - - -/* clear a preparsing info structure */ -static void -clear_message_info (CamelMboxParserMessageInfo *preparsing_info) -{ - - preparsing_info->message_position = 0; - preparsing_info->size = 0; - preparsing_info->from = NULL; - preparsing_info->date = NULL; - preparsing_info->subject = NULL; - preparsing_info->priority = NULL; - preparsing_info->references = NULL; - preparsing_info->body_summary = NULL; - preparsing_info->end_of_headers_offset = 0; - - preparsing_info->x_evolution_offset = 0; - preparsing_info->status = 0; - preparsing_info->uid = 0; -} - - - -/** - * new_parser: create a new parser object - * @fd: file descriptor opened on the mbox file - * @message_delimiter: the string that announce the start of a new message. - * - * Create a new parser object. This object is the place where are - * stored all the information concerning the parsing process. - * - * Return value: The newly created parser object. - **/ -static CamelMboxPreParser * -new_parser (int fd, - const gchar *message_delimiter) -{ - CamelMboxPreParser *parser; - - parser = g_new0 (CamelMboxPreParser, 1); - - parser->fd = fd; - parser->buffer = g_new (gchar, MBOX_PARSER_BUF_SIZE); - parser->current_position = 0; - parser->message_delimiter = g_strdup (message_delimiter); - parser->message_delimiter_length = strlen (message_delimiter); - parser->real_position = 0; - parser->preparsed_messages = g_array_new (FALSE, FALSE, sizeof (CamelMboxParserMessageInfo)); - parser->message_summary_size = MBOX_PARSER_SUMMARY_SIZE; - - parser->left_chunk_size = MAX (parser->message_delimiter_length, MBOX_PARSER_MAX_KW_SIZE); - - parser->tmp_string = g_string_sized_new (1000); - - return parser; -} - - - -/** - * parser_free: free the parser object - * @parser: the parser objet to free. - * - * it is important to notice that all structures allocated - * in new_parser () are freed ** EXCEPT ** the message - * information array, i.e. the preparsed_messages - * field. - **/ -static void -parser_free (CamelMboxPreParser *parser) -{ - g_free (parser->buffer); - g_free (parser->message_delimiter); - g_string_free (parser->tmp_string, TRUE); - g_free (parser); -} - - - - -/* ** handle exceptions here */ -/** - * initialize_buffer: read the first chunk of data in the buffer - * @parser: parser object to fill - * @first_position: position to start the read at - * - * read the first chunk of data from the mbox file. - * - **/ -static void -initialize_buffer (CamelMboxPreParser *parser, - glong first_position) -{ - gint seek_res; - gint buf_nb_read; - - g_assert (parser); - - /* set the search start position */ - seek_res = lseek (parser->fd, first_position, SEEK_SET); - //if (seek_res == (off_t)-1) goto io_error; - - - /* the first part of the buffer is filled with newlines, - but the next time a chunk of buffer is read, it will - be filled with the last bytes of the previous chunk. - This allows simple g_strcasecmp to test for the presence of - the keyword */ - memset (parser->buffer, '\n', parser->left_chunk_size); - do { - buf_nb_read = read (parser->fd, parser->buffer + parser->left_chunk_size, - MBOX_PARSER_BUF_SIZE - parser->left_chunk_size); - } while ((buf_nb_read == -1) && (errno == EINTR)); - /* ** check for an error here */ - - if (buf_nb_read < MBOX_PARSER_BUF_SIZE - parser->left_chunk_size) { - /* fill the end of the buffer with 0\ */ - memset (parser->buffer + buf_nb_read + parser->left_chunk_size, '\0', - MIN (parser->left_chunk_size, MBOX_PARSER_BUF_SIZE - buf_nb_read - parser->left_chunk_size)); - }; - - parser->last_position = MIN (buf_nb_read + parser->left_chunk_size + 1, - MBOX_PARSER_BUF_SIZE - parser->left_chunk_size); - parser->current_position = parser->left_chunk_size; -} - - - - -/** - * read_next_buffer_chunk: read the next chunk of data in the mbox file - * @parser: parser object - * - * read the next chunk of data in the mbox file. - * Routine copies the last part of the buffer at - * the begining are concatenate the read data to - * it. This allows strcmp of keywords in the buffer, - * until the last postion. That means you can - * do a strcmp (buffer, keyword) for any of the - * keyword defined at the begining of this file. - * - **/ -static void -read_next_buffer_chunk (CamelMboxPreParser *parser) -{ - gint buf_nb_read; - - g_assert (parser); - - /* read the next chunk of data in the folder file : */ - /* - first, copy the last bytes from the previous - chunk at the begining of the new one. */ - memcpy (parser->buffer, - parser->buffer + MBOX_PARSER_BUF_SIZE - parser->left_chunk_size, - parser->left_chunk_size); - - /* - then read the next chunk on disk */ - do { - buf_nb_read = read (parser->fd, - parser->buffer + parser->left_chunk_size, - MBOX_PARSER_BUF_SIZE - parser->left_chunk_size); - } while ((buf_nb_read == -1) && (errno == EINTR)); - /* ** check for an error here */ - - if (buf_nb_read < MBOX_PARSER_BUF_SIZE - parser->left_chunk_size) { - /* fill the end of the buffer with 0\ */ - memset (parser->buffer + buf_nb_read + parser->left_chunk_size, '\0', - MIN (parser->left_chunk_size, MBOX_PARSER_BUF_SIZE - buf_nb_read - parser->left_chunk_size)); - }; - - parser->last_position = MIN (buf_nb_read + parser->left_chunk_size + 1, - MBOX_PARSER_BUF_SIZE - parser->left_chunk_size); - - parser->current_position = 0; -} - - - -/** - * goto_next_char: go one postion forward in the buffer - * @parser: parser object - * - * goto one position forward in the buffer. If necessary, - * read the next chunk of data in the file. - * - **/ -static void -goto_next_char (CamelMboxPreParser *parser) -{ - - if (parser->current_position < parser->last_position - 1) - parser->current_position++; - else - read_next_buffer_chunk (parser); - - parser->real_position++; - -} - - - - - - - -/** - * advance_n_chars: go n positions forward in the buffer. - * @parser: parser object - * @n: number of characters to advance. - * - **/ -static void -advance_n_chars (CamelMboxPreParser *parser, guint n) -{ - - gint position_to_the_end; - - position_to_the_end = parser->last_position - parser->current_position; - - if (n < position_to_the_end) - parser->current_position += n; - else { - read_next_buffer_chunk (parser); - parser->current_position = n - position_to_the_end; - } - - parser->real_position += n; -} - - - - - - -/* called when the buffer has detected the begining of - a new message. This routine is supposed to simply - store the previous message information and - clean the temporary structure used to store - the informations */ - - -/** - * new_message_detected: routine to call when a new message has been detected - * @parser: parser object. - * - * this routine must be called when the keyword determining the - * begining of a new message has been detected. It pushes the - * information fetched for the last message into the message information - * array. Also, it gets the parser to the end of the line. - **/ -static void -new_message_detected (CamelMboxPreParser *parser) -{ - - gchar c; - - /* if we were filling a message information - save it in the message information array */ - if (parser->is_pending_message) { - parser->current_message_info.size = - parser->real_position - parser->current_message_info.message_position; - g_array_append_vals (parser->preparsed_messages, (gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info), 1); - } - - clear_message_info ( &(parser->current_message_info)); - - /* go to the end of the line */ - do { - - c = parser->buffer[parser->current_position]; - goto_next_char (parser); - - } while (c != '\n'); - - /* save message position in the message information structure */ - (parser->current_message_info).message_position = parser->real_position; - - parser->is_pending_message = TRUE; -} - - - - - - - -/** - * read_header: read the header content contained after the current position. - * @parser: the parser object. - * @header_content: a pointer on a (char *) variable to feed with the obtained header string. - * - * This routine must be called when the parser has detected a header - * and it wants the header content to be stored. The parser current position - * must EXACTLY be located at the begining of the header content line. - * For example, if the file contains the line : - * from:Bertrand Guiheneuf <bertrand@helixcode.com> - * - * When this routine is called, the parser must be located - * on the "B" of "Bertrand". - * - * When this routine returns, the parser is located just - * after the "\n" at the end of the header content. - * - **/ -static void -read_header (CamelMboxPreParser *parser, gchar **header_content) -{ - gboolean space = FALSE; - gboolean newline = FALSE; - gboolean header_end = FALSE; - gchar *buffer; - gchar c; - - g_assert (parser); - - /* reset the header buffer string */ - parser->tmp_string = g_string_truncate (parser->tmp_string, 0); - - buffer = parser->buffer; - - /* read the current character */ - c = buffer[parser->current_position]; - - while (! ((c == '\0') || header_end )) { - - if (space) { - if (c == ' ' && c == '\t') - goto next_char; - else - space = FALSE; - } - - if (newline) { - if (c == ' ' && c == '\t') { - - space = TRUE; - newline = FALSE; - goto next_char; - } else { - - header_end = TRUE; - continue; - } - } - - if (c == '\n') { - newline = TRUE; - goto next_char; - } - - /* feed the header content */ - parser->tmp_string = g_string_append_c (parser->tmp_string, c); - - next_char: /* read next char in the buffer */ - goto_next_char (parser); - /* read the current character */ - c = buffer[parser->current_position]; - } - - - /* FIXME: this can cause a memory leak, for duplicated headers? */ - - /* copy the buffer in the preparsing information structure */ - *header_content = g_strndup (parser->tmp_string->str, parser->tmp_string->len); -} - - - - - - - -/** - * read_message_begining: read the first characters of a message body - * @parser: parser object - * @message_summary: a pointer on a (gchar *) variable where the obtained string will be stored. - * - * Read the first lines of a message. When calling this routine, the - * parser must be located at the begining of the message body. - * - * Return value: if the parsing inside this routine last read a newline, then %TRUE is returned, otherwise %FALSE is returned - **/ -static gboolean -read_message_begining (CamelMboxPreParser *parser, gchar **message_summary) -{ - guint nb_read = 0; - gchar *buffer; - gboolean new_message = FALSE; - guint nb_line = 0; - g_assert (parser); - - /* reset the header buffer string */ - parser->tmp_string = g_string_truncate (parser->tmp_string, 0); - - buffer = parser->buffer; - /* the message should not be filled character by - character but there is no g_string_n_append - function, so for the moment, this is a lazy - implementation */ - while (! (buffer[parser->current_position] != '\0') && - (nb_line <2) && (nb_read<parser->message_summary_size) && - (!new_message)) { - - - /* test if we are not at the end of the message */ - if (buffer[parser->current_position] == '\n') { - - nb_line++; - goto_next_char (parser); - if ((buffer[parser->current_position] == '\0') || - (g_strncasecmp (parser->buffer + parser->current_position, - parser->message_delimiter, - parser->message_delimiter_length) == 0)) { - new_message = TRUE; - continue; - } else { - /* we're not at the end, so let's just add the cr to the summary */ - parser->tmp_string = g_string_append_c (parser->tmp_string, - '\n'); - nb_read++; - continue; - } - - - } - - parser->tmp_string = g_string_append_c (parser->tmp_string, - buffer[parser->current_position]); - nb_read++; - goto_next_char (parser); - } - - *message_summary = g_strndup (parser->tmp_string->str, parser->tmp_string->len); - - return new_message; -} - - - - - - - - - - -/** - * camel_mbox_parse_file: read an mbox file and parse it. - * @fd: file descriptor opened on the mbox file. - * @message_delimiter: character string delimiting the beginig of a - * new message - * @start_position: position in the file where to start the parsing. - * @file_size: on output, the size in bytes of the file - * @next_uid: on output, the next uid available for use - * @get_message_summary: should the parser retrieve the begining of - * the messages - * @status_callback: function to call peridically to indicate the - * progress of the parser - * @status_interval: floating value between 0 and 1 indicate how often - * to call @status_callback. - * @user_data: user data that will be passed to the callback function - * - * This routine parses an mbox file and retreives both the message - * starting positions and some of the informations contained in the - * message. Those informations are mainly some RFC822 headers values - * but also (optionally) the first characters of the mail body. The - * @get_message_summary parameter allows to enable or disable this - * option. - * - * - * Return value: An array of CamelMboxParserMessageInfo containing the - * informations on each message parsed in the file - **/ -GArray * -camel_mbox_parse_file (int fd, - const gchar *message_delimiter, - glong start_position, - guint32 *file_size, - guint32 *next_uid, - gboolean get_message_summary, - camel_mbox_preparser_status_callback *status_callback, - double status_interval, - gpointer user_data) -{ - CamelMboxPreParser *parser; - gboolean is_parsing_a_message = FALSE; - gchar c; - struct stat stat_buf; - gint fstat_result; - glong total_file_size; - int last_status = 0; - int real_interval; - gboolean newline; - GArray *return_value; - gchar *x_ev_header_content; - guint32 next_available_uid = 1; - - - g_assert (next_uid); - - /* get file size */ - fstat_result = fstat (fd, &stat_buf); - if (fstat_result == -1) { - g_warning ("Manage exception here \n"); - } - - total_file_size = stat_buf.st_size; - real_interval = status_interval * total_file_size; - - - /* create the parser */ - parser = new_parser (fd, message_delimiter); - - /* initialize the temporary char buffer */ - initialize_buffer (parser, start_position); - - /* the first line is indeed at the begining of a new line ... */ - newline = TRUE; - - while (parser->buffer[parser->current_position] != '\0') { - - /* read the current character */ - if (!newline) { - c = parser->buffer[parser->current_position]; - newline = (c == '\n'); - goto_next_char (parser); - } - - if (newline) { - - /* check if we reached a status milestone */ - if ( status_callback && ((parser->real_position - last_status) > real_interval)) { - last_status += real_interval; - status_callback ((double)last_status / (double)total_file_size, - user_data); - } - - /* is the next part a message delimiter ? */ - if (strncmp (parser->buffer + parser->current_position, - parser->message_delimiter, - parser->message_delimiter_length) == 0) { - - is_parsing_a_message = TRUE; - new_message_detected (parser); - newline = TRUE; - continue; - } - - - if (is_parsing_a_message) { - /* we could find the headers in a clever way, like - storing them in a list of pair - [keyword, offset_in_CamelMboxParserMessageInfo] - I am too busy for now. Contribution welcome */ - - /* is the next part a "from" header ? */ - if (g_strncasecmp (parser->buffer + parser->current_position, - MBOX_PARSER_FROM_KW, - MBOX_PARSER_FROM_KW_SZ) == 0) { - - advance_n_chars (parser, MBOX_PARSER_FROM_KW_SZ); - read_header (parser, (gchar **) ((gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info) + - G_STRUCT_OFFSET (CamelMboxParserMessageInfo, from))); - - newline = TRUE; - continue; - } - - /* is the next part a "Date" header ? */ - if (g_strncasecmp (parser->buffer + parser->current_position, - MBOX_PARSER_DATE_KW, - MBOX_PARSER_DATE_KW_SZ) == 0) { - - advance_n_chars (parser, MBOX_PARSER_DATE_KW_SZ); - read_header (parser, (gchar **) ((gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info) + - G_STRUCT_OFFSET (CamelMboxParserMessageInfo, date))); - - newline = TRUE; - continue; - } - - - /* is the next part a "Subject" header ? */ - if (g_strncasecmp (parser->buffer + parser->current_position, - MBOX_PARSER_SUBJECT_KW, - MBOX_PARSER_SUBJECT_KW_SZ) == 0) { - - advance_n_chars (parser, MBOX_PARSER_SUBJECT_KW_SZ); - read_header (parser, (gchar **) ((gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info) + - G_STRUCT_OFFSET (CamelMboxParserMessageInfo, subject))); - - newline = TRUE; - continue; - } - - - /* is the next part a "To" header ? */ - if (g_strncasecmp (parser->buffer + parser->current_position, - MBOX_PARSER_TO_KW, - MBOX_PARSER_TO_KW_SZ) == 0) { - - advance_n_chars (parser, MBOX_PARSER_TO_KW_SZ); - read_header (parser, (gchar **) ((gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info) + - G_STRUCT_OFFSET (CamelMboxParserMessageInfo, to))); - - newline = TRUE; - continue; - } - - - /* is the next part a "X-evolution" header ? */ - if (g_strncasecmp (parser->buffer + parser->current_position, - MBOX_PARSER_X_EVOLUTION_KW, - MBOX_PARSER_X_EVOLUTION_KW_SZ) == 0) { - - /* in the case of the evolution private field, we store - the field position as well as its length because - we will have to change them */ - parser->current_message_info.x_evolution_offset = parser->real_position - - parser->current_message_info.message_position; - advance_n_chars (parser, MBOX_PARSER_X_EVOLUTION_KW_SZ); - - /* read the header */ - read_header (parser, &x_ev_header_content); - - /* parse it and put the result in the uid and status fields */ - camel_mbox_xev_parse_header_content (x_ev_header_content, - (guint32 *) ((gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info) + - G_STRUCT_OFFSET (CamelMboxParserMessageInfo, uid)), - (guchar *) ((gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info) + - G_STRUCT_OFFSET (CamelMboxParserMessageInfo, status))); - g_free (x_ev_header_content); - next_available_uid = MAX (next_available_uid, parser->current_message_info.uid + 1); - - newline = TRUE; - continue; - } - - - - - /* is it an empty line ? */ - if (parser->buffer[parser->current_position] == '\n') { - - parser->current_message_info.end_of_headers_offset = - parser->real_position - parser->current_message_info.message_position; - - goto_next_char (parser); - if (get_message_summary) - newline = read_message_begining (parser, (gchar **) ((gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info) + - G_STRUCT_OFFSET (CamelMboxParserMessageInfo, body_summary))); - - is_parsing_a_message = FALSE; - continue; - } - } - newline = FALSE; - } - - } - - /* if there is a pending message information put it in the array */ - if (parser->is_pending_message) { - parser->current_message_info.size = - parser->real_position - parser->current_message_info.message_position; - g_array_append_vals (parser->preparsed_messages, (gchar *)parser + - G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info), 1); - } - - return_value = parser->preparsed_messages; - *file_size = parser->real_position; - *next_uid = next_available_uid; - /* free the parser */ - parser_free (parser); - - return return_value; -} - - - - - - - - - - -#ifdef MBOX_PARSER_TEST -/* to build the test : - - gcc -O3 -I/opt/gnome/lib/glib/include `glib-config --cflags` -o test_parser -DMBOX_PARSER_TEST -I ../.. -I ../../.. -I /usr/lib/glib/include camel-mbox-parser.c `glib-config --libs` -lm - - - */ - - -#include <math.h> - -static void -status (double done, gpointer user_data) -{ - printf ("%d %% done\n", (int)floor (done * 100)); -} -int -main (int argc, char **argv) -{ - int test_file_fd; - int i; - int file_size; - int next_uid; - GArray *message_positions; - CamelMboxParserMessageInfo *message_info; - gchar tmp_buffer[50]; - - tmp_buffer[49] = '\0'; - - if (argc<2) { - printf("usage: %s mbox\n", argv[0]); - return 1; - } - - test_file_fd = open (argv[1], O_RDONLY); - message_positions = camel_mbox_parse_file (test_file_fd, - "From ", - 0, - &file_size, - &next_uid, - TRUE, - status, - 0.05, - NULL); - - printf ("Found %d messages \n", message_positions->len); - - - for (i=0; i<message_positions->len; i++) { - - message_info = ((CamelMboxParserMessageInfo *)(message_positions->data)) + i; - printf ("\n\n** Message %d : \n", i); - printf ("Size : %d\n", message_info->size); - printf ("From: %s\n", message_info->from); - printf ("Date: %s\n", message_info->date); - printf ("Subject: %s\n", message_info->subject); - printf ("Summary: %s\n", message_info->body_summary) ; - - - lseek (test_file_fd, message_info->message_position, SEEK_SET); - read (test_file_fd, tmp_buffer, 49); - printf ("File content at position %d : \n===\n%s\n===\n", message_info->message_position, tmp_buffer); - - } - - - - return 0; -} - - - - -#endif /* MBOX_PARSER_TEST */ diff --git a/camel/providers/mbox/camel-mbox-parser.h b/camel/providers/mbox/camel-mbox-parser.h deleted file mode 100644 index 9a566bf5af..0000000000 --- a/camel/providers/mbox/camel-mbox-parser.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-parser.c : mbox folder parser */ - -/* - * - * Author : Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 Helix Code . - * - * 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 <glib.h> -#include "camel-exception.h" - - -typedef struct { - - glong message_position; - glong size; - - gchar *from; - gchar *to; - gchar *date; - gchar *subject; - gchar *priority; - gchar *references; - gchar *body_summary; - gshort end_of_headers_offset; - - gchar *x_evolution; - gshort x_evolution_offset; - guint32 uid; - guchar status; - -} CamelMboxParserMessageInfo; - - -typedef void camel_mbox_preparser_status_callback (double percentage_done, gpointer user_data); - - -GArray * -camel_mbox_parse_file (int fd, - const gchar *message_delimiter, - glong start_position, - guint32 *file_size, - guint32 *next_uid, - gboolean get_message_summary, - camel_mbox_preparser_status_callback *status_callback, - double status_interval, - gpointer user_data); - diff --git a/camel/providers/mbox/camel-mbox-provider.c b/camel/providers/mbox/camel-mbox-provider.c deleted file mode 100644 index 74c4345306..0000000000 --- a/camel/providers/mbox/camel-mbox-provider.c +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-provider.c: mbox provider registration code */ - -/* - * Authors : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 2000 HelixCode (www.helixcode.com). - * - * 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 "camel-mbox-store.h" -#include "camel-provider.h" - - -static CamelProvider _mbox_provider = { - (GtkType) 0, - PROVIDER_STORE, - 0, - - "mbox", - "UNIX mbox-format mail files", - - "For reading mail delivered by the local system, and for " - "storing mail on local disk.", - - (GModule *) NULL -}; - -CamelProvider * -camel_provider_module_init (void); - - -CamelProvider * -camel_provider_module_init (void) -{ - _mbox_provider.object_type = camel_mbox_store_get_type(); - return &_mbox_provider; -} - - - diff --git a/camel/providers/mbox/camel-mbox-search.c b/camel/providers/mbox/camel-mbox-search.c deleted file mode 100644 index 1a584b8db6..0000000000 --- a/camel/providers/mbox/camel-mbox-search.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright 2000 HelixCode (http://www.helixcode.com). - * - * Author : - * Michael Zucchi <notzed@helixcode.com> - - * 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 <glib.h> -#include <stdio.h> -#include <time.h> -#include <string.h> - - -#include <camel/gmime-utils.h> -#include "camel/camel-mime-message.h" -#include "camel/camel-mime-part.h" -#include "camel/camel-stream.h" -#include "camel/camel-stream-fs.h" -#include "camel/camel.h" -#include "camel-mbox-folder.h" -#include "camel-mbox-summary.h" - -#include "camel-mbox-search.h" -#define HAVE_FILTER -#ifdef HAVE_FILTER -#include "e-sexp.h" - -#define HAVE_IBEX -#ifdef HAVE_IBEX -#include "ibex.h" -#endif - -#define p(x) /* parse debug */ -#define r(x) /* run debug */ -#define d(x) /* general debug */ - - -/* - - Matching operators: - - list = (body-contains string+) - bool = (body-contains string+) - Returns a list of all messages containing any of the strings in the message. - If within a match-all, then returns true for the current message. - - list = (match-all bool-expr) - Returns a list of all messages for which the bool expression is true. - The bool-expr is evaluated for each message in turn. - It is more efficient not to perform body-content comparisons inside a - match-all operator. - - int = (date-sent) - Returns a time_t of the date-sent of the message. - - bool = (header-contains string string+) - Returns true if the current message (inside a match-all operator) - has a header 'string1', which contains any of the following strings. -*/ - - -struct _searchcontext { - int id; /* id of this search */ - int cancelled; /* search cancelled? */ - - CamelFolder *folder; - -#ifdef HAVE_IBEX - ibex *index; /* index of content for this folder */ -#endif - - CamelFolderSummary *summary; - const GArray *message_info; - - CamelMessageInfo *message_current; /* when performing a (match operation */ -}; - -struct _glib_sux_donkeys { - int count; - GPtrArray *uids; -}; -/* or, store all unique values */ -static void -g_lib_sux_htor(char *key, int value, struct _glib_sux_donkeys *fuckup) -{ - g_ptr_array_add(fuckup->uids, key); -} - -static ESExpResult * -func_body_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - int i, j; - struct _searchcontext *ctx = data; - - if (ctx->message_current) { - int truth = FALSE; - - r = e_sexp_result_new(ESEXP_RES_BOOL); - if (ctx->index) { - for (i=0;i<argc && !truth;i++) { - if (argv[i]->type == ESEXP_RES_STRING) { - truth = ibex_find_name(ctx->index, ctx->message_current->uid, argv[i]->value.string); - } else { - g_warning("Invalid type passed to body-contains match function"); - } - } - } else { - g_warning("Cannot perform indexed query with no index"); - } - r->value.bool = truth; - } else { - r = e_sexp_result_new(ESEXP_RES_ARRAY_PTR); - - if (ctx->index) { - if (argc==1) { - /* common case */ - r->value.ptrarray = ibex_find(ctx->index, argv[0]->value.string); - } else { - GHashTable *ht = g_hash_table_new(g_str_hash, g_str_equal); - GPtrArray *pa; - struct _glib_sux_donkeys lambdafoo; - - /* this sux, perform an or operation on the result(s) of each word */ - for (i=0;i<argc;i++) { - if (argv[i]->type == ESEXP_RES_STRING) { - pa = ibex_find(ctx->index, argv[i]->value.string); - for (j=0;j<pa->len;j++) { - g_hash_table_insert(ht, g_ptr_array_index(pa, j), (void *)1); - } - g_ptr_array_free(pa, FALSE); - } - } - lambdafoo.uids = g_ptr_array_new(); - g_hash_table_foreach(ht, (GHFunc)g_lib_sux_htor, &lambdafoo); - r->value.ptrarray = lambdafoo.uids; - } - } else { - r->value.ptrarray = g_ptr_array_new(); - } - } - - return r; -} - -static ESExpResult * -func_date_sent(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - struct _searchcontext *ctx = data; - - r = e_sexp_result_new(ESEXP_RES_INT); - - if (ctx->message_current) { - g_warning("FIXME: implement date parsing ..."); - /* r->value.number = get_date(ctx->message_current); */ - } else { - r->value.number = time(0); - } - return r; -} - - -static ESExpResult * -func_match_all(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data) -{ - int i; - ESExpResult *r, *r1; - struct _searchcontext *ctx = data; - - if (argc>1) { - g_warning("match-all only takes a single argument, other arguments ignored"); - } - r = e_sexp_result_new(ESEXP_RES_ARRAY_PTR); - r->value.ptrarray = g_ptr_array_new(); - - for (i=0;i<ctx->message_info->len;i++) { - if (argc>0) { - ctx->message_current = &g_array_index(ctx->message_info, CamelMessageInfo, i); - r1 = e_sexp_term_eval(f, argv[0]); - if (r1->type == ESEXP_RES_BOOL) { - if (r1->value.bool) - g_ptr_array_add(r->value.ptrarray, ctx->message_current->uid); - } else { - g_warning("invalid syntax, matches require a single bool result"); - } - e_sexp_result_free(r1); - } else { - g_ptr_array_add(r->value.ptrarray, ctx->message_current->uid); - } - } - ctx->message_current = NULL; - - return r; -} - -static ESExpResult * -func_header_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - struct _searchcontext *ctx = data; - int truth = FALSE; - - r(printf("executing header-contains\n")); - - /* are we inside a match-all? */ - if (ctx->message_current && argc>1 - && argv[0]->type == ESEXP_RES_STRING) { - char *headername, *header; - int i; - - /* only a subset of headers are supported .. */ - headername = argv[0]->value.string; - if (!strcasecmp(headername, "subject")) { - header = ctx->message_current->subject; - } else if (!strcasecmp(headername, "date")) { - header = ctx->message_current->sent_date; - } else if (!strcasecmp(headername, "from")) { - header = ctx->message_current->sender; - } else { - g_warning("Performing query on unknown header: %s", headername); - header = NULL; - } - - if (header) { - for (i=1;i<argc && !truth;i++) { - if (argv[i]->type == ESEXP_RES_STRING - && strstr(header, argv[i]->value.string)) { - printf("%s got a match with %s of %s\n", ctx->message_current->uid, header, argv[i]->value.string); - truth = TRUE; - break; - } - } - } - } - r = e_sexp_result_new(ESEXP_RES_BOOL); - r->value.bool = truth; - - return r; -} - - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "body-contains", func_body_contains, 0 }, - { "date-sent", func_date_sent, 0 }, - { "match-all", (ESExpFunc *)func_match_all, 1 }, - { "header-contains", func_header_contains, 0 }, -}; - -int camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expression, - CamelSearchFunc *func, void *data, CamelException *ex) -{ - int i; - struct _searchcontext *ctx; - GList *matches = NULL; - ESExp *f; - ESExpResult *r; - - /* setup our expression evaluator */ - f = e_sexp_new(); - - ctx = g_malloc0(sizeof(*ctx)); - - ctx->id = ((CamelMboxFolder *)folder)->search_id++; - - /* setup out context */ - ctx->folder = folder; - ctx->summary = camel_folder_get_summary(folder, ex); - - if (ctx->summary == NULL || camel_exception_get_id (ex)) { - printf ("Cannot get summary\n" - "Full description : %s\n", camel_exception_get_description (ex)); - g_free(ctx); - gtk_object_unref((GtkObject *)f); - return -1; - } - - gtk_object_ref((GtkObject *)ctx->summary); - - /* FIXME: the index should be global to the folder */ - ctx->message_info = CAMEL_MBOX_SUMMARY(ctx->summary)->message_info; - ctx->message_current = NULL; - ctx->index = CAMEL_MBOX_FOLDER(folder)->index; - if (!ctx->index) { - g_warning("No folder index, searches will not function fully"); - } - - ((CamelMboxFolder *)folder)->searches = g_list_append(((CamelMboxFolder *)folder)->searches, ctx); - - for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) { - if (symbols[i].type == 1) { - e_sexp_add_ifunction(f, 0, symbols[i].name, (ESExpIFunc *)symbols[i].func, ctx); - } else { - e_sexp_add_function(f, 0, symbols[i].name, symbols[i].func, ctx); - } - } - - e_sexp_input_text(f, expression, strlen(expression)); - e_sexp_parse(f); - r = e_sexp_eval(f); - - /* now create a folder summary to return?? */ - if (r - && r->type == ESEXP_RES_ARRAY_PTR) { - d(printf("got result ...\n")); - for (i=0;i<r->value.ptrarray->len;i++) { - d(printf("adding match: %s\n", (char *)g_ptr_array_index(r->value.ptrarray, i))); - matches = g_list_prepend(matches, g_strdup(g_ptr_array_index(r->value.ptrarray, i))); - } - if (!ctx->cancelled) { - func(folder, ctx->id, TRUE, matches, data); - } - g_list_free(matches); - e_sexp_result_free(r); - } else { - printf("no result!\n"); - } - - gtk_object_unref((GtkObject *)ctx->summary); - gtk_object_unref((GtkObject *)f); - i = ctx->id; - - ((CamelMboxFolder *)folder)->searches = g_list_remove(((CamelMboxFolder *)folder)->searches, ctx); - - g_free(ctx); - - return i; -} - -static struct _searchcontext * -find_context(CamelMboxFolder *f, int id) -{ - struct _searchcontext *ctx; - GList *l; - - l = f->searches; - while (l) { - ctx = l->data; - if (ctx->id == id) { - return ctx; - } - l = g_list_next(l); - } - - return NULL; -} - -gboolean camel_mbox_folder_search_complete(CamelFolder *folder, int searchid, int wait, CamelException *ex) -{ - struct _searchcontext *ctx; - - ctx = find_context((CamelMboxFolder *)folder, searchid); - - if (ctx) - return ctx->cancelled; - - /* if its been removed, its complete ... */ - return TRUE; -} - -void camel_mbox_folder_search_cancel(CamelFolder *folder, int searchid, CamelException *ex) -{ - struct _searchcontext *ctx; - - ctx = find_context((CamelMboxFolder *)folder, searchid); - if (ctx) { - ctx->cancelled = TRUE; - return; - } - - /* FIXME: set exception, return */ -} - -#else /* HAVE_FILTER */ - -int camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expression, - CamelSearchFunc *func, void *data, CamelException *ex) -{ - return -1; -} - -gboolean camel_mbox_folder_search_complete(CamelFolder *folder, int searchid, int wait, CamelException *ex) -{ - return TRUE; -} - -void camel_mbox_folder_search_cancel(CamelFolder *folder, int searchid, CamelException *ex) -{ - /* empty */ -} - -#endif /*! HAVE_FILTER */ diff --git a/camel/providers/mbox/camel-mbox-search.h b/camel/providers/mbox/camel-mbox-search.h deleted file mode 100644 index d3fe328a2c..0000000000 --- a/camel/providers/mbox/camel-mbox-search.h +++ /dev/null @@ -1,14 +0,0 @@ - -#ifndef _CAMEL_MBOX_SEARCH_H -#define _CAMEL_MBOX_SEARCH_H - -#include <glib.h> -#include "camel-mbox-folder.h" - -int camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expression, - CamelSearchFunc *func, void *data, CamelException *ex); -gboolean camel_mbox_folder_search_complete(CamelFolder *folder, int searchid, gboolean wait, CamelException *ex); -void camel_mbox_folder_search_cancel(CamelFolder *folder, int searchid, CamelException *ex); - -#endif /* ! _CAMEL_MBOX_SEARCH_H */ - diff --git a/camel/providers/mbox/camel-mbox-store.c b/camel/providers/mbox/camel-mbox-store.c deleted file mode 100644 index 8db2f9338e..0000000000 --- a/camel/providers/mbox/camel-mbox-store.c +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-store.c : class for an mbox store */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. <bertrand@helixcode.com> - * - * 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 "camel-mbox-store.h" -#include "camel-mbox-folder.h" -#include "camel-exception.h" -#include "camel-url.h" - -/* Returns the class for a CamelMboxStore */ -#define CMBOXS_CLASS(so) CAMEL_MBOX_STORE_CLASS (GTK_OBJECT(so)->klass) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (GTK_OBJECT(so)->klass) -#define CMBOXF_CLASS(so) CAMEL_MBOX_FOLDER_CLASS (GTK_OBJECT(so)->klass) - -static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); - -static void -camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class) -{ - CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_mbox_store_class); - - /* virtual method overload */ - camel_store_class->get_folder = get_folder; - camel_store_class->get_folder_name = get_folder_name; -} - - - -static void -camel_mbox_store_init (gpointer object, gpointer klass) -{ - CamelService *service = CAMEL_SERVICE (object); - CamelStore *store = CAMEL_STORE (object); - - service->url_flags = CAMEL_SERVICE_URL_NEED_PATH; - - /* mbox names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new (g_str_hash, g_str_equal); -} - - - - -GtkType -camel_mbox_store_get_type (void) -{ - static GtkType camel_mbox_store_type = 0; - - if (!camel_mbox_store_type) { - GtkTypeInfo camel_mbox_store_info = - { - "CamelMboxStore", - sizeof (CamelMboxStore), - sizeof (CamelMboxStoreClass), - (GtkClassInitFunc) camel_mbox_store_class_init, - (GtkObjectInitFunc) camel_mbox_store_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - camel_mbox_store_type = gtk_type_unique (CAMEL_STORE_TYPE, &camel_mbox_store_info); - } - - return camel_mbox_store_type; -} - - -const gchar * -camel_mbox_store_get_toplevel_dir (CamelMboxStore *store) -{ - CamelURL *url = CAMEL_SERVICE (store)->url; - - g_assert(url != NULL); - return url->path; -} - - - -static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, CamelException *ex) -{ - CamelMboxFolder *new_mbox_folder; - CamelFolder *new_folder; - - new_mbox_folder = gtk_type_new (CAMEL_MBOX_FOLDER_TYPE); - new_folder = CAMEL_FOLDER (new_mbox_folder); - - /* 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 char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - return g_strdup (folder_name); -} diff --git a/camel/providers/mbox/camel-mbox-store.h b/camel/providers/mbox/camel-mbox-store.h deleted file mode 100644 index 06a971ada4..0000000000 --- a/camel/providers/mbox/camel-mbox-store.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-store.h : class for an mbox store */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. <bertrand@helixcode.com> - * - * 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 - */ - - -#ifndef CAMEL_MBOX_STORE_H -#define CAMEL_MBOX_STORE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <gtk/gtk.h> -#include "camel-store.h" - -#define CAMEL_MBOX_STORE_TYPE (camel_mbox_store_get_type ()) -#define CAMEL_MBOX_STORE(obj) (GTK_CHECK_CAST((obj), CAMEL_MBOX_STORE_TYPE, CamelMboxStore)) -#define CAMEL_MBOX_STORE_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MBOX_STORE_TYPE, CamelMboxStoreClass)) -#define IS_CAMEL_MBOX_STORE(o) (GTK_CHECK_TYPE((o), CAMEL_MBOX_STORE_TYPE)) - - -typedef struct { - CamelStore parent_object; - -} CamelMboxStore; - - - -typedef struct { - CamelStoreClass parent_class; - -} CamelMboxStoreClass; - - -/* public methods */ - -/* Standard Gtk function */ -GtkType camel_mbox_store_get_type (void); - -const gchar *camel_mbox_store_get_toplevel_dir (CamelMboxStore *store); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_MBOX_STORE_H */ - - diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c deleted file mode 100644 index e15bb13b03..0000000000 --- a/camel/providers/mbox/camel-mbox-summary.c +++ /dev/null @@ -1,420 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 - 2000 Helix Code . - - * 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 "camel-exception.h" -#include "camel-mbox-folder.h" -#include "camel-mbox-summary.h" -#include "md5-utils.h" - - -#include <sys/stat.h> -#include <unistd.h> -#include <sys/types.h> -#include <fcntl.h> -#include <dirent.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <netinet/in.h> - -static CamelFolderSummaryClass *parent_class = NULL; - -static int count_messages (CamelFolderSummary *summary); -static int count_subfolders (CamelFolderSummary *summary); -static GPtrArray *get_subfolder_info (CamelFolderSummary *summary, - int first, int count); -static GPtrArray *get_message_info (CamelFolderSummary *summary, - int first, int count); -static void finalize (GtkObject *object); - -static void -camel_mbox_summary_class_init (CamelMboxSummaryClass *camel_mbox_summary_class) -{ - GtkObjectClass *gtk_object_class = - GTK_OBJECT_CLASS (camel_mbox_summary_class); - CamelFolderSummaryClass *camel_folder_summary_class = - CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_class); - - parent_class = gtk_type_class (camel_folder_summary_get_type ()); - - /* virtual method override */ - camel_folder_summary_class->count_messages = count_messages; - camel_folder_summary_class->count_subfolders = count_subfolders; - camel_folder_summary_class->get_subfolder_info = get_subfolder_info; - camel_folder_summary_class->get_message_info = get_message_info; - - gtk_object_class->finalize = finalize; -} - - -GtkType -camel_mbox_summary_get_type (void) -{ - static GtkType camel_mbox_summary_type = 0; - - if (!camel_mbox_summary_type) { - GtkTypeInfo camel_mbox_summary_info = - { - "CamelMboxSummary", - sizeof (CamelMboxSummary), - sizeof (CamelMboxSummaryClass), - (GtkClassInitFunc) camel_mbox_summary_class_init, - (GtkObjectInitFunc) NULL, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - camel_mbox_summary_type = gtk_type_unique (camel_folder_summary_get_type (), &camel_mbox_summary_info); - } - - return camel_mbox_summary_type; -} - -static void -finalize (GtkObject *object) -{ - CamelMboxSummary *summary = CAMEL_MBOX_SUMMARY (object); - CamelMboxSummaryInformation *info; - int i; - - for (i = 0; i < summary->message_info->len; i++) { - info = &(((CamelMboxSummaryInformation *)summary->message_info->data)[i]); - g_free (info->headers.subject); - g_free (info->headers.sender); - g_free (info->headers.to); - g_free (info->headers.sent_date); - g_free (info->headers.received_date); - g_free (info->headers.uid); - } - g_array_free (summary->message_info, TRUE); - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - -static int -count_messages (CamelFolderSummary *summary) -{ - return CAMEL_MBOX_SUMMARY (summary)->nb_message; -} - -static int -count_subfolders (CamelFolderSummary *summary) -{ - /* XXX */ - g_warning ("CamelMboxSummary::count_subfolders not implemented"); - return 0; -} - -static GPtrArray * -get_subfolder_info (CamelFolderSummary *summary, int first, int count) -{ - /* XXX */ - g_warning ("CamelMboxSummary::count_subfolders not implemented"); - return 0; -} - -static GPtrArray * -get_message_info (CamelFolderSummary *summary, int first, int count) -{ - CamelMboxSummary *mbox_summary = CAMEL_MBOX_SUMMARY (summary); - CamelMboxSummaryInformation *info; - GPtrArray *arr; - - /* XXX bounds check */ - - arr = g_ptr_array_new (); - for (; count; count--) { - info = &((CamelMboxSummaryInformation *)mbox_summary->message_info->data)[first++]; - g_ptr_array_add (arr, info); - } - - return arr; -} - -/** - * camel_mbox_summary_save: - * @summary: - * @filename: - * @ex: - * - * save the summary into a file - **/ -void -camel_mbox_summary_save (CamelMboxSummary *summary, const gchar *filename, - CamelException *ex) -{ - CamelMboxSummaryInformation *msg_info; - guint cur_msg; - guint field_length; - gint fd; - gint write_result; /* XXX use this */ - guint32 data; - - fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR); - if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not create the mbox summary " - "file\n\t%s\nFull error is : %s\n", - filename, - strerror (errno)); - return; - } - - /* We write the file out in network byte order, not because - * that makes sense, but because it's easy. - */ - - data = htonl (CAMEL_MBOX_SUMMARY_VERSION); - write (fd, &data, sizeof (data)); - - data = htonl (summary->nb_message); - write (fd, &data, sizeof (data)); - data = htonl (summary->next_uid); - write (fd, &data, sizeof (data)); - data = htonl (summary->mbox_file_size); - write (fd, &data, sizeof (data)); - data = htonl (summary->mbox_modtime); - write (fd, &data, sizeof (data)); - - for (cur_msg = 0; cur_msg < summary->nb_message; cur_msg++) { - msg_info = (CamelMboxSummaryInformation *) - (summary->message_info->data) + cur_msg; - - /* Write meta-info. */ - data = htonl (msg_info->position); - write (fd, &data, sizeof (data)); - data = htonl (msg_info->size); - write (fd, &data, sizeof (data)); - data = htonl (msg_info->x_evolution_offset); - write (fd, &data, sizeof (data)); - data = htonl (msg_info->uid); - write (fd, &data, sizeof (data)); - write (fd, &msg_info->status, 1); - - /* Write subject. */ - if (msg_info->headers.subject) - field_length = strlen (msg_info->headers.subject); - else - field_length = 0; - data = htonl (field_length); - write (fd, &data, sizeof (data)); - if (msg_info->headers.subject) - write (fd, msg_info->headers.subject, field_length); - - /* Write sender. */ - if (msg_info->headers.sender) - field_length = strlen (msg_info->headers.sender); - else - field_length = 0; - data = htonl (field_length); - write (fd, &data, sizeof (data)); - if (msg_info->headers.sender) - write (fd, msg_info->headers.sender, field_length); - - /* Write to. */ - if (msg_info->headers.to) - field_length = strlen (msg_info->headers.to); - else - field_length = 0; - data = htonl (field_length); - write (fd, &data, sizeof (data)); - if (msg_info->headers.to) - write (fd, msg_info->headers.to, field_length); - - /* Write sent date. */ - if (msg_info->headers.sent_date) - field_length = strlen (msg_info->headers.sent_date); - else - field_length = 0; - data = htonl (field_length); - write (fd, &data, sizeof (data)); - if (msg_info->headers.sent_date) - write (fd, msg_info->headers.sent_date, field_length); - - /* Write received date. */ - if (msg_info->headers.received_date) - field_length = strlen (msg_info->headers.received_date); - else - field_length = 0; - data = htonl (field_length); - write (fd, &data, sizeof (data)); - if (msg_info->headers.received_date) - write (fd, msg_info->headers.received_date, field_length); - } - - close (fd); -} - - - -/** - * camel_mbox_summary_load: - * @filename: - * @ex: - * - * load the summary from a file - * - * Return value: - **/ -CamelMboxSummary * -camel_mbox_summary_load (const gchar *filename, CamelException *ex) -{ - CamelMboxSummaryInformation *msg_info; - guint cur_msg; - guint field_length; - gint fd; - CamelMboxSummary *summary; - gint read_result; - guint32 data; - - fd = open (filename, O_RDONLY); - if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not open the mbox summary file\n" - "\t%s\nFull error is : %s\n", - filename, strerror (errno)); - return NULL; - } - - /* Verify version number. */ - read (fd, &data, sizeof(data)); - data = ntohl (data); - - if (data != CAMEL_MBOX_SUMMARY_VERSION) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID, - "This folder summary was written by " - "%s version of this software.", - data < CAMEL_MBOX_SUMMARY_VERSION ? - "an older" : "a newer"); - return NULL; - } - - summary = CAMEL_MBOX_SUMMARY (gtk_object_new (camel_mbox_summary_get_type (), NULL)); - - read (fd, &data, sizeof(data)); - summary->nb_message = ntohl (data); - read (fd, &data, sizeof(data)); - summary->next_uid = ntohl (data); - read (fd, &data, sizeof(data)); - summary->mbox_file_size = ntohl (data); - read (fd, &data, sizeof(data)); - summary->mbox_modtime = ntohl (data); - - summary->message_info = - g_array_new (FALSE, FALSE, - sizeof (CamelMboxSummaryInformation)); - g_array_set_size (summary->message_info, summary->nb_message); - - for (cur_msg = 0; cur_msg < summary->nb_message; cur_msg++) { - msg_info = (CamelMboxSummaryInformation *) - (summary->message_info->data) + cur_msg; - - /* Read the meta-info. */ - read (fd, &data, sizeof(data)); - msg_info->position = ntohl (data); - read (fd, &data, sizeof(data)); - msg_info->size = ntohl (data); - read (fd, &data, sizeof(data)); - msg_info->x_evolution_offset = ntohl (data); - read (fd, &data, sizeof(data)); - msg_info->uid = ntohl (data); - msg_info->headers.uid = g_strdup_printf ("%d", msg_info->uid); - read (fd, &msg_info->status, 1); - - /* Read the subject. */ - read (fd, &field_length, sizeof (field_length)); - field_length = ntohl (field_length); - if (field_length > 0) { - msg_info->headers.subject = - g_new0 (gchar, field_length + 1); - read (fd, msg_info->headers.subject, field_length); - } else - msg_info->headers.subject = NULL; - - /* Read the sender. */ - read (fd, &field_length, sizeof (field_length)); - field_length = ntohl (field_length); - if (field_length > 0) { - msg_info->headers.sender = - g_new0 (gchar, field_length + 1); - read (fd, msg_info->headers.sender, field_length); - } else - msg_info->headers.sender = NULL; - - /* Read the "to" field. */ - read (fd, &field_length, sizeof (field_length)); - field_length = ntohl (field_length); - if (field_length > 0) { - msg_info->headers.to = - g_new0 (gchar, field_length + 1); - read (fd, msg_info->headers.to, field_length); - } else - msg_info->headers.to = NULL; - - /* Read the sent date field. */ - read (fd, &field_length, sizeof (field_length)); - field_length = ntohl (field_length); - if (field_length > 0) { - msg_info->headers.sent_date = - g_new0 (gchar, field_length + 1); - read (fd, msg_info->headers.sent_date, field_length); - } else - msg_info->headers.sent_date = NULL; - - /* Read the received date field. */ - read (fd, &field_length, sizeof (field_length)); - field_length = ntohl (field_length); - if (field_length > 0) { - msg_info->headers.received_date = - g_new0 (gchar, field_length + 1); - read (fd, msg_info->headers.received_date, - field_length); - } else - msg_info->headers.received_date = NULL; - } - - close (fd); - return summary; -} - - -/** - * camel_mbox_summary_append_entries: - * @summary: - * @entries: - * - * append an entry to a summary - **/ -void -camel_mbox_summary_append_entries (CamelMboxSummary *summary, GArray *entries) -{ - - summary->message_info = g_array_append_vals (summary->message_info, - entries->data, - entries->len); -} diff --git a/camel/providers/mbox/camel-mbox-summary.h b/camel/providers/mbox/camel-mbox-summary.h deleted file mode 100644 index f8570f15c0..0000000000 --- a/camel/providers/mbox/camel-mbox-summary.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * - * Author : Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 Helix Code (http://www.helixcode.com). - * - * 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 - */ - -#ifndef MBOX_SUMMARY_H -#define MBOX_SUMMARY_H 1 - -#include <camel-folder-summary.h> - -#define CAMEL_MBOX_SUMMARY_TYPE (camel_mbox_summary_get_type ()) -#define CAMEL_MBOX_SUMMARY(obj) (GTK_CHECK_CAST((obj), CAMEL_MBOX_SUMMARY_TYPE, CamelMboxSummary)) -#define CAMEL_MBOX_SUMMARY_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MBOX_SUMMARY_TYPE, CamelMboxSummaryClass)) -#define CAMEL_IS_MBOX_SUMMARY(o) (GTK_CHECK_TYPE((o), CAMEL_MBOX_SUMMARY_TYPE)) - - -#define CAMEL_MBOX_SUMMARY_VERSION 1 - - -typedef struct { - CamelMessageInfo headers; - - guint32 position; - guint size; - guint x_evolution_offset; - guint32 uid; - guchar status; - -} CamelMboxSummaryInformation; - - -/* this contains informations about the whole mbox file */ -typedef struct { - CamelFolderSummary parent_object; - - guint nb_message; /* number of messages in the summary */ - guint32 next_uid; - guint32 mbox_file_size; - guint32 mbox_modtime; - - GArray *message_info; /* array of CamelMboxSummaryInformation */ - -} CamelMboxSummary; - -typedef struct { - CamelFolderSummaryClass parent_class; - -} CamelMboxSummaryClass; - - -GtkType camel_mbox_summary_get_type (void); - -void camel_mbox_summary_save (CamelMboxSummary *summary, - const gchar *filename, CamelException *ex); -CamelMboxSummary *camel_mbox_summary_load (const gchar *filename, - CamelException *ex); - -gboolean camel_mbox_summary_check_sync (gchar *summary_filename, - gchar *mbox_filename, - CamelException *ex); - -void camel_mbox_summary_append_entries (CamelMboxSummary *summary, - GArray *entries); - - -#endif /* MBOX_SUMMARY_H */ diff --git a/camel/providers/mbox/camel-mbox-utils.c b/camel/providers/mbox/camel-mbox-utils.c deleted file mode 100644 index cd7da089e9..0000000000 --- a/camel/providers/mbox/camel-mbox-utils.c +++ /dev/null @@ -1,574 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Various utilities for the mbox provider */ - -/* - * Authors : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 Helix Code. - * - * 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 - */ - - -/* "xev" stands for x-evolution, which is the name of the - * evolution specific header where are stored informations - * like : - * - mail status - * - mail uid - * ... - * - * - * The evolution line has the following format : - * - * X-Evolution:XXXXX-X - * \___/ \/ - * UID ---' `- Status - * - * the UID is internally used as a 32 bits long integer, but only the first 24 bits are - * used. The UID is coded as a string on 4 characters. Each character is a 6 bits - * integer coded using the b64 alphabet. - * - */ - - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - - -#include <glib.h> -#include "camel-mbox-utils.h" -#include "camel-mbox-parser.h" -#include "camel-mbox-summary.h" -#include "camel-mime-message.h" -#include "camel/camel-mime-part.h" -#include "camel/camel-multipart.h" -#include "camel/camel-stream-fs.h" - -static gchar b64_alphabet[64] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - - -static void -uid_to_string (guint32 uid, gchar string[4]) -{ - - string [0] = b64_alphabet [(uid >> 18) & 0x3f]; - string [1] = b64_alphabet [(uid >> 12) & 0x3f]; - string [2] = b64_alphabet [(uid >> 6) & 0x3f]; - string [3] = b64_alphabet [(uid ) & 0x3f]; -} - - -static guint32 -string_to_uid (gchar *string) -{ - guint32 i; - - i = - (((string [0] >= 97) ? ( string [0] - 71 ) : - ((string [0] >= 65) ? ( string [0] - 65 ) : - ((string [0] >= 48) ? ( string [0] + 4 ) : - ((string [0] == 43) ? 62 : 63 )))) << 18) - - + (((string [1] >= 97) ? ( string [1] - 71 ) : - ((string [1] >= 65) ? ( string [1] - 65 ) : - ((string [1] >= 48) ? ( string [1] + 4 ) : - ((string [1] == 43) ? 62 : 63 )))) << 12) - - - + ((((string [2] >= 97) ? ( string [2] - 71 ) : - ((string [2] >= 65) ? ( string [2] - 65 ) : - ((string [2] >= 48) ? ( string [2] + 4 ) : - ((string [2] == 43) ? 62 : 63 ))))) << 6) - - - + (((string [3] >= 97) ? ( string [3] - 71 ) : - ((string [3] >= 65) ? ( string [3] - 65 ) : - ((string [3] >= 48) ? ( string [3] + 4 ) : - ((string [3] == 43) ? 62 : 63 ))))); - - return i; - -} - - -static gchar -flag_to_string (guchar status) -{ - return b64_alphabet [status & 0x3f]; -} - - -static guchar -string_to_flag (gchar string) -{ - return (string >= 97) ? ( string - 71 ) : - ((string >= 65) ? ( string - 65 ) : - ((string >= 48) ? ( string + 4 ) : - ((string == 43) ? 62 : 63 ))); -} - - - - - -void -camel_mbox_xev_parse_header_content (gchar header_content[6], - guint32 *uid, - guchar *status) -{ - - /* we assume that the first 4 characters of the header content - are actually the uid stuff. If somebody messed with it ... - toooo bad. - */ - *uid = string_to_uid (header_content); - *status = string_to_flag (header_content[5]); -} - -void -camel_mbox_xev_write_header_content (gchar header_content[6], - guint32 uid, - guchar status) -{ - uid_to_string (uid, header_content); - header_content[5] = flag_to_string (status); - header_content[4] = '-'; -} - - - - - - -void -camel_mbox_copy_file_chunk (gint fd_src, - gint fd_dest, - glong nb_bytes, - CamelException *ex) -{ - gchar buffer [1000]; - glong nb_to_read; - glong nb_read=1, v; - - nb_to_read = nb_bytes; - while (nb_to_read > 0 && nb_read>0) { - - do { - nb_read = read (fd_src, buffer, MIN (1000, nb_to_read)); - } while (nb_read == -1 && errno == EINTR); - - - if (nb_read == -1) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not read from the mbox file\n" - "Full error is : %s\n", - strerror (errno)); - return; - } - - - nb_to_read -= nb_read; - - do { - v = write (fd_dest, buffer, nb_read); - } while (v == -1 && errno == EINTR); - - if (v == -1) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not write to the mbox copy file\n" - "Full error is : %s\n", - strerror (errno)); - return; - } - - - } - - - -} - -typedef void (*index_data_callback)(ibex *index, char *text, int len, int *left); - -/* - needs to handle encoding? -*/ -static void -index_text(ibex *index, char *text, int len, int *left) -{ - /*printf("indexing %.*s\n", len, text);*/ - - ibex_index_buffer(index, "message", text, len, left); -/* - if (left) { - printf("%d bytes left from indexing\n", *left); - } -*/ -} - -/* - index html data, ignore tags for now. - could also index attribute values? - should also handle encoding types ... - should convert everything to utf8 -*/ -static void -index_html(ibex *index, char *text, int len, int *left) -{ - static int state = 0; - char indexbuf[128]; - char *out = indexbuf, *outend = indexbuf+128; - char *in, *inend; - int c; - - in = text; - inend = text+len; - - /*printf("indexing html: %d %d %.*s\n", state, len, len, text);*/ - - while (in<inend) { - c = *in++; - switch (state) { - case 0: /* no tag */ - if (c=='<') - state = 1; - else { - *out++ = c; - if (out==outend) { - index_text(index, indexbuf, out-indexbuf, left); - memcpy(indexbuf, indexbuf+(out-indexbuf)-*left, *left); - out = indexbuf+*left; - printf("** %d bytes left\n", *left); - } - } - break; - case 1: - if (c=='>') - state = 0; -#if 0 - else if (c=='"') - state = 2; - break; - case 2: - if (c=='"') { - state = 1; - } -#endif - break; - } - } - index_text(index, indexbuf, out-indexbuf, left); -} - -static void -index_message_content(ibex *index, CamelDataWrapper *object) -{ - CamelDataWrapper *containee; - CamelStream *stream; - int parts, i; - int len; - int left; - char buffer[128]; - - containee = camel_medium_get_content_object(CAMEL_MEDIUM(object)); - - if (containee) { - char *type = gmime_content_field_get_mime_type(containee->mime_type); - index_data_callback callback = NULL; - - /*printf("type = %s\n", type);*/ - - if (!strcasecmp(type, "text/plain")) { - callback = index_text; - } else if (!strcasecmp(type, "text/html")) { - callback = index_html; - } else if (!strncasecmp(type, "multipart/", 10)) { - parts = camel_multipart_get_number (CAMEL_MULTIPART(containee)); - /*printf("multipart message, scanning contents %d parts ...\n", parts);*/ - for (i=0;i<parts;i++) { - index_message_content(index, CAMEL_DATA_WRAPPER (camel_multipart_get_part(CAMEL_MULTIPART(containee), i))); - } - } else { - /*printf("\nunknwon format, ignored\n");*/ - } - - if (callback) { - int total=0; - - /*printf("reading containee\n"); - - printf("containee = %p\n", containee);*/ - - stream = camel_data_wrapper_get_output_stream(containee); - left = 0; - - if (stream) { - /*printf("stream = %p\n", stream);*/ - while ( (len = camel_stream_read(stream, buffer+left, sizeof(buffer)-left)) > 0) { - total = len+left; - callback(index, buffer, total, &left); - if (left>0) { - memcpy(buffer, buffer+total-left, left); - } - } - callback(index, buffer+total-left, left, NULL); - - /*camel_stream_close(stream);*/ - /*printf("\n");*/ - } else { - g_warning("cannot get stream for message?"); - } - } - - g_free(type); - } else { - printf("no containee?\n"); - } -} - - -static void -index_message(ibex *index, int fd, CamelMboxParserMessageInfo *mi) -{ - off_t pos; - CamelStream *stream; - CamelMimeMessage *message; - int newfd; - - if (index != NULL) { - /*printf("indexing message\n %s\n %d for %d bytes\n", mi->from, mi->message_position, mi->size);*/ - pos = lseek(fd, 0, SEEK_CUR); - - /* the stream will close the fd we have */ - newfd = dup(fd); - stream = camel_stream_fs_new_with_fd_and_bounds(newfd, mi->message_position, mi->message_position + mi->size); - message = camel_mime_message_new(); - - camel_data_wrapper_set_input_stream ( - CAMEL_DATA_WRAPPER (message), stream); - - index_message_content(index, CAMEL_DATA_WRAPPER (message)); - - /* printf("messageid = '%s'\n", message->message_uid);*/ - - gtk_object_unref (GTK_OBJECT (message)); - gtk_object_unref (GTK_OBJECT (stream)); - - lseek(fd, pos, SEEK_SET); - } -} - -guint32 -camel_mbox_write_xev (CamelMboxFolder *folder, - gchar *mbox_file_name, - GArray *summary_information, - guint32 *file_size, - guint32 next_uid, - CamelException *ex) -{ - gint cur_msg; - CamelMboxParserMessageInfo *cur_msg_info; - gint fd1, fd2; - guint bytes_to_copy = 0; - glong cur_pos = 0; - glong cur_offset = 0; - glong end_of_last_message = 0; - glong next_free_uid; - gchar xev_header[20] = "X-Evolution:XXXX-X\n"; - gchar *tmp_file_name; - gchar *tmp_file_name_secure; - gint rename_result; - gint unlink_result; - int changed = FALSE; - - tmp_file_name = g_strdup_printf ("%s__.ev_tmp", mbox_file_name); - tmp_file_name_secure = g_strdup_printf ("%s__.ev_tmp_secure", mbox_file_name); - - fd1 = open (mbox_file_name, O_RDONLY); - fd2 = open (tmp_file_name, - O_WRONLY | O_CREAT | O_TRUNC , - 0600); - - if (fd2 == -1) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not create the temporary mbox copy file\n" - "\t%s\n" - "Full error is : %s\n", - tmp_file_name, - strerror (errno)); - return next_uid; - } - - next_free_uid = next_uid; - for (cur_msg = 0; cur_msg < summary_information->len; cur_msg++) { - - cur_msg_info = (CamelMboxParserMessageInfo *)(summary_information->data) + cur_msg; - end_of_last_message = cur_msg_info->message_position + cur_msg_info->size; - - if (cur_msg_info->uid == 0) { - - bytes_to_copy = cur_msg_info->message_position - + cur_msg_info->end_of_headers_offset - - cur_pos; - - cur_pos = cur_msg_info->message_position - + cur_msg_info->end_of_headers_offset; - - cur_msg_info->uid = next_free_uid; - index_message(folder->index, fd1, cur_msg_info); - changed = TRUE; - - camel_mbox_copy_file_chunk (fd1, fd2, bytes_to_copy, ex); - if (camel_exception_get_id (ex)) { - close (fd1); - close (fd2); - goto end; - } - - cur_msg_info->status = 0; - - camel_mbox_xev_write_header_content (xev_header + 12, next_free_uid, 0); - next_free_uid++; - write (fd2, xev_header, 19); - cur_offset += 19; - cur_msg_info->size += 19; - cur_msg_info->x_evolution_offset = cur_msg_info->end_of_headers_offset; - cur_msg_info->x_evolution = g_strdup_printf ("%.6s", xev_header + 12); - cur_msg_info->end_of_headers_offset += 19; - *file_size += 19; - cur_msg_info->message_position += cur_offset; - } else { - cur_msg_info->message_position += cur_offset; - } - } - - /* make sure the index is in sync */ - if (changed) { - ibex_write(folder->index); - } - - bytes_to_copy = end_of_last_message - cur_pos; - camel_mbox_copy_file_chunk (fd1, fd2, bytes_to_copy, ex); - - - /* close the original file as well as the - newly created one */ - close (fd1); - close (fd2); - - - - /* replace the mbox file with the temporary - file we just created */ - - /* first rename the old mbox file to a temporary file */ - rename_result = rename (mbox_file_name, tmp_file_name_secure); - if (rename_result == -1) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not rename the mbox file to a temporary file"); - goto end; - } - - /* then rename the newly created mbox file to the name - of the original one */ - rename_result = rename (tmp_file_name, mbox_file_name); - if (rename_result == -1) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not rename the X-Evolution fed file to the mbox file"); - goto end; - } - - /* finally, remove the old renamed mbox file */ - unlink_result = unlink (tmp_file_name_secure); - if (unlink_result == -1) { - camel_exception_set (ex, - CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, - "could not remove the saved original mbox file"); - goto end; - } - - - end: /* free everything and return */ - - g_free (tmp_file_name); - g_free (tmp_file_name_secure); - return next_free_uid; -} - - - - - - -GArray * -parsed_information_to_mbox_summary (GArray *parsed_information) -{ - guint cur_msg; - CamelMboxParserMessageInfo *cur_msg_info; - GArray *mbox_summary; - CamelMboxSummaryInformation *cur_sum_info; - - mbox_summary = g_array_new (FALSE, FALSE, sizeof (CamelMboxSummaryInformation)); - mbox_summary = g_array_set_size (mbox_summary, parsed_information->len); - - for (cur_msg = 0; cur_msg < parsed_information->len; cur_msg++) { - - cur_msg_info = (CamelMboxParserMessageInfo *)(parsed_information->data) + cur_msg; - cur_sum_info = (CamelMboxSummaryInformation *)(mbox_summary->data) + cur_msg; - - cur_sum_info->position = cur_msg_info->message_position; - - cur_sum_info->size = cur_msg_info->size; - - cur_sum_info->x_evolution_offset = cur_msg_info->x_evolution_offset; - - cur_sum_info->uid = cur_msg_info->uid; - cur_sum_info->headers.uid = g_strdup_printf ("%d", - cur_sum_info->uid); - - cur_sum_info->status = cur_msg_info->status; - - cur_sum_info->headers.subject = cur_msg_info->subject; - cur_msg_info->subject = NULL; - - cur_sum_info->headers.sender = cur_msg_info->from; - cur_msg_info->from = NULL; - - cur_sum_info->headers.to = cur_msg_info->to; - cur_msg_info->to = NULL; - - /* XXX I'm guessing one of these is wrong. */ - cur_sum_info->headers.received_date = cur_msg_info->date; - cur_sum_info->headers.sent_date = g_strdup (cur_msg_info->date); - cur_msg_info->date = NULL; - - } - - return mbox_summary; -} diff --git a/camel/providers/mbox/camel-mbox-utils.h b/camel/providers/mbox/camel-mbox-utils.h deleted file mode 100644 index 8142f97c91..0000000000 --- a/camel/providers/mbox/camel-mbox-utils.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Various utilities for the mbox provider */ - -/* - * Authors : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 Helix Code. - * - * 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 - */ - - -#ifndef CAMEL_MBOX_UTILS_H -#define CAMEL_MBOX_UTILS_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - - -#include "camel-exception.h" -#include "camel-mbox-folder.h" - -void -camel_mbox_xev_parse_header_content (gchar header_content[6], - guint32 *uid, - guchar *status); - -void -camel_mbox_xev_write_header_content (gchar header_content[6], - guint32 uid, - guchar status); - -guint32 -camel_mbox_write_xev (CamelMboxFolder *folder, - gchar *mbox_file_name, - GArray *summary_information, - guint32 *file_size, - guint32 last_uid, - CamelException *ex); - -GArray * -parsed_information_to_mbox_summary (GArray *parsed_information); - -void -camel_mbox_copy_file_chunk (gint fd_src, - gint fd_dest, - glong nb_bytes, - CamelException *ex); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_MBOX_UTILS_H */ |