diff options
author | nobody <nobody@localhost> | 2003-12-09 09:57:09 +0800 |
---|---|---|
committer | nobody <nobody@localhost> | 2003-12-09 09:57:09 +0800 |
commit | 504784e79583087b09520024d76529545259a4a9 (patch) | |
tree | 75bb0caf9afd4b94842023406d6a7938c5d8b2b7 /camel/providers/local | |
parent | 0031a7166cd0f3fc0cec0b60c468ca22a8c45b0b (diff) | |
download | gsoc2013-evolution-GNOME-MEDIA-2-5-5.tar.gz gsoc2013-evolution-GNOME-MEDIA-2-5-5.tar.zst gsoc2013-evolution-GNOME-MEDIA-2-5-5.zip |
This commit was manufactured by cvs2svn to create tagGNOME-MEDIA-2-5-5
'GNOME-MEDIA-2-5-5'.
svn path=/tags/GNOME-MEDIA-2-5-5/; revision=23752
Diffstat (limited to 'camel/providers/local')
35 files changed, 0 insertions, 9080 deletions
diff --git a/camel/providers/local/.cvsignore b/camel/providers/local/.cvsignore deleted file mode 100644 index 3fa8afaa38..0000000000 --- a/camel/providers/local/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la -*.bb -*.bbg -*.da -*.gcov diff --git a/camel/providers/local/Makefile.am b/camel/providers/local/Makefile.am deleted file mode 100644 index ad07472e85..0000000000 --- a/camel/providers/local/Makefile.am +++ /dev/null @@ -1,61 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamellocalincludedir = $(privincludedir)/camel - -camel_provider_LTLIBRARIES = libcamellocal.la -camel_provider_DATA = libcamellocal.urls - -INCLUDES = -I.. \ - -I$(srcdir)/.. \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/e-util \ - -I$(top_srcdir) \ - $(CAMEL_CFLAGS) \ - $(GNOME_INCLUDEDIR) \ - $(GTK_INCLUDEDIR) \ - -DG_LOG_DOMAIN=\"camel-local-provider\" - -libcamellocal_la_SOURCES = \ - camel-local-folder.c \ - camel-local-store.c \ - camel-local-summary.c \ - camel-local-provider.c \ - camel-mh-folder.c \ - camel-mh-store.c \ - camel-mh-summary.c \ - camel-mbox-folder.c \ - camel-mbox-store.c \ - camel-mbox-summary.c \ - camel-maildir-folder.c \ - camel-maildir-store.c \ - camel-maildir-summary.c \ - camel-spool-folder.c \ - camel-spool-store.c \ - camel-spool-summary.c - -libcamellocalinclude_HEADERS = \ - camel-local-folder.h \ - camel-local-store.h \ - camel-local-summary.h \ - camel-mh-folder.h \ - camel-mh-store.h \ - camel-mh-summary.h \ - camel-mbox-folder.h \ - camel-mbox-store.h \ - camel-mbox-summary.h \ - camel-maildir-folder.h \ - camel-maildir-store.h \ - camel-maildir-summary.h \ - camel-spool-folder.h \ - camel-spool-store.h \ - camel-spool-summary.h - -noinst_HEADERS = \ - camel-local-private.h - -libcamellocal_la_LDFLAGS = -avoid-version -module - -libcamellocal_la_LIBADD = $(top_builddir)/e-util/libeutil.la - -EXTRA_DIST = libcamellocal.urls diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c deleted file mode 100644 index 5bf2142f35..0000000000 --- a/camel/providers/local/camel-local-folder.c +++ /dev/null @@ -1,646 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright 1999-2003 Ximian, Inc. (www.ximian.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 Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <limits.h> -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> - -#ifndef _POSIX_PATH_MAX -#include <posix1_lim.h> -#endif - -#include "camel-local-folder.h" -#include "camel-local-store.h" -#include "camel-stream-fs.h" -#include "camel-local-summary.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-stream-filter.h" -#include "camel-mime-filter-from.h" -#include "camel-exception.h" - -#include "camel-local-private.h" - -#include "camel-text-index.h" - -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -#ifndef PATH_MAX -#define PATH_MAX _POSIX_PATH_MAX -#endif - -static CamelFolderClass *parent_class; -static GSList *local_folder_properties; - -/* Returns the class for a CamelLocalFolder */ -#define CLOCALF_CLASS(so) CAMEL_LOCAL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CLOCALS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static int local_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args); -static int local_setv(CamelObject *object, CamelException *ex, CamelArgV *args); - -static int local_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex); -static void local_unlock(CamelLocalFolder *lf); - -static char *local_get_full_path (const char *toplevel_dir, const char *full_name); -static char *local_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext); - -static void local_refresh_info(CamelFolder *folder, CamelException *ex); - -static void local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex); -static void local_expunge(CamelFolder *folder, CamelException *ex); - -static GPtrArray *local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); -static GPtrArray *local_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex); -static void local_search_free(CamelFolder *folder, GPtrArray * result); - -static void local_delete(CamelFolder *folder); -static void local_rename(CamelFolder *folder, const char *newname); - -static void local_finalize(CamelObject * object); - -static void -camel_local_folder_class_init(CamelLocalFolderClass * camel_local_folder_class) -{ - CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_local_folder_class); - CamelObjectClass *oklass = (CamelObjectClass *)camel_local_folder_class; - - /* virtual method definition */ - - /* virtual method overload */ - oklass->getv = local_getv; - oklass->setv = local_setv; - - camel_folder_class->refresh_info = local_refresh_info; - camel_folder_class->sync = local_sync; - camel_folder_class->expunge = local_expunge; - - camel_folder_class->search_by_expression = local_search_by_expression; - camel_folder_class->search_by_uids = local_search_by_uids; - camel_folder_class->search_free = local_search_free; - - camel_folder_class->delete = local_delete; - camel_folder_class->rename = local_rename; - - camel_local_folder_class->get_full_path = local_get_full_path; - camel_local_folder_class->get_meta_path = local_get_meta_path; - - camel_local_folder_class->lock = local_lock; - camel_local_folder_class->unlock = local_unlock; -} - -static void -local_init(gpointer object, gpointer klass) -{ - CamelFolder *folder = object; - CamelLocalFolder *local_folder = object; - - folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY | - CAMEL_FOLDER_HAS_SEARCH_CAPABILITY); - - folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | - CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT | - CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN | - CAMEL_MESSAGE_ANSWERED_ALL | CAMEL_MESSAGE_USER; - - folder->summary = NULL; - local_folder->search = NULL; - - local_folder->priv = g_malloc0(sizeof(*local_folder->priv)); - local_folder->priv->search_lock = g_mutex_new(); -} - -static void -local_finalize(CamelObject * object) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(object); - CamelFolder *folder = (CamelFolder *)object; - - if (folder->summary) { - camel_local_summary_sync((CamelLocalSummary *)folder->summary, FALSE, local_folder->changes, NULL); - camel_object_unref((CamelObject *)folder->summary); - folder->summary = NULL; - } - - if (local_folder->search) { - camel_object_unref((CamelObject *)local_folder->search); - } - - if (local_folder->index) - camel_object_unref((CamelObject *)local_folder->index); - - while (local_folder->locked> 0) - camel_local_folder_unlock(local_folder); - - g_free(local_folder->base_path); - g_free(local_folder->folder_path); - g_free(local_folder->summary_path); - g_free(local_folder->index_path); - - camel_folder_change_info_free(local_folder->changes); - - g_mutex_free(local_folder->priv->search_lock); - - g_free(local_folder->priv); -} - -static CamelProperty local_property_list[] = { - { CAMEL_LOCAL_FOLDER_INDEX_BODY, "index_body", N_("Index message body data") }, -}; - -CamelType -camel_local_folder_get_type(void) -{ - static CamelType camel_local_folder_type = CAMEL_INVALID_TYPE; - - if (camel_local_folder_type == CAMEL_INVALID_TYPE) { - int i; - - parent_class = (CamelFolderClass *)camel_folder_get_type(); - camel_local_folder_type = camel_type_register(camel_folder_get_type(), "CamelLocalFolder", - sizeof(CamelLocalFolder), - sizeof(CamelLocalFolderClass), - (CamelObjectClassInitFunc) camel_local_folder_class_init, - NULL, - (CamelObjectInitFunc) local_init, - (CamelObjectFinalizeFunc) local_finalize); - - for (i=0;i<sizeof(local_property_list)/sizeof(local_property_list[0]);i++) { - local_property_list[i].description = _(local_property_list[i].description); - local_folder_properties = g_slist_prepend(local_folder_properties, &local_property_list[i]); - } - } - - return camel_local_folder_type; -} - -CamelLocalFolder * -camel_local_folder_construct(CamelLocalFolder *lf, CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex) -{ - CamelFolderInfo *fi; - CamelFolder *folder; - const char *root_dir_path, *name; - char *tmp, *statepath; - char folder_path[PATH_MAX]; - struct stat st; - int forceindex, len; - - folder = (CamelFolder *)lf; - - name = strrchr(full_name, '/'); - if (name) - name++; - else - name = full_name; - - camel_folder_construct(folder, parent_store, full_name, name); - - root_dir_path = camel_local_store_get_toplevel_dir(CAMEL_LOCAL_STORE(folder->parent_store)); - /* strip the trailing '/' which is always present */ - len = strlen (root_dir_path); - tmp = g_alloca (len + 1); - strcpy (tmp, root_dir_path); - if (len>1 && tmp[len-1] == '/') - tmp[len-1] = 0; - - lf->base_path = g_strdup(root_dir_path); - - /* if the base store points to a file, then use that */ - if (stat(tmp, &st) != -1 && S_ISREG(st.st_mode)) { - lf->folder_path = g_strdup(tmp); - /* not really sure to do with these for now? */ - lf->summary_path = g_strdup_printf("%s.ev-summary", tmp); - lf->index_path = g_strdup_printf("%s.ibex", tmp); - statepath = g_strdup_printf ("%s.cmeta", tmp); - } else { - lf->folder_path = CLOCALF_CLASS (lf)->get_full_path (root_dir_path, full_name); - lf->summary_path = CLOCALF_CLASS (lf)->get_meta_path (root_dir_path, full_name, ".ev-summary"); - lf->index_path = CLOCALF_CLASS (lf)->get_meta_path (root_dir_path, full_name, ".ibex"); - statepath = CLOCALF_CLASS (lf)->get_meta_path (root_dir_path, full_name, ".cmeta"); - } - camel_object_set(lf, NULL, CAMEL_OBJECT_STATE_FILE, statepath, NULL); - g_free (statepath); - - lf->flags = flags; - - if (camel_object_state_read(lf) == -1) { - /* FIXME: load defaults? */ - } - - /* follow any symlinks to the mailbox */ - if (lstat (lf->folder_path, &st) != -1 && S_ISLNK (st.st_mode) && - realpath (lf->folder_path, folder_path) != NULL) { - g_free (lf->folder_path); - lf->folder_path = g_strdup (folder_path); - } - - lf->changes = camel_folder_change_info_new(); - - /* TODO: Remove the following line, it is a temporary workaround to remove - the old-format 'ibex' files that might be lying around */ - unlink(lf->index_path); - - /* FIXME: Need to run indexing off of the setv method */ -#if 1 - forceindex = FALSE; -#else - /* if we have no/invalid index file, force it */ - forceindex = camel_text_index_check(lf->index_path) == -1; - if (flags & CAMEL_STORE_FOLDER_BODY_INDEX) { - int flag = O_RDWR|O_CREAT; - if (forceindex) - flag |= O_TRUNC; - lf->index = (CamelIndex *)camel_text_index_new(lf->index_path, flag); - if (lf->index == NULL) { - /* yes, this isn't fatal at all */ - g_warning("Could not open/create index file: %s: indexing not performed", strerror (errno)); - forceindex = FALSE; - /* record that we dont have an index afterall */ - flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX; - } - } else { - /* if we do have an index file, remove it (?) */ - if (forceindex == FALSE) - camel_text_index_remove(lf->index_path); - forceindex = FALSE; - } - lf->flags = flags; -#endif - - folder->summary = (CamelFolderSummary *)CLOCALF_CLASS(lf)->create_summary(lf->summary_path, lf->folder_path, lf->index); - if (camel_local_summary_load((CamelLocalSummary *)folder->summary, forceindex, ex) == -1) { - camel_exception_clear(ex); - } - - /*if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) {*/ - /* we sync here so that any hard work setting up the folder isn't lost */ - if (camel_local_summary_sync((CamelLocalSummary *)folder->summary, FALSE, lf->changes, ex) == -1) { - camel_object_unref (CAMEL_OBJECT (folder)); - return NULL; - } - - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = g_strdup (full_name); - fi->name = g_strdup (name); - fi->url = g_strdup_printf("%s:%s#%s", ((CamelService *)parent_store)->url->protocol, ((CamelService *)parent_store)->url->path, full_name); - fi->unread_message_count = camel_folder_get_unread_message_count(folder); - camel_folder_info_build_path(fi, '/'); - - camel_object_trigger_event(CAMEL_OBJECT (parent_store), "folder_created", fi); - camel_folder_info_free(fi); - - return lf; -} - -/* lock the folder, may be called repeatedly (with matching unlock calls), - with type the same or less than the first call */ -int camel_local_folder_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex) -{ - if (lf->locked > 0) { - /* lets be anal here - its important the code knows what its doing */ - g_assert(lf->locktype == type || lf->locktype == CAMEL_LOCK_WRITE); - } else { - if (CLOCALF_CLASS(lf)->lock(lf, type, ex) == -1) - return -1; - lf->locktype = type; - } - - lf->locked++; - - return 0; -} - -/* unlock folder */ -int camel_local_folder_unlock(CamelLocalFolder *lf) -{ - g_assert(lf->locked>0); - lf->locked--; - if (lf->locked == 0) - CLOCALF_CLASS(lf)->unlock(lf); - - return 0; -} - -static int -local_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args) -{ - CamelFolder *folder = (CamelFolder *)object; - int i; - guint32 tag; - - for (i=0;i<args->argc;i++) { - CamelArgGet *arg = &args->argv[i]; - - tag = arg->tag; - - switch (tag & CAMEL_ARG_TAG) { - case CAMEL_OBJECT_ARG_DESCRIPTION: - if (folder->description == NULL) { - char *tmp, *path; - - /* check some common prefixes to shorten the name */ - tmp = ((CamelService *)folder->parent_store)->url->path; - if (tmp == NULL) - goto skip; - - path = g_alloca (strlen (tmp) + strlen (folder->full_name) + 1); - sprintf (path, "%s/%s", tmp, folder->full_name); - - if ((tmp = getenv("HOME")) && strncmp(tmp, path, strlen(tmp)) == 0) - /* $HOME relative path + protocol string */ - folder->description = g_strdup_printf(_("~%s (%s)"), path+strlen(tmp), - ((CamelService *)folder->parent_store)->url->protocol); - else if ((tmp = "/var/spool/mail") && strncmp(tmp, path, strlen(tmp)) == 0) - /* /var/spool/mail relative path + protocol */ - folder->description = g_strdup_printf(_("mailbox:%s (%s)"), path+strlen(tmp), - ((CamelService *)folder->parent_store)->url->protocol); - else if ((tmp = "/var/mail") && strncmp(tmp, path, strlen(tmp)) == 0) - folder->description = g_strdup_printf(_("mailbox:%s (%s)"), path+strlen(tmp), - ((CamelService *)folder->parent_store)->url->protocol); - else - /* a full path + protocol */ - folder->description = g_strdup_printf(_("%s (%s)"), path, - ((CamelService *)folder->parent_store)->url->protocol); - } - *arg->ca_str = folder->description; - break; - - case CAMEL_OBJECT_ARG_PERSISTENT_PROPERTIES: - case CAMEL_FOLDER_ARG_PROPERTIES: { - CamelArgGetV props; - - props.argc = 1; - props.argv[0] = *arg; - ((CamelObjectClass *)parent_class)->getv(object, ex, &props); - *arg->ca_ptr = g_slist_concat(*arg->ca_ptr, g_slist_copy(local_folder_properties)); - - break; } - - case CAMEL_LOCAL_FOLDER_ARG_INDEX_BODY: - printf("getv:'%s' flags %08x\n", ((CamelFolder *)object)->full_name, ((CamelLocalFolder *)object)->flags); - - /* FIXME: remove this from sotre flags */ - *arg->ca_int = (((CamelLocalFolder *)folder)->flags & CAMEL_STORE_FOLDER_BODY_INDEX) != 0; - break; - - default: skip: - continue; - } - - arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE; - } - - return ((CamelObjectClass *)parent_class)->getv(object, ex, args); -} - -static int -local_setv(CamelObject *object, CamelException *ex, CamelArgV *args) -{ - int i; - guint32 tag; - - for (i=0;i<args->argc;i++) { - CamelArg *arg = &args->argv[i]; - - tag = arg->tag; - - switch (tag & CAMEL_ARG_TAG) { - case CAMEL_LOCAL_FOLDER_ARG_INDEX_BODY: - /* FIXME: implement */ - /* TODO: When turning on (off?) the index, we want to launch a task for it, - and make sure we dont have multiple tasks doing the same job */ - if (arg->ca_int) - ((CamelLocalFolder *)object)->flags |= CAMEL_STORE_FOLDER_BODY_INDEX; - else - ((CamelLocalFolder *)object)->flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX; - break; - default: - continue; - } - - arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE; - } - - return ((CamelObjectClass *)parent_class)->setv(object, ex, args); -} - -static char * -local_get_full_path (const char *toplevel_dir, const char *full_name) -{ - return g_strdup_printf ("%s/%s", toplevel_dir, full_name); -} - -static char * -local_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext) -{ - return g_strdup_printf ("%s/%s%s", toplevel_dir, full_name, ext); -} - -static int -local_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex) -{ - return 0; -} - -static void -local_unlock(CamelLocalFolder *lf) -{ - /* nothing */ -} - -/* for auto-check to work */ -static void -local_refresh_info(CamelFolder *folder, CamelException *ex) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - - if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) - return; - - if (camel_folder_change_info_changed(lf->changes)) { - camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes); - camel_folder_change_info_clear(lf->changes); - } -} - -static void -local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - CamelLocalFolder *lf = CAMEL_LOCAL_FOLDER(folder); - - d(printf("local sync, expunge=%s\n", expunge?"true":"false")); - - if (camel_local_folder_lock(lf, CAMEL_LOCK_WRITE, ex) == -1) - return; - - camel_object_state_write(lf); - - /* if sync fails, we'll pass it up on exit through ex */ - camel_local_summary_sync((CamelLocalSummary *)folder->summary, expunge, lf->changes, ex); - camel_local_folder_unlock(lf); - - if (camel_folder_change_info_changed(lf->changes)) { - camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", lf->changes); - camel_folder_change_info_clear(lf->changes); - } -} - -static void -local_expunge(CamelFolder *folder, CamelException *ex) -{ - d(printf("expunge\n")); - - /* Just do a sync with expunge, serves the same purpose */ - /* call the callback directly, to avoid locking problems */ - CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->sync(folder, TRUE, ex); -} - -static void -local_delete(CamelFolder *folder) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - - if (lf->index) - camel_index_delete(lf->index); - - parent_class->delete(folder); -} - -static void -local_rename(CamelFolder *folder, const char *newname) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - - d(printf("renaming local folder paths to '%s'\n", newname)); - - /* Sync? */ - - g_free(lf->folder_path); - g_free(lf->summary_path); - g_free(lf->index_path); - lf->folder_path = g_strdup_printf("%s/%s", lf->base_path, newname); - lf->summary_path = g_strdup_printf("%s/%s.ev-summary", lf->base_path, newname); - lf->index_path = g_strdup_printf("%s/%s.ibex", lf->base_path, newname); - - /* FIXME: Poke some internals, sigh */ - camel_folder_summary_set_filename(folder->summary, lf->summary_path); - g_free(((CamelLocalSummary *)folder->summary)->folder_path); - ((CamelLocalSummary *)folder->summary)->folder_path = g_strdup(lf->folder_path); - - parent_class->rename(folder, newname); -} - -static GPtrArray * -local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); - GPtrArray *summary, *matches; - - /* NOTE: could get away without the search lock by creating a new - search object each time */ - - CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock); - - if (local_folder->search == NULL) - local_folder->search = camel_folder_search_new(); - - camel_folder_search_set_folder(local_folder->search, folder); - camel_folder_search_set_body_index(local_folder->search, local_folder->index); - summary = camel_folder_get_summary(folder); - camel_folder_search_set_summary(local_folder->search, summary); - - matches = camel_folder_search_execute_expression(local_folder->search, expression, ex); - - CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock); - - camel_folder_free_summary(folder, summary); - - return matches; -} - -static GPtrArray * -local_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); - GPtrArray *summary, *matches; - int i; - - /* NOTE: could get away without the search lock by creating a new - search object each time */ - - summary = g_ptr_array_new(); - for (i=0;i<uids->len;i++) { - CamelMessageInfo *info; - - info = camel_folder_get_message_info(folder, uids->pdata[i]); - if (info) - g_ptr_array_add(summary, info); - } - - if (summary->len == 0) - return summary; - - CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock); - - if (local_folder->search == NULL) - local_folder->search = camel_folder_search_new(); - - camel_folder_search_set_folder(local_folder->search, folder); - camel_folder_search_set_body_index(local_folder->search, local_folder->index); - camel_folder_search_set_summary(local_folder->search, summary); - - matches = camel_folder_search_execute_expression(local_folder->search, expression, ex); - - CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock); - - for (i=0;i<summary->len;i++) - camel_folder_free_message_info(folder, summary->pdata[i]); - g_ptr_array_free(summary, TRUE); - - return matches; -} - -static void -local_search_free(CamelFolder *folder, GPtrArray * result) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); - - /* we need to lock this free because of the way search_free_result works */ - /* FIXME: put the lock inside search_free_result */ - CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock); - - camel_folder_search_free_result(local_folder->search, result); - - CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock); -} diff --git a/camel/providers/local/camel-local-folder.h b/camel/providers/local/camel-local-folder.h deleted file mode 100644 index 73059f03b3..0000000000 --- a/camel/providers/local/camel-local-folder.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Author: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999 Ximian (www.ximian.com/). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_LOCAL_FOLDER_H -#define CAMEL_LOCAL_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <camel/camel-folder.h> -#include <camel/camel-folder-search.h> -#include <camel/camel-index.h> -#include "camel-local-summary.h" -#include "camel-lock.h" - -/* #include "camel-store.h" */ - -#define CAMEL_LOCAL_FOLDER_TYPE (camel_local_folder_get_type ()) -#define CAMEL_LOCAL_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_LOCAL_FOLDER_TYPE, CamelLocalFolder)) -#define CAMEL_LOCAL_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_LOCAL_FOLDER_TYPE, CamelLocalFolderClass)) -#define CAMEL_IS_LOCAL_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_LOCAL_FOLDER_TYPE)) - -enum { - CAMEL_LOCAL_FOLDER_ARG_INDEX_BODY = CAMEL_FOLDER_ARG_LAST, - - CAMEL_LOCAL_FOLDER_ARG_LAST = CAMEL_FOLDER_ARG_LAST + 0x100 -}; - -enum { - CAMEL_LOCAL_FOLDER_INDEX_BODY = CAMEL_LOCAL_FOLDER_ARG_INDEX_BODY | CAMEL_ARG_BOO, -}; - -typedef struct { - CamelFolder parent_object; - struct _CamelLocalFolderPrivate *priv; - - guint32 flags; /* open mode flags */ - - int locked; /* lock counter */ - CamelLockType locktype; /* what type of lock we have */ - - char *base_path; /* base path of the local folder */ - char *folder_path; /* the path to the folder itself */ - char *summary_path; /* where the summary lives */ - char *index_path; /* where the index file lives */ - - CamelIndex *index; /* index for this folder */ - CamelFolderSearch *search; /* used to run searches, we just use the real thing (tm) */ - CamelFolderChangeInfo *changes; /* used to store changes to the folder during processing */ -} CamelLocalFolder; - -typedef struct { - CamelFolderClass parent_class; - - /* Virtual methods */ - - /* path construction, only used at init */ - char * (* get_full_path) (const char *toplevel_dir, const char *full_name); - char * (* get_meta_path) (const char *toplevel_dir, const char *full_name, const char *ext); - - /* summary factory, only used at init */ - CamelLocalSummary *(*create_summary)(const char *path, const char *folder, CamelIndex *index); - - /* Lock the folder for my operations */ - int (*lock)(CamelLocalFolder *, CamelLockType type, CamelException *ex); - - /* Unlock the folder for my operations */ - void (*unlock)(CamelLocalFolder *); -} CamelLocalFolderClass; - - -/* public methods */ -/* flags are taken from CAMEL_STORE_FOLDER_* flags */ -CamelLocalFolder *camel_local_folder_construct(CamelLocalFolder *lf, CamelStore *parent_store, - const char *full_name, guint32 flags, CamelException *ex); - -/* Standard Camel function */ -CamelType camel_local_folder_get_type(void); - -/* Lock the folder for internal use. May be called repeatedly */ -/* UNIMPLEMENTED */ -int camel_local_folder_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex); -int camel_local_folder_unlock(CamelLocalFolder *lf); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_LOCAL_FOLDER_H */ diff --git a/camel/providers/local/camel-local-private.h b/camel/providers/local/camel-local-private.h deleted file mode 100644 index e8e5061fae..0000000000 --- a/camel/providers/local/camel-local-private.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright 1999-2003 Ximian, Inc. (www.ximian.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 Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#ifndef CAMEL_LOCAL_PRIVATE_H -#define CAMEL_LOCAL_PRIVATE_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -/* need a way to configure and save this data, if this header is to - be installed. For now, dont install it */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <pthread.h> - -struct _CamelLocalFolderPrivate { - GMutex *search_lock; /* for locking the search object */ -}; - -#define CAMEL_LOCAL_FOLDER_LOCK(f, l) (g_mutex_lock(((CamelLocalFolder *)f)->priv->l)) -#define CAMEL_LOCAL_FOLDER_UNLOCK(f, l) (g_mutex_unlock(((CamelLocalFolder *)f)->priv->l)) - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_LOCAL_PRIVATE_H */ - diff --git a/camel/providers/local/camel-local-provider.c b/camel/providers/local/camel-local-provider.c deleted file mode 100644 index a52dfbde5f..0000000000 --- a/camel/providers/local/camel-local-provider.c +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2000 Ximian (www.ximian.com). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> - -#include "camel-provider.h" -#include "camel-session.h" -#include "camel-url.h" - -#include "camel-mh-store.h" -#include "camel-mbox-store.h" -#include "camel-maildir-store.h" -#include "camel-spool-store.h" - -#define d(x) - -static CamelProviderConfEntry mh_conf_entries[] = { - CAMEL_PROVIDER_CONF_DEFAULT_PATH, - { CAMEL_PROVIDER_CONF_CHECKBOX, "dotfolders", NULL, - N_("Use the `.folders' folder summary file (exmh)"), "0" }, - { CAMEL_PROVIDER_CONF_END } -}; - -static CamelProvider mh_provider = { - "mh", - N_("MH-format mail directories"), - N_("For storing local mail in MH-like mail directories."), - "mail", - CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL, - CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH, - mh_conf_entries, - /* ... */ -}; - -static CamelProviderConfEntry mbox_conf_entries[] = { - CAMEL_PROVIDER_CONF_DEFAULT_PATH, - { CAMEL_PROVIDER_CONF_END } -}; - -static CamelProvider mbox_provider = { - "mbox", - N_("Local delivery"), - N_("For retrieving (moving) local mail from standard mbox formated spools into folders managed by Evolution."), - "mail", - CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL, - CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH, - mbox_conf_entries, - /* ... */ -}; - -static CamelProviderConfEntry maildir_conf_entries[] = { - CAMEL_PROVIDER_CONF_DEFAULT_PATH, - { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL, - N_("Apply filters to new messages in INBOX"), "0" }, - { CAMEL_PROVIDER_CONF_END } -}; - -static CamelProvider maildir_provider = { - "maildir", - N_("Maildir-format mail directories"), - N_("For storing local mail in maildir directories."), - "mail", - CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL, - CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH, - maildir_conf_entries, - /* ... */ -}; - -static CamelProviderConfEntry spool_conf_entries[] = { - CAMEL_PROVIDER_CONF_DEFAULT_PATH, - { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL, N_("Apply filters to new messages in INBOX"), "0" }, - { CAMEL_PROVIDER_CONF_CHECKBOX, "xstatus", NULL, N_("Store status headers in Elm/Pine/Mutt format"), "0" }, - { CAMEL_PROVIDER_CONF_END } -}; - -static CamelProvider spool_provider = { - "spool", - N_("Standard Unix mbox spool or directory"), - N_("For reading and storing local mail in external standard mbox spool files.\nMay also be used to read a tree of Elm, Pine, or Mutt style folders."), - "mail", - CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE, - CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH, - spool_conf_entries, - /* ... */ -}; - -/* build a canonical 'path' */ -static char * -make_can_path(char *p, char *o) -{ - char c, last, *start = o; - - d(printf("canonical '%s' = ", p)); - - last = 0; - while ((c = *p++)) { - if (c!='/' - || (c=='/' && last != '/')) - *o++ = c; - last = c; - } - if (o>start && o[-1] == '/') - o[-1] = 0; - else - *o = 0; - - d(printf("'%s'\n", start)); - - return start; -} - -/* 'helper' function for it */ -#define get_can_path(p) ((p == NULL) ? NULL : (make_can_path ((p), g_alloca (strlen (p) + 1)))) - -static guint -local_url_hash (const void *v) -{ - const CamelURL *u = v; - guint hash = 0; - -#define ADD_HASH(s) if (s) hash ^= g_str_hash (s); - - ADD_HASH (u->protocol); - ADD_HASH (u->user); - ADD_HASH (u->authmech); - ADD_HASH (u->host); - if (u->path) - hash ^= g_str_hash(get_can_path(u->path)); - ADD_HASH (u->path); - ADD_HASH (u->query); - hash ^= u->port; - - return hash; -} - -static int -check_equal (char *s1, char *s2) -{ - if (s1 == NULL) { - if (s2 == NULL) - return TRUE; - else - return FALSE; - } - - if (s2 == NULL) - return FALSE; - - return strcmp (s1, s2) == 0; -} - -static int -local_url_equal(const void *v, const void *v2) -{ - const CamelURL *u1 = v, *u2 = v2; - char *p1, *p2; - - p1 = get_can_path(u1->path); - p2 = get_can_path(u2->path); - return check_equal(p1, p2) - && check_equal(u1->protocol, u2->protocol) - && check_equal(u1->user, u2->user) - && check_equal(u1->authmech, u2->authmech) - && check_equal(u1->host, u2->host) - && check_equal(u1->query, u2->query) - && u1->port == u2->port; -} - -void camel_provider_module_init(CamelSession * session) -{ - char *path; - - mh_conf_entries[0].value = ""; /* default path */ - mh_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mh_store_get_type (); - mh_provider.url_hash = local_url_hash; - mh_provider.url_equal = local_url_equal; - camel_session_register_provider(session, &mh_provider); - - if (!(path = getenv ("MAIL"))) - path = g_strdup_printf (SYSTEM_MAIL_DIR "/%s", g_get_user_name ()); - mbox_conf_entries[0].value = path; /* default path */ - mbox_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mbox_store_get_type (); - mbox_provider.url_hash = local_url_hash; - mbox_provider.url_equal = local_url_equal; - camel_session_register_provider(session, &mbox_provider); - - spool_conf_entries[0].value = path; /* default path - same as mbox */ - spool_provider.object_types[CAMEL_PROVIDER_STORE] = camel_spool_store_get_type (); - spool_provider.url_hash = local_url_hash; - spool_provider.url_equal = local_url_equal; - camel_session_register_provider(session, &spool_provider); - - path = getenv ("MAILDIR"); - maildir_conf_entries[0].value = path ? path : ""; /* default path */ - maildir_provider.object_types[CAMEL_PROVIDER_STORE] = camel_maildir_store_get_type (); - maildir_provider.url_hash = local_url_hash; - maildir_provider.url_equal = local_url_equal; - camel_session_register_provider(session, &maildir_provider); -} diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c deleted file mode 100644 index a0eaf9d68f..0000000000 --- a/camel/providers/local/camel-local-store.c +++ /dev/null @@ -1,442 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/stat.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> - -#include <glib.h> - -#include "camel-private.h" - -#include "camel-local-store.h" -#include "camel-exception.h" -#include "camel-url.h" - -#include "camel-local-folder.h" -#include <camel/camel-text-index.h> - -#define d(x) - -/* Returns the class for a CamelLocalStore */ -#define CLOCALS_CLASS(so) CAMEL_LOCAL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static void construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex); -static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex); -static char *get_name(CamelService *service, gboolean brief); -static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); -static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex); -static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex); -static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex); -static CamelFolderInfo *create_folder(CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex); - -static CamelStoreClass *parent_class = NULL; - -static void -camel_local_store_class_init (CamelLocalStoreClass *camel_local_store_class) -{ - CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_local_store_class); - CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_local_store_class); - - parent_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ())); - - /* virtual method overload */ - camel_service_class->construct = construct; - camel_service_class->get_name = get_name; - camel_store_class->get_folder = get_folder; - camel_store_class->get_inbox = get_inbox; - camel_store_class->get_folder_info = get_folder_info; - camel_store_class->free_folder_info = camel_store_free_folder_info_full; - - camel_store_class->create_folder = create_folder; - camel_store_class->delete_folder = delete_folder; - camel_store_class->rename_folder = rename_folder; -} - -static void -camel_local_store_finalize (CamelLocalStore *local_store) -{ - if (local_store->toplevel_dir) - g_free (local_store->toplevel_dir); -} - -CamelType -camel_local_store_get_type (void) -{ - static CamelType camel_local_store_type = CAMEL_INVALID_TYPE; - - if (camel_local_store_type == CAMEL_INVALID_TYPE) { - camel_local_store_type = camel_type_register (CAMEL_STORE_TYPE, "CamelLocalStore", - sizeof (CamelLocalStore), - sizeof (CamelLocalStoreClass), - (CamelObjectClassInitFunc) camel_local_store_class_init, - NULL, - NULL, - (CamelObjectFinalizeFunc) camel_local_store_finalize); - } - - return camel_local_store_type; -} - -static void -construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex) -{ - CamelLocalStore *local_store = CAMEL_LOCAL_STORE (service); - int len; - - CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex); - if (camel_exception_is_set (ex)) - return; - - len = strlen (service->url->path); - if (service->url->path[len - 1] != '/') - local_store->toplevel_dir = g_strdup_printf ("%s/", service->url->path); - else - local_store->toplevel_dir = g_strdup (service->url->path); -} - -const char * -camel_local_store_get_toplevel_dir (CamelLocalStore *store) -{ - return store->toplevel_dir; -} - -static CamelFolder * -get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex) -{ - struct stat st; - char *path = ((CamelLocalStore *)store)->toplevel_dir; - char *sub, *slash; - - if (path[0] != '/') { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Store root %s is not an absolute path"), path); - return NULL; - } - - if (stat(path, &st) == 0) { - if (!S_ISDIR(st.st_mode)) { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Store root %s is not a regular directory"), path); - return NULL; - } - return (CamelFolder *) 0xdeadbeef; - } - - if (errno != ENOENT - || (flags & CAMEL_STORE_FOLDER_CREATE) == 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Cannot get folder: %s: %s"), - path, g_strerror (errno)); - return NULL; - } - - /* need to create the dir heirarchy */ - sub = g_alloca (strlen (path) + 1); - strcpy (sub, path); - slash = sub; - do { - slash = strchr (slash + 1, '/'); - if (slash) - *slash = 0; - if (stat (sub, &st) == -1) { - if (errno != ENOENT || mkdir (sub, 0700) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Cannot get folder: %s: %s"), - path, g_strerror (errno)); - return NULL; - } - } - if (slash) - *slash = '/'; - } while (slash); - - return (CamelFolder *) 0xdeadbeef; -} - -static CamelFolder * -get_inbox(CamelStore *store, CamelException *ex) -{ - camel_exception_set(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Local stores do not have an inbox")); - return NULL; -} - -static char * -get_name (CamelService *service, gboolean brief) -{ - char *dir = ((CamelLocalStore*)service)->toplevel_dir; - - if (brief) - return g_strdup (dir); - else - return g_strdup_printf (_("Local mail file %s"), dir); -} - -static CamelFolderInfo * -get_folder_info (CamelStore *store, const char *top, - guint32 flags, CamelException *ex) -{ - /* FIXME: This is broken, but it corresponds to what was - * there before. - */ - - d(printf("-- LOCAL STORE -- get folder info: %s\n", top)); - - return NULL; -} - -static CamelFolderInfo * -create_folder(CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex) -{ - char *path = ((CamelLocalStore *)store)->toplevel_dir; - char *name; - CamelFolder *folder; - CamelFolderInfo *info = NULL; - struct stat st; - - /* This is a pretty hacky version of create folder, but should basically work */ - - if (path[0] != '/') { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Store root %s is not an absolute path"), path); - return NULL; - } - - if (parent_name) - name = g_strdup_printf("%s/%s/%s", path, parent_name, folder_name); - else - name = g_strdup_printf("%s/%s", path, folder_name); - - if (stat(name, &st) == 0 || errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Cannot get folder: %s: %s"), - name, g_strerror (errno)); - g_free(name); - return NULL; - } - - g_free(name); - - if (parent_name) - name = g_strdup_printf("%s/%s", parent_name, folder_name); - else - name = g_strdup_printf("%s", folder_name); - - folder = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder(store, name, CAMEL_STORE_FOLDER_CREATE, ex); - if (folder) { - camel_object_unref((CamelObject *)folder); - info = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder_info(store, name, 0, ex); - - /* get_folder(CREATE) will emit a folder_created event for us */ - /*if (info) - camel_object_trigger_event((CamelObject *)store, "folder_created", info);*/ - } - - g_free(name); - - return info; -} - -static int xrename(const char *oldp, const char *newp, const char *prefix, const char *suffix, int missingok, CamelException *ex) -{ - struct stat st; - char *old = g_strconcat(prefix, oldp, suffix, 0); - char *new = g_strconcat(prefix, newp, suffix, 0); - int ret = -1; - int err = 0; - - d(printf("renaming %s%s to %s%s\n", oldp, suffix, newp, suffix)); - - if (stat(old, &st) == -1) { - if (missingok && errno == ENOENT) { - ret = 0; - } else { - err = errno; - ret = -1; - } - } else if (S_ISDIR(st.st_mode)) { /* use rename for dirs */ - if (rename(old, new) == 0 - || stat(new, &st) == 0) { - ret = 0; - } else { - err = errno; - ret = -1; - } - } else if (link(old, new) == 0 /* and link for files */ - || (stat(new, &st) == 0 && st.st_nlink == 2)) { - if (unlink(old) == 0) { - ret = 0; - } else { - err = errno; - unlink(new); - ret = -1; - } - } else { - err = errno; - ret = -1; - } - - if (ret == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename folder %s to %s: %s"), - old, new, g_strerror (err)); - } - - g_free(old); - g_free(new); - return ret; -} - -/* default implementation, rename all */ -static void -rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex) -{ - char *path = CAMEL_LOCAL_STORE (store)->toplevel_dir; - CamelLocalFolder *folder = NULL; - char *newibex = g_strdup_printf("%s%s.ibex", path, new); - char *oldibex = g_strdup_printf("%s%s.ibex", path, old); - - /* try to rollback failures, has obvious races */ - - d(printf("local rename folder '%s' '%s'\n", old, new)); - - folder = camel_object_bag_get(store->folders, old); - if (folder && folder->index) { - if (camel_index_rename(folder->index, newibex) == -1) - goto ibex_failed; - } else { - /* TODO: camel_text_index_rename should find out if we have an active index itself? */ - if (camel_text_index_rename(oldibex, newibex) == -1) - goto ibex_failed; - } - - if (xrename(old, new, path, ".ev-summary", TRUE, ex)) - goto summary_failed; - - if (xrename(old, new, path, "", FALSE, ex)) - goto base_failed; - - g_free(newibex); - g_free(oldibex); - - if (folder) - camel_object_unref(folder); - - return; - -base_failed: - xrename(new, old, path, ".ev-summary", TRUE, ex); - -summary_failed: - if (folder) { - if (folder->index) - camel_index_rename(folder->index, oldibex); - } else - camel_text_index_rename(newibex, oldibex); -ibex_failed: - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename '%s': %s"), - old, g_strerror (errno)); - - g_free(newibex); - g_free(oldibex); - - if (folder) - camel_object_unref(folder); -} - -/* default implementation, only delete metadata */ -static void -delete_folder(CamelStore *store, const char *folder_name, CamelException *ex) -{ - CamelFolderInfo *fi; - CamelException lex; - CamelFolder *lf; - char *name; - char *str; - - /* remove metadata only */ - name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); - str = g_strdup_printf("%s.ev-summary", name); - if (unlink(str) == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder summary file `%s': %s"), - str, g_strerror (errno)); - g_free(str); - g_free (name); - return; - } - g_free(str); - str = g_strdup_printf("%s.ibex", name); - if (camel_text_index_remove(str) == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder index file `%s': %s"), - str, g_strerror (errno)); - g_free(str); - g_free (name); - return; - } - g_free(str); - - camel_exception_init (&lex); - if ((lf = camel_store_get_folder (store, folder_name, 0, &lex))) { - camel_object_get (lf, NULL, CAMEL_OBJECT_STATE_FILE, &str, NULL); - camel_object_set (lf, NULL, CAMEL_OBJECT_STATE_FILE, NULL, NULL); - camel_object_unref (lf); - } else { - camel_exception_clear (&lex); - } - - if (str == NULL) - str = g_strdup_printf ("%s.cmeta", name); - - if (unlink (str) == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder meta file `%s': %s"), - str, g_strerror (errno)); - g_free (name); - g_free (str); - return; - } - - g_free (str); - g_free (name); - - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = g_strdup (folder_name); - fi->name = g_path_get_basename (folder_name); - fi->url = g_strdup_printf ("%s:%s#%s", ((CamelService *) store)->url->protocol, - CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); - fi->unread_message_count = -1; - camel_folder_info_build_path(fi, '/'); - - camel_object_trigger_event (store, "folder_deleted", fi); - - camel_folder_info_free (fi); -} diff --git a/camel/providers/local/camel-local-store.h b/camel/providers/local/camel-local-store.h deleted file mode 100644 index 21d854c562..0000000000 --- a/camel/providers/local/camel-local-store.h +++ /dev/null @@ -1,68 +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 Ximian, Inc. <bertrand@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_LOCAL_STORE_H -#define CAMEL_LOCAL_STORE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-store.h" - -#define CAMEL_LOCAL_STORE_TYPE (camel_local_store_get_type ()) -#define CAMEL_LOCAL_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_LOCAL_STORE_TYPE, CamelLocalStore)) -#define CAMEL_LOCAL_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_LOCAL_STORE_TYPE, CamelLocalStoreClass)) -#define CAMEL_IS_LOCAL_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_LOCAL_STORE_TYPE)) - - -typedef struct { - CamelStore parent_object; - char *toplevel_dir; - -} CamelLocalStore; - - - -typedef struct { - CamelStoreClass parent_class; - -} CamelLocalStoreClass; - - -/* public methods */ - -/* Standard Camel function */ -CamelType camel_local_store_get_type (void); - -const gchar *camel_local_store_get_toplevel_dir (CamelLocalStore *store); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_LOCAL_STORE_H */ - - diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c deleted file mode 100644 index 42534b361d..0000000000 --- a/camel/providers/local/camel-local-summary.c +++ /dev/null @@ -1,614 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <sys/stat.h> -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include "camel-local-summary.h" -#include "camel/camel-mime-message.h" -#include "camel/camel-stream-null.h" - -#define w(x) -#define io(x) -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -#define CAMEL_LOCAL_SUMMARY_VERSION (0x200) - -static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *); - -static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi); -static char *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi); - -static int local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex); -static int local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); -static int local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); -static CamelMessageInfo *local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex); - -static void camel_local_summary_class_init (CamelLocalSummaryClass *klass); -static void camel_local_summary_init (CamelLocalSummary *obj); -static void camel_local_summary_finalise (CamelObject *obj); -static CamelFolderSummaryClass *camel_local_summary_parent; - -CamelType -camel_local_summary_get_type(void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register(camel_folder_summary_get_type(), "CamelLocalSummary", - sizeof (CamelLocalSummary), - sizeof (CamelLocalSummaryClass), - (CamelObjectClassInitFunc) camel_local_summary_class_init, - NULL, - (CamelObjectInitFunc) camel_local_summary_init, - (CamelObjectFinalizeFunc) camel_local_summary_finalise); - } - - return type; -} - -static void -camel_local_summary_class_init(CamelLocalSummaryClass *klass) -{ - CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *) klass; - - camel_local_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type())); - - sklass->message_info_new = message_info_new; - - klass->load = local_summary_load; - klass->check = local_summary_check; - klass->sync = local_summary_sync; - klass->add = local_summary_add; - - klass->encode_x_evolution = local_summary_encode_x_evolution; - klass->decode_x_evolution = local_summary_decode_x_evolution; -} - -static void -camel_local_summary_init(CamelLocalSummary *obj) -{ - struct _CamelFolderSummary *s = (CamelFolderSummary *)obj; - - /* subclasses need to set the right instance data sizes */ - s->message_info_size = sizeof(CamelMessageInfo); - s->content_info_size = sizeof(CamelMessageContentInfo); - - /* and a unique file version */ - s->version += CAMEL_LOCAL_SUMMARY_VERSION; -} - -static void -camel_local_summary_finalise(CamelObject *obj) -{ - CamelLocalSummary *mbs = CAMEL_LOCAL_SUMMARY(obj); - - if (mbs->index) - camel_object_unref((CamelObject *)mbs->index); - g_free(mbs->folder_path); -} - -void -camel_local_summary_construct(CamelLocalSummary *new, const char *filename, const char *local_name, CamelIndex *index) -{ - camel_folder_summary_set_build_content(CAMEL_FOLDER_SUMMARY(new), FALSE); - camel_folder_summary_set_filename(CAMEL_FOLDER_SUMMARY(new), filename); - new->folder_path = g_strdup(local_name); - new->index = index; - if (index) - camel_object_ref((CamelObject *)index); -} - -static int -local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex) -{ - return camel_folder_summary_load((CamelFolderSummary *)cls); -} - -/* load/check the summary */ -int -camel_local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex) -{ - struct stat st; - CamelFolderSummary *s = (CamelFolderSummary *)cls; - - d(printf("Loading summary ...\n")); - - if (forceindex - || stat(s->summary_path, &st) == -1 - || ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->load(cls, forceindex, ex) == -1) { - w(g_warning("Could not load summary: flags may be reset")); - camel_folder_summary_clear((CamelFolderSummary *)cls); - return -1; - } - - return 0; -} - -void camel_local_summary_check_force(CamelLocalSummary *cls) -{ - cls->check_force = 1; -} - -char * -camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *info) -{ - return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->encode_x_evolution(cls, info); -} - -int -camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info) -{ - return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->decode_x_evolution(cls, xev, info); -} - -/*#define DOSTATS*/ -#ifdef DOSTATS -struct _stat_info { - int mitotal; - int micount; - int citotal; - int cicount; - int msgid; - int msgcount; -}; - -static void -do_stat_ci(CamelLocalSummary *cls, struct _stat_info *info, CamelMessageContentInfo *ci) -{ - info->cicount++; - info->citotal += ((CamelFolderSummary *)cls)->content_info_size /*+ 4 memchunks are 1/4 byte overhead per mi */; - if (ci->id) - info->citotal += strlen(ci->id) + 4; - if (ci->description) - info->citotal += strlen(ci->description) + 4; - if (ci->encoding) - info->citotal += strlen(ci->encoding) + 4; - if (ci->type) { - CamelContentType *ct = ci->type; - struct _camel_header_param *param; - - info->citotal += sizeof(*ct) + 4; - if (ct->type) - info->citotal += strlen(ct->type) + 4; - if (ct->subtype) - info->citotal += strlen(ct->subtype) + 4; - param = ct->params; - while (param) { - info->citotal += sizeof(*param) + 4; - if (param->name) - info->citotal += strlen(param->name)+4; - if (param->value) - info->citotal += strlen(param->value)+4; - param = param->next; - } - } - ci = ci->childs; - while (ci) { - do_stat_ci(cls, info, ci); - ci = ci->next; - } -} - -static void -do_stat_mi(CamelLocalSummary *cls, struct _stat_info *info, CamelMessageInfo *mi) -{ - info->micount++; - info->mitotal += ((CamelFolderSummary *)cls)->content_info_size /*+ 4*/; - - if (mi->subject) - info->mitotal += strlen(mi->subject) + 4; - if (mi->to) - info->mitotal += strlen(mi->to) + 4; - if (mi->from) - info->mitotal += strlen(mi->from) + 4; - if (mi->cc) - info->mitotal += strlen(mi->cc) + 4; - if (mi->uid) - info->mitotal += strlen(mi->uid) + 4; - - if (mi->references) { - info->mitotal += (mi->references->size-1) * sizeof(CamelSummaryMessageID) + sizeof(CamelSummaryReferences) + 4; - info->msgid += (mi->references->size) * sizeof(CamelSummaryMessageID); - info->msgcount += mi->references->size; - } - - /* dont have any user flags yet */ - - if (mi->content) { - do_stat_ci(cls, info, mi->content); - } -} - -#endif - -int -camel_local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - int ret; - - ret = ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->check(cls, changeinfo, ex); - -#ifdef DOSTATS - if (ret != -1) { - int i; - CamelFolderSummary *s = (CamelFolderSummary *)cls; - struct _stat_info stats = { 0 }; - - for (i=0;i<camel_folder_summary_count(s);i++) { - CamelMessageInfo *info = camel_folder_summary_index(s, i); - do_stat_mi(cls, &stats, info); - camel_folder_summary_info_free(s, info); - } - - printf("\nMemory used by summary:\n\n"); - printf("Total of %d messages\n", camel_folder_summary_count(s)); - printf("Total: %d bytes (ave %f)\n", stats.citotal + stats.mitotal, - (double)(stats.citotal+stats.mitotal)/(double)camel_folder_summary_count(s)); - printf("Message Info: %d (ave %f)\n", stats.mitotal, (double)stats.mitotal/(double)stats.micount); - printf("Content Info; %d (ave %f) count %d\n", stats.citotal, (double)stats.citotal/(double)stats.cicount, stats.cicount); - printf("message id's: %d (ave %f) count %d\n", stats.msgid, (double)stats.msgid/(double)stats.msgcount, stats.msgcount); - } -#endif - return ret; -} - -int -camel_local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->sync(cls, expunge, changeinfo, ex); -} - -CamelMessageInfo * -camel_local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex) -{ - return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->add(cls, msg, info, ci, ex); -} - -/** - * camel_local_summary_write_headers: - * @fd: - * @header: - * @xevline: - * @status: - * @xstatus: - * - * Write a bunch of headers to the file @fd. IF xevline is non NULL, then - * an X-Evolution header line is created at the end of all of the headers. - * If @status is non NULL, then a Status header line is also written. - * The headers written are termianted with a blank line. - * - * Return value: -1 on error, otherwise the number of bytes written. - **/ -int -camel_local_summary_write_headers(int fd, struct _camel_header_raw *header, const char *xevline, const char *status, const char *xstatus) -{ - int outlen = 0, len; - int newfd; - FILE *out; - - /* dum de dum, maybe the whole sync function should just use stdio for output */ - newfd = dup(fd); - if (newfd == -1) - return -1; - - out = fdopen(newfd, "w"); - if (out == NULL) { - close(newfd); - errno = EINVAL; - return -1; - } - - while (header) { - if (strcmp(header->name, "X-Evolution") != 0 - && (status == NULL || strcmp(header->name, "Status") != 0) - && (xstatus == NULL || strcmp(header->name, "X-Status") != 0)) { - len = fprintf(out, "%s:%s\n", header->name, header->value); - if (len == -1) { - fclose(out); - return -1; - } - outlen += len; - } - header = header->next; - } - - if (status) { - len = fprintf(out, "Status: %s\n", status); - if (len == -1) { - fclose(out); - return -1; - } - outlen += len; - } - - if (xstatus) { - len = fprintf(out, "X-Status: %s\n", xstatus); - if (len == -1) { - fclose(out); - return -1; - } - outlen += len; - } - - if (xevline) { - len = fprintf(out, "X-Evolution: %s\n", xevline); - if (len == -1) { - fclose(out); - return -1; - } - outlen += len; - } - - len = fprintf(out, "\n"); - if (len == -1) { - fclose(out); - return -1; - } - outlen += len; - - if (fclose(out) == -1) - return -1; - - return outlen; -} - -static int -local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - /* FIXME: sync index here ? */ - return 0; -} - -static int -local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - int ret = 0; - - ret = camel_folder_summary_save((CamelFolderSummary *)cls); - if (ret == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not save summary: %s: %s"), - cls->folder_path, g_strerror (errno)); - - g_warning ("Could not save summary for %s: %s", cls->folder_path, strerror (errno)); - } - - if (cls->index && camel_index_sync(cls->index) == -1) - g_warning ("Could not sync index for %s: %s", cls->folder_path, strerror (errno)); - - return ret; -} - -static CamelMessageInfo * -local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex) -{ - CamelMessageInfo *mi; - char *xev; - - d(printf("Adding message to summary\n")); - - mi = camel_folder_summary_add_from_message((CamelFolderSummary *)cls, msg); - if (mi) { - d(printf("Added, uid = %s\n", mi->uid)); - if (info) { - CamelTag *tag = info->user_tags; - CamelFlag *flag = info->user_flags; - - while (flag) { - camel_flag_set(&mi->user_flags, flag->name, TRUE); - flag = flag->next; - } - - while (tag) { - camel_tag_set(&mi->user_tags, tag->name, tag->value); - tag = tag->next; - } - - mi->flags = mi->flags | (info->flags & 0xffff); - if (info->size) - mi->size = info->size; - } - - /* we need to calculate the size ourselves */ - if (mi->size == 0) { - CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new(); - - camel_data_wrapper_write_to_stream((CamelDataWrapper *)msg, (CamelStream *)sn); - mi->size = sn->written; - camel_object_unref((CamelObject *)sn); - } - - mi->flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED); - xev = camel_local_summary_encode_x_evolution(cls, mi); - camel_medium_set_header((CamelMedium *)msg, "X-Evolution", xev); - g_free(xev); - camel_folder_change_info_add_uid(ci, camel_message_info_uid(mi)); - } else { - d(printf("Failed!\n")); - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Unable to add message to summary: unknown reason")); - } - return mi; -} - -static char * -local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi) -{ - GString *out = g_string_new(""); - struct _camel_header_param *params = NULL; - GString *val = g_string_new(""); - CamelFlag *flag = mi->user_flags; - CamelTag *tag = mi->user_tags; - char *ret; - const char *p, *uidstr; - guint32 uid; - - /* FIXME: work out what to do with uid's that aren't stored here? */ - /* FIXME: perhaps make that a mbox folder only issue?? */ - p = uidstr = camel_message_info_uid(mi); - while (*p && isdigit(*p)) - p++; - if (*p == 0 && sscanf (uidstr, "%u", &uid) == 1) { - g_string_printf (out, "%08x-%04x", uid, mi->flags & 0xffff); - } else { - g_string_printf (out, "%s-%04x", uidstr, mi->flags & 0xffff); - } - - if (flag || tag) { - val = g_string_new (""); - - if (flag) { - while (flag) { - g_string_append (val, flag->name); - if (flag->next) - g_string_append_c (val, ','); - flag = flag->next; - } - camel_header_set_param (¶ms, "flags", val->str); - g_string_truncate (val, 0); - } - if (tag) { - while (tag) { - g_string_append (val, tag->name); - g_string_append_c (val, '='); - g_string_append (val, tag->value); - if (tag->next) - g_string_append_c (val, ','); - tag = tag->next; - } - camel_header_set_param (¶ms, "tags", val->str); - } - g_string_free (val, TRUE); - camel_header_param_list_format_append (out, params); - camel_header_param_list_free (params); - } - ret = out->str; - g_string_free (out, FALSE); - - return ret; -} - -static int -local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi) -{ - struct _camel_header_param *params, *scan; - guint32 uid, flags; - char *header; - int i; - - /* check for uid/flags */ - header = camel_header_token_decode(xev); - if (header && strlen(header) == strlen("00000000-0000") - && sscanf(header, "%08x-%04x", &uid, &flags) == 2) { - char uidstr[20]; - if (mi) { - sprintf(uidstr, "%u", uid); - camel_message_info_set_uid(mi, g_strdup(uidstr)); - mi->flags = flags; - } - } else { - g_free(header); - return -1; - } - g_free(header); - - if (mi == NULL) - return 0; - - /* check for additional data */ - header = strchr(xev, ';'); - if (header) { - params = camel_header_param_list_decode(header+1); - scan = params; - while (scan) { - if (!strcasecmp(scan->name, "flags")) { - char **flagv = g_strsplit(scan->value, ",", 1000); - - for (i=0;flagv[i];i++) { - camel_flag_set(&mi->user_flags, flagv[i], TRUE); - } - g_strfreev(flagv); - } else if (!strcasecmp(scan->name, "tags")) { - char **tagv = g_strsplit(scan->value, ",", 10000); - char *val; - - for (i=0;tagv[i];i++) { - val = strchr(tagv[i], '='); - if (val) { - *val++ = 0; - camel_tag_set(&mi->user_tags, tagv[i], val); - val[-1]='='; - } - } - g_strfreev(tagv); - } - scan = scan->next; - } - camel_header_param_list_free(params); - } - return 0; -} - -static CamelMessageInfo * -message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) -{ - CamelMessageInfo *mi; - CamelLocalSummary *cls = (CamelLocalSummary *)s; - - mi = ((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new(s, h); - if (mi) { - const char *xev; - int doindex = FALSE; - - xev = camel_header_raw_find(&h, "X-Evolution", NULL); - if (xev==NULL || camel_local_summary_decode_x_evolution(cls, xev, mi) == -1) { - /* to indicate it has no xev header */ - mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV; - camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s)); - - /* shortcut, no need to look it up in the index library */ - doindex = TRUE; - } - - if (cls->index - && (doindex - || cls->index_force - || !camel_index_has_name(cls->index, camel_message_info_uid(mi)))) { - d(printf("Am indexing message %s\n", camel_message_info_uid(mi))); - camel_folder_summary_set_index(s, cls->index); - } else { - d(printf("Not indexing message %s\n", camel_message_info_uid(mi))); - camel_folder_summary_set_index(s, NULL); - } - } - - return mi; -} diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h deleted file mode 100644 index 25d77e62c3..0000000000 --- a/camel/providers/local/camel-local-summary.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _CAMEL_LOCAL_SUMMARY_H -#define _CAMEL_LOCAL_SUMMARY_H - -#include <camel/camel-folder-summary.h> -#include <camel/camel-folder.h> -#include <camel/camel-exception.h> -#include <camel/camel-index.h> - -#define CAMEL_LOCAL_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_local_summary_get_type (), CamelLocalSummary) -#define CAMEL_LOCAL_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_local_summary_get_type (), CamelLocalSummaryClass) -#define CAMEL_IS_LOCAL_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_local_summary_get_type ()) - -typedef struct _CamelLocalSummary CamelLocalSummary; -typedef struct _CamelLocalSummaryClass CamelLocalSummaryClass; - -/* extra summary flags */ -enum { - CAMEL_MESSAGE_FOLDER_NOXEV = 1<<17, - CAMEL_MESSAGE_FOLDER_XEVCHANGE = 1<<18, - CAMEL_MESSAGE_FOLDER_NOTSEEN = 1<<19, /* have we seen this in processing this loop? */ -}; - -struct _CamelLocalSummary { - CamelFolderSummary parent; - - char *folder_path; /* name of matching folder */ - - CamelIndex *index; - unsigned int index_force:1; /* do we force index during creation? */ - unsigned int check_force:1; /* does a check force a full check? */ -}; - -struct _CamelLocalSummaryClass { - CamelFolderSummaryClass parent_class; - - int (*load)(CamelLocalSummary *cls, int forceindex, CamelException *ex); - int (*check)(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); - int (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); - CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex); - - char *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelMessageInfo *info); - int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info); -}; - -CamelType camel_local_summary_get_type (void); -void camel_local_summary_construct (CamelLocalSummary *new, const char *filename, const char *local_name, CamelIndex *index); - -/* load/check the summary */ -int camel_local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex); -/* check for new/removed messages */ -int camel_local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *, CamelException *ex); -/* perform a folder sync or expunge, if needed */ -int camel_local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *, CamelException *ex); -/* add a new message to the summary */ -CamelMessageInfo *camel_local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex); - -/* force the next check to be a full check/rebuild */ -void camel_local_summary_check_force(CamelLocalSummary *cls); - -/* generate an X-Evolution header line */ -char *camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *info); -int camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info); - -/* utility functions - write headers to a file with optional X-Evolution header and/or status header */ -int camel_local_summary_write_headers(int fd, struct _camel_header_raw *header, const char *xevline, const char *status, const char *xstatus); - -#endif /* ! _CAMEL_LOCAL_SUMMARY_H */ - diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c deleted file mode 100644 index eca07efbef..0000000000 --- a/camel/providers/local/camel-maildir-folder.c +++ /dev/null @@ -1,245 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999, 2003 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> - -#include "camel-maildir-folder.h" -#include "camel-maildir-store.h" -#include "camel-stream-fs.h" -#include "camel-maildir-summary.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-exception.h" - -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -static CamelLocalFolderClass *parent_class = NULL; - -/* Returns the class for a CamelMaildirFolder */ -#define CMAILDIRF_CLASS(so) CAMEL_MAILDIR_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CMAILDIRS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static CamelLocalSummary *maildir_create_summary(const char *path, const char *folder, CamelIndex *index); - -static void maildir_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex); -static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex); - -static void maildir_finalize(CamelObject * object); - -static void camel_maildir_folder_class_init(CamelObjectClass * camel_maildir_folder_class) -{ - CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_maildir_folder_class); - CamelLocalFolderClass *lclass = (CamelLocalFolderClass *)camel_maildir_folder_class; - - parent_class = CAMEL_LOCAL_FOLDER_CLASS (camel_type_get_global_classfuncs(camel_local_folder_get_type())); - - /* virtual method definition */ - - /* virtual method overload */ - camel_folder_class->append_message = maildir_append_message; - camel_folder_class->get_message = maildir_get_message; - - lclass->create_summary = maildir_create_summary; -} - -static void maildir_init(gpointer object, gpointer klass) -{ - /*CamelFolder *folder = object; - CamelMaildirFolder *maildir_folder = object;*/ -} - -static void maildir_finalize(CamelObject * object) -{ - /*CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER(object);*/ -} - -CamelType camel_maildir_folder_get_type(void) -{ - static CamelType camel_maildir_folder_type = CAMEL_INVALID_TYPE; - - if (camel_maildir_folder_type == CAMEL_INVALID_TYPE) { - camel_maildir_folder_type = camel_type_register(CAMEL_LOCAL_FOLDER_TYPE, "CamelMaildirFolder", - sizeof(CamelMaildirFolder), - sizeof(CamelMaildirFolderClass), - (CamelObjectClassInitFunc) camel_maildir_folder_class_init, - NULL, - (CamelObjectInitFunc) maildir_init, - (CamelObjectFinalizeFunc) maildir_finalize); - } - - return camel_maildir_folder_type; -} - -CamelFolder * -camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex) -{ - CamelFolder *folder; - - d(printf("Creating maildir folder: %s\n", full_name)); - - folder = (CamelFolder *)camel_object_new(CAMEL_MAILDIR_FOLDER_TYPE); - - if (parent_store->flags & CAMEL_STORE_FILTER_INBOX - && strcmp(full_name, ".") == 0) - folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT; - - folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder, - parent_store, full_name, flags, ex); - - return folder; -} - -static CamelLocalSummary *maildir_create_summary(const char *path, const char *folder, CamelIndex *index) -{ - return (CamelLocalSummary *)camel_maildir_summary_new(path, folder, index); -} - -static void -maildir_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder = (CamelMaildirFolder *)folder; - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - CamelStream *output_stream; - CamelMessageInfo *mi; - CamelMaildirMessageInfo *mdi; - char *name, *dest = NULL; - - d(printf("Appending message\n")); - - /* add it to the summary/assign the uid, etc */ - mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex); - if (camel_exception_is_set (ex)) - return; - - mdi = (CamelMaildirMessageInfo *)mi; - - d(printf("Appending message: uid is %s filename is %s\n", camel_message_info_uid(mi), mdi->filename)); - - /* write it out to tmp, use the uid we got from the summary */ - name = g_strdup_printf ("%s/tmp/%s", lf->folder_path, camel_message_info_uid(mi)); - output_stream = camel_stream_fs_new_with_name (name, O_WRONLY|O_CREAT, 0600); - if (output_stream == NULL) - goto fail_write; - - if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)message, output_stream) == -1 - || camel_stream_close (output_stream) == -1) - goto fail_write; - - /* now move from tmp to cur (bypass new, does it matter?) */ - dest = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); - if (rename (name, dest) == 1) - goto fail_write; - - g_free (dest); - g_free (name); - - camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", - ((CamelLocalFolder *)maildir_folder)->changes); - camel_folder_change_info_clear (((CamelLocalFolder *)maildir_folder)->changes); - - if (appended_uid) - *appended_uid = g_strdup(camel_message_info_uid(mi)); - - return; - - fail_write: - - /* remove the summary info so we are not out-of-sync with the mh folder */ - camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary), - camel_message_info_uid (mi)); - - if (errno == EINTR) - camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, - _("Maildir append message cancelled")); - else - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot append message to maildir folder: %s: %s"), - name, g_strerror (errno)); - - if (output_stream) { - camel_object_unref (CAMEL_OBJECT (output_stream)); - unlink (name); - } - - g_free (name); - g_free (dest); -} - -static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - CamelStream *message_stream = NULL; - CamelMimeMessage *message = NULL; - CamelMessageInfo *info; - char *name; - CamelMaildirMessageInfo *mdi; - - d(printf("getting message: %s\n", uid)); - - /* get the message summary info */ - if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) { - camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), uid, _("No such message")); - return NULL; - } - - mdi = (CamelMaildirMessageInfo *)info; - - /* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */ - name = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi)); - - camel_folder_summary_info_free(folder->summary, info); - - if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Cannot get message: %s\n %s"), - name, g_strerror (errno)); - g_free(name); - return NULL; - } - - message = camel_mime_message_new(); - if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) { - camel_exception_setv(ex, (errno==EINTR)?CAMEL_EXCEPTION_USER_CANCEL:CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Cannot get message: %s\n %s"), - name, _("Invalid message contents")); - g_free(name); - camel_object_unref((CamelObject *)message_stream); - camel_object_unref((CamelObject *)message); - return NULL; - - } - camel_object_unref((CamelObject *)message_stream); - g_free(name); - - return message; -} diff --git a/camel/providers/local/camel-maildir-folder.h b/camel/providers/local/camel-maildir-folder.h deleted file mode 100644 index c495d9b14d..0000000000 --- a/camel/providers/local/camel-maildir-folder.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: - * Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_MAILDIR_FOLDER_H -#define CAMEL_MAILDIR_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus } */ -#include "camel-local-folder.h" - -#define CAMEL_MAILDIR_FOLDER_TYPE (camel_maildir_folder_get_type ()) -#define CAMEL_MAILDIR_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MAILDIR_FOLDER_TYPE, CamelMaildirFolder)) -#define CAMEL_MAILDIR_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MAILDIR_FOLDER_TYPE, CamelMaildirFolderClass)) -#define CAMEL_IS_MAILDIR_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_MAILDIR_FOLDER_TYPE)) - -typedef struct { - CamelLocalFolder parent_object; - -} CamelMaildirFolder; - -typedef struct { - CamelLocalFolderClass parent_class; - - /* Virtual methods */ - -} CamelMaildirFolderClass; - -/* public methods */ -CamelFolder *camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex); - -/* Standard Camel function */ -CamelType camel_maildir_folder_get_type(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CAMEL_MAILDIR_FOLDER_H */ diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c deleted file mode 100644 index c84c37158c..0000000000 --- a/camel/providers/local/camel-maildir-store.c +++ /dev/null @@ -1,416 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#include <dirent.h> - -#include "camel-maildir-store.h" -#include "camel-maildir-folder.h" -#include "camel-exception.h" -#include "camel-url.h" -#include "camel-private.h" - -#define d(x) - -static CamelLocalStoreClass *parent_class = NULL; - -/* Returns the class for a CamelMaildirStore */ -#define CMAILDIRS_CLASS(so) CAMEL_MAILDIR_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CMAILDIRF_CLASS(so) CAMEL_MAILDIR_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex); -static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); -static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex); - -static CamelFolderInfo * get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex); - -static void camel_maildir_store_class_init(CamelObjectClass * camel_maildir_store_class) -{ - CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS(camel_maildir_store_class); - /*CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_maildir_store_class);*/ - - parent_class = (CamelLocalStoreClass *)camel_type_get_global_classfuncs(camel_local_store_get_type()); - - /* virtual method overload, use defaults for most */ - camel_store_class->get_folder = get_folder; - camel_store_class->get_inbox = get_inbox; - camel_store_class->delete_folder = delete_folder; - - camel_store_class->get_folder_info = get_folder_info; - camel_store_class->free_folder_info = camel_store_free_folder_info_full; -} - -CamelType camel_maildir_store_get_type(void) -{ - static CamelType camel_maildir_store_type = CAMEL_INVALID_TYPE; - - if (camel_maildir_store_type == CAMEL_INVALID_TYPE) { - camel_maildir_store_type = camel_type_register(CAMEL_LOCAL_STORE_TYPE, "CamelMaildirStore", - sizeof(CamelMaildirStore), - sizeof(CamelMaildirStoreClass), - (CamelObjectClassInitFunc) camel_maildir_store_class_init, - NULL, - NULL, - NULL); - } - - return camel_maildir_store_type; -} - -static CamelFolder * -get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex) -{ - char *name, *tmp, *cur, *new; - struct stat st; - CamelFolder *folder = NULL; - - if (!((CamelStoreClass *)parent_class)->get_folder(store, folder_name, flags, ex)) - return NULL; - - name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); - tmp = g_strdup_printf("%s/tmp", name); - cur = g_strdup_printf("%s/cur", name); - new = g_strdup_printf("%s/new", name); - - if (stat(name, &st) == -1) { - if (errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open folder `%s':\n%s"), - folder_name, g_strerror (errno)); - } else if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Folder `%s' does not exist."), folder_name); - } else { - if (mkdir(name, 0700) != 0 - || mkdir(tmp, 0700) != 0 - || mkdir(cur, 0700) != 0 - || mkdir(new, 0700) != 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not create folder `%s':\n%s"), - folder_name, g_strerror (errno)); - rmdir(tmp); - rmdir(cur); - rmdir(new); - rmdir(name); - } else { - folder = camel_maildir_folder_new(store, folder_name, flags, ex); - } - } - } else if (!S_ISDIR(st.st_mode) - || stat(tmp, &st) != 0 || !S_ISDIR(st.st_mode) - || stat(cur, &st) != 0 || !S_ISDIR(st.st_mode) - || stat(new, &st) != 0 || !S_ISDIR(st.st_mode)) { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("`%s' is not a maildir directory."), name); - } else { - folder = camel_maildir_folder_new(store, folder_name, flags, ex); - } - - g_free(name); - g_free(tmp); - g_free(cur); - g_free(new); - - return folder; -} - -static CamelFolder * -get_inbox (CamelStore *store, CamelException *ex) -{ - return get_folder (store, ".", 0, ex); -} - -static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex) -{ - char *name, *tmp, *cur, *new; - struct stat st; - - name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); - - tmp = g_strdup_printf("%s/tmp", name); - cur = g_strdup_printf("%s/cur", name); - new = g_strdup_printf("%s/new", name); - - if (stat(name, &st) == -1 || !S_ISDIR(st.st_mode) - || stat(tmp, &st) == -1 || !S_ISDIR(st.st_mode) - || stat(cur, &st) == -1 || !S_ISDIR(st.st_mode) - || stat(new, &st) == -1 || !S_ISDIR(st.st_mode)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s': %s"), - folder_name, errno ? g_strerror (errno) : - _("not a maildir directory")); - } else { - int err = 0; - - /* remove subdirs first - will fail if not empty */ - if (rmdir(cur) == -1 || rmdir(new) == -1) { - err = errno; - } else { - DIR *dir; - struct dirent *d; - - /* for tmp (only), its contents is irrelevant */ - dir = opendir(tmp); - if (dir) { - while ( (d=readdir(dir)) ) { - char *name = d->d_name, *file; - - if (!strcmp(name, ".") || !strcmp(name, "..")) - continue; - file = g_strdup_printf("%s/%s", tmp, name); - unlink(file); - g_free(file); - } - closedir(dir); - } - if (rmdir(tmp) == -1 || rmdir(name) == -1) - err = errno; - } - - if (err != 0) { - /* easier just to mkdir all (and let them fail), than remember what we got to */ - mkdir(name, 0700); - mkdir(cur, 0700); - mkdir(new, 0700); - mkdir(tmp, 0700); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s': %s"), - folder_name, g_strerror (err)); - } else { - /* and remove metadata */ - ((CamelStoreClass *)parent_class)->delete_folder(store, folder_name, ex); - } - } - - g_free(name); - g_free(tmp); - g_free(cur); - g_free(new); -} - -static CamelFolderInfo *camel_folder_info_new(const char *url, const char *full, const char *name, int unread) -{ - CamelFolderInfo *fi; - - fi = g_malloc0(sizeof(*fi)); - fi->url = g_strdup(url); - fi->full_name = g_strdup(full); - fi->name = g_strdup(name); - fi->unread_message_count = unread; - camel_folder_info_build_path(fi, '/'); - - d(printf("Adding maildir info: '%s' '%s' '%s' '%s'\n", fi->path, fi->name, fi->full_name, fi->url)); - - return fi; -} - -/* used to find out where we've visited already */ -struct _inode { - dev_t dnode; - ino_t inode; -}; - -/* returns number of records found at or below this level */ -static int scan_dir(CamelStore *store, GHashTable *visited, char *root, const char *path, guint32 flags, CamelFolderInfo *parent, CamelFolderInfo **fip, CamelException *ex) -{ - DIR *dir; - struct dirent *d; - char *name, *uri, *tmp, *cur, *new; - const char *base; - CamelFolderInfo *fi = NULL; - struct stat st; - CamelFolder *folder; - int unread; - - /* look for folders matching the right structure, recursively */ - name = g_strdup_printf("%s/%s", root, path); - - d(printf("checking dir '%s' part '%s' for maildir content\n", root, path)); - - tmp = g_strdup_printf("%s/tmp", name); - cur = g_strdup_printf("%s/cur", name); - new = g_strdup_printf("%s/new", name); - - if (stat(tmp, &st) == 0 && S_ISDIR(st.st_mode) - && stat(cur, &st) == 0 && S_ISDIR(st.st_mode) - && stat(new, &st) == 0 && S_ISDIR(st.st_mode)) { - uri = g_strdup_printf("maildir:%s#%s", root, path); - } else - uri = g_strdup_printf("maildir:%s;noselect=yes#%s", root, path); - - base = strrchr(path, '/'); - if (base) - base++; - else - base = path; - - /* if we have this folder open, get the real unread count */ - folder = camel_object_bag_get(store->folders, path); - if (folder) { - if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info(folder, NULL); - unread = camel_folder_get_unread_message_count(folder); - camel_object_unref(folder); - } else { - unread = -1; - } - - /* if we dont have a folder, then scan the directory and get the unread - count from there, which is reasonably cheap (on decent filesystem) */ - /* Well we could get this from the summary, but this is more accurate */ - if (folder == NULL - && (flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) { - unread = 0; - dir = opendir(new); - if (dir) { - /* we assume that all files here are unread ones */ - while ( (d = readdir(dir)) ) { - if (d->d_name[0] != '.') - unread++; - } - closedir(dir); - } - dir = opendir(cur); - if (dir) { - /* any files with flags but not the 'S' (seen) flag are unread */ - while ( (d = readdir(dir)) ) { - char *p = strstr(d->d_name, ":2,"); - - if (p && strchr(p, 'S') == NULL) - unread++; - } - closedir(dir); - } - } - - fi = camel_folder_info_new(uri, path, base, unread); - - d(printf("found! uri = %s\n", fi->url)); - d(printf(" full_name = %s\n name = '%s'\n", fi->full_name, fi->name)); - - fi->parent = parent; - fi->sibling = *fip; - *fip = fi; - g_free(uri); - - g_free(tmp); - g_free(cur); - g_free(new); - - unread = 0; - - /* always look further if asked */ - if (((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || parent == NULL)) { - dir = opendir(name); - if (dir == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not scan folder `%s': %s"), - root, g_strerror (errno)); - g_free(name); - return -1; - } - - while ( (d = readdir(dir)) ) { - if (strcmp(d->d_name, "tmp") == 0 - || strcmp(d->d_name, "cur") == 0 - || strcmp(d->d_name, "new") == 0 - || strcmp(d->d_name, ".") == 0 - || strcmp(d->d_name, "..") == 0) - continue; - - tmp = g_strdup_printf("%s/%s", name, d->d_name); - if (stat(tmp, &st) == 0 && S_ISDIR(st.st_mode)) { - struct _inode in = { st.st_dev, st.st_ino }; - - /* see if we've visited already */ - if (g_hash_table_lookup(visited, &in) == NULL) { - struct _inode *inew = g_malloc(sizeof(*inew)); - - *inew = in; - g_hash_table_insert(visited, inew, inew); - new = g_strdup_printf("%s/%s", path, d->d_name); - if (scan_dir(store, visited, root, new, flags, fi, &fi->child, ex) == -1) { - g_free(tmp); - g_free(new); - closedir(dir); - return -1; - } - g_free(new); - } - } - g_free(tmp); - } - closedir(dir); - } - - g_free(name); - - return 0; -} - -static guint inode_hash(const void *d) -{ - const struct _inode *v = d; - - return v->inode ^ v->dnode; -} - -static gboolean inode_equal(const void *a, const void *b) -{ - const struct _inode *v1 = a, *v2 = b; - - return v1->inode == v2->inode && v1->dnode == v2->dnode; -} - -static void inode_free(void *k, void *v, void *d) -{ - g_free(k); -} - -static CamelFolderInfo * -get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex) -{ - CamelFolderInfo *fi = NULL; - CamelLocalStore *local_store = (CamelLocalStore *)store; - GHashTable *visited; - - visited = g_hash_table_new(inode_hash, inode_equal); - - if (scan_dir(store, visited, ((CamelService *)local_store)->url->path, top?top:".", flags, NULL, &fi, ex) == -1 && fi != NULL) { - camel_store_free_folder_info_full(store, fi); - fi = NULL; - } - - g_hash_table_foreach(visited, inode_free, NULL); - g_hash_table_destroy(visited); - - return fi; -} diff --git a/camel/providers/local/camel-maildir-store.h b/camel/providers/local/camel-maildir-store.h deleted file mode 100644 index f7725bc189..0000000000 --- a/camel/providers/local/camel-maildir-store.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_MAILDIR_STORE_H -#define CAMEL_MAILDIR_STORE_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus } */ - -#include "camel-local-store.h" - -#define CAMEL_MAILDIR_STORE_TYPE (camel_maildir_store_get_type ()) -#define CAMEL_MAILDIR_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MAILDIR_STORE_TYPE, CamelMaildirStore)) -#define CAMEL_MAILDIR_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MAILDIR_STORE_TYPE, CamelMaildirStoreClass)) -#define CAMEL_IS_MAILDIR_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_MAILDIR_STORE_TYPE)) - -typedef struct { - CamelLocalStore parent_object; - -} CamelMaildirStore; - -typedef struct { - CamelLocalStoreClass parent_class; - -} CamelMaildirStoreClass; - -/* public methods */ - -/* Standard Camel function */ -CamelType camel_maildir_store_get_type(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CAMEL_MAILDIR_STORE_H */ diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c deleted file mode 100644 index 37e1ac2ce7..0000000000 --- a/camel/providers/local/camel-maildir-summary.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Not Zed <notzed@lostzed.mmc.com.au> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include <sys/types.h> -#include <dirent.h> - -#include <ctype.h> - -#include "camel-maildir-summary.h" -#include <camel/camel-mime-message.h> -#include <camel/camel-operation.h> - -#include "camel-private.h" -#include "e-util/e-memory.h" - -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -#define CAMEL_MAILDIR_SUMMARY_VERSION (0x2000) - -static CamelMessageInfo *message_info_load(CamelFolderSummary *s, FILE *in); -static CamelMessageInfo *message_info_new(CamelFolderSummary *, struct _camel_header_raw *); -static void message_info_free(CamelFolderSummary *, CamelMessageInfo *mi); - -static int maildir_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex); -static int maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); -static int maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); -static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex); - -static char *maildir_summary_next_uid_string(CamelFolderSummary *s); -static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi); -static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi); - -static void camel_maildir_summary_class_init (CamelMaildirSummaryClass *class); -static void camel_maildir_summary_init (CamelMaildirSummary *gspaper); -static void camel_maildir_summary_finalise (CamelObject *obj); - -#define _PRIVATE(x) (((CamelMaildirSummary *)(x))->priv) - -struct _CamelMaildirSummaryPrivate { - char *current_file; - char *hostname; - - GHashTable *load_map; -}; - -static CamelLocalSummaryClass *parent_class; - -CamelType -camel_maildir_summary_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register(camel_local_summary_get_type (), "CamelMaildirSummary", - sizeof(CamelMaildirSummary), - sizeof(CamelMaildirSummaryClass), - (CamelObjectClassInitFunc)camel_maildir_summary_class_init, - NULL, - (CamelObjectInitFunc)camel_maildir_summary_init, - (CamelObjectFinalizeFunc)camel_maildir_summary_finalise); - } - - return type; -} - -static void -camel_maildir_summary_class_init (CamelMaildirSummaryClass *class) -{ - CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *) class; - CamelLocalSummaryClass *lklass = (CamelLocalSummaryClass *)class; - - parent_class = (CamelLocalSummaryClass *)camel_type_get_global_classfuncs(camel_local_summary_get_type ()); - - /* override methods */ - sklass->message_info_load = message_info_load; - sklass->message_info_new = message_info_new; - sklass->message_info_free = message_info_free; - sklass->next_uid_string = maildir_summary_next_uid_string; - - lklass->load = maildir_summary_load; - lklass->check = maildir_summary_check; - lklass->sync = maildir_summary_sync; - lklass->add = maildir_summary_add; - lklass->encode_x_evolution = maildir_summary_encode_x_evolution; - lklass->decode_x_evolution = maildir_summary_decode_x_evolution; -} - -static void -camel_maildir_summary_init (CamelMaildirSummary *o) -{ - struct _CamelFolderSummary *s = (CamelFolderSummary *) o; - char hostname[256]; - - o->priv = g_malloc0(sizeof(*o->priv)); - /* set unique file version */ - s->version += CAMEL_MAILDIR_SUMMARY_VERSION; - - s->message_info_size = sizeof(CamelMaildirMessageInfo); - s->content_info_size = sizeof(CamelMaildirMessageContentInfo); - -#if defined (DOEPOOLV) || defined (DOESTRV) - s->message_info_strings = CAMEL_MAILDIR_INFO_LAST; -#endif - - if (gethostname(hostname, 256) == 0) { - o->priv->hostname = g_strdup(hostname); - } else { - o->priv->hostname = g_strdup("localhost"); - } -} - -static void -camel_maildir_summary_finalise(CamelObject *obj) -{ - CamelMaildirSummary *o = (CamelMaildirSummary *)obj; - - g_free(o->priv->hostname); - g_free(o->priv); -} - -/** - * camel_maildir_summary_new: - * - * Create a new CamelMaildirSummary object. - * - * Return value: A new #CamelMaildirSummary object. - **/ -CamelMaildirSummary *camel_maildir_summary_new (const char *filename, const char *maildirdir, CamelIndex *index) -{ - CamelMaildirSummary *o = (CamelMaildirSummary *)camel_object_new(camel_maildir_summary_get_type ()); - - camel_local_summary_construct((CamelLocalSummary *)o, filename, maildirdir, index); - return o; -} - -/* the 'standard' maildir flags. should be defined in sorted order. */ -static struct { - char flag; - guint32 flagbit; -} flagbits[] = { - { 'F', CAMEL_MESSAGE_FLAGGED }, - { 'R', CAMEL_MESSAGE_ANSWERED }, - { 'S', CAMEL_MESSAGE_SEEN }, - { 'T', CAMEL_MESSAGE_DELETED }, -}; - -/* convert the uid + flags into a unique:info maildir format */ -char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info) -{ - const char *uid; - char *p, *buf; - int i; - - uid = camel_message_info_uid (info); - buf = g_alloca (strlen (uid) + strlen (":2,") + (sizeof (flagbits) / sizeof (flagbits[0])) + 1); - p = buf + sprintf (buf, "%s:2,", uid); - for (i = 0; i < sizeof (flagbits) / sizeof (flagbits[0]); i++) { - if (info->flags & flagbits[i].flagbit) - *p++ = flagbits[i].flag; - } - *p = 0; - - return g_strdup(buf); -} - -/* returns 0 if the info matches (or there was none), otherwise we changed it */ -int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name) -{ - char *p, c; - guint32 set = 0; /* what we set */ - /*guint32 all = 0;*/ /* all flags */ - int i; - - p = strstr(name, ":2,"); - if (p) { - p+=3; - while ((c = *p++)) { - /* we could assume that the flags are in order, but its just as easy not to require */ - for (i=0;i<sizeof(flagbits)/sizeof(flagbits[0]);i++) { - if (flagbits[i].flag == c && (info->flags & flagbits[i].flagbit) == 0) { - set |= flagbits[i].flagbit; - } - /*all |= flagbits[i].flagbit;*/ - } - } - - /* changed? */ - /*if ((info->flags & all) != set) {*/ - if ((info->flags & set) != set) { - /* ok, they did change, only add the new flags ('merge flags'?) */ - /*info->flags &= all; if we wanted to set only the new flags, which we probably dont */ - info->flags |= set; - return 1; - } - } - - return 0; -} - -/* for maildir, x-evolution isn't used, so dont try and get anything out of it */ -static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi) -{ - return -1; -} - -static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi) -{ - return NULL; -} - -/* FIXME: - both 'new' and 'add' will try and set the filename, this is not ideal ... -*/ -static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *changes, CamelException *ex) -{ - CamelMessageInfo *mi; - - mi = ((CamelLocalSummaryClass *) parent_class)->add(cls, msg, info, changes, ex); - if (mi) { - if (info) { - camel_maildir_info_set_filename(mi, camel_maildir_summary_info_to_name(mi)); - d(printf("Setting filename to %s\n", camel_maildir_info_filename(mi))); - } - } - - return mi; -} - -static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _camel_header_raw *h) -{ - CamelMessageInfo *mi, *info; - CamelMaildirSummary *mds = (CamelMaildirSummary *)s; - CamelMaildirMessageInfo *mdi; - const char *uid; - - mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new(s, h); - /* assign the uid and new filename */ - if (mi) { - mdi = (CamelMaildirMessageInfo *)mi; - - uid = camel_message_info_uid(mi); - if (uid==NULL || uid[0] == 0) - camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s)); - - /* handle 'duplicates' */ - info = camel_folder_summary_uid(s, uid); - if (info) { - d(printf("already seen uid '%s', just summarising instead\n", uid)); - camel_folder_summary_info_free(s, mi); - mdi = (CamelMaildirMessageInfo *)mi = info; - } - - /* with maildir we know the real received date, from the filename */ - mi->date_received = strtoul(camel_message_info_uid(mi), NULL, 10); - - if (mds->priv->current_file) { -#if 0 - char *p1, *p2, *p3; - unsigned long uid; -#endif - /* if setting from a file, grab the flags from it */ - camel_maildir_info_set_filename(mi, g_strdup(mds->priv->current_file)); - camel_maildir_summary_name_to_info(mi, mds->priv->current_file); - -#if 0 - /* Actually, I dont think all this effort is worth it at all ... */ - - /* also, see if we can extract the next-id from tne name, and safe-if-fy ourselves against collisions */ - /* we check for something.something_number.something */ - p1 = strchr(mdi->filename, '.'); - if (p1) { - p2 = strchr(p1+1, '.'); - p3 = strchr(p1+1, '_'); - if (p2 && p3 && p3<p2) { - uid = strtoul(p3+1, &p1, 10); - if (p1 == p2 && uid>0) - camel_folder_summary_set_uid(s, uid); - } - } -#endif - } else { - /* if creating a file, set its name from the flags we have */ - camel_maildir_info_set_filename(mdi, camel_maildir_summary_info_to_name(mi)); - d(printf("Setting filename to %s\n", camel_maildir_info_filename(mi))); - } - } - - return mi; -} - - -static void message_info_free(CamelFolderSummary *s, CamelMessageInfo *mi) -{ -#if !defined (DOEPOOLV) && !defined (DOESTRV) - CamelMaildirMessageInfo *mdi = (CamelMaildirMessageInfo *)mi; - - g_free(mdi->filename); -#endif - ((CamelFolderSummaryClass *) parent_class)->message_info_free(s, mi); -} - - -static char *maildir_summary_next_uid_string(CamelFolderSummary *s) -{ - CamelMaildirSummary *mds = (CamelMaildirSummary *)s; - - d(printf("next uid string called?\n")); - - /* if we have a current file, then use that to get the uid */ - if (mds->priv->current_file) { - char *cln; - - cln = strchr(mds->priv->current_file, ':'); - if (cln) - return g_strndup(mds->priv->current_file, cln-mds->priv->current_file); - else - return g_strdup(mds->priv->current_file); - } else { - /* the first would probably work, but just to be safe, check for collisions */ -#if 0 - return g_strdup_printf("%ld.%d_%u.%s", time(0), getpid(), camel_folder_summary_next_uid(s), mds->priv->hostname); -#else - CamelLocalSummary *cls = (CamelLocalSummary *)s; - char *name = NULL, *uid = NULL; - struct stat st; - int retry = 0; - guint32 nextuid = camel_folder_summary_next_uid(s); - - /* we use time.pid_count.hostname */ - do { - if (retry > 0) { - g_free(name); - g_free(uid); - sleep(2); - } - uid = g_strdup_printf("%ld.%d_%u.%s", time(0), getpid(), nextuid, mds->priv->hostname); - name = g_strdup_printf("%s/tmp/%s", cls->folder_path, uid); - retry++; - } while (stat(name, &st) == 0 && retry<3); - - /* I dont know what we're supposed to do if it fails to find a unique name?? */ - - g_free(name); - return uid; -#endif - } -} - -static CamelMessageInfo * -message_info_load(CamelFolderSummary *s, FILE *in) -{ - CamelMessageInfo *mi; - CamelMaildirSummary *mds = (CamelMaildirSummary *)s; - - mi = ((CamelFolderSummaryClass *) parent_class)->message_info_load(s, in); - if (mi) { - char *name; - - if (mds->priv->load_map - && (name = g_hash_table_lookup(mds->priv->load_map, camel_message_info_uid(mi)))) { - d(printf("Setting filename of %s to %s\n", camel_message_info_uid(mi), name)); - camel_maildir_info_set_filename(mi, g_strdup(name)); - camel_maildir_summary_name_to_info(mi, name); - } - } - - return mi; -} - -static int maildir_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex) -{ - char *cur; - DIR *dir; - struct dirent *d; - CamelMaildirSummary *mds = (CamelMaildirSummary *)cls; - char *uid; - EMemPool *pool; - int ret; - - cur = g_strdup_printf("%s/cur", cls->folder_path); - - d(printf("pre-loading uid <> filename map\n")); - - dir = opendir(cur); - if (dir == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot open maildir directory path: %s: %s"), - cls->folder_path, g_strerror (errno)); - g_free(cur); - return -1; - } - - mds->priv->load_map = g_hash_table_new(g_str_hash, g_str_equal); - pool = e_mempool_new(1024, 512, E_MEMPOOL_ALIGN_BYTE); - - while ( (d = readdir(dir)) ) { - if (d->d_name[0] == '.') - continue; - - /* map the filename -> uid */ - uid = strchr(d->d_name, ':'); - if (uid) { - int len = uid-d->d_name; - uid = e_mempool_alloc(pool, len+1); - memcpy(uid, d->d_name, len); - uid[len] = 0; - g_hash_table_insert(mds->priv->load_map, uid, e_mempool_strdup(pool, d->d_name)); - } else { - uid = e_mempool_strdup(pool, d->d_name); - g_hash_table_insert(mds->priv->load_map, uid, uid); - } - } - closedir(dir); - g_free(cur); - - ret = ((CamelLocalSummaryClass *) parent_class)->load(cls, forceindex, ex); - - g_hash_table_destroy(mds->priv->load_map); - mds->priv->load_map = NULL; - e_mempool_destroy(pool); - - return ret; -} - -static int camel_maildir_summary_add(CamelLocalSummary *cls, const char *name, int forceindex) -{ - CamelMaildirSummary *maildirs = (CamelMaildirSummary *)cls; - char *filename = g_strdup_printf("%s/cur/%s", cls->folder_path, name); - int fd; - CamelMimeParser *mp; - - d(printf("summarising: %s\n", name)); - - fd = open(filename, O_RDONLY); - if (fd == -1) { - g_warning ("Cannot summarise/index: %s: %s", filename, strerror (errno)); - g_free(filename); - return -1; - } - mp = camel_mime_parser_new(); - camel_mime_parser_scan_from(mp, FALSE); - camel_mime_parser_init_with_fd(mp, fd); - if (cls->index && (forceindex || !camel_index_has_name(cls->index, name))) { - d(printf("forcing indexing of message content\n")); - camel_folder_summary_set_index((CamelFolderSummary *)maildirs, cls->index); - } else { - camel_folder_summary_set_index((CamelFolderSummary *)maildirs, NULL); - } - maildirs->priv->current_file = (char *)name; - camel_folder_summary_add_from_parser((CamelFolderSummary *)maildirs, mp); - camel_object_unref((CamelObject *)mp); - maildirs->priv->current_file = NULL; - camel_folder_summary_set_index((CamelFolderSummary *)maildirs, NULL); - g_free(filename); - return 0; -} - -struct _remove_data { - CamelLocalSummary *cls; - CamelFolderChangeInfo *changes; -}; - -static void -remove_summary(char *key, CamelMessageInfo *info, struct _remove_data *rd) -{ - d(printf("removing message %s from summary\n", key)); - if (rd->cls->index) - camel_index_delete_name(rd->cls->index, camel_message_info_uid(info)); - if (rd->changes) - camel_folder_change_info_remove_uid(rd->changes, key); - camel_folder_summary_remove((CamelFolderSummary *)rd->cls, info); - camel_folder_summary_info_free((CamelFolderSummary *)rd->cls, info); -} - -static int -sort_receive_cmp(const void *ap, const void *bp) -{ - const CamelMessageInfo - *a = *((CamelMessageInfo **)ap), - *b = *((CamelMessageInfo **)bp); - - if (a->date_received < b->date_received) - return -1; - else if (a->date_received > b->date_received) - return 1; - - return 0; -} - -static int -maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, CamelException *ex) -{ - DIR *dir; - struct dirent *d; - char *p; - CamelMessageInfo *info; - CamelMaildirMessageInfo *mdi; - CamelFolderSummary *s = (CamelFolderSummary *)cls; - GHashTable *left; - int i, count, total; - int forceindex; - char *new, *cur; - char *uid; - struct _remove_data rd = { cls, changes }; - - new = g_strdup_printf("%s/new", cls->folder_path); - cur = g_strdup_printf("%s/cur", cls->folder_path); - - d(printf("checking summary ...\n")); - - camel_operation_start(NULL, _("Checking folder consistency")); - - /* scan the directory, check for mail files not in the index, or index entries that - no longer exist */ - dir = opendir(cur); - if (dir == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot open maildir directory path: %s: %s"), - cls->folder_path, g_strerror (errno)); - g_free(cur); - g_free(new); - camel_operation_end(NULL); - return -1; - } - - /* keeps track of all uid's that have not been processed */ - left = g_hash_table_new(g_str_hash, g_str_equal); - count = camel_folder_summary_count((CamelFolderSummary *)cls); - forceindex = count == 0; - for (i=0;i<count;i++) { - info = camel_folder_summary_index((CamelFolderSummary *)cls, i); - if (info) { - g_hash_table_insert(left, (char *)camel_message_info_uid(info), info); - } - } - - /* joy, use this to pre-count the total, so we can report progress meaningfully */ - total = 0; - count = 0; - while ( (d = readdir(dir)) ) - total++; - rewinddir(dir); - - while ( (d = readdir(dir)) ) { - int pc = count * 100 / total; - - camel_operation_progress(NULL, pc); - count++; - - /* FIXME: also run stat to check for regular file */ - p = d->d_name; - if (p[0] == '.') - continue; - - /* map the filename -> uid */ - uid = strchr(d->d_name, ':'); - if (uid) - uid = g_strndup(d->d_name, uid-d->d_name); - else - uid = g_strdup(d->d_name); - - info = g_hash_table_lookup(left, uid); - if (info) { - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); - g_hash_table_remove(left, uid); - } - - info = camel_folder_summary_uid((CamelFolderSummary *)cls, uid); - if (info == NULL) { - /* must be a message incorporated by another client, this is not a 'recent' uid */ - if (camel_maildir_summary_add(cls, d->d_name, forceindex) == 0) - if (changes) - camel_folder_change_info_add_uid(changes, uid); - } else { - const char *filename; - - if (cls->index && (!camel_index_has_name(cls->index, uid))) { - /* message_info_new will handle duplicates */ - camel_maildir_summary_add(cls, d->d_name, forceindex); - } - - mdi = (CamelMaildirMessageInfo *)info; - filename = camel_maildir_info_filename(mdi); - /* TODO: only store the extension in the mdi->filename struct, not the whole lot */ - if (filename == NULL || strcmp(filename, d->d_name) != 0) { -#ifdef DOESTRV -#warning "cannot modify the estrv after its been setup, for mt-safe code" - CAMEL_SUMMARY_LOCK(s, summary_lock); - /* need to update the summary hash ref */ - g_hash_table_remove(s->messages_uid, camel_message_info_uid(info)); - info->strings = e_strv_set_ref(info->strings, CAMEL_MAILDIR_INFO_FILENAME, d->d_name); - info->strings = e_strv_pack(info->strings); - g_hash_table_insert(s->messages_uid, (char *)camel_message_info_uid(info), info); - CAMEL_SUMMARY_UNLOCK(s, summary_lock); -#else -# ifdef DOEPOOLV - info->strings = e_poolv_set(info->strings, CAMEL_MAILDIR_INFO_FILENAME, d->d_name, FALSE); -# else - g_free(mdi->filename); - mdi->filename = g_strdup(d->d_name); -# endif -#endif - } - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); - } - g_free(uid); - } - closedir(dir); - g_hash_table_foreach(left, (GHFunc)remove_summary, &rd); - g_hash_table_destroy(left); - - camel_operation_end(NULL); - - camel_operation_start(NULL, _("Checking for new messages")); - - /* now, scan new for new messages, and copy them to cur, and so forth */ - dir = opendir(new); - if (dir != NULL) { - total = 0; - count = 0; - while ( (d = readdir(dir)) ) - total++; - rewinddir(dir); - - while ( (d = readdir(dir)) ) { - char *name, *newname, *destname, *destfilename; - char *src, *dest; - int pc = count * 100 / total; - - camel_operation_progress(NULL, pc); - count++; - - name = d->d_name; - if (name[0] == '.') - continue; - - /* already in summary? shouldn't happen, but just incase ... */ - if ((info = camel_folder_summary_uid((CamelFolderSummary *)cls, name))) { - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); - newname = destname = camel_folder_summary_next_uid_string(s); - } else { - newname = NULL; - destname = name; - } - - /* copy this to the destination folder, use 'standard' semantics for maildir info field */ - src = g_strdup_printf("%s/%s", new, name); - destfilename = g_strdup_printf("%s:2,", destname); - dest = g_strdup_printf("%s/%s", cur, destfilename); - - /* FIXME: This should probably use link/unlink */ - - if (rename(src, dest) == 0) { - camel_maildir_summary_add(cls, destfilename, forceindex); - if (changes) { - camel_folder_change_info_add_uid(changes, destname); - camel_folder_change_info_recent_uid(changes, destname); - } - } else { - /* else? we should probably care about failures, but wont */ - g_warning("Failed to move new maildir message %s to cur %s", src, dest); - } - - /* c strings are painful to work with ... */ - g_free(destfilename); - g_free(newname); - g_free(src); - g_free(dest); - } - camel_operation_end(NULL); - } - closedir(dir); - - g_free(new); - g_free(cur); - - /* sort the summary based on receive time, since the directory order is not useful */ - CAMEL_SUMMARY_LOCK(s, summary_lock); - qsort(s->messages->pdata, s->messages->len, sizeof(CamelMessageInfo *), sort_receive_cmp); - CAMEL_SUMMARY_UNLOCK(s, summary_lock); - - return 0; -} - -/* sync the summary with the ondisk files. */ -static int -maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changes, CamelException *ex) -{ - int count, i; - CamelMessageInfo *info; - CamelMaildirMessageInfo *mdi; -#ifdef DOESTRV - CamelFolderSummary *s = (CamelFolderSummary *)cls; -#endif - char *name; - struct stat st; - - d(printf("summary_sync(expunge=%s)\n", expunge?"true":"false")); - - if (camel_local_summary_check(cls, changes, ex) == -1) - return -1; - - camel_operation_start(NULL, _("Storing folder")); - - count = camel_folder_summary_count((CamelFolderSummary *)cls); - for (i=count-1;i>=0;i--) { - camel_operation_progress(NULL, (count-i)*100/count); - - info = camel_folder_summary_index((CamelFolderSummary *)cls, i); - mdi = (CamelMaildirMessageInfo *)info; - if (info && (info->flags & CAMEL_MESSAGE_DELETED) && expunge) { - name = g_strdup_printf("%s/cur/%s", cls->folder_path, camel_maildir_info_filename(mdi)); - d(printf("deleting %s\n", name)); - if (unlink(name) == 0 || errno==ENOENT) { - - /* FIXME: put this in folder_summary::remove()? */ - if (cls->index) - camel_index_delete_name(cls->index, camel_message_info_uid(info)); - - camel_folder_change_info_remove_uid(changes, camel_message_info_uid(info)); - camel_folder_summary_remove((CamelFolderSummary *)cls, info); - } - g_free(name); - } else if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) { - char *newname = camel_maildir_summary_info_to_name(info); - char *dest; - - /* do we care about additional metainfo stored inside the message? */ - /* probably should all go in the filename? */ - - /* have our flags/ i.e. name changed? */ - if (strcmp(newname, camel_maildir_info_filename(mdi))) { - name = g_strdup_printf("%s/cur/%s", cls->folder_path, camel_maildir_info_filename(mdi)); - dest = g_strdup_printf("%s/cur/%s", cls->folder_path, newname); - rename(name, dest); - if (stat(dest, &st) == -1) { - /* we'll assume it didn't work, but dont change anything else */ - g_free(newname); - } else { - /* TODO: If this is made mt-safe, then this code could be a problem, since - the estrv is being modified. - Sigh, this may mean the maildir name has to be cached another way */ -#ifdef DOESTRV -#warning "cannot modify the estrv after its been setup, for mt-safe code" - CAMEL_SUMMARY_LOCK(s, summary_lock); - /* need to update the summary hash ref */ - g_hash_table_remove(s->messages_uid, camel_message_info_uid(info)); - info->strings = e_strv_set_ref_free(info->strings, CAMEL_MAILDIR_INFO_FILENAME, newname); - info->strings = e_strv_pack(info->strings); - g_hash_table_insert(s->messages_uid, (char *)camel_message_info_uid(info), info); - CAMEL_SUMMARY_UNLOCK(s, summary_lock); -#else -# ifdef DOEPOOLV - info->strings = e_poolv_set(info->strings, CAMEL_MAILDIR_INFO_FILENAME, newname, TRUE); -# else - g_free(mdi->filename); - mdi->filename = newname; -# endif -#endif - } - g_free(name); - g_free(dest); - } else { - g_free(newname); - } - - /* strip FOLDER_MESSAGE_FLAGED, etc */ - info->flags &= 0xffff; - } - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); - } - - camel_operation_end(NULL); - - return ((CamelLocalSummaryClass *)parent_class)->sync(cls, expunge, changes, ex); -} - diff --git a/camel/providers/local/camel-maildir-summary.h b/camel/providers/local/camel-maildir-summary.h deleted file mode 100644 index 0cae785c6c..0000000000 --- a/camel/providers/local/camel-maildir-summary.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Not Zed <notzed@lostzed.mmc.com.au> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _CAMEL_MAILDIR_SUMMARY_H -#define _CAMEL_MAILDIR_SUMMARY_H - -#include "camel-local-summary.h" -#include <camel/camel-folder.h> -#include <camel/camel-exception.h> -#include <camel/camel-index.h> - -#define CAMEL_MAILDIR_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_maildir_summary_get_type (), CamelMaildirSummary) -#define CAMEL_MAILDIR_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_maildir_summary_get_type (), CamelMaildirSummaryClass) -#define CAMEL_IS_MAILDIR_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_maildir_summary_get_type ()) - -typedef struct _CamelMaildirSummary CamelMaildirSummary; -typedef struct _CamelMaildirSummaryClass CamelMaildirSummaryClass; - -typedef struct _CamelMaildirMessageContentInfo { - CamelMessageContentInfo info; -} CamelMaildirMessageContentInfo; - -#if defined (DOEPOOLV) || defined (DOESTRV) -enum { - CAMEL_MAILDIR_INFO_FILENAME = CAMEL_MESSAGE_INFO_LAST, - CAMEL_MAILDIR_INFO_LAST, -}; -#endif - -typedef struct _CamelMaildirMessageInfo { - CamelMessageInfo info; - -#if !defined (DOEPOOLV) && !defined (DOESTRV) - char *filename; /* maildir has this annoying status shit on the end of the filename, use this to get the real message id */ -#endif -} CamelMaildirMessageInfo; - -struct _CamelMaildirSummary { - CamelLocalSummary parent; - struct _CamelMaildirSummaryPrivate *priv; -}; - -struct _CamelMaildirSummaryClass { - CamelLocalSummaryClass parent_class; - - /* virtual methods */ - - /* signals */ -}; - -CamelType camel_maildir_summary_get_type (void); -CamelMaildirSummary *camel_maildir_summary_new (const char *filename, const char *maildirdir, CamelIndex *index); - -/* convert some info->flags to/from the messageinfo */ -char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info); -int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name); - -#if defined (DOEPOOLV) || defined (DOESTRV) -#define camel_maildir_info_filename(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MAILDIR_INFO_FILENAME) -#define camel_maildir_info_set_filename(x, s) camel_message_info_set_string((CamelMessageInfo *)(x), CAMEL_MAILDIR_INFO_FILENAME, s) -#else -#define camel_maildir_info_filename(x) (((CamelMaildirMessageInfo *)x)->filename) -#define camel_maildir_info_set_filename(x, s) (g_free(((CamelMaildirMessageInfo *)x)->filename),((CamelMaildirMessageInfo *)x)->filename = s) -#endif - -#endif /* ! _CAMEL_MAILDIR_SUMMARY_H */ - diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c deleted file mode 100644 index 9c3a7036f2..0000000000 --- a/camel/providers/local/camel-mbox-folder.c +++ /dev/null @@ -1,549 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999, 2003 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <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 "camel-stream-fs.h" -#include "camel-mbox-summary.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-stream-filter.h" -#include "camel-mime-filter-from.h" -#include "camel-exception.h" - -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -static CamelLocalFolderClass *parent_class = NULL; - -/* Returns the class for a CamelMboxFolder */ -#define CMBOXF_CLASS(so) CAMEL_MBOX_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CMBOXS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -char *camel_mbox_folder_get_full_path (const char *toplevel_dir, const char *full_name); -char *camel_mbox_folder_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext); - -static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex); -static void mbox_unlock(CamelLocalFolder *lf); - -#ifdef STATUS_PINE -static void mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set); -#endif - -static void mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value); -static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); - -static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, char **appended_uid, CamelException *ex); -static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex); -static CamelLocalSummary *mbox_create_summary(const char *path, const char *folder, CamelIndex *index); - -static void mbox_finalise(CamelObject * object); - -static void -camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class) -{ - CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_mbox_folder_class); - CamelLocalFolderClass *lclass = (CamelLocalFolderClass *)camel_mbox_folder_class; - - parent_class = (CamelLocalFolderClass *)camel_type_get_global_classfuncs(camel_local_folder_get_type()); - - /* virtual method definition */ - - /* virtual method overload */ - camel_folder_class->append_message = mbox_append_message; - camel_folder_class->get_message = mbox_get_message; - -#ifdef STATUS_PINE - camel_folder_class->set_message_flags = mbox_set_message_flags; -#endif - camel_folder_class->set_message_user_flag = mbox_set_message_user_flag; - camel_folder_class->set_message_user_tag = mbox_set_message_user_tag; - - lclass->get_full_path = camel_mbox_folder_get_full_path; - lclass->get_meta_path = camel_mbox_folder_get_meta_path; - lclass->create_summary = mbox_create_summary; - lclass->lock = mbox_lock; - lclass->unlock = mbox_unlock; -} - -static void -mbox_init(gpointer object, gpointer klass) -{ - /*CamelFolder *folder = object;*/ - CamelMboxFolder *mbox_folder = object; - - mbox_folder->lockfd = -1; -} - -static void -mbox_finalise(CamelObject * object) -{ - CamelMboxFolder *mbox_folder = (CamelMboxFolder *)object; - - g_assert(mbox_folder->lockfd == -1); -} - -CamelType camel_mbox_folder_get_type(void) -{ - static CamelType camel_mbox_folder_type = CAMEL_INVALID_TYPE; - - if (camel_mbox_folder_type == CAMEL_INVALID_TYPE) { - camel_mbox_folder_type = camel_type_register(CAMEL_LOCAL_FOLDER_TYPE, "CamelMboxFolder", - sizeof(CamelMboxFolder), - sizeof(CamelMboxFolderClass), - (CamelObjectClassInitFunc) camel_mbox_folder_class_init, - NULL, - (CamelObjectInitFunc) mbox_init, - (CamelObjectFinalizeFunc) mbox_finalise); - } - - return camel_mbox_folder_type; -} - -CamelFolder * -camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex) -{ - CamelFolder *folder; - - d(printf("Creating mbox folder: %s in %s\n", full_name, camel_local_store_get_toplevel_dir((CamelLocalStore *)parent_store))); - - folder = (CamelFolder *)camel_object_new(CAMEL_MBOX_FOLDER_TYPE); - folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder, - parent_store, full_name, flags, ex); - - return folder; -} - -char * -camel_mbox_folder_get_full_path (const char *toplevel_dir, const char *full_name) -{ - const char *inptr = full_name; - int subdirs = 0; - char *path, *p; - - while (*inptr != '\0') { - if (*inptr == '/') - subdirs++; - inptr++; - } - - path = g_malloc (strlen (toplevel_dir) + (inptr - full_name) + (4 * subdirs) + 1); - p = g_stpcpy (path, toplevel_dir); - - inptr = full_name; - while (*inptr != '\0') { - while (*inptr != '/' && *inptr != '\0') - *p++ = *inptr++; - - if (*inptr == '/') { - p = g_stpcpy (p, ".sbd/"); - inptr++; - - /* strip extranaeous '/'s */ - while (*inptr == '/') - inptr++; - } - } - - *p = '\0'; - - return path; -} - -char * -camel_mbox_folder_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext) -{ -/*#define USE_HIDDEN_META_FILES*/ -#ifdef USE_HIDDEN_META_FILES - char *name, *slash; - - name = g_alloca (strlen (full_name) + strlen (ext) + 2); - if ((slash = strrchr (full_name, '/'))) - sprintf (name, "%.*s.%s%s", slash - full_name + 1, full_name, slash + 1, ext); - else - sprintf (name, ".%s%s", full_name, ext); - - return camel_mbox_folder_get_full_path (toplevel_dir, name); -#else - char *full_path, *path; - - full_path = camel_mbox_folder_get_full_path (toplevel_dir, full_name); - path = g_strdup_printf ("%s%s", full_path, ext); - g_free (full_path); - - return path; -#endif -} - -static CamelLocalSummary *mbox_create_summary(const char *path, const char *folder, CamelIndex *index) -{ - return (CamelLocalSummary *)camel_mbox_summary_new(path, folder, index); -} - -static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex) -{ - CamelMboxFolder *mf = (CamelMboxFolder *)lf; - - /* make sure we have matching unlocks for locks, camel-local-folder class should enforce this */ - g_assert(mf->lockfd == -1); - - mf->lockfd = open(lf->folder_path, O_RDWR, 0); - if (mf->lockfd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot create folder lock on %s: %s"), - lf->folder_path, g_strerror (errno)); - return -1; - } - - if (camel_lock_folder(lf->folder_path, mf->lockfd, type, ex) == -1) { - close(mf->lockfd); - mf->lockfd = -1; - return -1; - } - - return 0; -} - -static void mbox_unlock(CamelLocalFolder *lf) -{ - CamelMboxFolder *mf = (CamelMboxFolder *)lf; - - g_assert(mf->lockfd != -1); - camel_unlock_folder(lf->folder_path, mf->lockfd); - close(mf->lockfd); - mf->lockfd = -1; -} - -static void -mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, char **appended_uid, CamelException *ex) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - CamelStream *output_stream = NULL, *filter_stream = NULL; - CamelMimeFilter *filter_from = NULL; - CamelMboxSummary *mbs = (CamelMboxSummary *)folder->summary; - CamelMessageInfo *mi; - char *fromline = NULL; - int fd, retval; - struct stat st; -#if 0 - char *xev; -#endif - /* If we can't lock, dont do anything */ - if (camel_local_folder_lock(lf, CAMEL_LOCK_WRITE, ex) == -1) - return; - - d(printf("Appending message\n")); - - /* first, check the summary is correct (updates folder_size too) */ - retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, ex); - if (retval == -1) - goto fail; - - /* add it to the summary/assign the uid, etc */ - mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex); - if (mi == NULL) - goto fail; - - d(printf("Appending message: uid is %s\n", camel_message_info_uid(mi))); - - output_stream = camel_stream_fs_new_with_name(lf->folder_path, O_WRONLY|O_APPEND, 0600); - if (output_stream == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot open mailbox: %s: %s\n"), - lf->folder_path, g_strerror (errno)); - goto fail; - } - - /* and we need to set the frompos/XEV explicitly */ - ((CamelMboxMessageInfo *)mi)->frompos = mbs->folder_size; -#if 0 - xev = camel_local_summary_encode_x_evolution((CamelLocalSummary *)folder->summary, mi); - if (xev) { - /* the x-ev header should match the 'current' flags, no problem, so store as much */ - camel_medium_set_header((CamelMedium *)message, "X-Evolution", xev); - mi->flags &= ~ CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED; - g_free(xev); - } -#endif - - /* we must write this to the non-filtered stream ... */ - fromline = camel_mime_message_build_mbox_from(message); - if (camel_stream_write(output_stream, fromline, strlen(fromline)) == -1) - goto fail_write; - - /* and write the content to the filtering stream, that translates '\nFrom' into '\n>From' */ - filter_stream = (CamelStream *) camel_stream_filter_new_with_stream(output_stream); - filter_from = (CamelMimeFilter *) camel_mime_filter_from_new(); - camel_stream_filter_add((CamelStreamFilter *) filter_stream, filter_from); - if (camel_data_wrapper_write_to_stream((CamelDataWrapper *)message, filter_stream) == -1 - || camel_stream_write(filter_stream, "\n", 1) == -1 - || camel_stream_close(filter_stream) == -1) - goto fail_write; - - /* filter stream ref's the output stream itself, so we need to unref it too */ - camel_object_unref((CamelObject *)filter_from); - camel_object_unref((CamelObject *)filter_stream); - camel_object_unref((CamelObject *)output_stream); - g_free(fromline); - - /* now we 'fudge' the summary to tell it its uptodate, because its idea of uptodate has just changed */ - /* the stat really shouldn't fail, we just wrote to it */ - if (stat(lf->folder_path, &st) == 0) { - mbs->folder_size = st.st_size; - ((CamelFolderSummary *)mbs)->time = st.st_mtime; - } - - /* unlock as soon as we can */ - camel_local_folder_unlock(lf); - - if (camel_folder_change_info_changed(lf->changes)) { - camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes); - camel_folder_change_info_clear(lf->changes); - } - - if (appended_uid) - *appended_uid = g_strdup(camel_message_info_uid(mi)); - - return; - -fail_write: - if (errno == EINTR) - camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, - _("Mail append cancelled")); - else - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot append message to mbox file: %s: %s"), - lf->folder_path, g_strerror (errno)); - - if (filter_stream) - camel_object_unref(CAMEL_OBJECT(filter_stream)); - - if (output_stream) - camel_object_unref(CAMEL_OBJECT(output_stream)); - - if (filter_from) - camel_object_unref(CAMEL_OBJECT(filter_from)); - - g_free(fromline); - - /* reset the file to original size */ - fd = open(lf->folder_path, O_WRONLY, 0600); - if (fd != -1) { - ftruncate(fd, mbs->folder_size); - close(fd); - } - - /* remove the summary info so we are not out-of-sync with the mbox */ - camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (mbs), camel_message_info_uid (mi)); - - /* and tell the summary its uptodate */ - if (stat(lf->folder_path, &st) == 0) { - mbs->folder_size = st.st_size; - ((CamelFolderSummary *)mbs)->time = st.st_mtime; - } - -fail: - /* make sure we unlock the folder - before we start triggering events into appland */ - camel_local_folder_unlock(lf); - - /* cascade the changes through, anyway, if there are any outstanding */ - if (camel_folder_change_info_changed(lf->changes)) { - camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes); - camel_folder_change_info_clear(lf->changes); - } -} - -static CamelMimeMessage * -mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - CamelMimeMessage *message = NULL; - CamelMboxMessageInfo *info; - CamelMimeParser *parser = NULL; - int fd, retval; - int retried = FALSE; - off_t frompos; - - d(printf("Getting message %s\n", uid)); - - /* lock the folder first, burn if we can't, need write lock for summary check */ - if (camel_local_folder_lock(lf, CAMEL_LOCK_WRITE, ex) == -1) - return NULL; - - /* check for new messages always */ - if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) { - camel_local_folder_unlock(lf); - return NULL; - } - -retry: - /* get the message summary info */ - info = (CamelMboxMessageInfo *) camel_folder_summary_uid(folder->summary, uid); - - if (info == NULL) { - camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Cannot get message: %s\n %s"), uid, _("No such message")); - goto fail; - } - - /* no frompos, its an error in the library (and we can't do anything with it) */ - g_assert(info->frompos != -1); - - frompos = info->frompos; - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info); - - /* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache - the whole message in memory if the stream is non-seekable (which it is when built from a parser - with no stream). This means we dont have to lock the mbox for the life of the message, but only - while it is being created. */ - - fd = open(lf->folder_path, O_RDONLY); - if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Cannot get message: %s from folder %s\n %s"), - uid, lf->folder_path, g_strerror (errno)); - goto fail; - } - - /* we use a parser to verify the message is correct, and in the correct position */ - parser = camel_mime_parser_new(); - camel_mime_parser_init_with_fd(parser, fd); - camel_mime_parser_scan_from(parser, TRUE); - - camel_mime_parser_seek(parser, frompos, SEEK_SET); - if (camel_mime_parser_step(parser, NULL, NULL) != CAMEL_MIME_PARSER_STATE_FROM - || camel_mime_parser_tell_start_from(parser) != frompos) { - - g_warning("Summary doesn't match the folder contents! eek!\n" - " expecting offset %ld got %ld, state = %d", (long int)frompos, - (long int)camel_mime_parser_tell_start_from(parser), - camel_mime_parser_state(parser)); - - camel_object_unref((CamelObject *)parser); - parser = NULL; - - if (!retried) { - retried = TRUE; - camel_local_summary_check_force((CamelLocalSummary *)folder->summary); - retval = camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex); - if (retval != -1) - goto retry; - } - - camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Cannot get message: %s from folder %s\n %s"), uid, lf->folder_path, - _("The folder appears to be irrecoverably corrupted.")); - goto fail; - } - - message = camel_mime_message_new(); - if (camel_mime_part_construct_from_parser((CamelMimePart *)message, parser) == -1) { - camel_exception_setv(ex, errno==EINTR?CAMEL_EXCEPTION_USER_CANCEL:CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Cannot get message: %s from folder %s\n %s"), uid, lf->folder_path, - _("Message construction failed: Corrupt mailbox?")); - camel_object_unref((CamelObject *)message); - message = NULL; - goto fail; - } - - camel_medium_remove_header((CamelMedium *)message, "X-Evolution"); -fail: - /* and unlock now we're finished with it */ - camel_local_folder_unlock(lf); - - if (parser) - camel_object_unref((CamelObject *)parser); - - /* use the opportunity to notify of changes (particularly if we had a rebuild) */ - if (camel_folder_change_info_changed(lf->changes)) { - camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes); - camel_folder_change_info_clear(lf->changes); - } - - return message; -} - -#ifdef STATUS_PINE -static void -mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set) -{ - /* Basically, if anything could change the Status line, presume it does */ - if (((CamelMboxSummary *)folder->summary)->xstatus - && (flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED))) { - flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED; - set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED; - } - - ((CamelFolderClass *)parent_class)->set_message_flags(folder, uid, flags, set); -} -#endif - -static void -mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value) -{ - CamelMessageInfo *info; - - g_return_if_fail(folder->summary != NULL); - - info = camel_folder_summary_uid(folder->summary, uid); - if (info == NULL) - return; - - if (camel_flag_set(&info->user_flags, name, value)) { - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; - camel_folder_summary_touch(folder->summary); - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); - } - camel_folder_summary_info_free(folder->summary, info); -} - -static void -mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value) -{ - CamelMessageInfo *info; - - g_return_if_fail(folder->summary != NULL); - - info = camel_folder_summary_uid(folder->summary, uid); - if (info == NULL) - return; - - if (camel_tag_set(&info->user_tags, name, value)) { - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; - camel_folder_summary_touch(folder->summary); - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); - } - camel_folder_summary_info_free(folder->summary, info); -} diff --git a/camel/providers/local/camel-mbox-folder.h b/camel/providers/local/camel-mbox-folder.h deleted file mode 100644 index aa0b67201f..0000000000 --- a/camel/providers/local/camel-mbox-folder.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999 Ximian . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_MBOX_FOLDER_H -#define CAMEL_MBOX_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-local-folder.h" -#include "camel-mbox-summary.h" - -#define CAMEL_MBOX_FOLDER_TYPE (camel_mbox_folder_get_type ()) -#define CAMEL_MBOX_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MBOX_FOLDER_TYPE, CamelMboxFolder)) -#define CAMEL_MBOX_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MBOX_FOLDER_TYPE, CamelMboxFolderClass)) -#define CAMEL_IS_MBOX_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_MBOX_FOLDER_TYPE)) - -typedef struct { - CamelLocalFolder parent_object; - - int lockfd; /* for when we have a lock on the folder */ -} CamelMboxFolder; - -typedef struct { - CamelLocalFolderClass parent_class; - - /* Virtual methods */ - -} CamelMboxFolderClass; - -/* public methods */ -/* flags are taken from CAMEL_STORE_FOLDER_* flags */ -CamelFolder *camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex); - -/* Standard Camel function */ -CamelType camel_mbox_folder_get_type(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_MBOX_FOLDER_H */ diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c deleted file mode 100644 index ffce19171f..0000000000 --- a/camel/providers/local/camel-mbox-store.c +++ /dev/null @@ -1,753 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <dirent.h> -#include <fcntl.h> -#include <errno.h> - -#include "camel-mbox-store.h" -#include "camel-mbox-folder.h" -#include "camel-file-utils.h" -#include "camel-text-index.h" -#include "camel-exception.h" -#include "camel-url.h" - -#define d(x) - -static CamelLocalStoreClass *parent_class = NULL; - -/* Returns the class for a CamelMboxStore */ -#define CMBOXS_CLASS(so) CAMEL_MBOX_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CMBOXF_CLASS(so) CAMEL_MBOX_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -extern char *camel_mbox_folder_get_full_path (const char *toplevel_dir, const char *full_name); -extern char *camel_mbox_folder_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext); - -static CamelFolder *get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex); -static void rename_folder (CamelStore *store, const char *old, const char *new, CamelException *ex); -static CamelFolderInfo *create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex); -static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, guint32 flags, 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); - - parent_class = (CamelLocalStoreClass *)camel_type_get_global_classfuncs(camel_local_store_get_type()); - - /* virtual method overload */ - camel_store_class->get_folder = get_folder; - camel_store_class->delete_folder = delete_folder; - camel_store_class->rename_folder = rename_folder; - camel_store_class->create_folder = create_folder; - - camel_store_class->get_folder_info = get_folder_info; - camel_store_class->free_folder_info = camel_store_free_folder_info_full; -} - -CamelType -camel_mbox_store_get_type (void) -{ - static CamelType camel_mbox_store_type = CAMEL_INVALID_TYPE; - - if (camel_mbox_store_type == CAMEL_INVALID_TYPE) { - camel_mbox_store_type = camel_type_register (CAMEL_LOCAL_STORE_TYPE, "CamelMboxStore", - sizeof (CamelMboxStore), - sizeof (CamelMboxStoreClass), - (CamelObjectClassInitFunc) camel_mbox_store_class_init, - NULL, - NULL, - NULL); - } - - return camel_mbox_store_type; -} - -static char * -mbox_folder_name_to_path (CamelStore *store, const char *folder_name) -{ - const char *toplevel_dir = CAMEL_LOCAL_STORE (store)->toplevel_dir; - - return camel_mbox_folder_get_full_path (toplevel_dir, folder_name); -} - -static char * -mbox_folder_name_to_meta_path (CamelStore *store, const char *folder_name, const char *ext) -{ - const char *toplevel_dir = CAMEL_LOCAL_STORE (store)->toplevel_dir; - - return camel_mbox_folder_get_meta_path (toplevel_dir, folder_name, ext); -} - -static char *extensions[] = { - ".msf", ".ev-summary", ".ibex.index", ".ibex.index.data", ".cmeta" -}; - -static gboolean -ignore_file (const char *filename, gboolean sbd) -{ - int flen, len, i; - - flen = strlen (filename); - for (i = 0; i < (sizeof (extensions) / sizeof (extensions[0])); i++) { - len = strlen (extensions[i]); - if (len < flen && !strcmp (filename + flen - len, extensions[i])) - return TRUE; - } - - if (sbd && flen > 4 && !strcmp (filename + flen - 4, ".sbd")) - return TRUE; - - return FALSE; -} - -static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) -{ - struct stat st; - char *name; - - if (!((CamelStoreClass *) parent_class)->get_folder (store, folder_name, flags, ex)) - return NULL; - - name = mbox_folder_name_to_path (store, folder_name); - - if (stat (name, &st) == -1) { - char *dirname; - int fd; - - if (errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open file `%s':\n%s"), - name, g_strerror (errno)); - g_free (name); - return NULL; - } - - if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Folder `%s' does not exist."), - folder_name); - g_free (name); - return NULL; - } - - dirname = g_path_get_dirname (name); - if (camel_mkdir (dirname, 0777) == -1 && errno != EEXIST) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Could not create directory `%s':\n%s"), - dirname, g_strerror (errno)); - g_free (dirname); - g_free (name); - return NULL; - } - - g_free (dirname); - - fd = open (name, O_WRONLY | O_CREAT | O_APPEND, 0666); - if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not create file `%s':\n%s"), - name, g_strerror (errno)); - g_free (name); - return NULL; - } - - g_free (name); - close (fd); - } else if (!S_ISREG (st.st_mode)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("`%s' is not a regular file."), - name); - g_free (name); - return NULL; - } else - g_free (name); - - return camel_mbox_folder_new (store, folder_name, flags, ex); -} - -static void -delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) -{ - CamelFolderInfo *fi; - CamelException lex; - CamelFolder *lf; - char *name, *path; - struct stat st; - - name = mbox_folder_name_to_path (store, folder_name); - path = g_strdup_printf ("%s.sbd", name); - - if (rmdir (path) == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s':\n%s"), - folder_name, g_strerror (errno)); - g_free (path); - g_free (name); - return; - } - - g_free (path); - - if (stat (name, &st) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s':\n%s"), - folder_name, g_strerror (errno)); - g_free (name); - return; - } - - if (!S_ISREG (st.st_mode)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("`%s' is not a regular file."), name); - g_free (name); - return; - } - - if (st.st_size != 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_NON_EMPTY, - _("Folder `%s' is not empty. Not deleted."), - folder_name); - g_free (name); - return; - } - - if (unlink (name) == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s':\n%s"), - name, g_strerror (errno)); - g_free (name); - return; - } - - /* FIXME: we have to do our own meta cleanup here rather than - * calling our parent class' delete_folder() method since our - * naming convention is different. Need to find a way for - * CamelLocalStore to be able to construct the folder & meta - * paths itself */ - path = mbox_folder_name_to_meta_path (store, folder_name, ".ev-summary"); - if (unlink (path) == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder summary file `%s': %s"), - path, g_strerror (errno)); - g_free (path); - g_free (name); - return; - } - - g_free (path); - - path = mbox_folder_name_to_meta_path (store, folder_name, ".ibex"); - if (camel_text_index_remove (path) == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder index file `%s': %s"), - path, g_strerror (errno)); - g_free (path); - g_free (name); - return; - } - - g_free (path); - - camel_exception_init (&lex); - if ((lf = camel_store_get_folder (store, folder_name, 0, &lex))) { - camel_object_get (lf, NULL, CAMEL_OBJECT_STATE_FILE, &path, NULL); - camel_object_set (lf, NULL, CAMEL_OBJECT_STATE_FILE, NULL, NULL); - camel_object_unref (lf); - } else { - camel_exception_clear (&lex); - } - - if (path == NULL) - path = mbox_folder_name_to_meta_path (store, folder_name, ".cmeta"); - - if (unlink (path) == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder meta file `%s': %s"), - path, g_strerror (errno)); - - g_free (path); - g_free (name); - return; - } - - g_free (path); - g_free (name); - - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = g_strdup (folder_name); - fi->name = g_path_get_basename (folder_name); - fi->url = g_strdup_printf ("mbox:%s#%s", ((CamelService *) store)->url->path, folder_name); - fi->unread_message_count = -1; - camel_folder_info_build_path (fi, '/'); - - camel_object_trigger_event (store, "folder_deleted", fi); - - camel_folder_info_free (fi); -} - -static CamelFolderInfo * -create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex) -{ - /* FIXME: this is almost an exact copy of CamelLocalStore::create_folder() except that we use - * different path schemes... need to find a way to share parent's code? */ - const char *toplevel_dir = ((CamelLocalStore *) store)->toplevel_dir; - CamelFolderInfo *info = NULL; - char *path, *name, *dir; - CamelFolder *folder; - struct stat st; - - if (toplevel_dir[0] != '/') { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Store root %s is not an absolute path"), toplevel_dir); - return NULL; - } - - if (folder_name[0] == '.' || ignore_file (folder_name, TRUE)) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot create a folder by this name.")); - return NULL; - } - - if (parent_name && *parent_name) - name = g_strdup_printf ("%s/%s", parent_name, folder_name); - else - name = g_strdup (folder_name); - - path = mbox_folder_name_to_path (store, name); - - dir = g_path_get_dirname (path); - if (camel_mkdir (dir, 0777) == -1 && errno != EEXIST) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create directory `%s': %s."), - dir, g_strerror (errno)); - - g_free (path); - g_free (name); - g_free (dir); - - return NULL; - } - - g_free (dir); - - if (stat (path, &st) == 0 || errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Cannot create folder: %s: %s"), - path, errno ? g_strerror (errno) : - _("Folder already exists")); - - g_free (path); - g_free (name); - - return NULL; - } - - g_free (path); - - folder = ((CamelStoreClass *) ((CamelObject *) store)->klass)->get_folder (store, name, CAMEL_STORE_FOLDER_CREATE, ex); - if (folder) { - camel_object_unref (folder); - info = ((CamelStoreClass *) ((CamelObject *) store)->klass)->get_folder_info (store, name, 0, ex); - } - - g_free (name); - - return info; -} - -static int -xrename (CamelStore *store, const char *old_name, const char *new_name, const char *ext, gboolean missingok, CamelException *ex) -{ - const char *toplevel_dir = ((CamelLocalStore *) store)->toplevel_dir; - char *oldpath, *newpath; - struct stat st; - int ret = -1; - int err = 0; - - if (ext != NULL) { - oldpath = camel_mbox_folder_get_meta_path (toplevel_dir, old_name, ext); - newpath = camel_mbox_folder_get_meta_path (toplevel_dir, new_name, ext); - } else { - oldpath = camel_mbox_folder_get_full_path (toplevel_dir, old_name); - newpath = camel_mbox_folder_get_full_path (toplevel_dir, new_name); - } - - if (stat (oldpath, &st) == -1) { - if (missingok && errno == ENOENT) { - ret = 0; - } else { - err = errno; - ret = -1; - } - } else if (S_ISDIR (st.st_mode)) { - /* use rename for dirs */ - if (rename (oldpath, newpath) == 0 || stat (newpath, &st) == 0) { - ret = 0; - } else { - err = errno; - ret = -1; - } - } else if (link (oldpath, newpath) == 0 /* and link for files */ - || (stat (newpath, &st) == 0 && st.st_nlink == 2)) { - if (unlink (oldpath) == 0) { - ret = 0; - } else { - err = errno; - unlink (newpath); - ret = -1; - } - } else { - err = errno; - ret = -1; - } - - if (ret == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename %s to %s: %s"), - oldpath, newpath, g_strerror (err)); - } - - g_free (oldpath); - g_free (newpath); - - return ret; -} - -static void -rename_folder (CamelStore *store, const char *old, const char *new, CamelException *ex) -{ - CamelLocalFolder *folder = NULL; - char *oldibex, *newibex; - - if (new[0] == '.' || ignore_file (new, TRUE)) { - printf ("exception: The new folder name is illegal.\n"); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("The new folder name is illegal.")); - return; - } - - /* try to rollback failures, has obvious races */ - - oldibex = mbox_folder_name_to_meta_path (store, old, ".ibex"); - newibex = mbox_folder_name_to_meta_path (store, new, ".ibex"); - - folder = camel_object_bag_get (store->folders, old); - if (folder && folder->index) { - if (camel_index_rename (folder->index, newibex) == -1) - goto ibex_failed; - } else { - /* TODO: camel_text_index_rename should find out if we have an active index itself? */ - if (camel_text_index_rename (oldibex, newibex) == -1) - goto ibex_failed; - } - - if (xrename (store, old, new, ".ev-summary", TRUE, ex)) - goto summary_failed; - - if (xrename (store, old, new, NULL, FALSE, ex)) - goto base_failed; - - g_free (oldibex); - g_free (newibex); - - if (folder) - camel_object_unref (folder); - - return; - - base_failed: - - xrename (store, new, old, ".ev-summary", TRUE, ex); - - summary_failed: - - if (folder) { - if (folder->index) - camel_index_rename (folder->index, oldibex); - } else - camel_text_index_rename (newibex, oldibex); - ibex_failed: - - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename '%s': %s"), - old, g_strerror (errno)); - - g_free (newibex); - g_free (oldibex); - - if (folder) - camel_object_unref (folder); -} - - -/* used to find out where we've visited already */ -struct _inode { - dev_t dnode; - ino_t inode; -}; - -static guint -inode_hash (const void *d) -{ - const struct _inode *v = d; - - return v->inode ^ v->dnode; -} - -static gboolean -inode_equal (const void *a, const void *b) -{ - const struct _inode *v1 = a, *v2 = b; - - return v1->inode == v2->inode && v1->dnode == v2->dnode; -} - -static void -inode_free (void *k, void *v, void *d) -{ - g_free (k); -} - -static CamelFolderInfo * -scan_dir (CamelStore *store, GHashTable *visited, CamelFolderInfo *parent, const char *root, - const char *name, guint32 flags, CamelException *ex) -{ - CamelFolderInfo *folders, *tail, *fi; - GHashTable *folder_hash; - struct dirent *dent; - DIR *dir; - - tail = folders = NULL; - - if (!(dir = opendir (root))) - return NULL; - - folder_hash = g_hash_table_new (g_str_hash, g_str_equal); - - /* FIXME: it would be better if we queue'd up the recursive - * scans till the end so that we can limit the number of - * directory descriptors open at any given time... */ - - while ((dent = readdir (dir))) { - char *short_name, *full_name, *path, *ext; - CamelFolder *folder; - struct stat st; - int unread = -1; - - if (dent->d_name[0] == '.') - continue; - - if (ignore_file (dent->d_name, FALSE)) - continue; - - path = g_strdup_printf ("%s/%s", root, dent->d_name); - if (stat (path, &st) == -1) { - g_free (path); - continue; - } - - if (S_ISDIR (st.st_mode)) { - struct _inode in = { st.st_dev, st.st_ino }; - - if (g_hash_table_lookup (visited, &in)) { - g_free (path); - continue; - } - } - - short_name = g_strdup (dent->d_name); - if ((ext = strrchr (short_name, '.')) && !strcmp (ext, ".sbd")) - *ext = '\0'; - - if (name != NULL) - full_name = g_strdup_printf ("%s/%s", name, short_name); - else - full_name = g_strdup (short_name); - - if (!S_ISDIR (st.st_mode)) { - folder = camel_object_bag_get (store->folders, full_name); - if (folder) { - if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info (folder, NULL); - unread = camel_folder_get_unread_message_count (folder); - camel_object_unref (folder); - } - } - - if ((fi = g_hash_table_lookup (folder_hash, short_name)) != NULL) { - g_free (short_name); - g_free (full_name); - - if (S_ISDIR (st.st_mode)) { - fi->flags = (fi->flags & ~CAMEL_FOLDER_NOINFERIORS) | CAMEL_FOLDER_CHILDREN; - } else { - fi->unread_message_count = unread; - fi->flags &= ~CAMEL_FOLDER_NOSELECT; - if ((ext = strchr (fi->url, ';')) && !strncmp (ext, ";noselect=yes", 13)) - memmove (ext, ext + 13, strlen (ext + 13) + 1); - } - } else { - fi = g_new0 (CamelFolderInfo, 1); - fi->parent = parent; - - /* add ";noselect=yes" if we haven't found the mbox file yet. when we find it, remove the noselect */ - fi->url = g_strdup_printf ("mbox:%s%s#%s", ((CamelService *) store)->url->path, - S_ISDIR (st.st_mode) ? ";noselect=yes" : "", full_name); - fi->name = short_name; - fi->full_name = full_name; - fi->path = g_strdup_printf ("/%s", full_name); - fi->unread_message_count = unread; - - if (S_ISDIR (st.st_mode)) - fi->flags = CAMEL_FOLDER_NOSELECT; - else - fi->flags = CAMEL_FOLDER_NOINFERIORS; - - if (tail == NULL) - folders = fi; - else - tail->sibling = fi; - - tail = fi; - - g_hash_table_insert (folder_hash, fi->name, fi); - } - - if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) && S_ISDIR (st.st_mode)) { - struct _inode in = { st.st_dev, st.st_ino }; - - if (g_hash_table_lookup (visited, &in) == NULL) { - struct _inode *inew = g_new (struct _inode, 1); - - *inew = in; - - g_hash_table_insert (visited, inew, inew); - - if ((fi->child = scan_dir (store, visited, fi, path, fi->full_name, flags, ex))) - fi->flags |= CAMEL_FOLDER_CHILDREN; - } - } - - g_free (path); - } - - closedir (dir); - - g_hash_table_destroy (folder_hash); - - return folders; -} - -static CamelFolderInfo * -get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex) -{ - GHashTable *visited; - struct _inode *inode; - char *path, *subdir; - CamelFolderInfo *fi; - CamelFolder *folder; - const char *base; - struct stat st; - int unread = -1; - - top = top ? top : ""; - path = mbox_folder_name_to_path (store, top); - - if (*top == '\0') { - /* requesting root dir scan */ - if (stat (path, &st) == -1 || !S_ISDIR (st.st_mode)) { - g_free (path); - return NULL; - } - - visited = g_hash_table_new (inode_hash, inode_equal); - - inode = g_new (struct _inode, 1); - inode->dnode = st.st_dev; - inode->inode = st.st_ino; - - g_hash_table_insert (visited, inode, inode); - - fi = scan_dir (store, visited, NULL, path, NULL, flags, ex); - g_hash_table_foreach (visited, inode_free, NULL); - g_hash_table_destroy (visited); - g_free (path); - - return fi; - } - - /* requesting scan of specific folder */ - if (stat (path, &st) == -1 || !S_ISREG (st.st_mode)) { - g_free (path); - return NULL; - } - - visited = g_hash_table_new (inode_hash, inode_equal); - - if (!(base = strrchr (top, '/'))) - base = top; - else - base++; - - folder = camel_object_bag_get (store->folders, top); - if (folder) { - if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info (folder, NULL); - unread = camel_folder_get_unread_message_count (folder); - camel_object_unref (folder); - } - - fi = g_new0 (CamelFolderInfo, 1); - fi->parent = NULL; - fi->url = g_strdup_printf ("mbox:%s#%s", ((CamelService *) store)->url->path, top); - fi->name = g_strdup (base); - fi->full_name = g_strdup (top); - fi->unread_message_count = unread; - fi->path = g_strdup_printf ("/%s", top); - - subdir = g_strdup_printf ("%s.sbd", path); - if (stat (subdir, &st) == 0 && S_ISDIR (st.st_mode)) - fi->child = scan_dir (store, visited, fi, subdir, top, flags, ex); - - if (fi->child) - fi->flags |= CAMEL_FOLDER_CHILDREN; - else - fi->flags |= CAMEL_FOLDER_NOINFERIORS; - - g_free (subdir); - - g_hash_table_foreach (visited, inode_free, NULL); - g_hash_table_destroy (visited); - g_free (path); - - return fi; -} diff --git a/camel/providers/local/camel-mbox-store.h b/camel/providers/local/camel-mbox-store.h deleted file mode 100644 index 5b6fbdd926..0000000000 --- a/camel/providers/local/camel-mbox-store.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_MBOX_STORE_H -#define CAMEL_MBOX_STORE_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-local-store.h" - -#define CAMEL_MBOX_STORE_TYPE (camel_mbox_store_get_type ()) -#define CAMEL_MBOX_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MBOX_STORE_TYPE, CamelMboxStore)) -#define CAMEL_MBOX_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MBOX_STORE_TYPE, CamelMboxStoreClass)) -#define CAMEL_IS_MBOX_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_MBOX_STORE_TYPE)) - -typedef struct { - CamelLocalStore parent_object; - -} CamelMboxStore; - -typedef struct { - CamelLocalStoreClass parent_class; - -} CamelMboxStoreClass; - -/* public methods */ - -/* Standard Camel function */ -CamelType camel_mbox_store_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_MBOX_STORE_H */ - - diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c deleted file mode 100644 index 4018fc93c9..0000000000 --- a/camel/providers/local/camel-mbox-summary.c +++ /dev/null @@ -1,1029 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- - * - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "camel-mbox-summary.h" -#include "camel/camel-mime-message.h" -#include "camel/camel-operation.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include "camel-mbox-summary.h" -#include "camel/camel-file-utils.h" -#include "camel/camel-mime-message.h" -#include "camel/camel-operation.h" - -#define io(x) -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -#define CAMEL_MBOX_SUMMARY_VERSION (0x1000) - -static int summary_header_load (CamelFolderSummary *, FILE *); -static int summary_header_save (CamelFolderSummary *, FILE *); - -static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *); -static CamelMessageInfo * message_info_new_from_parser (CamelFolderSummary *, CamelMimeParser *); -static CamelMessageInfo * message_info_load (CamelFolderSummary *, FILE *); -static int message_info_save (CamelFolderSummary *, FILE *, CamelMessageInfo *); -/*static void message_info_free (CamelFolderSummary *, CamelMessageInfo *);*/ - -static int mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); -static int mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); -#ifdef STATUS_PINE -static CamelMessageInfo *mbox_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex); -#endif - -static int mbox_summary_sync_quick(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); -static int mbox_summary_sync_full(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); - -static void camel_mbox_summary_class_init (CamelMboxSummaryClass *klass); -static void camel_mbox_summary_init (CamelMboxSummary *obj); -static void camel_mbox_summary_finalise (CamelObject *obj); - -#ifdef STATUS_PINE -/* Which status flags are stored in each separate header */ -#define STATUS_XSTATUS (CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED) -#define STATUS_STATUS (CAMEL_MESSAGE_SEEN) - -static void encode_status(guint32 flags, char status[8]); -static guint32 decode_status(const char *status); -#endif - -static CamelLocalSummaryClass *camel_mbox_summary_parent; - -CamelType -camel_mbox_summary_get_type(void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register(camel_local_summary_get_type(), "CamelMboxSummary", - sizeof (CamelMboxSummary), - sizeof (CamelMboxSummaryClass), - (CamelObjectClassInitFunc) camel_mbox_summary_class_init, - NULL, - (CamelObjectInitFunc) camel_mbox_summary_init, - (CamelObjectFinalizeFunc) camel_mbox_summary_finalise); - } - - return type; -} - -static void -camel_mbox_summary_class_init(CamelMboxSummaryClass *klass) -{ - CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *)klass; - CamelLocalSummaryClass *lklass = (CamelLocalSummaryClass *)klass; - - camel_mbox_summary_parent = (CamelLocalSummaryClass *)camel_type_get_global_classfuncs(camel_local_summary_get_type()); - - sklass->summary_header_load = summary_header_load; - sklass->summary_header_save = summary_header_save; - - sklass->message_info_new = message_info_new; - sklass->message_info_new_from_parser = message_info_new_from_parser; - sklass->message_info_load = message_info_load; - sklass->message_info_save = message_info_save; - /*sklass->message_info_free = message_info_free;*/ - - lklass->check = mbox_summary_check; - lklass->sync = mbox_summary_sync; -#ifdef STATUS_PINE - lklass->add = mbox_summary_add; -#endif - - klass->sync_quick = mbox_summary_sync_quick; - klass->sync_full = mbox_summary_sync_full; -} - -static void -camel_mbox_summary_init(CamelMboxSummary *obj) -{ - struct _CamelFolderSummary *s = (CamelFolderSummary *)obj; - - /* subclasses need to set the right instance data sizes */ - s->message_info_size = sizeof(CamelMboxMessageInfo); - s->content_info_size = sizeof(CamelMboxMessageContentInfo); - - /* and a unique file version */ - s->version += CAMEL_MBOX_SUMMARY_VERSION; -} - -static void -camel_mbox_summary_finalise(CamelObject *obj) -{ - /*CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(obj);*/ -} - -/** - * camel_mbox_summary_new: - * - * Create a new CamelMboxSummary object. - * - * Return value: A new CamelMboxSummary widget. - **/ -CamelMboxSummary * -camel_mbox_summary_new(const char *filename, const char *mbox_name, CamelIndex *index) -{ - CamelMboxSummary *new = (CamelMboxSummary *)camel_object_new(camel_mbox_summary_get_type()); - - camel_local_summary_construct((CamelLocalSummary *)new, filename, mbox_name, index); - return new; -} - -void camel_mbox_summary_xstatus(CamelMboxSummary *mbs, int state) -{ - mbs->xstatus = state; -} - -static int -summary_header_load(CamelFolderSummary *s, FILE *in) -{ - CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s); - - if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_load(s, in) == -1) - return -1; - - return camel_file_util_decode_uint32(in, (guint32 *) &mbs->folder_size); -} - -static int -summary_header_save(CamelFolderSummary *s, FILE *out) -{ - CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s); - - if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_save(s, out) == -1) - return -1; - - return camel_file_util_encode_uint32(out, mbs->folder_size); -} - -static CamelMessageInfo * -message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) -{ - CamelMessageInfo *mi; - CamelMboxSummary *mbs = (CamelMboxSummary *)s; - - mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new(s, h); - if (mi) { - CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi; - const char *xev, *uid; - CamelMessageInfo *info = NULL; - int add = 0; /* bitmask of things to add, 1 assign uid, 2, just add as new, 4 = recent */ -#ifdef STATUS_PINE - const char *status = NULL, *xstatus = NULL; - guint32 flags = 0; - - if (mbs->xstatus) { - /* check for existance of status & x-status headers */ - status = camel_header_raw_find(&h, "Status", NULL); - if (status) - flags = decode_status(status); - xstatus = camel_header_raw_find(&h, "X-Status", NULL); - if (xstatus) - flags |= decode_status(xstatus); - } -#endif - /* if we have an xev header, use it, else assign a new one */ - xev = camel_header_raw_find(&h, "X-Evolution", NULL); - if (xev != NULL - && camel_local_summary_decode_x_evolution((CamelLocalSummary *)s, xev, mi) == 0) { - uid = camel_message_info_uid(mi); - d(printf("found valid x-evolution: %s\n", uid)); - info = camel_folder_summary_uid(s, uid); - if (info) { - if ((info->flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) { - info->flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN; - camel_folder_summary_info_free(s, mi); - mbi = (CamelMboxMessageInfo *)mi = info; - } else { - add = 7; - d(printf("seen '%s' before, adding anew\n", uid)); - camel_folder_summary_info_free(s, info); - } - } else { - add = 2; - d(printf("but isn't present in summary\n")); - } - } else { - d(printf("didn't find x-evolution\n")); - add = 7; - } - - if (add&1) { - mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV; - camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s)); - } else { - camel_folder_summary_set_uid(s, strtoul(camel_message_info_uid(mi), NULL, 10)); - } -#ifdef STATUS_PINE - if (mbs->xstatus && add&2) { - /* use the status as the flags when we read it the first time */ - if (status) - mi->flags = (mi->flags & ~(STATUS_STATUS)) | (flags & STATUS_STATUS); - if (xstatus) - mi->flags = (mi->flags & ~(STATUS_XSTATUS)) | (flags & STATUS_XSTATUS); - } -#endif - if (mbs->changes) { - if (add&2) - camel_folder_change_info_add_uid(mbs->changes, camel_message_info_uid(mi)); - if ((add&4) && status == NULL) - camel_folder_change_info_recent_uid(mbs->changes, camel_message_info_uid(mi)); - } - - mbi->frompos = -1; - } - - return mi; -} - -static CamelMessageInfo * -message_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp) -{ - CamelMessageInfo *mi; - - mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new_from_parser(s, mp); - if (mi) { - CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi; - - mbi->frompos = camel_mime_parser_tell_start_from(mp); - } - - return mi; -} - -static CamelMessageInfo * -message_info_load(CamelFolderSummary *s, FILE *in) -{ - CamelMessageInfo *mi; - - io(printf("loading mbox message info\n")); - - mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_load(s, in); - if (mi) { - CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi; - - if (camel_file_util_decode_off_t(in, &mbi->frompos) == -1) - goto error; - } - - return mi; -error: - camel_folder_summary_info_free(s, mi); - return NULL; -} - -static int -message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi) -{ - CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi; - - io(printf("saving mbox message info\n")); - - if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_save(s, out, mi) == -1 - || camel_file_util_encode_off_t(out, mbi->frompos) == -1) - return -1; - - return 0; -} - -/* like summary_rebuild, but also do changeinfo stuff (if supplied) */ -static int -summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - int i, count; - CamelFolderSummary *s = (CamelFolderSummary *)cls; - CamelMboxSummary *mbs = (CamelMboxSummary *)cls; - CamelMimeParser *mp; - CamelMessageInfo *mi; - int fd; - int ok = 0; - struct stat st; - off_t size = 0; - - d(printf("Calling summary update, from pos %d\n", (int)offset)); - - cls->index_force = FALSE; - - camel_operation_start(NULL, _("Storing folder")); - - fd = open(cls->folder_path, O_RDONLY); - if (fd == -1) { - d(printf("%s failed to open: %s\n", cls->folder_path, strerror (errno))); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open folder: %s: %s"), - cls->folder_path, g_strerror (errno)); - camel_operation_end(NULL); - return -1; - } - - if (fstat(fd, &st) == 0) - size = st.st_size; - - mp = camel_mime_parser_new(); - camel_mime_parser_init_with_fd(mp, fd); - camel_mime_parser_scan_from(mp, TRUE); - camel_mime_parser_seek(mp, offset, SEEK_SET); - - if (offset > 0) { - if (camel_mime_parser_step(mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM - && camel_mime_parser_tell_start_from(mp) == offset) { - camel_mime_parser_unstep(mp); - } else { - g_warning("The next message didn't start where I expected, building summary from start"); - camel_mime_parser_drop_step(mp); - offset = 0; - camel_mime_parser_seek(mp, offset, SEEK_SET); - } - } - - /* we mark messages as to whether we've seen them or not. - If we're not starting from the start, we must be starting - from the old end, so everything must be treated as new */ - count = camel_folder_summary_count(s); - for (i=0;i<count;i++) { - mi = camel_folder_summary_index(s, i); - if (offset == 0) - mi->flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN; - else - mi->flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN; - camel_folder_summary_info_free(s, mi); - } - mbs->changes = changeinfo; - - while (camel_mime_parser_step(mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) { - CamelMessageInfo *info; - off_t pc = camel_mime_parser_tell_start_from (mp) + 1; - - camel_operation_progress (NULL, (int) (((float) pc / size) * 100)); - - info = camel_folder_summary_add_from_parser(s, mp); - if (info == NULL) { - camel_exception_setv(ex, 1, _("Fatal mail parser error near position %ld in folder %s"), - camel_mime_parser_tell(mp), cls->folder_path); - ok = -1; - break; - } - - g_assert(camel_mime_parser_step(mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM_END); - } - - camel_object_unref(CAMEL_OBJECT (mp)); - - count = camel_folder_summary_count(s); - for (i=0;i<count;i++) { - mi = camel_folder_summary_index(s, i); - /* must've dissapeared from the file? */ - if (mi->flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) { - d(printf("uid '%s' vanished, removing", camel_message_info_uid(mi))); - if (changeinfo) - camel_folder_change_info_remove_uid(changeinfo, camel_message_info_uid(mi)); - camel_folder_summary_remove(s, mi); - count--; - i--; - } - camel_folder_summary_info_free(s, mi); - } - mbs->changes = NULL; - - /* update the file size/mtime in the summary */ - if (ok != -1) { - if (stat(cls->folder_path, &st) == 0) { - camel_folder_summary_touch(s); - mbs->folder_size = st.st_size; - s->time = st.st_mtime; - } - } - - camel_operation_end(NULL); - - return ok; -} - -static int -mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, CamelException *ex) -{ - CamelMboxSummary *mbs = (CamelMboxSummary *)cls; - CamelFolderSummary *s = (CamelFolderSummary *)cls; - struct stat st; - int ret = 0; - int i, count; - - d(printf("Checking summary\n")); - - /* check if the summary is up-to-date */ - if (stat(cls->folder_path, &st) == -1) { - camel_folder_summary_clear(s); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot check folder: %s: %s"), - cls->folder_path, g_strerror (errno)); - return -1; - } - - if (cls->check_force) - mbs->folder_size = 0; - cls->check_force = 0; - - if (st.st_size == 0) { - /* empty? No need to scan at all */ - d(printf("Empty mbox, clearing summary\n")); - count= camel_folder_summary_count(s); - for (i=0;i<count;i++) { - CamelMessageInfo *info = camel_folder_summary_index(s, i); - - if (info) { - camel_folder_change_info_remove_uid(changes, camel_message_info_uid(info)); - camel_folder_summary_info_free(s, info); - } - } - camel_folder_summary_clear(s); - ret = 0; - } else { - /* is the summary uptodate? */ - if (st.st_size != mbs->folder_size || st.st_mtime != s->time) { - if (mbs->folder_size < st.st_size) { - /* this will automatically rescan from 0 if there is a problem */ - d(printf("folder grew, attempting to rebuild from %d\n", mbs->folder_size)); - ret = summary_update(cls, mbs->folder_size, changes, ex); - } else { - d(printf("folder shrank! rebuilding from start\n")); - ret = summary_update(cls, 0, changes, ex); - } - } else { - d(printf("Folder unchanged, do nothing\n")); - } - } - - /* FIXME: move upstream? */ - - if (ret != -1) { - if (mbs->folder_size != st.st_size || s->time != st.st_mtime) { - mbs->folder_size = st.st_size; - s->time = st.st_mtime; - camel_folder_summary_touch(s); - } - } - - return ret; -} - -/* perform a full sync */ -static int -mbox_summary_sync_full(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - CamelLocalSummary *cls = (CamelLocalSummary *)mbs; - int fd = -1, fdout = -1; - char *tmpname = NULL; - guint32 flags = (expunge?1:0); - - d(printf("performing full summary/sync\n")); - - camel_operation_start(NULL, _("Storing folder")); - - fd = open(cls->folder_path, O_RDONLY); - if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open file: %s: %s"), - cls->folder_path, g_strerror (errno)); - camel_operation_end(NULL); - return -1; - } - - tmpname = g_alloca (strlen (cls->folder_path) + 5); - sprintf (tmpname, "%s.tmp", cls->folder_path); - d(printf("Writing tmp file to %s\n", tmpname)); - fdout = open(tmpname, O_WRONLY|O_CREAT|O_TRUNC, 0600); - if (fdout == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot open temporary mailbox: %s"), - g_strerror (errno)); - goto error; - } - - if (camel_mbox_summary_sync_mbox((CamelMboxSummary *)cls, flags, changeinfo, fd, fdout, ex) == -1) - goto error; - - d(printf("Closing folders\n")); - - if (close(fd) == -1) { - g_warning("Cannot close source folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not close source folder %s: %s"), - cls->folder_path, g_strerror (errno)); - fd = -1; - goto error; - } - - if (close(fdout) == -1) { - g_warning("Cannot close tmp folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not close temp folder: %s"), - g_strerror (errno)); - fdout = -1; - goto error; - } - - /* this should probably either use unlink/link/unlink, or recopy over - the original mailbox, for various locking reasons/etc */ - if (rename(tmpname, cls->folder_path) == -1) { - g_warning("Cannot rename folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename folder: %s"), - g_strerror (errno)); - goto error; - } - tmpname = NULL; - - camel_operation_end(NULL); - - return 0; - error: - if (fd != -1) - close(fd); - - if (fdout != -1) - close(fdout); - - if (tmpname) - unlink(tmpname); - - camel_operation_end(NULL); - - return -1; -} - -/* perform a quick sync - only system flags have changed */ -static int -mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - CamelLocalSummary *cls = (CamelLocalSummary *)mbs; - CamelFolderSummary *s = (CamelFolderSummary *)mbs; - CamelMimeParser *mp = NULL; - int i, count; - CamelMboxMessageInfo *info = NULL; - int fd = -1; - char *xevnew, *xevtmp; - const char *xev; - int len; - off_t lastpos; - - d(printf("Performing quick summary sync\n")); - - camel_operation_start(NULL, _("Storing folder")); - - fd = open(cls->folder_path, O_RDWR); - if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open file: %s: %s"), - cls->folder_path, g_strerror (errno)); - - camel_operation_end(NULL); - return -1; - } - - mp = camel_mime_parser_new(); - camel_mime_parser_scan_from(mp, TRUE); - camel_mime_parser_scan_pre_from(mp, TRUE); - camel_mime_parser_init_with_fd(mp, fd); - - count = camel_folder_summary_count(s); - for (i = 0; i < count; i++) { - int xevoffset; - int pc = (i+1)*100/count; - - camel_operation_progress(NULL, pc); - - info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i); - - g_assert(info); - - d(printf("Checking message %s %08x\n", camel_message_info_uid(info), info->info.flags)); - - if ((info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) { - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); - info = NULL; - continue; - } - - d(printf("Updating message %s\n", camel_message_info_uid(info))); - - camel_mime_parser_seek(mp, info->frompos, SEEK_SET); - - if (camel_mime_parser_step(mp, 0, 0) != CAMEL_MIME_PARSER_STATE_FROM) { - g_warning("Expected a From line here, didn't get it"); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Summary and folder mismatch, even after a sync")); - goto error; - } - - if (camel_mime_parser_tell_start_from(mp) != info->frompos) { - g_warning("Didn't get the next message where I expected (%d) got %d instead", - (int)info->frompos, (int)camel_mime_parser_tell_start_from(mp)); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Summary and folder mismatch, even after a sync")); - goto error; - } - - if (camel_mime_parser_step(mp, 0, 0) == CAMEL_MIME_PARSER_STATE_FROM_END) { - g_warning("camel_mime_parser_step failed (2)"); - goto error; - } - - xev = camel_mime_parser_header(mp, "X-Evolution", &xevoffset); - if (xev == NULL || camel_local_summary_decode_x_evolution(cls, xev, NULL) == -1) { - g_warning("We're supposed to have a valid x-ev header, but we dont"); - goto error; - } - xevnew = camel_local_summary_encode_x_evolution(cls, (CamelMessageInfo *)info); - /* SIGH: encode_param_list is about the only function which folds headers by itself. - This should be fixed somehow differently (either parser doesn't fold headers, - or param_list doesn't, or something */ - xevtmp = camel_header_unfold(xevnew); - /* the raw header contains a leading ' ', so (dis)count that too */ - if (strlen(xev)-1 != strlen(xevtmp)) { - printf ("strlen(xev)-1 = %d; strlen(xevtmp) = %d\n", strlen(xev)-1, strlen(xevtmp)); - printf ("xev='%s'; xevtmp='%s'\n", xev, xevtmp); - g_free(xevnew); - g_free(xevtmp); - g_warning("Hmm, the xev headers shouldn't have changed size, but they did"); - goto error; - } - g_free(xevtmp); - - /* we write out the xevnew string, assuming its been folded identically to the original too! */ - - lastpos = lseek(fd, 0, SEEK_CUR); - lseek(fd, xevoffset+strlen("X-Evolution: "), SEEK_SET); - do { - len = write(fd, xevnew, strlen(xevnew)); - } while (len == -1 && errno == EINTR); - lseek(fd, lastpos, SEEK_SET); - g_free(xevnew); - - camel_mime_parser_drop_step(mp); - camel_mime_parser_drop_step(mp); - - info->info.flags &= 0xffff; - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); - } - - d(printf("Closing folders\n")); - - if (close(fd) == -1) { - g_warning ("Cannot close source folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not close source folder %s: %s"), - cls->folder_path, g_strerror (errno)); - fd = -1; - goto error; - } - - camel_object_unref((CamelObject *)mp); - - camel_operation_end(NULL); - - return 0; - error: - if (fd != -1) - close(fd); - if (mp) - camel_object_unref((CamelObject *)mp); - if (info) - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); - - camel_operation_end(NULL); - - return -1; -} - -static int -mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - struct stat st; - CamelMboxSummary *mbs = (CamelMboxSummary *)cls; - CamelFolderSummary *s = (CamelFolderSummary *)cls; - int i, count; - int quick = TRUE, work=FALSE; - int ret; - - /* first, sync ourselves up, just to make sure */ - if (camel_local_summary_check(cls, changeinfo, ex) == -1) - return -1; - - count = camel_folder_summary_count(s); - if (count == 0) - return 0; - - /* check what work we have to do, if any */ - for (i=0;quick && i<count; i++) { - CamelMessageInfo *info = camel_folder_summary_index(s, i); - g_assert(info); - if ((expunge && (info->flags & CAMEL_MESSAGE_DELETED)) || - (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_XEVCHANGE))) - quick = FALSE; - else - work |= (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0; - camel_folder_summary_info_free(s, info); - } - - /* yuck i hate this logic, but its to simplify the 'all ok, update summary' and failover cases */ - ret = -1; - if (quick) { - if (work) { - ret = ((CamelMboxSummaryClass *)((CamelObject *)cls)->klass)->sync_quick(mbs, expunge, changeinfo, ex); - if (ret == -1) { - g_warning("failed a quick-sync, trying a full sync"); - camel_exception_clear(ex); - } - } else { - ret = 0; - } - } - - if (ret == -1) - ret = ((CamelMboxSummaryClass *)((CamelObject *)cls)->klass)->sync_full(mbs, expunge, changeinfo, ex); - if (ret == -1) - return -1; - - if (stat(cls->folder_path, &st) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Unknown error: %s"), g_strerror (errno)); - return -1; - } - - if (mbs->folder_size != st.st_size || s->time != st.st_mtime) { - s->time = st.st_mtime; - mbs->folder_size = st.st_size; - camel_folder_summary_touch(s); - } - - return ((CamelLocalSummaryClass *)camel_mbox_summary_parent)->sync(cls, expunge, changeinfo, ex); -} - -int -camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderChangeInfo *changeinfo, int fd, int fdout, CamelException *ex) -{ - CamelMboxSummary *mbs = (CamelMboxSummary *)cls; - CamelFolderSummary *s = (CamelFolderSummary *)mbs; - CamelMimeParser *mp = NULL; - int i, count; - CamelMboxMessageInfo *info = NULL; - char *buffer, *xevnew = NULL; - size_t len; - const char *fromline; - int lastdel = FALSE; -#ifdef STATUS_PINE - char statnew[8], xstatnew[8]; -#endif - - d(printf("performing full summary/sync\n")); - - /* need to dup this because the mime-parser owns the fd after we give it to it */ - fd = dup(fd); - if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not store folder: %s"), - g_strerror (errno)); - return -1; - } - - mp = camel_mime_parser_new(); - camel_mime_parser_scan_from(mp, TRUE); - camel_mime_parser_scan_pre_from(mp, TRUE); - camel_mime_parser_init_with_fd(mp, fd); - - count = camel_folder_summary_count(s); - for (i = 0; i < count; i++) { - int pc = (i + 1) * 100 / count; - - camel_operation_progress(NULL, pc); - - info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i); - - g_assert(info); - - d(printf("Looking at message %s\n", camel_message_info_uid(info))); - - /* only need to seek past deleted messages, otherwise we should be at the right spot/state already */ - if (lastdel) { - d(printf("seeking to %d\n", (int)info->frompos)); - camel_mime_parser_seek(mp, info->frompos, SEEK_SET); - } - - if (camel_mime_parser_step(mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_FROM) { - g_warning("Expected a From line here, didn't get it"); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Summary and folder mismatch, even after a sync")); - goto error; - } - - if (camel_mime_parser_tell_start_from(mp) != info->frompos) { - g_warning("Didn't get the next message where I expected (%d) got %d instead", - (int)info->frompos, (int)camel_mime_parser_tell_start_from(mp)); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Summary and folder mismatch, even after a sync")); - goto error; - } - - lastdel = FALSE; - if ((flags&1) && info->info.flags & CAMEL_MESSAGE_DELETED) { - const char *uid = camel_message_info_uid(info); - - d(printf("Deleting %s\n", uid)); - - if (((CamelLocalSummary *)cls)->index) - camel_index_delete_name(((CamelLocalSummary *)cls)->index, uid); - - /* remove it from the change list */ - camel_folder_change_info_remove_uid(changeinfo, uid); - camel_folder_summary_remove(s, (CamelMessageInfo *)info); - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); - count--; - i--; - info = NULL; - lastdel = TRUE; - } else { - /* otherwise, the message is staying, copy its From_ line across */ -#if 0 - if (i>0) - write(fdout, "\n", 1); -#endif - info->frompos = lseek(fdout, 0, SEEK_CUR); - fromline = camel_mime_parser_from_line(mp); - write(fdout, fromline, strlen(fromline)); - } - - if (info && info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) { - d(printf("Updating header for %s flags = %08x\n", camel_message_info_uid(info), info->info.flags)); - - if (camel_mime_parser_step(mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_FROM_END) { - g_warning("camel_mime_parser_step failed (2)"); - goto error; - } - - xevnew = camel_local_summary_encode_x_evolution((CamelLocalSummary *)cls, (CamelMessageInfo *)info); -#ifdef STATUS_PINE - if (mbs->xstatus) { - encode_status(((CamelMessageInfo *)info)->flags & STATUS_STATUS, statnew); - encode_status(((CamelMessageInfo *)info)->flags & STATUS_XSTATUS, xstatnew); - len = camel_local_summary_write_headers(fdout, camel_mime_parser_headers_raw(mp), xevnew, statnew, xstatnew); - } else { -#endif - len = camel_local_summary_write_headers(fdout, camel_mime_parser_headers_raw(mp), xevnew, NULL, NULL); -#ifdef STATUS_PINE - } -#endif - if (len == -1) { - d(printf("Error writing to tmp mailbox\n")); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Error writing to temp mailbox: %s"), - g_strerror (errno)); - goto error; - } - info->info.flags &= 0xffff; - g_free(xevnew); - xevnew = NULL; - camel_mime_parser_drop_step(mp); - } - - camel_mime_parser_drop_step(mp); - if (info) { - d(printf("looking for message content to copy across from %d\n", (int)camel_mime_parser_tell(mp))); - while (camel_mime_parser_step(mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_PRE_FROM) { - /*d(printf("copying mbox contents to tmp: '%.*s'\n", len, buffer));*/ - if (write(fdout, buffer, len) != len) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Writing to tmp mailbox failed: %s: %s"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno)); - goto error; - } - } - - if (write(fdout, "\n", 1) != 1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Error writing to temp mailbox: %s"), - g_strerror (errno)); - goto error; - } - - d(printf("we are now at %d, from = %d\n", (int)camel_mime_parser_tell(mp), - (int)camel_mime_parser_tell_start_from(mp))); - camel_mime_parser_unstep(mp); - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); - info = NULL; - } - } - -#if 0 - /* if last was deleted, append the \n we removed */ - if (lastdel && count > 0) - write(fdout, "\n", 1); -#endif - - camel_object_unref((CamelObject *)mp); - - return 0; - error: - g_free(xevnew); - - if (mp) - camel_object_unref((CamelObject *)mp); - if (info) - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); - - return -1; -} - -#ifdef STATUS_PINE -static CamelMessageInfo * -mbox_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex) -{ - CamelMessageInfo *mi; - - mi = ((CamelLocalSummaryClass *)camel_mbox_summary_parent)->add(cls, msg, info, ci, ex); - if (mi && ((CamelMboxSummary *)cls)->xstatus) { - char status[8]; - - /* we snoop and add status/x-status headers to suit */ - encode_status(mi->flags & STATUS_STATUS, status); - camel_medium_set_header((CamelMedium *)msg, "Status", status); - encode_status(mi->flags & STATUS_XSTATUS, status); - camel_medium_set_header((CamelMedium *)msg, "X-Status", status); - } - - return mi; -} - -static struct { - char tag; - guint32 flag; -} status_flags[] = { - { 'F', CAMEL_MESSAGE_FLAGGED }, - { 'A', CAMEL_MESSAGE_ANSWERED }, - { 'D', CAMEL_MESSAGE_DELETED }, - { 'R', CAMEL_MESSAGE_SEEN }, -}; - -static void -encode_status(guint32 flags, char status[8]) -{ - char *p; - int i; - - p = status; - for (i=0;i<sizeof(status_flags)/sizeof(status_flags[0]);i++) - if (status_flags[i].flag & flags) - *p++ = status_flags[i].tag; - *p++ = 'O'; - *p=0; -} - -static guint32 -decode_status(const char *status) -{ - const char *p; - char c; - guint32 flags = 0; - int i; - - p = status; - while ((c = *p++)) { - for (i=0;i<sizeof(status_flags)/sizeof(status_flags[0]);i++) - if (status_flags[i].tag == *p) - flags |= status_flags[i].flag; - } - - return flags; -} - -#endif /* STATUS_PINE */ diff --git a/camel/providers/local/camel-mbox-summary.h b/camel/providers/local/camel-mbox-summary.h deleted file mode 100644 index dc64aa23fa..0000000000 --- a/camel/providers/local/camel-mbox-summary.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _CAMEL_MBOX_SUMMARY_H -#define _CAMEL_MBOX_SUMMARY_H - -#include "camel-local-summary.h" - -/* Enable the use of elm/pine style "Status" & "X-Status" headers */ -#define STATUS_PINE - -#define CAMEL_MBOX_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_mbox_summary_get_type (), CamelMboxSummary) -#define CAMEL_MBOX_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_mbox_summary_get_type (), CamelMboxSummaryClass) -#define CAMEL_IS_MBOX_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_mbox_summary_get_type ()) - -typedef struct _CamelMboxSummary CamelMboxSummary; -typedef struct _CamelMboxSummaryClass CamelMboxSummaryClass; - -typedef struct _CamelMboxMessageContentInfo { - CamelMessageContentInfo info; -} CamelMboxMessageContentInfo; - -typedef struct _CamelMboxMessageInfo { - CamelMessageInfo info; - - off_t frompos; -} CamelMboxMessageInfo; - -struct _CamelMboxSummary { - CamelLocalSummary parent; - - CamelFolderChangeInfo *changes; /* used to build change sets */ - - size_t folder_size; /* size of the mbox file, last sync */ - - unsigned int xstatus:1; /* do we store/honour xstatus/status headers */ -}; - -struct _CamelMboxSummaryClass { - CamelLocalSummaryClass parent_class; - - /* sync in-place */ - int (*sync_quick)(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); - /* sync requires copy */ - int (*sync_full)(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); -}; - -CamelType camel_mbox_summary_get_type (void); -CamelMboxSummary *camel_mbox_summary_new (const char *filename, const char *mbox_name, CamelIndex *index); - -/* do we honour/use xstatus headers, etc */ -void camel_mbox_summary_xstatus(CamelMboxSummary *mbs, int state); - -/* build a new mbox from an existing mbox storing summary information */ -int camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderChangeInfo *changeinfo, int fd, int fdout, CamelException *ex); - -#endif /* ! _CAMEL_MBOX_SUMMARY_H */ - diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c deleted file mode 100644 index 25dbacc49a..0000000000 --- a/camel/providers/local/camel-mh-folder.c +++ /dev/null @@ -1,231 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999, 2003 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <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-mh-folder.h" -#include "camel-mh-store.h" -#include "camel-stream-fs.h" -#include "camel-mh-summary.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-exception.h" - -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -static CamelLocalFolderClass *parent_class = NULL; - -/* Returns the class for a CamelMhFolder */ -#define CMHF_CLASS(so) CAMEL_MH_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CMHS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static CamelLocalSummary *mh_create_summary(const char *path, const char *folder, CamelIndex *index); - -static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex); -static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex); - -static void mh_finalize(CamelObject * object); - -static void camel_mh_folder_class_init(CamelObjectClass * camel_mh_folder_class) -{ - CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_mh_folder_class); - CamelLocalFolderClass *lclass = (CamelLocalFolderClass *)camel_mh_folder_class; - - parent_class = CAMEL_LOCAL_FOLDER_CLASS (camel_type_get_global_classfuncs(camel_local_folder_get_type())); - - /* virtual method definition */ - - /* virtual method overload */ - camel_folder_class->append_message = mh_append_message; - camel_folder_class->get_message = mh_get_message; - - lclass->create_summary = mh_create_summary; -} - -static void mh_init(gpointer object, gpointer klass) -{ - /*CamelFolder *folder = object; - CamelMhFolder *mh_folder = object;*/ -} - -static void mh_finalize(CamelObject * object) -{ - /*CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(object);*/ -} - -CamelType camel_mh_folder_get_type(void) -{ - static CamelType camel_mh_folder_type = CAMEL_INVALID_TYPE; - - if (camel_mh_folder_type == CAMEL_INVALID_TYPE) { - camel_mh_folder_type = camel_type_register(CAMEL_LOCAL_FOLDER_TYPE, "CamelMhFolder", - sizeof(CamelMhFolder), - sizeof(CamelMhFolderClass), - (CamelObjectClassInitFunc) camel_mh_folder_class_init, - NULL, - (CamelObjectInitFunc) mh_init, - (CamelObjectFinalizeFunc) mh_finalize); - } - - return camel_mh_folder_type; -} - -CamelFolder * -camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex) -{ - CamelFolder *folder; - - d(printf("Creating mh folder: %s\n", full_name)); - - folder = (CamelFolder *)camel_object_new(CAMEL_MH_FOLDER_TYPE); - folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder, - parent_store, full_name, flags, ex); - - return folder; -} - -static CamelLocalSummary *mh_create_summary(const char *path, const char *folder, CamelIndex *index) -{ - return (CamelLocalSummary *)camel_mh_summary_new(path, folder, index); -} - -static void -mh_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex) -{ - CamelMhFolder *mh_folder = (CamelMhFolder *)folder; - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - CamelStream *output_stream; - CamelMessageInfo *mi; - char *name; - - /* FIXME: probably needs additional locking (although mh doesn't appear do do it) */ - - d(printf("Appending message\n")); - - /* add it to the summary/assign the uid, etc */ - mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex); - if (camel_exception_is_set (ex)) - return; - - d(printf("Appending message: uid is %s\n", camel_message_info_uid(mi))); - - /* write it out, use the uid we got from the summary */ - name = g_strdup_printf("%s/%s", lf->folder_path, camel_message_info_uid(mi)); - output_stream = camel_stream_fs_new_with_name(name, O_WRONLY|O_CREAT, 0600); - if (output_stream == NULL) - goto fail_write; - - if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)message, output_stream) == -1 - || camel_stream_close (output_stream) == -1) - goto fail_write; - - /* close this? */ - camel_object_unref (CAMEL_OBJECT (output_stream)); - - g_free(name); - - camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", - ((CamelLocalFolder *)mh_folder)->changes); - camel_folder_change_info_clear (((CamelLocalFolder *)mh_folder)->changes); - - if (appended_uid) - *appended_uid = g_strdup(camel_message_info_uid(mi)); - - return; - - fail_write: - - /* remove the summary info so we are not out-of-sync with the mh folder */ - camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary), - camel_message_info_uid (mi)); - - if (errno == EINTR) - camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, - _("MH append message cancelled")); - else - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot append message to mh folder: %s: %s"), - name, g_strerror (errno)); - - if (output_stream) { - camel_object_unref (CAMEL_OBJECT (output_stream)); - unlink (name); - } - - g_free (name); -} - -static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex) -{ - CamelLocalFolder *lf = (CamelLocalFolder *)folder; - CamelStream *message_stream = NULL; - CamelMimeMessage *message = NULL; - CamelMessageInfo *info; - char *name; - - d(printf("getting message: %s\n", uid)); - - /* get the message summary info */ - if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) { - camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), uid, _("No such message")); - return NULL; - } - - /* we only need it to check the message exists */ - camel_folder_summary_info_free(folder->summary, info); - - name = g_strdup_printf("%s/%s", lf->folder_path, uid); - if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Cannot get message: %s\n %s"), - name, g_strerror (errno)); - g_free(name); - return NULL; - } - - message = camel_mime_message_new(); - if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Cannot get message: %s\n %s"), - name, _("Invalid message contents")); - g_free(name); - camel_object_unref((CamelObject *)message_stream); - camel_object_unref((CamelObject *)message); - return NULL; - - } - camel_object_unref((CamelObject *)message_stream); - g_free(name); - - return message; -} diff --git a/camel/providers/local/camel-mh-folder.h b/camel/providers/local/camel-mh-folder.h deleted file mode 100644 index 125f8c8ac5..0000000000 --- a/camel/providers/local/camel-mh-folder.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: - * Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_MH_FOLDER_H -#define CAMEL_MH_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus } */ -#include "camel-local-folder.h" - -#define CAMEL_MH_FOLDER_TYPE (camel_mh_folder_get_type ()) -#define CAMEL_MH_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MH_FOLDER_TYPE, CamelMhFolder)) -#define CAMEL_MH_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MH_FOLDER_TYPE, CamelMhFolderClass)) -#define CAMEL_IS_MH_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_MH_FOLDER_TYPE)) - -typedef struct { - CamelLocalFolder parent_object; - -} CamelMhFolder; - -typedef struct { - CamelLocalFolderClass parent_class; - - /* Virtual methods */ - -} CamelMhFolderClass; - -/* public methods */ -CamelFolder *camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex); - -/* Standard Camel function */ -CamelType camel_mh_folder_get_type(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CAMEL_MH_FOLDER_H */ diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c deleted file mode 100644 index 73a3d2046f..0000000000 --- a/camel/providers/local/camel-mh-store.c +++ /dev/null @@ -1,533 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/stat.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <dirent.h> - -#include "camel-mh-store.h" -#include "camel-mh-folder.h" -#include "camel-exception.h" -#include "camel-url.h" -#include "camel-private.h" - -#include <camel/camel-stream-fs.h> -#include <camel/camel-stream-buffer.h> - -static CamelLocalStoreClass *parent_class = NULL; - -#define d(x) - -/* Returns the class for a CamelMhStore */ -#define CMHS_CLASS(so) CAMEL_MH_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CMHF_CLASS(so) CAMEL_MH_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static void construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex); -static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex); -static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); -static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex); -static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex); -static CamelFolderInfo * get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex); - -static void camel_mh_store_class_init(CamelObjectClass * camel_mh_store_class) -{ - CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS(camel_mh_store_class); - CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_mh_store_class); - - parent_class = (CamelLocalStoreClass *)camel_type_get_global_classfuncs(camel_local_store_get_type()); - - /* virtual method overload, use defaults for most */ - camel_service_class->construct = construct; - - camel_store_class->get_folder = get_folder; - camel_store_class->get_inbox = get_inbox; - camel_store_class->delete_folder = delete_folder; - camel_store_class->rename_folder = rename_folder; - camel_store_class->get_folder_info = get_folder_info; -} - -CamelType camel_mh_store_get_type(void) -{ - static CamelType camel_mh_store_type = CAMEL_INVALID_TYPE; - - if (camel_mh_store_type == CAMEL_INVALID_TYPE) { - camel_mh_store_type = camel_type_register(CAMEL_LOCAL_STORE_TYPE, "CamelMhStore", - sizeof(CamelMhStore), - sizeof(CamelMhStoreClass), - (CamelObjectClassInitFunc) camel_mh_store_class_init, - NULL, - NULL, - NULL); - } - - return camel_mh_store_type; -} - -static void -construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex) -{ - CamelMhStore *mh_store = (CamelMhStore *)service; - - CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex); - if (camel_exception_is_set (ex)) - return; - - if (camel_url_get_param(url, "dotfolders")) - mh_store->flags |= CAMEL_MH_DOTFOLDERS; -} - -enum { - UPDATE_NONE, - UPDATE_ADD, - UPDATE_REMOVE, -}; - -/* update the .folders file if it exists, or create it if it doesn't */ -static void -folders_update(const char *root, const char *folder, int mode) -{ - char *tmp, *tmpnew, *line = NULL; - CamelStream *stream, *in = NULL, *out = NULL; - - tmpnew = g_alloca (strlen (root) + 16); - sprintf (tmpnew, "%s.folders~", root); - - out = camel_stream_fs_new_with_name(tmpnew, O_WRONLY|O_CREAT|O_TRUNC, 0666); - if (out == NULL) - goto fail; - - tmp = g_alloca (strlen (root) + 16); - sprintf (tmp, "%s.folders", root); - stream = camel_stream_fs_new_with_name(tmp, O_RDONLY, 0); - if (stream) { - in = camel_stream_buffer_new(stream, CAMEL_STREAM_BUFFER_READ); - camel_object_unref(stream); - } - if (in == NULL || stream == NULL) { - if (mode == UPDATE_ADD && camel_stream_printf(out, "%s\n", folder) == -1) - goto fail; - goto done; - } - - while ((line = camel_stream_buffer_read_line((CamelStreamBuffer *)in))) { - int copy = TRUE; - - switch (mode) { - case UPDATE_REMOVE: - if (strcmp(line, folder) == 0) - copy = FALSE; - break; - case UPDATE_ADD: { - int cmp = strcmp(line, folder); - - if (cmp > 0) { - /* found insertion point */ - if (camel_stream_printf(out, "%s\n", folder) == -1) - goto fail; - mode = UPDATE_NONE; - } else if (tmp == 0) { - /* already there */ - mode = UPDATE_NONE; - } - break; } - case UPDATE_NONE: - break; - } - - if (copy && camel_stream_printf(out, "%s\n", line) == -1) - goto fail; - - g_free(line); - line = NULL; - } - - /* add to end? */ - if (mode == UPDATE_ADD && camel_stream_printf(out, "%s\n", folder) == -1) - goto fail; - - if (camel_stream_close(out) == -1) - goto fail; - -done: - /* should we care if this fails? I suppose so ... */ - rename(tmpnew, tmp); -fail: - unlink(tmpnew); /* remove it if its there */ - g_free(line); - if (in) - camel_object_unref(in); - if (out) - camel_object_unref(out); -} - -static CamelFolder * -get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex) -{ - char *name; - struct stat st; - - if (!((CamelStoreClass *)parent_class)->get_folder(store, folder_name, flags, ex)) - return NULL; - - name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); - - if (stat(name, &st) == -1) { - if (errno != ENOENT) { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open folder `%s':\n%s"), - folder_name, g_strerror (errno)); - g_free (name); - return NULL; - } - if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Folder `%s' does not exist."), folder_name); - g_free (name); - return NULL; - } - - if (mkdir(name, 0700) != 0) { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not create folder `%s':\n%s"), - folder_name, g_strerror (errno)); - g_free (name); - return NULL; - } - - /* add to .folders if we are supposed to */ - /* FIXME: throw exception on error */ - if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) - folders_update(((CamelLocalStore *)store)->toplevel_dir, folder_name, UPDATE_ADD); - - } else if (!S_ISDIR(st.st_mode)) { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("`%s' is not a directory."), name); - g_free (name); - return NULL; - } - g_free(name); - - return camel_mh_folder_new(store, folder_name, flags, ex); -} - -static CamelFolder * -get_inbox (CamelStore *store, CamelException *ex) -{ - return get_folder (store, "inbox", 0, ex); -} - -static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex) -{ - char *name; - - /* remove folder directory - will fail if not empty */ - name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); - if (rmdir(name) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s': %s"), - folder_name, g_strerror (errno)); - g_free(name); - return; - } - g_free(name); - - /* remove from .folders if we are supposed to */ - if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) - folders_update(((CamelLocalStore *)store)->toplevel_dir, folder_name, UPDATE_REMOVE); - - /* and remove metadata */ - ((CamelStoreClass *)parent_class)->delete_folder(store, folder_name, ex); -} - -static void -rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex) -{ - CamelException e; - - camel_exception_init(&e); - ((CamelStoreClass *)parent_class)->rename_folder(store, old, new, &e); - if (camel_exception_is_set(&e)) { - camel_exception_xfer(ex, &e); - return; - } - camel_exception_clear(&e); - - if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) { - /* yeah this is messy, but so is mh! */ - folders_update(((CamelLocalStore *)store)->toplevel_dir, new, UPDATE_ADD); - folders_update(((CamelLocalStore *)store)->toplevel_dir, old, UPDATE_REMOVE); - } -} - -static CamelFolderInfo *folder_info_new(CamelStore *store, const char *root, const char *path) -{ - CamelFolderInfo *fi; - char *base; - CamelFolder *folder; - - base = strrchr(path, '/'); - - /* Build the folder info structure. */ - fi = g_malloc0(sizeof(*fi)); - fi->url = g_strdup_printf("mh:%s#%s", root, path); - fi->full_name = g_strdup(path); - fi->name = g_strdup(base?base+1:path); - fi->unread_message_count = 0; - - /* check unread count if open */ - folder = camel_object_bag_get(store->folders, path); - if (folder) { - if ((((CamelMhStore *)store)->flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) - camel_folder_refresh_info(folder, NULL); - fi->unread_message_count = camel_folder_get_unread_message_count(folder); - camel_object_unref(folder); - } - - /* We could: if we have no folder, and FAST isn't specified, perform a full - scan of all messages for their status flags. But its probably not worth - it as we need to read the top of every file, i.e. very very slow */ - - camel_folder_info_build_path(fi, '/'); - - d(printf("New folderinfo:\n '%s'\n '%s'\n '%s'\n", fi->full_name, fi->url, fi->path)); - - return fi; -} - -/* used to find out where we've visited already */ -struct _inode { - dev_t dnode; - ino_t inode; -}; - -/* Scan path, under root, for directories to add folders for. Both - * root and path should have a trailing "/" if they aren't empty. */ -static void recursive_scan(CamelStore *store, CamelFolderInfo **fip, CamelFolderInfo *parent, GHashTable *visited, const char *root, const char *path) -{ - char *fullpath, *tmp; - DIR *dp; - struct dirent *d; - struct stat st; - CamelFolderInfo *fi; - struct _inode in, *inew; - - /* Open the specified directory. */ - if (path[0]) { - fullpath = alloca (strlen (root) + strlen (path) + 2); - sprintf (fullpath, "%s/%s", root, path); - } else - fullpath = (char *)root; - - if (stat(fullpath, &st) == -1 || !S_ISDIR(st.st_mode)) - return; - - in.dnode = st.st_dev; - in.inode = st.st_ino; - - /* see if we've visited already */ - if (g_hash_table_lookup(visited, &in) != NULL) - return; - - inew = g_malloc(sizeof(*inew)); - *inew = in; - g_hash_table_insert(visited, inew, inew); - - /* link in ... */ - fi = folder_info_new(store, root, path); - fi->parent = parent; - fi->sibling = *fip; - *fip = fi; - - if ((( ((CamelMhStore *)store)->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || parent == NULL)) { - /* now check content for possible other directories */ - dp = opendir(fullpath); - if (dp == NULL) - return; - - /* Look for subdirectories to add and scan. */ - while ((d = readdir(dp)) != NULL) { - /* Skip current and parent directory. */ - if (strcmp(d->d_name, ".") == 0 - || strcmp(d->d_name, "..") == 0) - continue; - - /* skip fully-numerical entries (i.e. mh messages) */ - strtoul(d->d_name, &tmp, 10); - if (*tmp == 0) - continue; - - /* otherwise, treat at potential node, and recurse, a bit more expensive than needed, but tough! */ - if (path[0]) { - tmp = g_strdup_printf("%s/%s", path, d->d_name); - recursive_scan(store, &fi->child, fi, visited, root, tmp); - g_free(tmp); - } else { - recursive_scan(store, &fi->child, fi, visited, root, d->d_name); - } - } - - closedir(dp); - } -} - -/* scan a .folders file */ -static void -folders_scan(CamelStore *store, const char *root, const char *top, CamelFolderInfo **fip) -{ - CamelFolderInfo *fi; - char line[512], *path, *tmp; - CamelStream *stream, *in; - struct stat st; - GPtrArray *folders; - GHashTable *visited; - int len; - - tmp = g_alloca (strlen (root) + 16); - sprintf (tmp, "%s/.folders", root); - stream = camel_stream_fs_new_with_name(tmp, 0, O_RDONLY); - if (stream == NULL) - return; - - in = camel_stream_buffer_new(stream, CAMEL_STREAM_BUFFER_READ); - camel_object_unref(stream); - if (in == NULL) - return; - - visited = g_hash_table_new(g_str_hash, g_str_equal); - folders = g_ptr_array_new(); - - while ( (len = camel_stream_buffer_gets((CamelStreamBuffer *)in, line, sizeof(line))) > 0) { - /* ignore blank lines */ - if (len <= 1) - continue; - /* check for invalidly long lines, we abort evreything and fallback */ - if (line[len-1] != '\n') { - int i; - - for (i=0;i<folders->len;i++) - camel_folder_info_free(folders->pdata[i]); - g_ptr_array_set_size(folders, 0); - break; - } - line[len-1] = 0; - - /* check for \r ? */ - - if (top && top[0]) { - int toplen = strlen(top); - - /* check is subdir */ - if (strncmp(top, line, len) != 0) - continue; - - /* check is not sub-subdir if not recursive */ - if (( ((CamelMhStore *)store)->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0 - && (tmp = strrchr(line, '/')) - && tmp > line+toplen) - continue; - } - - if (g_hash_table_lookup(visited, line) != NULL) - continue; - - tmp = g_strdup(line); - g_hash_table_insert(visited, tmp, tmp); - - path = g_strdup_printf("%s/%s", root, line); - if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) { - fi = folder_info_new(store, root, line); - g_ptr_array_add(folders, fi); - } - g_free(path); - } - - if (folders->len) - *fip = camel_folder_info_build(folders, NULL, '/', TRUE); - g_ptr_array_free(folders, TRUE); - - g_hash_table_foreach(visited, (GHFunc)g_free, NULL); - g_hash_table_destroy(visited); - - camel_object_unref(in); -} - -/* FIXME: move to camel-local, this is shared with maildir code */ -static guint inode_hash(const void *d) -{ - const struct _inode *v = d; - - return v->inode ^ v->dnode; -} - -static gboolean inode_equal(const void *a, const void *b) -{ - const struct _inode *v1 = a, *v2 = b; - - return v1->inode == v2->inode && v1->dnode == v2->dnode; -} - -static void inode_free(void *k, void *v, void *d) -{ - g_free(k); -} - -static CamelFolderInfo * -get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex) -{ - CamelFolderInfo *fi = NULL; - char *root; - - root = ((CamelService *)store)->url->path; - - /* use .folders if we are supposed to */ - if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) { - folders_scan(store, root, top, &fi); - } else { - GHashTable *visited = g_hash_table_new(inode_hash, inode_equal); - - if (top == NULL) - top = ""; - - recursive_scan(store, &fi, NULL, visited, root, top); - - /* if we actually scanned from root, we have a "" root node we dont want */ - if (fi != NULL && top[0] == 0) { - CamelFolderInfo *rfi; - - rfi = fi; - fi = rfi->child; - rfi->child = NULL; - camel_folder_info_free(rfi); - } - - g_hash_table_foreach(visited, inode_free, NULL); - g_hash_table_destroy(visited); - } - - return fi; -} diff --git a/camel/providers/local/camel-mh-store.h b/camel/providers/local/camel-mh-store.h deleted file mode 100644 index 96522cb01f..0000000000 --- a/camel/providers/local/camel-mh-store.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_MH_STORE_H -#define CAMEL_MH_STORE_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus } */ - -#include "camel-local-store.h" - -#define CAMEL_MH_STORE_TYPE (camel_mh_store_get_type ()) -#define CAMEL_MH_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MH_STORE_TYPE, CamelMhStore)) -#define CAMEL_MH_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MH_STORE_TYPE, CamelMhStoreClass)) -#define CAMEL_IS_MH_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_MH_STORE_TYPE)) - -enum { - CAMEL_MH_DOTFOLDERS = (1<<0), /* update/use .folders file */ -}; - -typedef struct { - CamelLocalStore parent_object; - - guint32 flags; -} CamelMhStore; - -typedef struct { - CamelLocalStoreClass parent_class; - -} CamelMhStoreClass; - -/* public methods */ - -/* Standard Camel function */ -CamelType camel_mh_store_get_type(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CAMEL_MH_STORE_H */ diff --git a/camel/providers/local/camel-mh-summary.c b/camel/providers/local/camel-mh-summary.c deleted file mode 100644 index 5dd26ac9ba..0000000000 --- a/camel/providers/local/camel-mh-summary.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Not Zed <notzed@lostzed.mmc.com.au> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include <dirent.h> - -#include <ctype.h> - -#include "camel-mh-summary.h" -#include <camel/camel-mime-message.h> - -#include "camel-private.h" - -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -#define CAMEL_MH_SUMMARY_VERSION (0x2000) - -static int mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); -static int mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); -/*static int mh_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);*/ - -static char *mh_summary_next_uid_string(CamelFolderSummary *s); - -static void camel_mh_summary_class_init (CamelMhSummaryClass *class); -static void camel_mh_summary_init (CamelMhSummary *gspaper); -static void camel_mh_summary_finalise (CamelObject *obj); - -#define _PRIVATE(x) (((CamelMhSummary *)(x))->priv) - -struct _CamelMhSummaryPrivate { - char *current_uid; -}; - -static CamelLocalSummaryClass *parent_class; - -CamelType -camel_mh_summary_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register(camel_local_summary_get_type (), "CamelMhSummary", - sizeof(CamelMhSummary), - sizeof(CamelMhSummaryClass), - (CamelObjectClassInitFunc)camel_mh_summary_class_init, - NULL, - (CamelObjectInitFunc)camel_mh_summary_init, - (CamelObjectFinalizeFunc)camel_mh_summary_finalise); - } - - return type; -} - -static void -camel_mh_summary_class_init (CamelMhSummaryClass *class) -{ - CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *) class; - CamelLocalSummaryClass *lklass = (CamelLocalSummaryClass *)class; - - parent_class = (CamelLocalSummaryClass *)camel_type_get_global_classfuncs(camel_local_summary_get_type ()); - - /* override methods */ - sklass->next_uid_string = mh_summary_next_uid_string; - - lklass->check = mh_summary_check; - lklass->sync = mh_summary_sync; - /*lklass->add = mh_summary_add;*/ -} - -static void -camel_mh_summary_init (CamelMhSummary *o) -{ - struct _CamelFolderSummary *s = (CamelFolderSummary *) o; - - o->priv = g_malloc0(sizeof(*o->priv)); - /* set unique file version */ - s->version += CAMEL_MH_SUMMARY_VERSION; -} - -static void -camel_mh_summary_finalise(CamelObject *obj) -{ - CamelMhSummary *o = (CamelMhSummary *)obj; - - g_free(o->priv); -} - -/** - * camel_mh_summary_new: - * - * Create a new CamelMhSummary object. - * - * Return value: A new #CamelMhSummary object. - **/ -CamelMhSummary *camel_mh_summary_new (const char *filename, const char *mhdir, CamelIndex *index) -{ - CamelMhSummary *o = (CamelMhSummary *)camel_object_new(camel_mh_summary_get_type ()); - - camel_local_summary_construct((CamelLocalSummary *)o, filename, mhdir, index); - return o; -} - -static char *mh_summary_next_uid_string(CamelFolderSummary *s) -{ - CamelMhSummary *mhs = (CamelMhSummary *)s; - CamelLocalSummary *cls = (CamelLocalSummary *)s; - int fd = -1; - guint32 uid; - char *name; - char *uidstr; - - /* if we are working to add an existing file, then use current_uid */ - if (mhs->priv->current_uid) { - uidstr = g_strdup(mhs->priv->current_uid); - /* tell the summary of this, so we always append numbers to the end */ - camel_folder_summary_set_uid(s, strtoul(uidstr, NULL, 10)+1); - } else { - /* else scan for one - and create it too, to make sure */ - do { - close(fd); - uid = camel_folder_summary_next_uid(s); - name = g_strdup_printf("%s/%u", cls->folder_path, uid); - /* O_EXCL isn't guaranteed, sigh. Oh well, bad luck, mh has problems anyway */ - fd = open(name, O_WRONLY|O_CREAT|O_EXCL, 0600); - g_free(name); - } while (fd == -1 && errno == EEXIST); - - close(fd); - - uidstr = g_strdup_printf("%u", uid); - } - - return uidstr; -} - -static int camel_mh_summary_add(CamelLocalSummary *cls, const char *name, int forceindex) -{ - CamelMhSummary *mhs = (CamelMhSummary *)cls; - char *filename = g_strdup_printf("%s/%s", cls->folder_path, name); - int fd; - CamelMimeParser *mp; - - d(printf("summarising: %s\n", name)); - - fd = open(filename, O_RDONLY); - if (fd == -1) { - g_warning ("Cannot summarise/index: %s: %s", filename, strerror (errno)); - g_free(filename); - return -1; - } - mp = camel_mime_parser_new(); - camel_mime_parser_scan_from(mp, FALSE); - camel_mime_parser_init_with_fd(mp, fd); - if (cls->index && (forceindex || !camel_index_has_name(cls->index, name))) { - d(printf("forcing indexing of message content\n")); - camel_folder_summary_set_index((CamelFolderSummary *)mhs, cls->index); - } else { - camel_folder_summary_set_index((CamelFolderSummary *)mhs, NULL); - } - mhs->priv->current_uid = (char *)name; - camel_folder_summary_add_from_parser((CamelFolderSummary *)mhs, mp); - camel_object_unref((CamelObject *)mp); - mhs->priv->current_uid = NULL; - camel_folder_summary_set_index((CamelFolderSummary *)mhs, NULL); - g_free(filename); - return 0; -} - -static void -remove_summary(char *key, CamelMessageInfo *info, CamelLocalSummary *cls) -{ - d(printf("removing message %s from summary\n", key)); - if (cls->index) - camel_index_delete_name(cls->index, camel_message_info_uid(info)); - camel_folder_summary_remove((CamelFolderSummary *)cls, info); - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); -} - -static int -sort_uid_cmp(const void *ap, const void *bp) -{ - const CamelMessageInfo - *a = *((CamelMessageInfo **)ap), - *b = *((CamelMessageInfo **)bp); - const char - *auid = camel_message_info_uid(a), - *buid = camel_message_info_uid(b); - int aval = atoi(auid), bval = atoi(buid); - - return (aval < bval) ? -1 : (aval > bval) ? 1 : 0; -} - -static int -mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - DIR *dir; - struct dirent *d; - char *p, c; - CamelMessageInfo *info; - CamelFolderSummary *s = (CamelFolderSummary *)cls; - GHashTable *left; - int i, count; - int forceindex; - - /* FIXME: Handle changeinfo */ - - d(printf("checking summary ...\n")); - - /* scan the directory, check for mail files not in the index, or index entries that - no longer exist */ - dir = opendir(cls->folder_path); - if (dir == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot open MH directory path: %s: %s"), - cls->folder_path, g_strerror (errno)); - return -1; - } - - /* keeps track of all uid's that have not been processed */ - left = g_hash_table_new(g_str_hash, g_str_equal); - count = camel_folder_summary_count((CamelFolderSummary *)cls); - forceindex = count == 0; - for (i=0;i<count;i++) { - info = camel_folder_summary_index((CamelFolderSummary *)cls, i); - if (info) { - g_hash_table_insert(left, (char *)camel_message_info_uid(info), info); - } - } - - while ( (d = readdir(dir)) ) { - /* FIXME: also run stat to check for regular file */ - p = d->d_name; - while ( (c = *p++) ) { - if (!isdigit(c)) - break; - } - if (c==0) { - info = camel_folder_summary_uid((CamelFolderSummary *)cls, d->d_name); - if (info == NULL || (cls->index && (!camel_index_has_name(cls->index, d->d_name)))) { - /* need to add this file to the summary */ - if (info != NULL) { - g_hash_table_remove(left, camel_message_info_uid(info)); - camel_folder_summary_remove((CamelFolderSummary *)cls, info); - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); - } - camel_mh_summary_add(cls, d->d_name, forceindex); - } else { - const char *uid = camel_message_info_uid(info); - CamelMessageInfo *old = g_hash_table_lookup(left, uid); - - if (old) { - camel_folder_summary_info_free((CamelFolderSummary *)cls, old); - g_hash_table_remove(left, uid); - } - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); - } - } - } - closedir(dir); - g_hash_table_foreach(left, (GHFunc)remove_summary, cls); - g_hash_table_destroy(left); - - /* sort the summary based on message number (uid), since the directory order is not useful */ - CAMEL_SUMMARY_LOCK(s, summary_lock); - qsort(s->messages->pdata, s->messages->len, sizeof(CamelMessageInfo *), sort_uid_cmp); - CAMEL_SUMMARY_UNLOCK(s, summary_lock); - - return 0; -} - -static int -mh_summary_sync_message(CamelLocalSummary *cls, CamelMessageInfo *info, CamelException *ex) -{ - CamelMimeParser *mp; - const char *xev, *buffer; - int xevoffset; - int fd, outfd, len, outlen, ret=0; - char *name, *tmpname, *xevnew; - - name = g_strdup_printf("%s/%s", cls->folder_path, camel_message_info_uid(info)); - fd = open(name, O_RDWR); - if (fd == -1) - return -1; - - mp = camel_mime_parser_new(); - camel_mime_parser_init_with_fd(mp, fd); - if (camel_mime_parser_step(mp, 0, 0) != CAMEL_MIME_PARSER_STATE_EOF) { - xev = camel_mime_parser_header(mp, "X-Evolution", &xevoffset); - d(printf("xev = '%s'\n", xev)); - xevnew = camel_local_summary_encode_x_evolution(cls, info); - if (xev == NULL - || camel_local_summary_decode_x_evolution(cls, xev, NULL) == -1 - || strlen(xev)-1 != strlen(xevnew)) { - - d(printf("camel local summary_decode_xev = %d\n", camel_local_summary_decode_x_evolution(cls, xev, NULL))); - - /* need to write a new copy/unlink old */ - tmpname = g_strdup_printf("%s/.tmp.%d.%s", cls->folder_path, getpid(), camel_message_info_uid(info)); - d(printf("old xev was %d %s new xev is %d %s\n", strlen(xev), xev, strlen(xevnew), xevnew)); - d(printf("creating new message %s\n", tmpname)); - outfd = open(tmpname, O_CREAT|O_WRONLY|O_TRUNC, 0600); - if (outfd != -1) { - outlen = 0; - len = camel_local_summary_write_headers(outfd, camel_mime_parser_headers_raw(mp), xevnew, NULL, NULL); - if (len != -1) { - while (outlen != -1 && (len = camel_mime_parser_read(mp, &buffer, 10240)) > 0) { - d(printf("camel mime parser read, read %d bytes: %.*s\n", len, len, buffer)); - do { - outlen = write(outfd, buffer, len); - } while (outlen == -1 && errno == EINTR); - } - } - - d(printf("len = %d outlen = %d, renaming/finishing\n", len, outlen)); - if (close(outfd) == -1 - || len == -1 - || outlen == -1 - || rename(tmpname, name) == -1) { - unlink(tmpname); - ret = -1; - } - } else { - g_warning("sync can't create tmp file: %s", strerror (errno)); - } - g_free(tmpname); - } else { - d(printf("stamping in updated X-EV at %d\n", (int)xevoffset)); - /* else, we can just update the flags field */ - lseek(fd, xevoffset+strlen("X-Evolution: "), SEEK_SET); - do { - len = write(fd, xevnew, strlen(xevnew)); - } while (len == -1 && errno == EINTR); - if (len == -1) - ret = -1; - } - - g_free(xevnew); - } - - camel_object_unref((CamelObject *)mp); - g_free(name); - return ret; -} - -/* sync the summary file with the ondisk files */ -static int -mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changes, CamelException *ex) -{ - int count, i; - CamelMessageInfo *info; - char *name; - const char *uid; - - d(printf("summary_sync(expunge=%s)\n", expunge?"true":"false")); - - /* we could probably get away without this ... but why not use it, esp if we're going to - be doing any significant io already */ - if (camel_local_summary_check(cls, changes, ex) == -1) - return -1; - - count = camel_folder_summary_count((CamelFolderSummary *)cls); - for (i=count-1;i>=0;i--) { - info = camel_folder_summary_index((CamelFolderSummary *)cls, i); - g_assert(info); - if (expunge && (info->flags & CAMEL_MESSAGE_DELETED)) { - uid = camel_message_info_uid(info); - name = g_strdup_printf("%s/%s", cls->folder_path, uid); - d(printf("deleting %s\n", name)); - if (unlink(name) == 0 || errno==ENOENT) { - - /* FIXME: put this in folder_summary::remove()? */ - if (cls->index) - camel_index_delete_name(cls->index, (char *)uid); - - camel_folder_change_info_remove_uid(changes, uid); - camel_folder_summary_remove((CamelFolderSummary *)cls, info); - } - g_free(name); - } else if (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED)) { - if (mh_summary_sync_message(cls, info, ex) != -1) { - info->flags &= 0xffff; - } else { - g_warning("Problem occured when trying to expunge, ignored"); - } - } - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); - } - - return ((CamelLocalSummaryClass *)parent_class)->sync(cls, expunge, changes, ex); -} diff --git a/camel/providers/local/camel-mh-summary.h b/camel/providers/local/camel-mh-summary.h deleted file mode 100644 index 4ee30df63b..0000000000 --- a/camel/providers/local/camel-mh-summary.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Not Zed <notzed@lostzed.mmc.com.au> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _CAMEL_MH_SUMMARY_H -#define _CAMEL_MH_SUMMARY_H - -#include "camel-local-summary.h" -#include <camel/camel-folder.h> -#include <camel/camel-exception.h> -#include <camel/camel-index.h> - -#define CAMEL_MH_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_mh_summary_get_type (), CamelMhSummary) -#define CAMEL_MH_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_mh_summary_get_type (), CamelMhSummaryClass) -#define CAMEL_IS_MH_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_mh_summary_get_type ()) - -typedef struct _CamelMhSummary CamelMhSummary; -typedef struct _CamelMhSummaryClass CamelMhSummaryClass; - -struct _CamelMhSummary { - CamelLocalSummary parent; - struct _CamelMhSummaryPrivate *priv; -}; - -struct _CamelMhSummaryClass { - CamelLocalSummaryClass parent_class; - - /* virtual methods */ - - /* signals */ -}; - -CamelType camel_mh_summary_get_type (void); -CamelMhSummary *camel_mh_summary_new (const char *filename, const char *mhdir, CamelIndex *index); - -#endif /* ! _CAMEL_MH_SUMMARY_H */ - diff --git a/camel/providers/local/camel-spool-folder.c b/camel/providers/local/camel-spool-folder.c deleted file mode 100644 index 4c4a49fbf9..0000000000 --- a/camel/providers/local/camel-spool-folder.c +++ /dev/null @@ -1,186 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2001-2003 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <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-spool-folder.h" -#include "camel-spool-store.h" -#include "camel-stream-fs.h" -#include "camel-spool-summary.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-stream-filter.h" -#include "camel-mime-filter-from.h" -#include "camel-exception.h" - -#include "camel-lock-client.h" - -#include "camel-local-private.h" - -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -static CamelFolderClass *parent_class = NULL; - -/* Returns the class for a CamelSpoolFolder */ -#define CSPOOLF_CLASS(so) CAMEL_SPOOL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CSPOOLS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static CamelLocalSummary *spool_create_summary(const char *path, const char *folder, CamelIndex *index); - -static int spool_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex); -static void spool_unlock(CamelLocalFolder *lf); - -static void spool_finalize(CamelObject * object); - -static void -camel_spool_folder_class_init(CamelSpoolFolderClass *klass) -{ - CamelLocalFolderClass *lklass = (CamelLocalFolderClass *)klass; - - parent_class = (CamelFolderClass *)camel_mbox_folder_get_type(); - - /* virtual method overload */ - lklass->create_summary = spool_create_summary; - lklass->lock = spool_lock; - lklass->unlock = spool_unlock; -} - -static void -spool_init(gpointer object, gpointer klass) -{ - CamelSpoolFolder *spool_folder = object; - - spool_folder->lockid = -1; -} - -static void -spool_finalize(CamelObject * object) -{ - /*CamelSpoolFolder *spool_folder = CAMEL_SPOOL_FOLDER(object);*/ -} - -CamelType camel_spool_folder_get_type(void) -{ - static CamelType camel_spool_folder_type = CAMEL_INVALID_TYPE; - - if (camel_spool_folder_type == CAMEL_INVALID_TYPE) { - camel_spool_folder_type = camel_type_register(camel_mbox_folder_get_type(), "CamelSpoolFolder", - sizeof(CamelSpoolFolder), - sizeof(CamelSpoolFolderClass), - (CamelObjectClassInitFunc) camel_spool_folder_class_init, - NULL, - (CamelObjectInitFunc) spool_init, - (CamelObjectFinalizeFunc) spool_finalize); - } - - return camel_spool_folder_type; -} - -CamelFolder * -camel_spool_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex) -{ - CamelFolder *folder; - - d(printf("Creating spool folder: %s in %s\n", full_name, camel_local_store_get_toplevel_dir((CamelLocalStore *)parent_store))); - - folder = (CamelFolder *)camel_object_new(CAMEL_SPOOL_FOLDER_TYPE); - - if (parent_store->flags & CAMEL_STORE_FILTER_INBOX - && strcmp(full_name, "INBOX") == 0) - folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT; - flags &= CAMEL_STORE_FOLDER_BODY_INDEX; - - folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder, parent_store, full_name, flags, ex); - if (folder) { - if (camel_url_get_param(((CamelService *)parent_store)->url, "xstatus")) - camel_mbox_summary_xstatus((CamelMboxSummary *)folder->summary, TRUE); - } - - return folder; -} - -static CamelLocalSummary * -spool_create_summary(const char *path, const char *folder, CamelIndex *index) -{ - return (CamelLocalSummary *)camel_spool_summary_new(folder); -} - -static int -spool_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex) -{ - int retry = 0; - CamelMboxFolder *mf = (CamelMboxFolder *)lf; - CamelSpoolFolder *sf = (CamelSpoolFolder *)lf; - - mf->lockfd = open(lf->folder_path, O_RDWR, 0); - if (mf->lockfd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot create folder lock on %s: %s"), - lf->folder_path, g_strerror (errno)); - return -1; - } - - while (retry < CAMEL_LOCK_RETRY) { - if (retry > 0) - sleep(CAMEL_LOCK_DELAY); - - camel_exception_clear(ex); - - if (camel_lock_fcntl(mf->lockfd, type, ex) == 0) { - if (camel_lock_flock(mf->lockfd, type, ex) == 0) { - if ((sf->lockid = camel_lock_helper_lock(lf->folder_path, ex)) != -1) - return 0; - camel_unlock_flock(mf->lockfd); - } - camel_unlock_fcntl(mf->lockfd); - } - retry++; - } - - return -1; -} - -static void -spool_unlock(CamelLocalFolder *lf) -{ - CamelMboxFolder *mf = (CamelMboxFolder *)lf; - CamelSpoolFolder *sf = (CamelSpoolFolder *)lf; - - camel_lock_helper_unlock(sf->lockid); - sf->lockid = -1; - camel_unlock_flock(mf->lockfd); - camel_unlock_fcntl(mf->lockfd); - - close(mf->lockfd); - mf->lockfd = -1; -} diff --git a/camel/providers/local/camel-spool-folder.h b/camel/providers/local/camel-spool-folder.h deleted file mode 100644 index e778cdecf7..0000000000 --- a/camel/providers/local/camel-spool-folder.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Author: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2001 Ximian Inc (www.ximian.com/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_SPOOL_FOLDER_H -#define CAMEL_SPOOL_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-mbox-folder.h" -#include <camel/camel-folder-search.h> -#include <camel/camel-index.h> -#include "camel-spool-summary.h" -#include "camel-lock.h" - -/* #include "camel-store.h" */ - -#define CAMEL_SPOOL_FOLDER_TYPE (camel_spool_folder_get_type ()) -#define CAMEL_SPOOL_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SPOOL_FOLDER_TYPE, CamelSpoolFolder)) -#define CAMEL_SPOOL_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SPOOL_FOLDER_TYPE, CamelSpoolFolderClass)) -#define CAMEL_IS_SPOOL_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_SPOOL_FOLDER_TYPE)) - -typedef struct { - CamelMboxFolder parent; - - struct _CamelSpoolFolderPrivate *priv; - - int lockid; /* lock id for dot locking */ -} CamelSpoolFolder; - -typedef struct { - CamelMboxFolderClass parent_class; -} CamelSpoolFolderClass; - -/* Standard Camel function */ -CamelType camel_spool_folder_get_type(void); - -CamelFolder *camel_spool_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_SPOOL_FOLDER_H */ diff --git a/camel/providers/local/camel-spool-store.c b/camel/providers/local/camel-spool-store.c deleted file mode 100644 index 09720e4a01..0000000000 --- a/camel/providers/local/camel-spool-store.c +++ /dev/null @@ -1,483 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2001 Ximian Inc (www.ximian.com/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> -#include <dirent.h> - -#include "camel-spool-store.h" -#include "camel-spool-folder.h" -#include "camel-exception.h" -#include "camel-url.h" -#include "camel-private.h" - -#define d(x) - -/* Returns the class for a CamelSpoolStore */ -#define CSPOOLS_CLASS(so) CAMEL_SPOOL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static void construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex); -static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex); -static char *get_name(CamelService *service, gboolean brief); -static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); -static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); -static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex); -static void free_folder_info (CamelStore *store, CamelFolderInfo *fi); - -static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex); -static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex); - -static CamelStoreClass *parent_class = NULL; - -static void -camel_spool_store_class_init (CamelSpoolStoreClass *camel_spool_store_class) -{ - CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_spool_store_class); - CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_spool_store_class); - - parent_class = CAMEL_STORE_CLASS(camel_mbox_store_get_type()); - - /* virtual method overload */ - camel_service_class->construct = construct; - camel_service_class->get_name = get_name; - camel_store_class->get_folder = get_folder; - camel_store_class->get_inbox = get_inbox; - camel_store_class->get_folder_info = get_folder_info; - camel_store_class->free_folder_info = free_folder_info; - - camel_store_class->delete_folder = delete_folder; - camel_store_class->rename_folder = rename_folder; -} - -CamelType -camel_spool_store_get_type (void) -{ - static CamelType camel_spool_store_type = CAMEL_INVALID_TYPE; - - if (camel_spool_store_type == CAMEL_INVALID_TYPE) { - camel_spool_store_type = camel_type_register (camel_mbox_store_get_type(), "CamelSpoolStore", - sizeof (CamelSpoolStore), - sizeof (CamelSpoolStoreClass), - (CamelObjectClassInitFunc) camel_spool_store_class_init, - NULL, - NULL, - NULL); - } - - return camel_spool_store_type; -} - -static void -construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex) -{ - struct stat st; - - d(printf("constructing store of type %s '%s:%s'\n", - camel_type_to_name(((CamelObject *)service)->s.type), url->protocol, url->path)); - - CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex); - if (camel_exception_is_set (ex)) - return; - - if (service->url->path[0] != '/') { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Store root %s is not an absolute path"), service->url->path); - return; - } - - if (stat(service->url->path, &st) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Spool `%s' cannot be opened: %s"), - service->url->path, g_strerror (errno)); - return; - } - - if (S_ISREG(st.st_mode)) - ((CamelSpoolStore *)service)->type = CAMEL_SPOOL_STORE_MBOX; - else if (S_ISDIR(st.st_mode)) - /* we could check here for slight variations */ - ((CamelSpoolStore *)service)->type = CAMEL_SPOOL_STORE_ELM; - else { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Spool `%s' is not a regular file or directory"), - service->url->path); - return; - } -} - -static CamelFolder * -get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex) -{ - CamelFolder *folder = NULL; - struct stat st; - char *name; - - d(printf("opening folder %s on path %s\n", folder_name, path)); - - /* we only support an 'INBOX' in mbox mode */ - if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX) { - if (strcmp(folder_name, "INBOX") != 0) { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Folder `%s/%s' does not exist."), - ((CamelService *)store)->url->path, folder_name); - } else { - folder = camel_spool_folder_new(store, folder_name, flags, ex); - } - } else { - name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name); - if (stat(name, &st) == -1) { - if (errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open folder `%s':\n%s"), - folder_name, g_strerror (errno)); - } else if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Folder `%s' does not exist."), - folder_name); - } else { - if (creat (name, 0600) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not create folder `%s':\n%s"), - folder_name, g_strerror (errno)); - } else { - folder = camel_spool_folder_new(store, folder_name, flags, ex); - } - } - } else if (!S_ISREG(st.st_mode)) { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("`%s' is not a mailbox file."), name); - } else { - folder = camel_spool_folder_new(store, folder_name, flags, ex); - } - g_free(name); - } - - return folder; -} - -static CamelFolder * -get_inbox(CamelStore *store, CamelException *ex) -{ - if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX) - return get_folder (store, "INBOX", CAMEL_STORE_FOLDER_CREATE, ex); - else { - camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Store does not support an INBOX")); - return NULL; - } -} - -static char * -get_name (CamelService *service, gboolean brief) -{ - if (brief) - return g_strdup(service->url->path); - else - return g_strdup_printf(((CamelSpoolStore *)service)->type == CAMEL_SPOOL_STORE_MBOX? - _("Spool mail file %s"):_("Spool folder tree %s"), service->url->path); -} - -/* default implementation, rename all */ -static void -rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex) -{ - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Spool folders cannot be renamed")); -} - -/* default implementation, only delete metadata */ -static void -delete_folder(CamelStore *store, const char *folder_name, CamelException *ex) -{ - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Spool folders cannot be deleted")); -} - -static void free_folder_info (CamelStore *store, CamelFolderInfo *fi) -{ - if (fi) { - g_free(fi->url); - g_free(fi->name); - g_free(fi->full_name); - g_free(fi->path); - g_free(fi); - } -} - -static CamelFolderInfo * -camel_folder_info_new(const char *url, const char *full, const char *name, int unread) -{ - CamelFolderInfo *fi; - - fi = g_malloc0(sizeof(*fi)); - fi->url = g_strdup(url); - fi->full_name = g_strdup(full); - fi->name = g_strdup(name); - fi->unread_message_count = unread; - camel_folder_info_build_path(fi, '/'); - - d(printf("Adding spoold info: '%s' '%s' '%s' '%s'\n", fi->path, fi->name, fi->full_name, fi->url)); - - return fi; -} - -/* used to find out where we've visited already */ -struct _inode { - dev_t dnode; - ino_t inode; -}; - -/* returns number of records found at or below this level */ -static int scan_dir(CamelStore *store, GHashTable *visited, char *root, const char *path, guint32 flags, CamelFolderInfo *parent, CamelFolderInfo **fip, CamelException *ex) -{ - DIR *dir; - struct dirent *d; - char *name, *uri, *tmp, *fname; - CamelFolderInfo *fi = NULL; - struct stat st; - CamelFolder *folder; - int unread; - char from[80]; - FILE *fp; - - d(printf("checking dir '%s' part '%s' for mbox content\n", root, path)); - - /* look for folders matching the right structure, recursively */ - if (path) { - name = alloca(strlen(root) + strlen(path) + 2); - sprintf(name, "%s/%s", root, path); - } else - name = root; - - if (stat(name, &st) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not scan folder `%s': %s"), - name, g_strerror (errno)); - } else if (S_ISREG(st.st_mode)) { - /* incase we start scanning from a file. messy duplication :-/ */ - if (path) { - folder = camel_object_bag_get(store->folders, path); - if (folder) { - /* should this refresh if ! FAST? */ - unread = camel_folder_get_unread_message_count(folder); - camel_object_unref(folder); - } else - unread = -1; - tmp = strrchr(path, '/'); - if (tmp) - tmp++; - else - tmp = (char *)path; - uri = g_strdup_printf("%s:%s#%s", ((CamelService *)store)->url->protocol, root, path); - fi = camel_folder_info_new(uri, path, tmp, unread); - fi->parent = parent; - fi->sibling = *fip; - *fip = fi; - g_free(uri); - } - return 0; - } - - dir = opendir(name); - if (dir == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not scan folder `%s': %s"), - name, g_strerror (errno)); - return -1; - } - - if (path != NULL) { - uri = g_strdup_printf("%s:%s;noselect=yes#%s", ((CamelService *)store)->url->protocol, root, path); - tmp = strrchr(path, '/'); - if (tmp == NULL) - tmp = (char *)path; - else - tmp++; - fi = camel_folder_info_new(uri, path, tmp, -1); - fi->parent = parent; - fi->sibling = *fip; - *fip = fi; - g_free(uri); - - fip = &fi->child; - parent = fi; - } - - while ( (d = readdir(dir)) ) { - if (strcmp(d->d_name, ".") == 0 - || strcmp(d->d_name, "..") == 0) - continue; - - tmp = g_strdup_printf("%s/%s", name, d->d_name); - if (stat(tmp, &st) == 0) { - if (path) - fname = g_strdup_printf("%s/%s", path, d->d_name); - else - fname = g_strdup(d->d_name); - - if (S_ISREG(st.st_mode)) { - /* first, see if we already have it open */ - folder = camel_object_bag_get(store->folders, fname); - if (folder) { - /* should this refresh if ! FAST? */ - unread = camel_folder_get_unread_message_count(folder); - camel_object_unref(folder); - } else - unread = -1; - - /* no? check its content to see if its a folder or not */ - if (folder == NULL) { - fp = fopen(tmp, "r"); - if (fp != NULL) { - if (st.st_size == 0 - || (fgets(from, sizeof(from), fp) != NULL - && strncmp(from, "From ", 5) == 0)) { - folder = (CamelFolder *)1; - /* TODO: if slow mode selected, we could look up unread counts here - - but its pretty expensive */ - } - fclose(fp); - } - } - - if (folder != NULL) { - uri = g_strdup_printf("%s:%s#%s", ((CamelService *)store)->url->protocol, root, fname); - fi = camel_folder_info_new(uri, fname, d->d_name, unread); - fi->parent = parent; - fi->sibling = *fip; - *fip = fi; - g_free(uri); - } - - } else if (S_ISDIR(st.st_mode)) { - struct _inode in = { st.st_dev, st.st_ino }; - - /* see if we've visited already */ - if (g_hash_table_lookup(visited, &in) == NULL) { - struct _inode *inew = g_malloc(sizeof(*inew)); - - *inew = in; - g_hash_table_insert(visited, inew, inew); - - if (scan_dir(store, visited, root, fname, flags, parent, fip, ex) == -1) { - g_free(tmp); - g_free(fname); - closedir(dir); - return -1; - } - } - } - g_free(fname); - - } - g_free(tmp); - } - closedir(dir); - - return 0; -} - -static guint inode_hash(const void *d) -{ - const struct _inode *v = d; - - return v->inode ^ v->dnode; -} - -static gboolean inode_equal(const void *a, const void *b) -{ - const struct _inode *v1 = a, *v2 = b; - - return v1->inode == v2->inode && v1->dnode == v2->dnode; -} - -static void inode_free(void *k, void *v, void *d) -{ - g_free(k); -} - -static CamelFolderInfo * -get_folder_info_elm(CamelStore *store, const char *top, guint32 flags, CamelException *ex) -{ - CamelFolderInfo *fi = NULL; - GHashTable *visited; - - visited = g_hash_table_new(inode_hash, inode_equal); - - if (scan_dir(store, visited, ((CamelService *)store)->url->path, top, flags, NULL, &fi, ex) == -1 && fi != NULL) { - camel_store_free_folder_info_full(store, fi); - fi = NULL; - } - - g_hash_table_foreach(visited, inode_free, NULL); - g_hash_table_destroy(visited); - - return fi; -} - -static CamelFolderInfo * -get_folder_info_mbox(CamelStore *store, const char *top, guint32 flags, CamelException *ex) -{ - CamelFolderInfo *fi = NULL; - CamelService *service = (CamelService *)store; - CamelFolder *folder; - - if (top == NULL || strcmp(top, "INBOX") == 0) { - fi = g_malloc0(sizeof(*fi)); - fi->full_name = g_strdup("INBOX"); - fi->name = g_strdup("INBOX"); - fi->url = g_strdup_printf("%s:%s#%s", service->url->protocol, service->url->path, fi->name); - - folder = camel_object_bag_get(store->folders, fi->full_name); - if (folder) { - fi->unread_message_count = camel_folder_get_unread_message_count(folder); - camel_object_unref(folder); - } else - fi->unread_message_count = -1; - - camel_folder_info_build_path(fi, '/'); - } - - return fi; -} - -static CamelFolderInfo * -get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex) -{ - if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX) - return get_folder_info_mbox(store, top, flags, ex); - else - return get_folder_info_elm(store, top, flags, ex); -} diff --git a/camel/providers/local/camel-spool-store.h b/camel/providers/local/camel-spool-store.h deleted file mode 100644 index 1e1753481b..0000000000 --- a/camel/providers/local/camel-spool-store.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2001 Ximian Inc (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_SPOOL_STORE_H -#define CAMEL_SPOOL_STORE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-mbox-store.h" - -#define CAMEL_SPOOL_STORE_TYPE (camel_spool_store_get_type ()) -#define CAMEL_SPOOL_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SPOOL_STORE_TYPE, CamelSpoolStore)) -#define CAMEL_SPOOL_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SPOOL_STORE_TYPE, CamelSpoolStoreClass)) -#define CAMEL_IS_SPOOL_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_SPOOL_STORE_TYPE)) - -typedef enum _camel_spool_store_t { - CAMEL_SPOOL_STORE_MBOX, /* a single mbox */ - CAMEL_SPOOL_STORE_ELM, /* elm/pine/etc tree of mbox files in folders */ -} camel_spool_store_t; - -typedef struct { - CamelMboxStore parent_object; - - camel_spool_store_t type; -} CamelSpoolStore; - - - -typedef struct { - CamelMboxStoreClass parent_class; - -} CamelSpoolStoreClass; - - -/* public methods */ - -/* Standard Camel function */ -CamelType camel_spool_store_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_SPOOL_STORE_H */ - - diff --git a/camel/providers/local/camel-spool-summary.c b/camel/providers/local/camel-spool-summary.c deleted file mode 100644 index 7991a881cc..0000000000 --- a/camel/providers/local/camel-spool-summary.c +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- - * - * Copyright (C) 2001 Ximian Inc. (www.ximian.com) - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include <ctype.h> - -#include "camel-spool-summary.h" -#include "camel-mime-message.h" -#include "camel-file-utils.h" -#include "camel-operation.h" - -#define io(x) -#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ - -#define CAMEL_SPOOL_SUMMARY_VERSION (0x400) - -static int spool_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex); -static int spool_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); - -static int spool_summary_sync_full(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); - -static void camel_spool_summary_class_init (CamelSpoolSummaryClass *klass); -static void camel_spool_summary_init (CamelSpoolSummary *obj); -static void camel_spool_summary_finalise (CamelObject *obj); - -static CamelFolderSummaryClass *camel_spool_summary_parent; - -CamelType -camel_spool_summary_get_type(void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register(camel_mbox_summary_get_type(), "CamelSpoolSummary", - sizeof (CamelSpoolSummary), - sizeof (CamelSpoolSummaryClass), - (CamelObjectClassInitFunc) camel_spool_summary_class_init, - NULL, - (CamelObjectInitFunc) camel_spool_summary_init, - (CamelObjectFinalizeFunc) camel_spool_summary_finalise); - } - - return type; -} - -static void -camel_spool_summary_class_init(CamelSpoolSummaryClass *klass) -{ - CamelLocalSummaryClass *lklass = (CamelLocalSummaryClass *)klass; - CamelMboxSummaryClass *mklass = (CamelMboxSummaryClass *)klass; - - camel_spool_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_mbox_summary_get_type()); - - lklass->load = spool_summary_load; - lklass->check = spool_summary_check; - - mklass->sync_full = spool_summary_sync_full; -} - -static void -camel_spool_summary_init(CamelSpoolSummary *obj) -{ - struct _CamelFolderSummary *s = (CamelFolderSummary *)obj; - - /* message info size is from mbox parent */ - - /* and a unique file version */ - s->version += CAMEL_SPOOL_SUMMARY_VERSION; -} - -static void -camel_spool_summary_finalise(CamelObject *obj) -{ - /*CamelSpoolSummary *mbs = CAMEL_SPOOL_SUMMARY(obj);*/ -} - -CamelSpoolSummary * -camel_spool_summary_new(const char *mbox_name) -{ - CamelSpoolSummary *new = (CamelSpoolSummary *)camel_object_new(camel_spool_summary_get_type()); - - camel_local_summary_construct((CamelLocalSummary *)new, NULL, mbox_name, NULL); - return new; -} - -static int -spool_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex) -{ - g_warning("spool summary - not loading anything\n"); - return 0; -} - -/* perform a full sync */ -static int -spool_summary_sync_full(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - int fd = -1, fdout = -1; - char *tmpname = NULL; - char *buffer, *p; - off_t spoollen, outlen; - int size, sizeout; - struct stat st; - guint32 flags = (expunge?1:0); - - d(printf("performing full summary/sync\n")); - - camel_operation_start(NULL, _("Storing folder")); - - fd = open(((CamelLocalSummary *)cls)->folder_path, O_RDWR); - if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open file: %s: %s"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno)); - camel_operation_end(NULL); - return -1; - } - -#ifdef HAVE_MKSTEMP - tmpname = alloca (64); - sprintf (tmpname, "/tmp/spool.camel.XXXXXX"); - fdout = mkstemp (tmpname); -#else -#warning "Your system has no mkstemp(3), spool updating may be insecure" - tmpname = alloca (L_tmpnam); - tmpnam (tmpname); - fdout = open (tmpname, O_RDWR|O_CREAT|O_EXCL, 0600); -#endif - d(printf("Writing tmp file to %s\n", tmpname)); - if (fdout == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot open temporary mailbox: %s"), - g_strerror (errno)); - goto error; - } - - if (camel_mbox_summary_sync_mbox((CamelMboxSummary *)cls, flags, changeinfo, fd, fdout, ex) == -1) - goto error; - - - /* sync out content */ - if (fsync(fdout) == -1) { - g_warning("Cannot sync temporary folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not sync temporary folder %s: %s"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno)); - goto error; - } - - /* see if we can write this much to the spool file */ - if (fstat(fd, &st) == -1) { - g_warning("Cannot sync temporary folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not sync temporary folder %s: %s"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno)); - goto error; - } - spoollen = st.st_size; - - if (fstat(fdout, &st) == -1) { - g_warning("Cannot sync temporary folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not sync temporary folder %s: %s"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno)); - goto error; - } - outlen = st.st_size; - - /* I think this is the right way to do this - checking that the file will fit the new data */ - if (outlen>0 - && (lseek(fd, outlen-1, SEEK_SET) == -1 - || write(fd, "", 1) != 1 - || fsync(fd) == -1 - || lseek(fd, 0, SEEK_SET) == -1 - || lseek(fdout, 0, SEEK_SET) == -1)) { - g_warning("Cannot sync spool folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not sync spool folder %s: %s"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno)); - /* incase we ran out of room, remove any trailing space first */ - ftruncate(fd, spoollen); - goto error; - } - - - /* now copy content back */ - buffer = g_malloc(8192); - size = 1; - while (size>0) { - do { - size = read(fdout, buffer, 8192); - } while (size == -1 && errno == EINTR); - - if (size > 0) { - p = buffer; - do { - sizeout = write(fd, p, size); - if (sizeout > 0) { - p+= sizeout; - size -= sizeout; - } - } while ((sizeout == -1 && errno == EINTR) && size > 0); - size = sizeout; - } - - if (size == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not sync spool folder %s: %s\n" - "Folder may be corrupt, copy saved in `%s'"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno), tmpnam); - /* so we dont delete it */ - close(fdout); - tmpname = NULL; - fdout = -1; - g_free(buffer); - goto error; - } - } - - g_free(buffer); - - d(printf("Closing folders\n")); - - if (ftruncate(fd, outlen) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not sync spool folder %s: %s\n" - "Folder may be corrupt, copy saved in `%s'"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno), tmpnam); - close(fdout); - tmpname = NULL; - fdout = -1; - goto error; - } - - if (close(fd) == -1) { - g_warning("Cannot close source folder: %s", strerror (errno)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not sync spool folder %s: %s\n" - "Folder may be corrupt, copy saved in `%s'"), - ((CamelLocalSummary *)cls)->folder_path, - g_strerror (errno), tmpnam); - close(fdout); - tmpname = NULL; - fdout = -1; - fd = -1; - goto error; - } - - close(fdout); - unlink(tmpname); - - camel_operation_end(NULL); - - return 0; - error: - if (fd != -1) - close(fd); - - if (fdout != -1) - close(fdout); - - if (tmpname) - unlink(tmpname); - - camel_operation_end(NULL); - - return -1; -} - -static int -spool_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - int i, work, count; - struct stat st; - CamelFolderSummary *s = (CamelFolderSummary *)cls; - - if (((CamelLocalSummaryClass *)camel_spool_summary_parent)->check(cls, changeinfo, ex) == -1) - return -1; - - /* check to see if we need to copy/update the file; missing xev headers prompt this */ - work = FALSE; - count = camel_folder_summary_count(s); - for (i=0;!work && i<count; i++) { - CamelMessageInfo *info = camel_folder_summary_index(s, i); - g_assert(info); - work = (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0; - camel_folder_summary_info_free(s, info); - } - - /* if we do, then write out the headers using sync_full, etc */ - if (work) { - d(printf("Have to add new headers, re-syncing from the start to accomplish this\n")); - if (((CamelMboxSummaryClass *)((CamelObject *)cls)->klass)->sync_full((CamelMboxSummary *)cls, FALSE, changeinfo, ex) == -1) - return -1; - - if (stat(cls->folder_path, &st) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Unknown error: %s"), - g_strerror (errno)); - return -1; - } - - ((CamelMboxSummary *)cls)->folder_size = st.st_size; - ((CamelFolderSummary *)cls)->time = st.st_mtime; - } - - return 0; -} diff --git a/camel/providers/local/camel-spool-summary.h b/camel/providers/local/camel-spool-summary.h deleted file mode 100644 index b72aeda527..0000000000 --- a/camel/providers/local/camel-spool-summary.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2001 Ximian Inc. (www.ximian.com) - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _CAMEL_SPOOL_SUMMARY_H -#define _CAMEL_SPOOL_SUMMARY_H - -#include <camel/camel-folder-summary.h> -#include <camel/camel-folder.h> -#include <camel/camel-exception.h> -#include <camel/camel-index.h> -#include "camel-mbox-summary.h" - -#define CAMEL_SPOOL_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_spool_summary_get_type (), CamelSpoolSummary) -#define CAMEL_SPOOL_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_spool_summary_get_type (), CamelSpoolSummaryClass) -#define CAMEL_IS_SPOOL_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_spool_summary_get_type ()) - -typedef struct _CamelSpoolSummary CamelSpoolSummary; -typedef struct _CamelSpoolSummaryClass CamelSpoolSummaryClass; - -struct _CamelSpoolSummary { - CamelMboxSummary parent; - -}; - -struct _CamelSpoolSummaryClass { - CamelMboxSummaryClass parent_class; -}; - -CamelType camel_spool_summary_get_type (void); -void camel_spool_summary_construct (CamelSpoolSummary *new, const char *filename, const char *spool_name, CamelIndex *index); - -/* create the summary, in-memory only */ -CamelSpoolSummary *camel_spool_summary_new(const char *filename); - -/* load/check the summary */ -int camel_spool_summary_load(CamelSpoolSummary *cls, int forceindex, CamelException *ex); -/* check for new/removed messages */ -int camel_spool_summary_check(CamelSpoolSummary *cls, CamelFolderChangeInfo *, CamelException *ex); -/* perform a folder sync or expunge, if needed */ -int camel_spool_summary_sync(CamelSpoolSummary *cls, gboolean expunge, CamelFolderChangeInfo *, CamelException *ex); -/* add a new message to the summary */ -CamelMessageInfo *camel_spool_summary_add(CamelSpoolSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex); - -/* generate an X-Evolution header line */ -char *camel_spool_summary_encode_x_evolution(CamelSpoolSummary *cls, const CamelMessageInfo *info); -int camel_spool_summary_decode_x_evolution(CamelSpoolSummary *cls, const char *xev, CamelMessageInfo *info); - -/* utility functions - write headers to a file with optional X-Evolution header */ -int camel_spool_summary_write_headers(int fd, struct _camel_header_raw *header, char *xevline); - -#endif /* ! _CAMEL_SPOOL_SUMMARY_H */ - diff --git a/camel/providers/local/libcamellocal.urls b/camel/providers/local/libcamellocal.urls deleted file mode 100644 index e2279ed72a..0000000000 --- a/camel/providers/local/libcamellocal.urls +++ /dev/null @@ -1,5 +0,0 @@ -mh -mbox -maildir -spool -spoold |