diff options
Diffstat (limited to 'camel/providers')
104 files changed, 0 insertions, 16636 deletions
diff --git a/camel/providers/.cvsignore b/camel/providers/.cvsignore deleted file mode 100644 index 3dda72986f..0000000000 --- a/camel/providers/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/camel/providers/Makefile.am b/camel/providers/Makefile.am deleted file mode 100644 index dedeaa0b3b..0000000000 --- a/camel/providers/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# SUBDIRS = mbox pop3 sendmail smtp vee -SUBDIRS = mbox pop3 sendmail smtp vee imap mh nntp - -# these ones are disabled for the moment. -# maildir diff --git a/camel/providers/cache/.cvsignore b/camel/providers/cache/.cvsignore deleted file mode 100644 index fd6b811c68..0000000000 --- a/camel/providers/cache/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la diff --git a/camel/providers/cache/Makefile.am b/camel/providers/cache/Makefile.am deleted file mode 100644 index 7f9f6a9df5..0000000000 --- a/camel/providers/cache/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -## Process this file with automake to produce Makefile.in - -SUBDIRS = - -libcamelcacheincludedir = $(includedir)/camel - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelcache.la -provider_DATA = libcamelcache.urls - -INCLUDES = \ - -I.. \ - -I$(srcdir)/.. \ - -I$(srcdir)/../../.. \ - -I$(includedir) \ - -I$(top_srcdir)/intl \ - $(GTK_INCLUDEDIR) \ - -I$(top_srcdir)/camel \ - -DG_LOG_DOMAIN=\"camel-cache-provider\" - -libcamelcache_la_SOURCES = \ - camel-cache-folder.c \ - camel-cache-provider.c \ - camel-cache-store.c \ - camel-cache-map.c - -libcamelcacheinclude_HEADERS = \ - camel-cache-folder.h \ - camel-cache-store.h - - -libcamelcache_la_LDFLAGS = -version-info 0:0:0 - -EXTRA_DIST = libcamelcache.urls diff --git a/camel/providers/cache/camel-cache-folder.c b/camel/providers/cache/camel-cache-folder.c deleted file mode 100644 index c4379f8135..0000000000 --- a/camel/providers/cache/camel-cache-folder.c +++ /dev/null @@ -1,810 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-cache-folder.c : class for a cache folder */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -/* - * Notes on the cache provider: - * - * We require that the remote folder have persistent UIDs, and nothing - * else. We require that the local store folder have persistent UIDs - * and summary capability. - * - * If the remote folder does not have summary capability, we will need - * to sync any new messages over to the local folder when the folder - * is opened or when it changes. If the remote folder does have - * summary capability, we can be more relaxed about doing this. - * - * If the remote folder has search capability, we will use it, at - * least when the folder isn't synced. Otherwise if the local folder - * has search capability, we will use that (but it will require - * syncing the remote folder locally to use). Otherwise the cache - * folder won't have search capability. - * - * CamelCacheFolder UIDs are remote UIDs, because we need to be able - * to return a complete list of them at get_uids time, and the - * messages might not all be present in the local folder, and we can't - * predict what UIDs will be assigned to them when they are cached - * there. We keep hash tables mapping remote to local UIDs and vice - * versa, and a map file to cache this information between sessions. - * The maps must always be 100% accurate. - * - * The messages in the local folder may not be in the same order as - * the messages in the remote folder. - * - * - * Many operations on the local folder are done with a NULL - * CamelException, because having them fail only results in efficiency - * problems, not actual permanent failures. (Eg, get_message will - * try to append the message to the local folder, but doesn't check - * for failure, because it already has the message to pass back to the - * user.) - */ - -#include "camel-cache-folder.h" -#include "camel-cache-store.h" -#include <camel/camel-exception.h> -#include <camel/camel-medium.h> - -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -static CamelFolderClass *folder_class = NULL; - -static void init (CamelFolder *folder, CamelStore *parent_store, - CamelFolder *parent_folder, const gchar *name, - gchar *separator, gboolean path_begins_with_sep, - CamelException *ex); - -static void refresh_info (CamelFolder *folder, CamelException *ex); - -static void cache_sync (CamelFolder *folder, gboolean expunge, - CamelException *ex); - -static void expunge (CamelFolder *folder, CamelException *ex); - -static gint get_message_count (CamelFolder *folder); - -static void append_message (CamelFolder *folder, CamelMimeMessage *message, - const CamelMessageInfo *info, CamelException *ex); - -static guint32 get_message_flags (CamelFolder *folder, const char *uid); -static void set_message_flags (CamelFolder *folder, const char *uid, - guint32 flags, guint32 set); -static gboolean get_message_user_flag (CamelFolder *folder, const char *uid, - const char *name); -static void set_message_user_flag (CamelFolder *folder, const char *uid, - const char *name, gboolean value); -static const char *get_message_user_tag (CamelFolder *folder, const char *uid, - const char *name); -static void set_message_user_tag (CamelFolder *folder, const char *uid, - const char *name, const char *value); - -static CamelMimeMessage *get_message (CamelFolder *folder, - const gchar *uid, - CamelException *ex); - -static GPtrArray *get_uids (CamelFolder *folder); -static GPtrArray *get_summary (CamelFolder *folder); -static GPtrArray *get_subfolder_names (CamelFolder *folder); -static void free_subfolder_names (CamelFolder *folder, GPtrArray *subfolders); - -static GPtrArray *search_by_expression (CamelFolder *folder, - const char *expression, - CamelException *ex); - -static const CamelMessageInfo *get_message_info (CamelFolder *folder, - const char *uid); - -static void copy_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex); - -static void move_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex); - -static void finalize (CamelObject *object); - -static void -camel_cache_folder_class_init (CamelCacheFolderClass *camel_cache_folder_class) -{ - CamelFolderClass *camel_folder_class = - CAMEL_FOLDER_CLASS (camel_cache_folder_class); - - folder_class = CAMEL_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_folder_get_type ())); - - /* virtual method overload */ - camel_folder_class->init = init; - camel_folder_class->refresh_info = refresh_info; - camel_folder_class->sync = cache_sync; - camel_folder_class->expunge = expunge; - camel_folder_class->get_message_count = get_message_count; - camel_folder_class->append_message = append_message; - camel_folder_class->get_message_flags = get_message_flags; - camel_folder_class->set_message_flags = set_message_flags; - camel_folder_class->get_message_user_flag = get_message_user_flag; - camel_folder_class->set_message_user_flag = set_message_user_flag; - camel_folder_class->get_message_user_tag = get_message_user_tag; - camel_folder_class->set_message_user_tag = set_message_user_tag; - camel_folder_class->get_message = get_message; - camel_folder_class->get_uids = get_uids; - camel_folder_class->free_uids = camel_folder_free_nop; - camel_folder_class->get_summary = get_summary; - camel_folder_class->free_summary = camel_folder_free_nop; - camel_folder_class->get_subfolder_names = get_subfolder_names; - camel_folder_class->free_subfolder_names = free_subfolder_names; - camel_folder_class->search_by_expression = search_by_expression; - camel_folder_class->get_message_info = get_message_info; - camel_folder_class->copy_message_to = copy_message_to; - camel_folder_class->move_message_to = move_message_to; -} - -CamelType -camel_cache_folder_get_type (void) -{ - static CamelType camel_cache_folder_type = CAMEL_INVALID_TYPE; - - if (camel_cache_folder_type == CAMEL_INVALID_TYPE) { - camel_cache_folder_type = camel_type_register ( - CAMEL_FOLDER_TYPE, "CamelCacheFolder", - sizeof (CamelCacheFolder), - sizeof (CamelCacheFolderClass), - (CamelObjectClassInitFunc) camel_cache_folder_class_init, - NULL, - NULL, - (CamelObjectFinalizeFunc) finalize); - } - - return camel_cache_folder_type; -} - - -static void -cache_free_summary (CamelCacheFolder *cache_folder) -{ - if (cache_folder->remote_summary) { - camel_folder_free_summary (cache_folder->remote, - cache_folder->summary); - } else { - int i; - - for (i = 0; i < cache_folder->summary->len; i++) { - camel_message_info_free ( - cache_folder->summary->pdata[i]); - } - g_ptr_array_free (cache_folder->summary, TRUE); - g_hash_table_destroy (cache_folder->summary_uids); - } -} - -static void -finalize (CamelObject *object) -{ - CamelCacheFolder *cache_folder = CAMEL_CACHE_FOLDER (object); - - if (cache_folder->uids) { - camel_folder_free_uids (cache_folder->remote, - cache_folder->uids); - } - if (cache_folder->summary) - cache_free_summary (cache_folder); - - if (cache_folder->uidmap) - camel_cache_map_destroy (cache_folder->uidmap); - - camel_object_unref (CAMEL_OBJECT (cache_folder->local)); - camel_object_unref (CAMEL_OBJECT (cache_folder->remote)); - - g_free (cache_folder->mapfile); -} - - -static void -update (CamelCacheFolder *cache_folder, CamelException *ex) -{ - if (cache_folder->uids) { - camel_folder_free_uids (cache_folder->remote, - cache_folder->uids); - } - cache_folder->uids = camel_folder_get_uids (cache_folder->remote); - - if (cache_folder->summary) - cache_free_summary (cache_folder); - - if (cache_folder->remote_summary) { - cache_folder->summary = - camel_folder_get_summary (cache_folder->remote); - } else { - CamelMessageInfo *mi; - GPtrArray *lsummary; - const char *ruid; - int i; - - if (!cache_folder->is_synced) { - camel_cache_folder_sync (cache_folder, ex); - if (camel_exception_is_set (ex)) - return; - } - - cache_folder->summary = g_ptr_array_new (); - cache_folder->summary_uids = g_hash_table_new (g_str_hash, - g_str_equal); - - lsummary = camel_folder_get_summary (cache_folder->local); - - /* For each local message, duplicate its info, replace - * the uid with the remote one, and add it to the - * uid->info cache. - */ - for (i = 0; i < lsummary->len; i++) { - mi = lsummary->pdata[i]; - ruid = camel_cache_map_get_remote (cache_folder->uidmap, mi->uid); - if (!ruid) { - /* Stale message. Delete it from cache. */ - camel_folder_delete_message ( - cache_folder->local, mi->uid); - continue; - } - - mi = g_new (CamelMessageInfo, 1); - camel_message_info_dup_to (lsummary->pdata[i], mi); - g_free (mi->uid); - mi->uid = g_strdup (ruid); - g_hash_table_insert (cache_folder->summary_uids, - mi->uid, mi); - } - camel_folder_free_summary (cache_folder->local, lsummary); - - /* Now build the summary array in remote UID order. */ - for (i = 0; i < cache_folder->uids->len; i++) { - mi = g_hash_table_lookup (cache_folder->summary_uids, - cache_folder->uids->pdata[i]); - g_ptr_array_add (cache_folder->summary, mi); - } - } - -} - -static void -init (CamelFolder *folder, CamelStore *parent_store, - CamelFolder *parent_folder, const gchar *name, gchar *separator, - gboolean path_begins_with_sep, CamelException *ex) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - char *path; - - CF_CLASS (folder)->init (folder, parent_store, parent_folder, - name, separator, path_begins_with_sep, ex); - if (camel_exception_is_set (ex)) - return; - - folder->permanent_flags = - camel_folder_get_permanent_flags (cache_folder->local); - folder->can_hold_folders = cache_folder->remote->can_hold_folders; - folder->can_hold_messages = cache_folder->remote->can_hold_messages; - folder->has_summary_capability = TRUE; - folder->has_search_capability = - camel_folder_has_search_capability (cache_folder->local) || - camel_folder_has_search_capability (cache_folder->remote); - - cache_folder->remote_summary = - camel_folder_has_summary_capability (cache_folder->remote); - - /* Load UIDs, summary, etc. */ - path = CAMEL_SERVICE (cache_folder->local->parent_store)->url->path; - cache_folder->mapfile = g_strdup_printf ("%s/%s.map", path, name); - cache_folder->uidmap = camel_cache_map_new (); - camel_cache_map_read (cache_folder->uidmap, cache_folder->mapfile, ex); - if (camel_exception_is_set (ex)) - return; - update (cache_folder, ex); - - return; -} - -/* If the remote folder changes, cache the new messages if necessary, - * update the summary, and propagate the signal. - */ -static void -remote_folder_changed (CamelObject *remote_folder, gpointer type, - gpointer user_data) -{ - CamelCacheFolder *cache_folder = user_data; - - update (cache_folder, NULL); - camel_object_trigger_event (CAMEL_OBJECT (cache_folder), - "folder_changed", type); -} - -/* If the local folder changes, it's because we just cached a message - * or expunged messages. Look for new messages and update the UID maps. - */ -static void -local_folder_changed (CamelObject *local, gpointer type, gpointer data) -{ - CamelFolder *local_folder = CAMEL_FOLDER (local); - CamelCacheFolder *cache_folder = data; - CamelMimeMessage *msg; - GPtrArray *new_luids; - char *luid; - const char *ruid; - int i; - - /* Get the updated list of local UIDs. For any that we didn't - * already know about, figure out the corresponding remote - * UID. - */ - new_luids = camel_folder_get_uids (local_folder); - for (i = 0; i < new_luids->len; i++) { - luid = new_luids->pdata[i]; - if (!camel_cache_map_get_remote (cache_folder->uidmap, luid)) { - msg = camel_folder_get_message (local_folder, - luid, NULL); - if (!msg) - continue; /* Hrmph. */ - ruid = camel_medium_get_header (CAMEL_MEDIUM (msg), - "X-Evolution-Remote-UID"); - if (!ruid) { - /* How'd that get here? */ - camel_folder_delete_message (local_folder, - luid); - continue; - } - - camel_cache_map_update (cache_folder->uidmap, - luid, ruid); - } - } - camel_folder_free_uids (local_folder, new_luids); - - /* FIXME: the uidmaps contain bad data now. */ -} - -/* DONE */ -static void -refresh_info (CamelFolder *folder, CamelException *ex) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - camel_folder_refresh_info (cache_folder->remote, ex); -} - -/* DONE */ -static void -cache_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - camel_folder_sync (cache_folder->remote, expunge, ex); - if (!camel_exception_is_set (ex)) { - camel_folder_sync (cache_folder->local, expunge, NULL); - camel_cache_map_write (cache_folder->uidmap, - cache_folder->mapfile, ex); - } -} - -/* DONE */ -static void -expunge (CamelFolder *folder, CamelException *ex) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - camel_folder_expunge (cache_folder->remote, ex); - if (!camel_exception_is_set (ex)) - camel_folder_expunge (cache_folder->local, NULL); -} - -/* DONE */ -static gint -get_message_count (CamelFolder *folder) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - return cache_folder->summary->len; -} - -/* DONE */ -static void -append_message (CamelFolder *folder, CamelMimeMessage *message, - const CamelMessageInfo *info, CamelException *ex) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - /* We'd like to cache this locally as well, but we have no - * 100% reliable way to determine the UID assigned to the - * remote message, so we can't. - */ - camel_folder_append_message (cache_folder->remote, message, info, ex); -} - -/* DONE */ -static guint32 -get_message_flags (CamelFolder *folder, const char *uid) -{ - const CamelMessageInfo *mi; - - mi = get_message_info (folder, uid); - g_return_val_if_fail (mi != NULL, 0); - return mi->flags; -} - -/* DONE */ -static void -set_message_flags (CamelFolder *folder, const char *uid, - guint32 flags, guint32 set) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - const char *luid; - - luid = camel_cache_map_get_local (cache_folder->uidmap, uid); - if (luid) { - camel_folder_set_message_flags (cache_folder->local, luid, - flags, set); - } - camel_folder_set_message_flags (cache_folder->remote, uid, flags, set); -} - -/* DONE */ -static gboolean -get_message_user_flag (CamelFolder *folder, const char *uid, const char *name) -{ - const CamelMessageInfo *mi; - - mi = get_message_info (folder, uid); - g_return_val_if_fail (mi != NULL, 0); - return camel_flag_get ((CamelFlag **)&mi->user_flags, name); -} - -/* DONE */ -static void -set_message_user_flag (CamelFolder *folder, const char *uid, - const char *name, gboolean value) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - const char *luid; - - luid = camel_cache_map_get_local (cache_folder->uidmap, uid); - if (luid) { - camel_folder_set_message_user_flag (cache_folder->local, luid, - name, value); - } - camel_folder_set_message_user_flag (cache_folder->remote, uid, - name, value); -} - - -/* DONE */ -static const char * -get_message_user_tag (CamelFolder *folder, const char *uid, const char *name) -{ - const CamelMessageInfo *mi; - - mi = get_message_info (folder, uid); - g_return_val_if_fail (mi != NULL, NULL); - return camel_tag_get ((CamelTag **)&mi->user_tags, name); -} - -/* DONE */ -static void -set_message_user_tag (CamelFolder *folder, const char *uid, - const char *name, const char *value) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - const char *luid; - - luid = camel_cache_map_get_local (cache_folder->uidmap, uid); - if (luid) { - camel_folder_set_message_user_tag (cache_folder->local, luid, - name, value); - } - camel_folder_set_message_user_tag (cache_folder->remote, uid, - name, value); -} - - -/* DONE */ -static CamelMimeMessage * -get_message (CamelFolder *folder, const gchar *uid, CamelException *ex) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - CamelMimeMessage *msg; - const CamelMessageInfo *info; - const char *luid; - - /* Check if we have it cached first. */ - luid = camel_cache_map_get_local (cache_folder->uidmap, uid); - if (luid) { - msg = camel_folder_get_message (cache_folder->local, - luid, NULL); - if (msg) - return msg; - - /* Hm... Oh well. Update the map and try for real. */ - camel_cache_map_remove (cache_folder->uidmap, NULL, uid); - } - - /* OK. It's not cached. Get the remote message. */ - msg = camel_folder_get_message (cache_folder->remote, uid, ex); - if (!msg) - return NULL; - info = camel_folder_get_message_info (cache_folder->remote, uid); - - /* Add a header giving the remote UID and append it to the - * local folder. (This should eventually invoke - * local_folder_changed(), which will take care of updating - * the uidmaps.) - */ - camel_medium_add_header (CAMEL_MEDIUM (msg), "X-Evolution-Remote-UID", - uid); - camel_folder_append_message (cache_folder->local, msg, info, NULL); - - return msg; -} - -/* DONE */ -static GPtrArray * -get_uids (CamelFolder *folder) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - return cache_folder->uids; -} - -/* DONE */ -static GPtrArray * -get_summary (CamelFolder *folder) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - return cache_folder->summary; -} - -/* DONE */ -static GPtrArray * -get_subfolder_names (CamelFolder *folder) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - return camel_folder_get_subfolder_names (cache_folder->remote); -} - -/* DONE */ -static void -free_subfolder_names (CamelFolder *folder, GPtrArray *subfolders) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - camel_folder_free_subfolder_names (cache_folder->remote, subfolders); -} - -/* DONE */ -static GPtrArray * -search_by_expression (CamelFolder *folder, const char *expression, - CamelException *ex) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - /* Search on the remote folder if we're not synced. */ - if (!cache_folder->is_synced && - camel_folder_has_search_capability (cache_folder->remote)) { - return camel_folder_search_by_expression (cache_folder->remote, - expression, ex); - } else { - GPtrArray *matches; - const char *ruid; - int i; - - if (!cache_folder->is_synced) - camel_cache_folder_sync (cache_folder, ex); - if (camel_exception_is_set (ex)) - return NULL; - matches = search_by_expression (cache_folder->local, - expression, ex); - if (camel_exception_is_set (ex)) - return NULL; - - /* Convert local uids to remote. */ - for (i = 0; i < matches->len; i++) { - ruid = camel_cache_map_get_remote (cache_folder->uidmap, - matches->pdata[i]); - g_free (matches->pdata[i]); - matches->pdata[i] = g_strdup (ruid); - } - - return matches; - } -} - -/* DONE */ -static const CamelMessageInfo * -get_message_info (CamelFolder *folder, const char *uid) -{ - CamelCacheFolder *cache_folder = (CamelCacheFolder *)folder; - - if (cache_folder->remote_summary) { - return camel_folder_get_message_info (cache_folder->remote, - uid); - } else - return g_hash_table_lookup (cache_folder->summary_uids, uid); -} - -/* DONE */ -static void -copy_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex) -{ - CamelCacheFolder *source_cache_folder = (CamelCacheFolder *)source; - CamelCacheFolder *dest_cache_folder = (CamelCacheFolder *)destination; - - /* If we are here, we know that the folders have the same parent - * store, which implies their remote and local folders have the - * same parent store as well. - */ - - if (CF_CLASS (source_cache_folder->remote)->copy_message_to != - folder_class->copy_message_to) { - /* The remote store has a non-default copy method, so - * use it to avoid unnecessary network traffic. - */ - CF_CLASS (source_cache_folder->remote)->copy_message_to ( - source_cache_folder->remote, uid, - dest_cache_folder->remote, ex); - } else { - /* The remote store uses the default copy method, - * meaning if we proxy the copy_message_to over to it, - * it will suck the message over the network. We may - * already have a local copy, and if we don't, we want - * to, and if we're going to have the message in - * memory, then we should get it into the destination - * cache too. So do this by hand. - */ - CamelMimeMessage *msg; - const CamelMessageInfo *info; - - msg = get_message (source, uid, ex); - if (camel_exception_is_set (ex)) - return; - info = camel_folder_get_message_info (source, uid); - - camel_medium_remove_header (CAMEL_MEDIUM (msg), - "X-Evolution-Remote-UID"); - append_message (destination, msg, info, ex); - } -} - -/* DONE */ -static void -move_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex) -{ - CamelCacheFolder *source_cache_folder = (CamelCacheFolder *)source; - CamelCacheFolder *dest_cache_folder = (CamelCacheFolder *)destination; - - /* See comments in copy_message_to. */ - - if (CF_CLASS (source_cache_folder)->move_message_to != - folder_class->move_message_to) { - CF_CLASS (source_cache_folder)->move_message_to ( - source_cache_folder->remote, uid, - dest_cache_folder->remote, ex); - } else { - CamelMimeMessage *msg; - const CamelMessageInfo *info; - - msg = get_message (source, uid, ex); - if (camel_exception_is_set (ex)) - return; - info = camel_folder_get_message_info (source, uid); - - camel_medium_remove_header (CAMEL_MEDIUM (msg), - "X-Evolution-Remote-UID"); - append_message (destination, msg, info, ex); - if (!camel_exception_is_set (ex)) - camel_folder_delete_message (source, uid); - } -} - - -CamelFolder * -camel_cache_folder_new (CamelStore *store, CamelFolder *parent, - CamelFolder *remote, CamelFolder *local, - CamelException *ex) -{ - CamelCacheFolder *cache_folder; - CamelFolder *folder; - - cache_folder = CAMEL_CACHE_FOLDER (camel_object_new (CAMEL_CACHE_FOLDER_TYPE)); - folder = (CamelFolder *)cache_folder; - - cache_folder->local = local; - camel_object_ref (CAMEL_OBJECT (local)); - camel_object_hook_event (CAMEL_OBJECT (local), "folder_changed", - local_folder_changed, cache_folder); - - cache_folder->remote = remote; - camel_object_ref (CAMEL_OBJECT (remote)); - camel_object_hook_event (CAMEL_OBJECT (remote), "folder_changed", - remote_folder_changed, cache_folder); - - /* XXX */ - - return folder; -} - -void -camel_cache_folder_sync (CamelCacheFolder *cache_folder, CamelException *ex) -{ - CamelMimeMessage *msg; - const char *ruid, *luid; - int lsize, i; - const CamelMessageInfo *info; - - lsize = camel_folder_get_message_count (cache_folder->local); - - camel_folder_freeze (cache_folder->local); - for (i = 0; i < cache_folder->uids->len; i++) { - ruid = cache_folder->uids->pdata[i]; - luid = camel_cache_map_get_local (cache_folder->uidmap, ruid); - - /* Don't re-copy messages we already have. */ - if (luid && - camel_folder_get_message_info (cache_folder->local, luid)) - continue; - - msg = camel_folder_get_message (cache_folder->remote, - ruid, ex); - if (camel_exception_is_set (ex)) - return; - info = camel_folder_get_message_info (cache_folder->remote, - ruid); - - camel_medium_add_header (CAMEL_MEDIUM (msg), - "X-Evolution-Remote-UID", ruid); - camel_folder_append_message (cache_folder->local, msg, - info, ex); - if (camel_exception_is_set (ex)) - return; - } - camel_folder_thaw (cache_folder->local); -} - -static void -get_mappings (CamelCacheFolder *cache_folder, int first, CamelException *ex) -{ - GPtrArray *uids; - CamelMimeMessage *msg; - const char *ruid; - int i; - - uids = camel_folder_get_uids (cache_folder->local); - for (i = first; i < uids->len; i++) { - msg = camel_folder_get_message (cache_folder->local, - uids->pdata[i], ex); - if (!msg) - break; - ruid = camel_medium_get_header (CAMEL_MEDIUM (msg), - "X-Evolution-Remote-UID"); - - camel_cache_map_add (cache_folder->uidmap, - uids->pdata[i], ruid); - } - camel_folder_free_uids (cache_folder->local, uids); -} diff --git a/camel/providers/cache/camel-cache-folder.h b/camel/providers/cache/camel-cache-folder.h deleted file mode 100644 index 3609de4d67..0000000000 --- a/camel/providers/cache/camel-cache-folder.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-cache-folder.h: Class for a cache folder */ - -/* - * Author: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_CACHE_FOLDER_H -#define CAMEL_CACHE_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <camel/camel-folder.h> -#include "camel-cache-map.h" - -#define CAMEL_CACHE_FOLDER_TYPE (camel_cache_folder_get_type ()) -#define CAMEL_CACHE_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_CACHE_FOLDER_TYPE, CamelCacheFolder)) -#define CAMEL_CACHE_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_CACHE_FOLDER_TYPE, CamelCacheFolderClass)) -#define IS_CAMEL_CACHE_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_CACHE_FOLDER_TYPE)) - - -typedef struct { - CamelFolder parent_object; - - /* Remote and local folders */ - CamelFolder *remote, *local; - - /* Remote UIDs, in order, summary, and uid->info map if - * summary is from local info. - */ - GPtrArray *uids, *summary; - GHashTable *summary_uids; - - /* UID map */ - CamelCacheMap *uidmap; - char *mapfile; - - /* Is the summary remote? Is the folder known to be synced? */ - gboolean remote_summary, is_synced; - -} CamelCacheFolder; - - - -typedef struct { - CamelFolderClass parent_class; - - /* Virtual methods */ - -} CamelCacheFolderClass; - - -CamelFolder *camel_cache_folder_new (CamelStore *store, CamelFolder *parent, - CamelFolder *remote, CamelFolder *local, - CamelException *ex); - -void camel_cache_folder_sync (CamelCacheFolder *cache_folder, - CamelException *ex); - -/* Standard Camel function */ -CamelType camel_cache_folder_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_CACHE_FOLDER_H */ diff --git a/camel/providers/cache/camel-cache-map.c b/camel/providers/cache/camel-cache-map.c deleted file mode 100644 index d3cece6f60..0000000000 --- a/camel/providers/cache/camel-cache-map.c +++ /dev/null @@ -1,255 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-cache-map.c : functions for a local<->remote uid map */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "camel-cache-map.h" -#include <camel/camel-exception.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> - -/** - * camel_cache_map_new: - * - * Return value: a new CamelCacheMap - **/ -CamelCacheMap * -camel_cache_map_new (void) -{ - CamelCacheMap *map = g_new (CamelCacheMap, 1); - - map->l2r = g_hash_table_new (g_str_hash, g_str_equal); - map->r2l = g_hash_table_new (g_str_hash, g_str_equal); - - return map; -} - -static void -free_mapping (gpointer key, gpointer value, gpointer data) -{ - g_free (key); - g_free (data); -} - -/** - * camel_cache_map_destroy: - * @map: a CamelCacheMap - * - * Frees @map and all of the data stored in it. - **/ -void -camel_cache_map_destroy (CamelCacheMap *map) -{ - g_hash_table_foreach (map->l2r, free_mapping, NULL); - g_hash_table_destroy (map->l2r); - g_hash_table_destroy (map->r2l); - g_free (map); -} - -/** - * camel_cache_map_add: - * @map: a CamelCacheMap - * @luid: the local uid - * @ruid: the remote uid - * - * Adds a mapping between @luid and @ruid. If either already exists - * in the map, this may leak memory and result in incorrect map entries. - * Use camel_cache_map_update() in that case instead. - **/ -void -camel_cache_map_add (CamelCacheMap *map, const char *luid, const char *ruid) -{ - char *map_luid = g_strdup (luid); - char *map_ruid = g_strdup (ruid); - - g_hash_table_insert (map->l2r, map_luid, map_ruid); - g_hash_table_insert (map->r2l, map_ruid, map_luid); -} - -/** - * camel_cache_map_remove: - * @map: a CamelCacheMap - * @luid: the local uid - * @ruid: the remote uid - * - * Removes the mapping between @luid and @ruid. Either (but not both) - * of the uids can be %NULL if they are not both known. - **/ -void -camel_cache_map_remove (CamelCacheMap *map, const char *luid, const char *ruid) -{ - gpointer map_luid, map_ruid; - - if ((luid && g_hash_table_lookup_extended (map->l2r, luid, - &map_luid, &map_ruid)) || - (ruid && g_hash_table_lookup_extended (map->r2l, ruid, - &map_luid, &map_ruid))) { - g_hash_table_remove (map->l2r, map_luid); - g_hash_table_remove (map->r2l, map_ruid); - g_free (map_luid); - g_free (map_ruid); - } -} - -/** - * camel_cache_map_update: - * @map: a CamelCacheMap - * @luid: the local uid - * @ruid: the remote uid - * - * Updates the mappings to associate @luid with @ruid, clearing any - * previous mappings for both of them. - **/ -void -camel_cache_map_update (CamelCacheMap *map, const char *luid, const char *ruid) -{ - camel_cache_map_remove (map, luid, ruid); - camel_cache_map_add (map, luid, ruid); -} - -/** - * camel_cache_map_get_local - * @map: a CamelCacheMap - * @ruid: the remote uid - * - * Return value: the corresponding local uid, or %NULL - **/ -const char * -camel_cache_map_get_local (CamelCacheMap *map, const char *ruid) -{ - return g_hash_table_lookup (map->r2l, ruid); -} - -/** - * camel_cache_map_get_remote - * @map: a CamelCacheMap - * @luid: the local uid - * - * Return value: the corresponding remote uid, or %NULL - **/ -const char * -camel_cache_map_get_remote (CamelCacheMap *map, const char *luid) -{ - return g_hash_table_lookup (map->l2r, luid); -} - - - -static void -write_mapping (gpointer key, gpointer value, gpointer user_data) -{ - int fd = *(int *)user_data; - - /* FIXME: We assume the local UID has no ':'s in it. */ - write (fd, key, strlen (key)); - write (fd, ":", 1); - write (fd, value, strlen (value)); - write (fd, "\n", 1); -} - -/** - * camel_cache_map_write: - * @map: a CamelCacheMap - * @file: the filename to write the map to - * @ex: a CamelException - * - * Writes @map out to @file, setting @ex if something goes wrong. - **/ -void -camel_cache_map_write (CamelCacheMap *map, const char *file, - CamelException *ex) -{ - int fd; - char *tmpfile; - - tmpfile = g_strdup_printf ("%s~", file); - fd = open (tmpfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); - if (fd == -1) { - g_free (tmpfile); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not create cache map file: %s", - g_strerror (errno)); - return; - } - - g_hash_table_foreach (map->l2r, write_mapping, &fd); - - if (close (fd) == -1 || - rename (tmpfile, file) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not save cache map file: %s", - g_strerror (errno)); - unlink (tmpfile); - } - g_free (tmpfile); -} - -/** - * camel_cache_map_read: - * @map: a CamelCacheMap - * @file: the filename to read the map from - * @ex: a CamelException - * - * Reads @map from @file, setting @ex if something goes wrong. @map - * should be a freshly-created CamelCacheMap. - **/ -void -camel_cache_map_read (CamelCacheMap *map, const char *file, CamelException *ex) -{ - FILE *f; - char buf[1024], *p, *q; - - /* FIXME: lazy implementation. We could make this work with - * lines longer than 1024 chars. :) - */ - - f = fopen (file, "r"); - if (!f) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not open cache map file: %s", - g_strerror (errno)); - return; - } - - while (fgets (buf, sizeof (buf), f)) { - p = strchr (buf, ':'); - if (p) - q = strchr (buf, '\n'); - if (!p || !q) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - "Bad cache file."); - return; - } - *p++ = *q = '\0'; - - /* Local uid at buf, remote at p. */ - camel_cache_map_add (map, buf, p); - } - - fclose (f); -} diff --git a/camel/providers/cache/camel-cache-map.h b/camel/providers/cache/camel-cache-map.h deleted file mode 100644 index a15c9afe1a..0000000000 --- a/camel/providers/cache/camel-cache-map.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-cache-map.h: functions for dealing with UID maps */ - -/* - * Author: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_CACHE_MAP_H -#define CAMEL_CACHE_MAP_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <glib.h> -#include <camel/camel-types.h> - -typedef struct { - GHashTable *l2r, *r2l; -} CamelCacheMap; - -CamelCacheMap *camel_cache_map_new (void); -void camel_cache_map_destroy (CamelCacheMap *map); - -void camel_cache_map_add (CamelCacheMap *map, const char *luid, - const char *ruid); -void camel_cache_map_remove (CamelCacheMap *map, const char *luid, - const char *ruid); -void camel_cache_map_update (CamelCacheMap *map, const char *luid, - const char *ruid); - -const char *camel_cache_map_get_local (CamelCacheMap *map, const char *ruid); -const char *camel_cache_map_get_remote (CamelCacheMap *map, const char *luid); - -void camel_cache_map_write (CamelCacheMap *map, const char *file, - CamelException *ex); -void camel_cache_map_read (CamelCacheMap *map, const char *file, - CamelException *ex); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_CACHE_MAP_H */ diff --git a/camel/providers/cache/camel-cache-provider.c b/camel/providers/cache/camel-cache-provider.c deleted file mode 100644 index 217f06816a..0000000000 --- a/camel/providers/cache/camel-cache-provider.c +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-cache-provider.c: cache provider registration code */ - -/* - * Authors : - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-cache-store.h" -#include "camel-provider.h" -#include "camel-session.h" - -static CamelProvider cache_provider = { - "cache", - "Cache", - - "For caching remote mail into a local store.", - - "cache", - - 0, - - { 0, 0 } -}; - -void -camel_provider_module_init (CamelSession *session) -{ - cache_provider.object_types[CAMEL_PROVIDER_STORE] = - camel_cache_store_get_type(); - - camel_session_register_provider (session, &cache_provider); -} diff --git a/camel/providers/cache/camel-cache-store.c b/camel/providers/cache/camel-cache-store.c deleted file mode 100644 index 544cca69a1..0000000000 --- a/camel/providers/cache/camel-cache-store.c +++ /dev/null @@ -1,297 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-cache-store.c : class for a cache store */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include "camel-cache-store.h" -#include "camel-cache-folder.h" -#include "camel-stream-buffer.h" -#include "camel-stream-fs.h" -#include "camel-session.h" -#include "camel-exception.h" -#include "camel-url.h" -#include "md5-utils.h" - -static CamelServiceClass *service_class = NULL; -#define CS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static void finalize (CamelObject *object); - -static gboolean cache_connect (CamelService *service, CamelException *ex); -static gboolean cache_disconnect (CamelService *service, CamelException *ex); -static char *get_path (CamelService *service); -static char *get_name (CamelService *service, gboolean brief); - -static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex); -static void delete_folder (CamelStore *store, const char *folder_name, - CamelException *ex); -static void rename_folder (CamelStore *store, const char *old_name, - const char *new_name, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); -static char *get_default_folder_name (CamelStore *store, CamelException *ex); - - -static void -camel_cache_store_class_init (CamelCacheStoreClass *camel_cache_store_class) -{ - CamelServiceClass *camel_service_class = - CAMEL_SERVICE_CLASS (camel_cache_store_class); - CamelStoreClass *camel_store_class = - CAMEL_STORE_CLASS (camel_cache_store_class); - - service_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ())); - - /* virtual method overload */ - camel_service_class->connect = cache_connect; - camel_service_class->disconnect = cache_disconnect; - camel_service_class->get_path = get_path; - camel_service_class->get_name = get_name; - - camel_store_class->get_folder = get_folder; - camel_store_class->delete_folder = delete_folder; - camel_store_class->rename_folder = rename_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; - camel_store_class->get_default_folder_name = get_default_folder_name; -} - - -CamelType -camel_cache_store_get_type (void) -{ - static CamelType camel_cache_store_type = CAMEL_INVALID_TYPE; - - if (camel_cache_store_type == CAMEL_INVALID_TYPE) { - camel_cache_store_type = camel_type_register ( - CAMEL_STORE_TYPE, "CamelCacheStore", - sizeof (CamelCacheStore), - sizeof (CamelCacheStoreClass), - (CamelObjectClassInitFunc) camel_cache_store_class_init, - NULL, - NULL, - (CamelObjectFinalizeFunc) finalize); - } - - return camel_cache_store_type; -} - -static void -finalize (CamelObject *object) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (object); - - camel_object_unref (CAMEL_OBJECT (cache_store->local)); - camel_object_unref (CAMEL_OBJECT (cache_store->remote)); - g_free (cache_store->local_base); -} - - -static gboolean -cache_connect (CamelService *service, CamelException *ex) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (service); - - return camel_service_connect (CAMEL_SERVICE (cache_store->remote), ex) && - camel_service_connect (CAMEL_SERVICE (cache_store->local), ex); -} - -static gboolean -cache_disconnect (CamelService *service, CamelException *ex) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (service); - - return camel_service_disconnect (CAMEL_SERVICE (cache_store->local), ex) && - camel_service_disconnect (CAMEL_SERVICE (cache_store->remote), ex); -} - -static char * -get_path (CamelService *service) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (service); - char *path, *subpath; - - subpath = camel_service_get_path (CAMEL_SERVICE (cache_store->remote)); - path = g_strdup_printf ("cache/%s", subpath); - g_free (subpath); - return path; -} - -static char * -get_name (CamelService *service, gboolean brief) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (service); - - return camel_service_get_name (CAMEL_SERVICE (cache_store->remote), - brief); -} - -static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (store); - CamelFolder *parent, *rf, *lf; - - rf = camel_store_get_folder (cache_store->remote, folder_name, - create, ex); - if (!rf) - return NULL; - - lf = camel_store_get_folder (cache_store->local, folder_name, - TRUE, ex); - if (!lf) { - camel_object_unref (CAMEL_OBJECT (rf)); - camel_exception_setv (ex, camel_exception_get_id (ex), - "Could not create cache folder:\n%s", - camel_exception_get_description (ex)); - return NULL; - } - - return camel_cache_folder_new (store, parent, rf, lf, ex); -} - -/* XXX these two need to be better about failure recovery. */ -static void -delete_folder (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (store); - - camel_store_delete_folder (cache_store->remote, folder_name, ex); - if (camel_exception_is_set (ex)) - return; - camel_store_delete_folder (cache_store->local, folder_name, NULL); -} - -static void -rename_folder (CamelStore *store, const char *old_name, - const char *new_name, CamelException *ex) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (store); - - camel_store_rename_folder (cache_store->remote, old_name, - new_name, ex); - if (camel_exception_is_set (ex)) - return; - camel_store_rename_folder (cache_store->local, old_name, - new_name, NULL); -} - -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (store); - - return CS_CLASS (cache_store->remote)->get_folder_name ( - cache_store->remote, folder_name, ex); -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (store); - - return CS_CLASS (cache_store->remote)->get_root_folder_name ( - cache_store->remote, ex); -} - -static char * -get_default_folder_name (CamelStore *store, CamelException *ex) -{ - CamelCacheStore *cache_store = CAMEL_CACHE_STORE (store); - - return CS_CLASS (cache_store->remote)->get_default_folder_name ( - cache_store->remote, ex); -} - - -/** - * camel_cache_store_new: - * @remote: a remote store - * @ex: a CamelException - * - * Return value: a CamelCacheStore for the given remote store. - **/ -CamelStore * -camel_cache_store_new (CamelStore *remote, CamelException *ex) -{ - CamelCacheStore *cache_store; - CamelService *remote_service = (CamelService *)remote; - CamelSession *session; - char *url_string; - CamelURL *url; - - session = camel_service_get_session (remote_service); - - url_string = camel_service_get_url (remote_service); - url = camel_url_new (url_string, ex); - g_free (url_string); - - if (!url) - return NULL; - - cache_store = (CamelCacheStore *) - camel_service_new (CAMEL_CACHE_STORE_TYPE, session, - camel_service_get_provider (remote_service), - url, ex); - if (camel_exception_is_set (ex)) { - camel_url_free (url); - return NULL; - } - - cache_store->remote = remote; - camel_object_ref (CAMEL_OBJECT (remote)); - - cache_store->local_base = camel_session_get_storage_path ( - session, (CamelService *)cache_store, ex); - if (camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (cache_store)); - return NULL; - } - - url_string = g_strdup_printf ("mbox:%s", cache_store->local_base); - cache_store->local = camel_session_get_store (session, url_string, ex); - g_free (url_string); - if (camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (cache_store)); - return NULL; - } - - return (CamelStore *)cache_store; -} diff --git a/camel/providers/cache/camel-cache-store.h b/camel/providers/cache/camel-cache-store.h deleted file mode 100644 index 7339d8a9f3..0000000000 --- a/camel/providers/cache/camel-cache-store.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-cache-store.h: class for a cache store */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_CACHE_STORE_H -#define CAMEL_CACHE_STORE_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <camel/camel-store.h> - -#define CAMEL_CACHE_STORE_TYPE (camel_cache_store_get_type ()) -#define CAMEL_CACHE_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_CACHE_STORE_TYPE, CamelCacheStore)) -#define CAMEL_CACHE_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_CACHE_STORE_TYPE, CamelCacheStoreClass)) -#define IS_CAMEL_CACHE_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_CACHE_STORE_TYPE)) - -typedef struct { - CamelStore parent_object; - - char *local_base; - CamelStore *remote, *local; - -} CamelCacheStore; - - -typedef struct { - CamelStoreClass parent_class; - -} CamelCacheStoreClass; - - -/* support functions */ -CamelStore *camel_cache_store_new (CamelStore *remote, CamelException *ex); - -/* Standard Camel function */ -CamelType camel_cache_store_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_CACHE_STORE_H */ - - diff --git a/camel/providers/cache/libcamelcache.urls b/camel/providers/cache/libcamelcache.urls deleted file mode 100644 index 06cf65390f..0000000000 --- a/camel/providers/cache/libcamelcache.urls +++ /dev/null @@ -1 +0,0 @@ -cache diff --git a/camel/providers/imap/.cvsignore b/camel/providers/imap/.cvsignore deleted file mode 100644 index fd6b811c68..0000000000 --- a/camel/providers/imap/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la diff --git a/camel/providers/imap/Makefile.am b/camel/providers/imap/Makefile.am deleted file mode 100644 index 19646f1960..0000000000 --- a/camel/providers/imap/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelimapincludedir = $(includedir)/camel - - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelimap.la -provider_DATA = libcamelimap.urls - -INCLUDES = -I.. \ - -I$(srcdir)/.. \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/libibex \ - -I$(top_srcdir)/e-util \ - -I$(top_srcdir) \ - -I$(includedir) \ - $(GTK_INCLUDEDIR) \ - $(KRB4_CFLAGS) \ - -DG_LOG_DOMAIN=\"camel-imap-provider\" - -libcamelimap_la_SOURCES = \ - camel-imap-auth.c \ - camel-imap-command.c \ - camel-imap-folder.c \ - camel-imap-provider.c \ - camel-imap-store.c \ - camel-imap-summary.c \ - camel-imap-utils.c - -libcamelimapinclude_HEADERS = \ - camel-imap-auth.h \ - camel-imap-command.h \ - camel-imap-folder.h \ - camel-imap-store.h \ - camel-imap-stream.h \ - camel-imap-summary.h \ - camel-imap-utils.h - -libcamelimap_la_LDFLAGS = $(KRB4_LDFLAGS) -version-info 0:0:0 - -EXTRA_DIST = libcamelimap.urls - - - - - diff --git a/camel/providers/imap/camel-imap-auth.c b/camel/providers/imap/camel-imap-auth.c deleted file mode 100644 index 3bf1af6535..0000000000 --- a/camel/providers/imap/camel-imap-auth.c +++ /dev/null @@ -1,195 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-auth.c: IMAP AUTHENTICATE implementations */ - -/* - * Authors: Dan Winship <danw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <config.h> - -#include <string.h> - -#ifdef HAVE_KRB4 -#include <krb.h> -/* MIT krb4 des.h #defines _. Sigh. We don't need it. */ -#undef _ -#endif - -#include "camel-exception.h" -#include "camel-mime-utils.h" - -#include "camel-imap-auth.h" -#include "camel-imap-command.h" -#include "camel-imap-utils.h" - -static char * -base64_encode_simple (const char *data, int len) -{ - unsigned char *out; - int state = 0, outlen; - unsigned int save = 0; - - out = g_malloc (len * 4 / 3 + 5); - outlen = base64_encode_close ((unsigned char *)data, len, FALSE, - out, &state, &save); - out[outlen] = '\0'; - return (char *)out; -} - -static int -base64_decode_simple (char *data, int len) -{ - int state = 0; - unsigned int save = 0; - - return base64_decode_step ((unsigned char *)data, len, - (unsigned char *)data, &state, &save); -} - -#ifdef HAVE_KRB4 -#define IMAP_KERBEROS_V4_PROTECTION_NONE 1 -#define IMAP_KERBEROS_V4_PROTECTION_INTEGRITY 2 -#define IMAP_KERBEROS_V4_PROTECTION_PRIVACY 4 - -gboolean -imap_try_kerberos_v4_auth (CamelImapStore *store, CamelException *ex) -{ - CamelImapResponse *response; - char *resp, *data; - int status, len; - char *inst, *realm, *buf, *username; - guint32 nonce_n, nonce_h, plus1; - struct hostent *h; - KTEXT_ST authenticator; - CREDENTIALS credentials; - des_cblock session; - des_key_schedule schedule; - - /* The kickoff. */ - response = camel_imap_command (store, NULL, ex, - "AUTHENTICATE KERBEROS_V4"); - if (!response) - return FALSE; - resp = camel_imap_response_extract_continuation (response, ex); - if (!resp) - return FALSE; - data = imap_next_word (resp); - - /* First server response is a base64-encoded 32-bit random number - * ("nonce") in network byte order. - */ - if (strlen (data) != 8 || base64_decode_simple (data, 8) != 4) { - g_free (resp); - goto lose; - } - memcpy (&nonce_n, data, 4); - g_free (resp); - nonce_h = ntohl (nonce_n); - - /* Our response is an authenticator including that number. */ - h = camel_service_gethost (CAMEL_SERVICE (store), ex); - if (!h) - goto lose; - inst = g_strndup (h->h_name, strcspn (h->h_name, ".")); - g_strdown (inst); - realm = g_strdup (krb_realmofhost (h->h_name)); - status = krb_mk_req (&authenticator, "imap", inst, realm, nonce_h); - if (status == KSUCCESS) { - status = krb_get_cred ("imap", inst, realm, &credentials); - memcpy (session, credentials.session, sizeof (session)); - memset (&credentials, 0, sizeof (credentials)); - } - g_free (inst); - g_free (realm); - - if (status != KSUCCESS) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Could not get Kerberos ticket:\n%s"), - krb_err_txt[status]); - goto lose; - } - des_key_sched (&session, schedule); - - buf = base64_encode_simple (authenticator.dat, authenticator.length); - response = camel_imap_command_continuation (store, ex, buf); - g_free (buf); - if (!response) - goto lose; - resp = camel_imap_response_extract_continuation (response, ex); - if (!resp) - goto lose; - data = imap_next_word (resp); - - len = strlen (data); - base64_decode_simple (data, strlen (data)); - - /* This one is encrypted. */ - des_ecb_encrypt ((des_cblock *)data, (des_cblock *)data, schedule, 0); - - /* Check that the returned value is the original nonce plus one. */ - memcpy (&plus1, data, 4); - if (ntohl (plus1) != nonce_h + 1) { - g_free (resp); - goto lose; - } - - /* "the fifth octet contain[s] a bit-mask specifying the - * protection mechanisms supported by the server" - */ - if (!(data[4] & IMAP_KERBEROS_V4_PROTECTION_NONE)) { - g_warning ("Server does not support `no protection' :-("); - g_free (resp); - goto lose; - } - g_free (resp); - - username = CAMEL_SERVICE (store)->url->user; - len = strlen (username) + 9; - len += 8 - len % 8; - data = g_malloc0 (len); - memcpy (data, &nonce_n, 4); - data[4] = IMAP_KERBEROS_V4_PROTECTION_NONE; - data[5] = data[6] = data[7] = 0; - strcpy (data + 8, username); - - des_pcbc_encrypt ((des_cblock *)data, (des_cblock *)data, len, - schedule, &session, 1); - memset (&session, 0, sizeof (session)); - buf = base64_encode_simple (data, len); - g_free (data); - - response = camel_imap_command_continuation (store, ex, buf); - if (!response) - goto lose; - camel_imap_response_free (response); - return TRUE; - - lose: - memset (&session, 0, sizeof (session)); - - /* Get the server out of "waiting for continuation data" mode. - */ - response = camel_imap_command_continuation (store, NULL, "*"); - if (response) - camel_imap_response_free (response); - - return FALSE; -} -#endif /* HAVE_KRB4 */ diff --git a/camel/providers/imap/camel-imap-auth.h b/camel/providers/imap/camel-imap-auth.h deleted file mode 100644 index fbbc5ef709..0000000000 --- a/camel/providers/imap/camel-imap-auth.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-auth.h: IMAP AUTHENTICATE implementations */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_IMAP_AUTH_H -#define CAMEL_IMAP_AUTH_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-imap-store.h" - -gboolean imap_try_kerberos_v4_auth (CamelImapStore *store, CamelException *ex); -gboolean imap_try_gssapi_auth (CamelImapStore *store, CamelException *ex); - -#endif /* CAMEL_IMAP_AUTH_H */ diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c deleted file mode 100644 index e9808d5a1f..0000000000 --- a/camel/providers/imap/camel-imap-command.c +++ /dev/null @@ -1,406 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-command.c: IMAP command sending/parsing routines */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#include <config.h> - -#include <stdio.h> -#include <string.h> - -#include "camel-imap-command.h" -#include "camel-imap-utils.h" -#include "camel-imap-folder.h" -#include <camel/camel-exception.h> - -static char *imap_read_untagged (CamelImapStore *store, char *line, - CamelException *ex); -static CamelImapResponse *imap_read_response (CamelImapStore *store, - CamelException *ex); - -/** - * camel_imap_command: Send a command to a IMAP server and get a response - * @store: the IMAP store - * @folder: The folder to perform the operation in (or %NULL if not - * relevant). - * @ex: a CamelException - * @fmt: a printf-style format string, followed by arguments - * - * This function makes sure that @folder (if non-%NULL) is the - * currently-selected folder on @store and then sends the IMAP command - * specified by @fmt and the following arguments. It then reads the - * server's response(s) and parses the final result. - * - * As a special case, if @fmt is %NULL, it will just select @folder - * and return the response from doing so. - * - * Return value: %NULL if an error occurred (in which case @ex will - * be set). Otherwise, a CamelImapResponse describing the server's - * response, which the caller must free with camel_imap_response_free(). - **/ -CamelImapResponse * -camel_imap_command (CamelImapStore *store, CamelFolder *folder, - CamelException *ex, const char *fmt, ...) -{ - gchar *cmdbuf; - va_list ap; - - /* Check for current folder */ - if (folder && (!fmt || folder != store->current_folder)) { - CamelImapResponse *response; - - store->current_folder = NULL; - response = camel_imap_command (store, NULL, ex, - "SELECT \"%s\"", - folder->full_name); - if (!response) - return NULL; - store->current_folder = folder; - - if (!fmt) - return response; - - camel_imap_response_free (response); - } - - /* Send the command */ - va_start (ap, fmt); - cmdbuf = g_strdup_vprintf (fmt, ap); - va_end (ap); - - camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex, - "A%.5d %s\r\n", store->command++, - cmdbuf); - g_free (cmdbuf); - if (camel_exception_is_set (ex)) - return NULL; - - /* Read the response. */ - return imap_read_response (store, ex); -} - -/** - * camel_imap_command_continuation: Send more command data to the IMAP server - * @store: the IMAP store - * @ex: a CamelException - * @cmdbuf: buffer containing the response/request data - * - * This method is for sending continuing responses to the IMAP server - * after camel_imap_command returns a CAMEL_IMAP_PLUS response. - * - * Return value: as for camel_imap_command() - **/ -CamelImapResponse * -camel_imap_command_continuation (CamelImapStore *store, CamelException *ex, - const char *cmdbuf) -{ - if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex, - "%s\r\n", cmdbuf) < 0) - return NULL; - - return imap_read_response (store, ex); -} - -/* Read the response to an IMAP command. */ -static CamelImapResponse * -imap_read_response (CamelImapStore *store, CamelException *ex) -{ - CamelImapResponse *response; - int number, exists = 0; - GArray *expunged = NULL; - char *respbuf, *retcode, *word, *p; - - /* Read first line */ - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), - &respbuf, ex) < 0) - return NULL; - - response = g_new0 (CamelImapResponse, 1); - response->untagged = g_ptr_array_new (); - - /* Check for untagged data */ - while (!strncmp (respbuf, "* ", 2)) { - /* Read the rest of the response if it is multi-line. */ - respbuf = imap_read_untagged (store, respbuf, ex); - if (camel_exception_is_set (ex)) - break; - - /* If it starts with a number, we might deal with - * it ourselves. - */ - word = imap_next_word (respbuf); - number = strtoul (word, &p, 10); - if (p != word && store->current_folder) { - word = imap_next_word (p); - if (!g_strcasecmp (word, "EXISTS")) { - exists = number; - g_free (respbuf); - goto next; - } else if (!g_strcasecmp (word, "EXPUNGE")) { - if (!expunged) { - expunged = g_array_new (FALSE, FALSE, - sizeof (int)); - } - g_array_append_val (expunged, number); - g_free (respbuf); - goto next; - } - } else { - if (!g_strncasecmp (word, "BYE", 3)) { - /* connection was lost, no more data to fetch */ - store->connected = FALSE; - g_free (respbuf); - respbuf = NULL; - break; - } - } - - g_ptr_array_add (response->untagged, respbuf); - next: - if (camel_remote_store_recv_line ( - CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0) - break; - } - - /* Update the summary */ - if (store->current_folder && (exists > 0 || expunged)) { - camel_imap_folder_changed (store->current_folder, exists, - expunged, NULL); - } - if (expunged) - g_array_free (expunged, TRUE); - - if (!respbuf || camel_exception_is_set (ex)) { - camel_imap_response_free (response); - return NULL; - } - - response->status = respbuf; - - /* Check for OK or continuation response. */ - if (!strncmp (respbuf, "+ ", 2)) - return response; - retcode = imap_next_word (respbuf); - if (!strncmp (retcode, "OK", 2)) - return response; - - /* We should never get BAD, or anything else but +, OK, or NO - * for that matter. - */ - if (strncmp (retcode, "NO", 2) != 0) { - g_warning ("Unexpected response from IMAP server: %s", - respbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Unexpected response from IMAP " - "server: %s"), respbuf); - camel_imap_response_free (response); - return NULL; - } - - retcode = imap_next_word (retcode); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("IMAP command failed: %s"), - retcode ? retcode : _("Unknown error")); - camel_imap_response_free (response); - return NULL; -} - -/* Given a line that is the start of an untagged response, read and - * return the complete response. (This will be a no-op if the line - * in question doesn't end with a literal.) - * - * FIXME: this won't deal with multiple literals in a single response. - */ -static char * -imap_read_untagged (CamelImapStore *store, char *line, CamelException *ex) -{ - int fulllen, length, left, i; - GPtrArray *data; - char *end, *p; - - p = strrchr (line, '{'); - if (!p) - return line; - - length = strtoul (p + 1, &end, 10); - if (*end != '}' || *(end + 1) || end == p + 1) - return line; - - fulllen = length + strlen (line) + 1; - - /* OK. We have a literal. @length is the length including CRLF - * pairs, which camel_remote_store_recv_line won't return. - */ - data = g_ptr_array_new (); - g_ptr_array_add (data, line); - left = length; - while (1) { - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), - &line, ex) < 0) { - for (i = 0; i < data->len; i++) - g_free (data->pdata[i]); - g_ptr_array_free (data, TRUE); - return NULL; - } - g_ptr_array_add (data, line); - - if (left <= 0) - break; - - left -= strlen (line) + 2; - - /* The output string will have only LF, not CRLF, so - * decrement the length by one. - */ - length--; - } - - /* Add the length of the post-literal line. */ - fulllen += strlen (line); - - /* p points to the "{" in the line that starts the literal. - * The length of the CR-less response must be less than or - * equal to the length of the response with CRs, therefore - * overwriting the old value with the new value cannot cause - * an overrun. - */ - sprintf (p, "{%d}", length); - - /* Now reassemble the data. */ - p = line = g_malloc (fulllen + 1); - for (i = 0; i < data->len; i++) { - length = strlen (data->pdata[i]); - memcpy (p, data->pdata[i], length); - g_free (data->pdata[i]); - p += length; - *p++ = '\n'; - } - *p = '\0'; - g_ptr_array_free (data, TRUE); - return line; -} - - -/** - * camel_imap_response_free: - * response: a CamelImapResponse: - * - * Frees all of the data in @response. - **/ -void -camel_imap_response_free (CamelImapResponse *response) -{ - int i; - - if (!response) - return; - for (i = 0; i < response->untagged->len; i++) - g_free (response->untagged->pdata[i]); - g_ptr_array_free (response->untagged, TRUE); - g_free (response->status); - g_free (response); -} - -/** - * camel_imap_response_extract: - * @response: the response data returned from camel_imap_command - * @type: the response type to extract - * @ex: a CamelException - * - * This checks that @response contains a single untagged response of - * type @type and returns just that response data. If @response - * doesn't contain the right information, the function will set @ex and - * return %NULL. Either way, @response will be freed. - * - * Return value: the desired response string, which the caller must free. - **/ -char * -camel_imap_response_extract (CamelImapResponse *response, const char *type, - CamelException *ex) -{ - int len = strlen (type), i; - char *resp; - - for (i = 0; i < response->untagged->len; i++) { - resp = response->untagged->pdata[i]; - /* Skip "* ", and initial sequence number, if present */ - strtoul (resp + 2, &resp, 10); - if (*resp == ' ') - resp = imap_next_word (resp); - - if (!g_strncasecmp (resp, type, len)) - break; - - g_free (response->untagged->pdata[i]); - } - - if (i < response->untagged->len) { - resp = response->untagged->pdata[i]; - for (i++; i < response->untagged->len; i++) - g_free (response->untagged->pdata[i]); - } else { - resp = NULL; - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("IMAP server response did not contain " - "%s information"), type); - } - - g_ptr_array_free (response->untagged, TRUE); - g_free (response->status); - g_free (response); - return resp; -} - -/** - * camel_imap_response_extract_continuation: - * @response: the response data returned from camel_imap_command - * @ex: a CamelException - * - * This checks that @response contains a continuation response, and - * returns just that data. If @response doesn't contain a continuation - * response, the function will set @ex and return %NULL. Either way, - * @response will be freed. - * - * Return value: the desired response string, which the caller must free. - **/ -char * -camel_imap_response_extract_continuation (CamelImapResponse *response, - CamelException *ex) -{ - char *status; - - if (response->status && !strncmp (response->status, "+ ", 2)) { - status = response->status; - response->status = NULL; - camel_imap_response_free (response); - return status; - } - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Unexpected OK response from IMAP server: %s"), - response->status); - camel_imap_response_free (response); - return NULL; -} diff --git a/camel/providers/imap/camel-imap-command.h b/camel/providers/imap/camel-imap-command.h deleted file mode 100644 index 38e290c379..0000000000 --- a/camel/providers/imap/camel-imap-command.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-command.h: IMAP command sending/parsing routines */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_IMAP_COMMAND_H -#define CAMEL_IMAP_COMMAND_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-imap-store.h" - -typedef struct { - GPtrArray *untagged; - char *status; -} CamelImapResponse; - -CamelImapResponse *camel_imap_command (CamelImapStore *store, - CamelFolder *folder, - CamelException *ex, - const char *fmt, ...); -CamelImapResponse *camel_imap_command_continuation (CamelImapStore *store, - CamelException *ex, - const char *cmdbuf); - -void camel_imap_response_free (CamelImapResponse *response); -char *camel_imap_response_extract (CamelImapResponse *response, - const char *type, - CamelException *ex); -char *camel_imap_response_extract_continuation (CamelImapResponse *response, - CamelException *ex); - -#endif /* CAMEL_IMAP_COMMAND_H */ diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c deleted file mode 100644 index a4b8b459de..0000000000 --- a/camel/providers/imap/camel-imap-folder.c +++ /dev/null @@ -1,850 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-folder.c: Abstract class for an imap folder */ - -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#include <config.h> - -#include <stdlib.h> -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> -#include <ctype.h> - -#include <gal/util/e-util.h> - -#include "camel-imap-folder.h" -#include "camel-imap-command.h" -#include "camel-imap-store.h" -#include "camel-imap-stream.h" -#include "camel-imap-summary.h" -#include "camel-imap-utils.h" -#include "string-utils.h" -#include "camel-stream.h" -#include "camel-stream-fs.h" -#include "camel-stream-mem.h" -#include "camel-stream-buffer.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-stream-filter.h" -#include "camel-mime-filter-from.h" -#include "camel-mime-filter-crlf.h" -#include "camel-exception.h" -#include "camel-mime-utils.h" - -#define d(x) x - -#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(o))) - -static CamelFolderClass *parent_class = NULL; - -static void imap_finalize (CamelObject *object); -static void imap_refresh_info (CamelFolder *folder, CamelException *ex); -static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex); -static const char *imap_get_full_name (CamelFolder *folder); -static void imap_expunge (CamelFolder *folder, CamelException *ex); - -/* message counts */ -static gint imap_get_message_count (CamelFolder *folder); -static gint imap_get_unread_message_count (CamelFolder *folder); - -/* message manipulation */ -static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid, - CamelException *ex); -static void imap_append_message (CamelFolder *folder, CamelMimeMessage *message, - const CamelMessageInfo *info, CamelException *ex); -static void imap_copy_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex); -static void imap_move_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex); - -/* summary info */ -static GPtrArray *imap_get_uids (CamelFolder *folder); -static GPtrArray *imap_get_summary (CamelFolder *folder); -static const CamelMessageInfo *imap_get_message_info (CamelFolder *folder, const char *uid); - -static void imap_update_summary (CamelFolder *folder, int first, int last, - CamelException *ex); - -/* searching */ -static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex); - -/* flag methods */ -static guint32 imap_get_message_flags (CamelFolder *folder, const char *uid); -static void imap_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set); -static gboolean imap_get_message_user_flag (CamelFolder *folder, const char *uid, const char *name); -static void imap_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, - gboolean value); - - -static void -camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class) -{ - CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_imap_folder_class); - - parent_class = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ())); - - /* virtual method definition */ - - /* virtual method overload */ - camel_folder_class->refresh_info = imap_refresh_info; - camel_folder_class->sync = imap_sync; - camel_folder_class->expunge = imap_expunge; - camel_folder_class->get_full_name = imap_get_full_name; - - camel_folder_class->get_uids = imap_get_uids; - camel_folder_class->free_uids = camel_folder_free_nop; - - camel_folder_class->get_message_count = imap_get_message_count; - camel_folder_class->get_unread_message_count = imap_get_unread_message_count; - camel_folder_class->get_message = imap_get_message; - camel_folder_class->append_message = imap_append_message; - camel_folder_class->copy_message_to = imap_copy_message_to; - camel_folder_class->move_message_to = imap_move_message_to; - - camel_folder_class->get_summary = imap_get_summary; - camel_folder_class->get_message_info = imap_get_message_info; - camel_folder_class->free_summary = camel_folder_free_nop; - - camel_folder_class->search_by_expression = imap_search_by_expression; - - camel_folder_class->get_message_flags = imap_get_message_flags; - camel_folder_class->set_message_flags = imap_set_message_flags; - camel_folder_class->get_message_user_flag = imap_get_message_user_flag; - camel_folder_class->set_message_user_flag = imap_set_message_user_flag; -} - -static void -camel_imap_folder_init (gpointer object, gpointer klass) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object); - CamelFolder *folder = CAMEL_FOLDER (object); - - folder->has_summary_capability = TRUE; - folder->has_search_capability = TRUE; - - imap_folder->summary = NULL; -} - -CamelType -camel_imap_folder_get_type (void) -{ - static CamelType camel_imap_folder_type = CAMEL_INVALID_TYPE; - - if (camel_imap_folder_type == CAMEL_INVALID_TYPE) { - camel_imap_folder_type = - camel_type_register (CAMEL_FOLDER_TYPE, "CamelImapFolder", - sizeof (CamelImapFolder), - sizeof (CamelImapFolderClass), - (CamelObjectClassInitFunc) camel_imap_folder_class_init, - NULL, - (CamelObjectInitFunc) camel_imap_folder_init, - (CamelObjectFinalizeFunc) imap_finalize); - } - - return camel_imap_folder_type; -} - -CamelFolder * -camel_imap_folder_new (CamelStore *parent, const char *folder_name, - const char *short_name, const char *summary_file, - CamelException *ex) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (parent); - CamelFolder *folder = CAMEL_FOLDER (camel_object_new (camel_imap_folder_get_type ())); - CamelImapFolder *imap_folder = (CamelImapFolder *)folder; - CamelImapResponse *response; - const char *resp; - guint32 validity = 0; - int i; - - camel_folder_construct (folder, parent, folder_name, short_name); - - response = camel_imap_command (imap_store, folder, ex, NULL); - if (!response) { - camel_object_unref ((CamelObject *)folder); - return NULL; - } - - for (i = 0; i < response->untagged->len; i++) { - resp = response->untagged->pdata[i] + 2; - if (!g_strncasecmp (resp, "FLAGS ", 6)) { - folder->permanent_flags = - imap_parse_flag_list (resp + 6); - } else if (!g_strncasecmp (resp, "OK [PERMANENTFLAGS ", 19)) { - folder->permanent_flags = - imap_parse_flag_list (resp + 19); - } else if (!g_strncasecmp (resp, "OK [UIDVALIDITY ", 16)) { - validity = strtoul (resp + 16, NULL, 10); - } else if (isdigit ((unsigned char)*resp)) { - unsigned long num = strtoul (resp, (char **)&resp, 10); - - if (!g_strncasecmp (resp, " EXISTS", 7)) - imap_folder->exists = num; - } - } - camel_imap_response_free (response); - - imap_folder->summary = camel_imap_summary_new (summary_file, validity); - if (!imap_folder->summary) { - camel_object_unref (CAMEL_OBJECT (folder)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not load summary for %s"), - folder_name); - return NULL; - } - - imap_refresh_info (folder, ex); - if (camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (folder)); - return NULL; - } - - return folder; -} - -static void -imap_finalize (CamelObject *object) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object); - - camel_object_unref ((CamelObject *)imap_folder->summary); -} - -static void -imap_refresh_info (CamelFolder *folder, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - CamelImapResponse *response; - struct { - char *uid; - guint32 flags; - } *new; - char *resp, *uid, *p, *flags; - int i, seq, summary_len; - CamelMessageInfo *info; - gboolean folder_changed = FALSE; - - if (imap_folder->exists == 0) { - if (camel_folder_summary_count != 0) { - camel_folder_summary_clear (imap_folder->summary); - camel_object_trigger_event (CAMEL_OBJECT (folder), - "folder_changed", NULL); - } - return; - } - - /* Get UIDs and flags of all messages. */ - response = camel_imap_command (store, folder, ex, - "FETCH 1:%d (UID FLAGS)", - imap_folder->exists); - if (!response) - return; - - new = g_malloc0 (imap_folder->exists * sizeof (*new)); - for (i = 0; i < response->untagged->len; i++) { - resp = response->untagged->pdata[i]; - - seq = strtoul (resp + 2, &resp, 10); - if (g_strncasecmp (resp, " FETCH ", 7) != 0) - continue; - - uid = e_strstrcase (resp, "UID "); - if (uid) { - uid += 4; - strtoul (uid, &p, 10); - new[seq - 1].uid = g_strndup (uid, p - uid); - } - - flags = e_strstrcase (resp, "FLAGS "); - if (flags) { - flags += 6; - new[seq - 1].flags = imap_parse_flag_list (flags); - } - } - - /* If we find a UID in the summary that doesn't correspond to - * the UID in the folder, that it means the message was - * deleted on the server, so we remove it from the summary. - */ - summary_len = camel_folder_summary_count (imap_folder->summary); - for (i = 0; i < summary_len && i < imap_folder->exists; i++) { - info = camel_folder_summary_index (imap_folder->summary, i); - - /* Shouldn't happen, but... */ - if (!new[i].uid) - continue; - - if (strcmp (info->uid, new[i].uid) != 0) { - camel_folder_summary_remove (imap_folder->summary, - info); - folder_changed = TRUE; - i--; - summary_len--; - continue; - } - - /* Update summary flags */ - if (info->flags != new[i].flags) { - info->flags = new[i].flags; - camel_object_trigger_event (CAMEL_OBJECT (folder), - "message_changed", - info->uid); - } - - g_free (new[i].uid); - } - - /* Remove any leftover cached summary messages. */ - while (summary_len > i + 1) { - camel_folder_summary_remove_index (imap_folder->summary, - --summary_len); - folder_changed = TRUE; - } - - /* Add any new folder messages. */ - if (i < imap_folder->exists) { - /* Fetch full summary for the remaining messages. */ - imap_update_summary (folder, i + 1, imap_folder->exists, ex); - folder_changed = TRUE; - - while (i < imap_folder->exists) - g_free (new[i++].uid); - } - g_free (new); - - if (folder_changed) { - camel_object_trigger_event (CAMEL_OBJECT (folder), - "folder_changed", NULL); - } -} - -static void -imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - CamelImapResponse *response; - int i, max; - - /* Set the flags on any messages that have changed this session */ - max = camel_folder_summary_count (imap_folder->summary); - for (i = 0; i < max; i++) { - CamelMessageInfo *info; - - info = camel_folder_summary_index (imap_folder->summary, i); - if (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) { - char *flags; - - flags = imap_create_flag_list (info->flags); - if (flags) { - response = camel_imap_command ( - store, folder, ex, - "UID STORE %s FLAGS.SILENT %s", - info->uid, flags); - g_free (flags); - if (!response) - return; - camel_imap_response_free (response); - } - info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED; - } - } - - if (expunge) { - response = camel_imap_command (store, folder, ex, "EXPUNGE"); - camel_imap_response_free (response); - } - - camel_folder_summary_save (imap_folder->summary); -} - -static void -imap_expunge (CamelFolder *folder, CamelException *ex) -{ - imap_sync (folder, TRUE, ex); -} - -static const char * -imap_get_full_name (CamelFolder *folder) -{ - CamelURL *url = ((CamelService *)folder->parent_store)->url; - int len; - - if (!url->path || !*url->path || !strcmp (url->path, "/")) - return folder->full_name; - len = strlen (url->path + 1); - if (!strncmp (url->path + 1, folder->full_name, len) && - strlen (folder->full_name) > len + 1) - return folder->full_name + len + 1; - return folder->full_name; -} - -static gint -imap_get_message_count (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - return camel_folder_summary_count (imap_folder->summary); -} - -static gint -imap_get_unread_message_count (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - CamelMessageInfo *info; - int i, max, count = 0; - - max = camel_folder_summary_count (imap_folder->summary); - for (i = 0; i < max; i++) { - info = camel_folder_summary_index (imap_folder->summary, i); - if (!(info->flags & CAMEL_MESSAGE_SEEN)) - count++; - } - - return count; -} - -static void -imap_append_message (CamelFolder *folder, CamelMimeMessage *message, - const CamelMessageInfo *info, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); - CamelImapResponse *response; - CamelStream *memstream; - CamelMimeFilter *crlf_filter; - CamelStreamFilter *streamfilter; - GByteArray *ba; - char *flagstr, *result; - - /* create flag string param */ - if (info && info->flags) - flagstr = imap_create_flag_list (info->flags); - else - flagstr = NULL; - - /* FIXME: We could avoid this if we knew how big the message was. */ - memstream = camel_stream_mem_new (); - ba = g_byte_array_new (); - camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (memstream), ba); - - streamfilter = camel_stream_filter_new_with_stream (memstream); - crlf_filter = camel_mime_filter_crlf_new ( - CAMEL_MIME_FILTER_CRLF_ENCODE, - CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY); - camel_stream_filter_add (streamfilter, crlf_filter); - camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), - CAMEL_STREAM (streamfilter)); - camel_object_unref (CAMEL_OBJECT (streamfilter)); - camel_object_unref (CAMEL_OBJECT (crlf_filter)); - camel_object_unref (CAMEL_OBJECT (memstream)); - - response = camel_imap_command (store, NULL, ex, "APPEND %s%s%s {%d}", - folder->full_name, flagstr ? " " : "", - flagstr ? flagstr : "", ba->len); - g_free (flagstr); - - if (!response) { - g_byte_array_free (ba, TRUE); - return; - } - result = camel_imap_response_extract_continuation (response, ex); - if (!result) { - g_byte_array_free (ba, TRUE); - return; - } - g_free (result); - - /* send the rest of our data - the mime message */ - g_byte_array_append (ba, "\0", 3); - response = camel_imap_command_continuation (store, ex, ba->data); - g_byte_array_free (ba, TRUE); - if (!response) - return; - camel_imap_response_free (response); -} - -static void -imap_copy_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store); - CamelImapResponse *response; - - response = camel_imap_command (store, source, ex, "UID COPY %s \"%s\"", - uid, destination->full_name); - camel_imap_response_free (response); - - /* FIXME: This should go away once folder_changed is being - * emitted by camel_imap_folder_changed on appends again. - */ - if (!camel_exception_is_set (ex)) { - camel_object_trigger_event (CAMEL_OBJECT (destination), - "folder_changed", NULL); - } -} - -static void -imap_move_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store); - CamelImapResponse *response; - - response = camel_imap_command (store, source, ex, "UID COPY %s \"%s\"", - uid, destination->full_name); - camel_imap_response_free (response); - - if (camel_exception_is_set (ex)) - return; - - /* FIXME: This should go away once folder_changed is being - * emitted by camel_imap_folder_changed on appends again. - */ - camel_object_trigger_event (CAMEL_OBJECT (destination), - "folder_changed", NULL); - - camel_folder_delete_message (source, uid); -} - -static GPtrArray * -imap_get_uids (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - const CamelMessageInfo *info; - GPtrArray *array; - int i, count; - - count = camel_folder_summary_count (imap_folder->summary); - - array = g_ptr_array_new (); - g_ptr_array_set_size (array, count); - - for (i = 0; i < count; i++) { - info = camel_folder_summary_index (imap_folder->summary, i); - array->pdata[i] = g_strdup (info->uid); - } - - return array; -} - -static CamelMimeMessage * -imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); - CamelImapResponse *response; - CamelStream *msgstream; - CamelMimeMessage *msg; - char *result, *mesg, *p; - int len; - - response = camel_imap_command (store, folder, ex, - "UID FETCH %s RFC822", uid); - if (!response) - return NULL; - result = camel_imap_response_extract (response, "FETCH", ex); - if (!result) - return NULL; - - p = strstr (result, "RFC822"); - if (p) { - p += 7; - mesg = imap_parse_nstring (&p, &len); - } - if (!p) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Could not find message body in FETCH " - "response.")); - g_free (result); - return NULL; - } - g_free (result); - - msgstream = camel_stream_mem_new_with_buffer (mesg, len); - msg = camel_mime_message_new (); - camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), - msgstream); - camel_object_unref (CAMEL_OBJECT (msgstream)); - g_free (mesg); - - return msg; -} - -/** - * imap_protocol_get_summary_specifier - * - * Make a data item specifier for the header lines we need, - * appropriate to the server level. - * - * IMAP4rev1: UID FLAGS BODY.PEEK[HEADER.FIELDS (SUBJECT FROM .. IN-REPLY-TO)] - * IMAP4: UID FLAGS RFC822.HEADER.LINES (SUBJECT FROM .. IN-REPLY-TO) - **/ -static char * -imap_protocol_get_summary_specifier (CamelImapStore *store) -{ - char *sect_begin, *sect_end; - char *headers_wanted = "SUBJECT FROM TO CC DATE MESSAGE-ID REFERENCES IN-REPLY-TO"; - - if (store->server_level >= IMAP_LEVEL_IMAP4REV1) { - sect_begin = "BODY.PEEK[HEADER.FIELDS"; - sect_end = "]"; - } else { - sect_begin = "RFC822.HEADER.LINES"; - sect_end = ""; - } - - return g_strdup_printf ("UID FLAGS %s (%s)%s", sect_begin, - headers_wanted, sect_end); -} - -static void -imap_update_summary (CamelFolder *folder, int first, int last, - CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - CamelImapResponse *response; - GPtrArray *headers = NULL; - char *q, *summary_specifier; - struct _header_raw *h = NULL; - int i; - - /* If the range we're updating overlaps with the range we already - * know about, then fetch just flags + uids first. If uids - * aren't "right", reorder them. Update flags appropriately. - * If that returned unknown UIDs, or we're updating unknown - * sequence numbers, do the full fetch for those. - */ - - summary_specifier = imap_protocol_get_summary_specifier (store); - if (first == last) { - response = camel_imap_command (store, folder, ex, - "FETCH %d (%s)", first, - summary_specifier); - } else { - response = camel_imap_command (store, folder, ex, - "FETCH %d:%d (%s)", first, - last, summary_specifier); - } - g_free (summary_specifier); - - if (!response) - return; - - headers = response->untagged; - for (i = 0; i < headers->len; i++) { - CamelMessageInfo *info; - char *uid, *flags, *header; - - /* Grab the UID... */ - if (!(uid = strstr (headers->pdata[i], "UID "))) { - d(fprintf (stderr, "Cannot get a uid for %d\n\n%s\n\n", i+1, (char *) headers->pdata[i])); - break; - } - - for (uid += 4; *uid && (*uid < '0' || *uid > '9'); uid++) - ; - for (q = uid; *q && *q >= '0' && *q <= '9'; q++) - ; - - /* construct the header list */ - /* fast-forward to beginning of header info... */ - header = strchr (headers->pdata[i], '\n') + 1; - h = NULL; - do { - char *line; - int len; - - len = strcspn (header, "\n"); - while (header[len + 1] == ' ' || - header[len + 1] == '\t') - len += 1 + strcspn (header + len + 1, "\n"); - line = g_strndup (header, len); - header_raw_append_parse (&h, line, -1); - g_free (line); - - header += len; - } while (*header++ == '\n' && *header != '\n'); - - /* We can't just call camel_folder_summary_add_from_parser - * because it will assign the wrong UID, and thus get the - * uid hash table wrong and all that. FIXME some day. - */ - info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(imap_folder->summary)))->message_info_new(imap_folder->summary, h); - header_raw_clear (&h); - info->uid = g_strndup (uid, q - uid); - - /* now lets grab the FLAGS */ - if (!(flags = strstr (headers->pdata[i], "FLAGS "))) { - d(fprintf (stderr, "We didn't seem to get any flags for %d...\n", i)); - } else { - for (flags += 6; *flags && *flags != '('; flags++) - ; - info->flags = imap_parse_flag_list (flags); - } - - camel_folder_summary_add (imap_folder->summary, info); - } - camel_imap_response_free (response); -} - -static GPtrArray * -imap_get_summary (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - return imap_folder->summary->messages; -} - -/* get a single message info, by uid */ -static const CamelMessageInfo * -imap_get_message_info (CamelFolder *folder, const char *uid) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - return camel_folder_summary_uid (imap_folder->summary, uid); -} - -static GPtrArray * -imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex) -{ - CamelImapResponse *response; - GPtrArray *uids = NULL; - char *result, *sexp, *p; - - d(fprintf (stderr, "camel sexp: '%s'\n", expression)); - sexp = imap_translate_sexp (expression); - d(fprintf (stderr, "imap sexp: '%s'\n", sexp)); - - uids = g_ptr_array_new (); - - if (!folder->has_search_capability) { - g_free (sexp); - return uids; - } - - response = camel_imap_command (CAMEL_IMAP_STORE (folder->parent_store), - folder, NULL, "UID SEARCH %s", sexp); - g_free (sexp); - if (!response) - return uids; - - result = camel_imap_response_extract (response, "SEARCH", NULL); - if (!result) - return uids; - - if ((p = strstr (result, "* SEARCH"))) { - char *word; - - word = imap_next_word (p); /* word now points to SEARCH */ - - for (word = imap_next_word (word); *word && *word != '*'; word = imap_next_word (word)) { - gboolean word_is_numeric = TRUE; - char *ep; - - /* find the end of this word and make sure it's a numeric uid */ - for (ep = word; *ep && *ep != ' ' && *ep != '\n'; ep++) - if (*ep < '0' || *ep > '9') - word_is_numeric = FALSE; - - if (word_is_numeric) - g_ptr_array_add (uids, g_strndup (word, (gint)(ep - word))); - } - } - - g_free (result); - - return uids; -} - -static guint32 -imap_get_message_flags (CamelFolder *folder, const char *uid) -{ - const CamelMessageInfo *info; - - info = imap_get_message_info (folder, uid); - g_return_val_if_fail (info != NULL, 0); - - return info->flags; -} - -static void -imap_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set) -{ - CamelImapFolder *imap_folder = (CamelImapFolder *)folder; - CamelMessageInfo *info; - - info = camel_folder_summary_uid (imap_folder->summary, uid); - g_return_if_fail (info != NULL); - - if ((info->flags & set) == flags) - return; - - info->flags = (info->flags & ~flags) | (set & flags) | CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch (imap_folder->summary); - - camel_object_trigger_event (CAMEL_OBJECT (folder), "message_changed", - (gpointer)uid); -} - -static gboolean -imap_get_message_user_flag (CamelFolder *folder, const char *uid, const char *name) -{ - /* FIXME */ - return FALSE; -} - -static void -imap_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, gboolean value) -{ - /* FIXME */ - camel_object_trigger_event (CAMEL_OBJECT (folder), "message_changed", - (gpointer)uid); -} - -void -camel_imap_folder_changed (CamelFolder *folder, int exists, - GArray *expunged, CamelException *ex) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - if (expunged) { - int i, id; - - for (i = 0; i < expunged->len; i++) { - id = g_array_index (expunged, int, i); - camel_folder_summary_remove_index ( - imap_folder->summary, id - 1); - } - camel_object_trigger_event (CAMEL_OBJECT (folder), - "folder_changed", NULL); - } - - if (exists != 0) - imap_folder->exists = exists; -} diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h deleted file mode 100644 index 109cc76506..0000000000 --- a/camel/providers/imap/camel-imap-folder.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-folder.h : Abstract class for an imap folder */ - -/* - * Author: - * Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_IMAP_FOLDER_H -#define CAMEL_IMAP_FOLDER_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-folder.h" -#include <camel/camel-folder-search.h> - -#define CAMEL_IMAP_FOLDER_TYPE (camel_imap_folder_get_type ()) -#define CAMEL_IMAP_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_FOLDER_TYPE, CamelImapFolder)) -#define CAMEL_IMAP_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAP_FOLDER_TYPE, CamelImapFolderClass)) -#define IS_CAMEL_IMAP_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_FOLDER_TYPE)) - -typedef struct { - CamelFolder parent_object; - - CamelFolderSummary *summary; - int exists; -} CamelImapFolder; - - -typedef struct { - CamelFolderClass parent_class; - - /* Virtual methods */ - -} CamelImapFolderClass; - - -/* public methods */ -CamelFolder *camel_imap_folder_new (CamelStore *parent, - const char *folder_name, - const char *short_name, - const char *summary_file, - CamelException *ex); - -void camel_imap_folder_changed (CamelFolder *folder, int exists, - GArray *expunged, CamelException *ex); - -/* Standard Camel function */ -CamelType camel_imap_folder_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_IMAP_FOLDER_H */ diff --git a/camel/providers/imap/camel-imap-provider.c b/camel/providers/imap/camel-imap-provider.c deleted file mode 100644 index 9b962df5f4..0000000000 --- a/camel/providers/imap/camel-imap-provider.c +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-provider.c: imap provider registration code */ - -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#include "config.h" -#include "camel-imap-store.h" -#include "camel-provider.h" -#include "camel-session.h" -#include "camel-url.h" - -static void add_hash (guint *hash, char *s); -static guint imap_url_hash (gconstpointer key); -static gint check_equal (char *s1, char *s2); -static gint imap_url_equal (gconstpointer a, gconstpointer b); - -static CamelProvider imap_provider = { - "imap", - N_("IMAPv4"), - - N_("For reading and storing mail on IMAP servers."), - - "mail", - - CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE | - CAMEL_PROVIDER_IS_STORAGE, - - CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | - CAMEL_URL_ALLOW_PATH | CAMEL_URL_ALLOW_AUTH, - - { 0, 0 }, - - NULL -}; - -void -camel_provider_module_init (CamelSession *session) -{ - imap_provider.object_types[CAMEL_PROVIDER_STORE] = - camel_imap_store_get_type(); - - imap_provider.service_cache = g_hash_table_new (imap_url_hash, imap_url_equal); - - camel_session_register_provider (session, &imap_provider); -} - -static void -add_hash (guint *hash, char *s) -{ - if (s) - *hash ^= g_str_hash(s); -} - -static guint -imap_url_hash (gconstpointer key) -{ - const CamelURL *u = (CamelURL *)key; - guint hash = 0; - - add_hash (&hash, u->user); - add_hash (&hash, u->authmech); - add_hash (&hash, u->host); - hash ^= u->port; - - return hash; -} - -static gint -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 gint -imap_url_equal (gconstpointer a, gconstpointer b) -{ - const CamelURL *u1 = a, *u2 = b; - - return check_equal (u1->user, u2->user) - && check_equal (u1->authmech, u2->authmech) - && check_equal (u1->host, u2->host) - && u1->port == u2->port; -} diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c deleted file mode 100644 index 0a8618ff90..0000000000 --- a/camel/providers/imap/camel-imap-store.c +++ /dev/null @@ -1,788 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-store.c : class for an imap store */ - -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <gal/util/e-util.h> - -#include "camel-imap-store.h" -#include "camel-imap-auth.h" -#include "camel-imap-folder.h" -#include "camel-imap-utils.h" -#include "camel-imap-command.h" -#include "camel-folder.h" -#include "camel-exception.h" -#include "camel-session.h" -#include "camel-stream.h" -#include "camel-stream-buffer.h" -#include "camel-stream-fs.h" -#include "camel-url.h" -#include "string-utils.h" - -#define d(x) x - -/* Specified in RFC 2060 */ -#define IMAP_PORT 143 - -static CamelRemoteStoreClass *remote_store_class = NULL; - -static gboolean imap_connect (CamelService *service, CamelException *ex); -static gboolean imap_disconnect (CamelService *service, gboolean clean, CamelException *ex); -static GList *query_auth_types_generic (CamelService *service, CamelException *ex); -static GList *query_auth_types_connected (CamelService *service, CamelException *ex); -static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); -static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, - gboolean fast, gboolean recursive, - gboolean subscribed_only, - CamelException *ex); -static gboolean folder_subscribed (CamelStore *store, const char *folder_name); -static void subscribe_folder (CamelStore *store, const char *folder_name, - CamelException *ex); -static void unsubscribe_folder (CamelStore *store, const char *folder_name, - CamelException *ex); -static void imap_keepalive (CamelRemoteStore *store); - -static void -camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class) -{ - /* virtual method overload */ - CamelServiceClass *camel_service_class = - CAMEL_SERVICE_CLASS (camel_imap_store_class); - CamelStoreClass *camel_store_class = - CAMEL_STORE_CLASS (camel_imap_store_class); - CamelRemoteStoreClass *camel_remote_store_class = - CAMEL_REMOTE_STORE_CLASS (camel_imap_store_class); - - remote_store_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs - (camel_remote_store_get_type ())); - - /* virtual method overload */ - camel_service_class->query_auth_types_generic = query_auth_types_generic; - camel_service_class->query_auth_types_connected = query_auth_types_connected; - camel_service_class->connect = imap_connect; - camel_service_class->disconnect = imap_disconnect; - - camel_store_class->get_folder = get_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; - camel_store_class->get_folder_info = get_folder_info; - camel_store_class->free_folder_info = camel_store_free_folder_info_full; - - camel_store_class->folder_subscribed = folder_subscribed; - camel_store_class->subscribe_folder = subscribe_folder; - camel_store_class->unsubscribe_folder = unsubscribe_folder; - - camel_remote_store_class->keepalive = imap_keepalive; -} - -static gboolean -free_sub (gpointer key, gpointer value, gpointer user_data) -{ - g_free (key); - return TRUE; -} - -static void -camel_imap_store_finalize (CamelObject *object) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (object); - - g_hash_table_foreach_remove (imap_store->subscribed_folders, - free_sub, NULL); - g_hash_table_destroy (imap_store->subscribed_folders); -} - -static void -camel_imap_store_init (gpointer object, gpointer klass) -{ - CamelRemoteStore *remote_store = CAMEL_REMOTE_STORE (object); - CamelImapStore *imap_store = CAMEL_IMAP_STORE (object); - CamelStore *store = CAMEL_STORE (object); - - remote_store->default_port = 143; - - imap_store->dir_sep = '\0'; - imap_store->current_folder = NULL; - - store->flags = CAMEL_STORE_SUBSCRIPTIONS; - - imap_store->connected = FALSE; - imap_store->subscribed_folders = g_hash_table_new (g_str_hash, g_str_equal); -} - -CamelType -camel_imap_store_get_type (void) -{ - static CamelType camel_imap_store_type = CAMEL_INVALID_TYPE; - - if (camel_imap_store_type == CAMEL_INVALID_TYPE) { - camel_imap_store_type = - camel_type_register (CAMEL_REMOTE_STORE_TYPE, "CamelImapStore", - sizeof (CamelImapStore), - sizeof (CamelImapStoreClass), - (CamelObjectClassInitFunc) camel_imap_store_class_init, - NULL, - (CamelObjectInitFunc) camel_imap_store_init, - (CamelObjectFinalizeFunc) camel_imap_store_finalize); - } - - return camel_imap_store_type; -} - -static struct { - const char *name; - guint32 flag; -} capabilities[] = { - { "IMAP4", IMAP_CAPABILITY_IMAP4 }, - { "IMAP4REV1", IMAP_CAPABILITY_IMAP4REV1 }, - { "STATUS", IMAP_CAPABILITY_STATUS }, - { "NAMESPACE", IMAP_CAPABILITY_NAMESPACE }, - { "AUTH=KERBEROS_V4", IMAP_CAPABILITY_AUTH_KERBEROS_V4 }, - { "AUTH=GSSAPI", IMAP_CAPABILITY_AUTH_GSSAPI }, - { "UIDPLUS", IMAP_CAPABILITY_UIDPLUS }, - { "LITERAL+", IMAP_CAPABILITY_LITERALPLUS }, - { NULL, 0 } -}; - -static gboolean -connect_to_server (CamelService *service, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (service); - CamelImapResponse *response; - char *result, *buf, *capa, *lasts; - int i; - - if (!CAMEL_SERVICE_CLASS (remote_store_class)->connect (service, ex)) - return FALSE; - - store->command = 0; - - /* Read the greeting, if any. FIXME: deal with PREAUTH */ - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (service), - &buf, ex) < 0) { - return FALSE; - } - g_free (buf); - store->connected = TRUE; - - /* Find out the IMAP capabilities */ - store->capabilities = 0; - response = camel_imap_command (store, NULL, ex, "CAPABILITY"); - if (!response) - return FALSE; - result = camel_imap_response_extract (response, "CAPABILITY", ex); - if (!result) - return FALSE; - - /* Skip over "* CAPABILITY". */ - capa = imap_next_word (result + 2); - - for (capa = strtok_r (capa, " ", &lasts); capa; - capa = strtok_r (NULL, " ", &lasts)) { - for (i = 0; capabilities[i].name; i++) { - if (g_strcasecmp (capa, capabilities[i].name) == 0) { - store->capabilities |= capabilities[i].flag; - break; - } - } - } - g_free (result); - - if (store->capabilities & IMAP_CAPABILITY_IMAP4REV1) { - store->server_level = IMAP_LEVEL_IMAP4REV1; - store->capabilities |= IMAP_CAPABILITY_STATUS; - } else if (store->capabilities & IMAP_CAPABILITY_IMAP4) - store->server_level = IMAP_LEVEL_IMAP4; - else - store->server_level = IMAP_LEVEL_UNKNOWN; - - return TRUE; -} - -static CamelServiceAuthType password_authtype = { - N_("Password"), - - N_("This option will connect to the IMAP server using a " - "plaintext password."), - - "", - TRUE -}; - -#ifdef HAVE_KRB4 -static CamelServiceAuthType kerberos_v4_authtype = { - N_("Kerberos 4"), - - N_("This option will connect to the IMAP server using " - "Kerberos 4 authentication."), - - "KERBEROS_V4", - FALSE -}; -#endif - -static GList * -query_auth_types_connected (CamelService *service, CamelException *ex) -{ - GList *types; - - if (!connect_to_server (service, ex)) - return NULL; - - types = CAMEL_SERVICE_CLASS (remote_store_class)->query_auth_types_connected (service, ex); -#ifdef HAVE_KRB4 - if (CAMEL_IMAP_STORE (service)->capabilities & - IMAP_CAPABILITY_AUTH_KERBEROS_V4) - types = g_list_prepend (types, &kerberos_v4_authtype); -#endif - return g_list_prepend (types, &password_authtype); -} - -static GList * -query_auth_types_generic (CamelService *service, CamelException *ex) -{ - GList *types; - - types = CAMEL_SERVICE_CLASS (remote_store_class)->query_auth_types_generic (service, ex); -#ifdef HAVE_KRB4 - types = g_list_prepend (types, &kerberos_v4_authtype); -#endif - return g_list_prepend (types, &password_authtype); -} - -static gboolean -imap_connect (CamelService *service, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (service); - CamelSession *session = camel_service_get_session (CAMEL_SERVICE (store)); - gchar *result, *errbuf = NULL, *namespace; - CamelImapResponse *response; - gboolean authenticated = FALSE; - int len; - - if (connect_to_server (service, ex) == 0) - return FALSE; - - /* authenticate the user */ -#ifdef HAVE_KRB4 - if (service->url->authmech && - !g_strcasecmp (service->url->authmech, "KERBEROS_V4")) { - if (!(store->capabilities & IMAP_CAPABILITY_AUTH_KERBEROS_V4)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - "IMAP server %s does not " - "support requested " - "authentication type %s", - service->url->host, - service->url->authmech); - camel_service_disconnect (service, TRUE, NULL); - return FALSE; - } - - authenticated = imap_try_kerberos_v4_auth (store, ex); - if (camel_exception_is_set (ex)) { - camel_service_disconnect (service, TRUE, NULL); - return FALSE; - } - } -#endif - - while (!authenticated) { - if (errbuf) { - /* We need to un-cache the password before prompting again */ - camel_session_query_authenticator ( - session, CAMEL_AUTHENTICATOR_TELL, NULL, - TRUE, service, "password", ex); - g_free (service->url->passwd); - service->url->passwd = NULL; - } - - if (!service->url->authmech && !service->url->passwd) { - char *prompt; - - prompt = g_strdup_printf (_("%sPlease enter the IMAP " - "password for %s@%s"), - errbuf ? errbuf : "", - service->url->user, - service->url->host); - service->url->passwd = - camel_session_query_authenticator ( - session, CAMEL_AUTHENTICATOR_ASK, - prompt, TRUE, service, "password", ex); - g_free (prompt); - g_free (errbuf); - errbuf = NULL; - - if (!service->url->passwd) { - camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, - "You didn\'t enter a password."); - camel_service_disconnect (service, TRUE, NULL); - return FALSE; - } - } - - response = camel_imap_command (store, NULL, ex, - "LOGIN \"%s\" \"%s\"", - service->url->user, - service->url->passwd); - if (!response) { - errbuf = g_strdup_printf (_("Unable to authenticate " - "to IMAP server.\n%s\n\n"), - camel_exception_get_description (ex)); - camel_exception_clear (ex); - } else { - authenticated = TRUE; - camel_imap_response_free (response); - } - } - - /* Find our storage path. */ - if (!store->storage_path) { - store->storage_path = - camel_session_get_storage_path (session, service, ex); - if (camel_exception_is_set (ex)) - return FALSE; - } - - /* Find the hierarchy separator for our namespace. */ - namespace = service->url->path; - if (namespace) - namespace++; - else - namespace = ""; - if (store->server_level >= IMAP_LEVEL_IMAP4REV1) { - /* This idiom means "tell me the hierarchy separator - * for the given path, even if that path doesn't exist. - */ - response = camel_imap_command (store, NULL, ex, - "LIST \"%s\" \"\"", - namespace); - } else { - /* Plain IMAP4 doesn't have that idiom, so we fall back - * to "tell me about this folder", which will fail if - * the folder doesn't exist (eg, if namespace is ""). - */ - response = camel_imap_command (store, NULL, ex, - "LIST \"\" \"%s\"", - namespace); - } - if (!response) - return FALSE; - - result = camel_imap_response_extract (response, "LIST", NULL); - if (result) { - imap_parse_list_response (result, NULL, &store->dir_sep, NULL); - g_free (result); - } - if (!store->dir_sep) - store->dir_sep = '/'; /* Guess */ - - /* Generate base URL */ - store->base_url = camel_url_to_string (service->url, FALSE); - len = strlen (store->base_url); - if (service->url->path) - store->base_url[len - strlen (service->url->path) + 1] = '\0'; - else { - store->base_url = g_realloc (store->base_url, len + 2); - store->base_url[len] = '/'; - store->base_url[len + 1] = '\0'; - } - - camel_remote_store_refresh_folders (CAMEL_REMOTE_STORE (store), ex); - - return !camel_exception_is_set (ex); -} - -static gboolean -imap_disconnect (CamelService *service, gboolean clean, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (service); - CamelImapResponse *response; - - if (store->connected && clean) { - /* send the logout command */ - response = camel_imap_command (store, NULL, ex, "LOGOUT"); - camel_imap_response_free (response); - } - - store->current_folder = NULL; - - return CAMEL_SERVICE_CLASS (remote_store_class)->disconnect (service, clean, ex); -} - -static gboolean -imap_folder_exists (CamelImapStore *store, const char *folder_name, - gboolean *selectable, char **short_name, - CamelException *ex) -{ - CamelImapResponse *response; - char *result, sep; - int flags; - - if (!g_strcasecmp (folder_name, "INBOX")) { - if (selectable) - *selectable = TRUE; - if (short_name) - *short_name = g_strdup ("INBOX"); - return TRUE; - } - - response = camel_imap_command (store, NULL, ex, "LIST \"\" \"%s\"", - folder_name); - if (!response) - return FALSE; - result = camel_imap_response_extract (response, "LIST", ex); - if (!result) - return FALSE; - - if (!imap_parse_list_response (result, &flags, &sep, NULL)) - return FALSE; - - if (selectable) - *selectable = !(flags & IMAP_LIST_FLAG_NOSELECT); - if (short_name) { - *short_name = strrchr (folder_name, sep); - if (*short_name) - *short_name = g_strdup (*short_name + 1); - else - *short_name = g_strdup (folder_name); - } - - return TRUE; -} - -static gboolean -imap_create (CamelImapStore *store, const char *folder_name, - CamelException *ex) -{ - CamelImapResponse *response; - - response = camel_imap_command (store, NULL, ex, "CREATE \"%s\"", - folder_name); - camel_imap_response_free (response); - - return !camel_exception_is_set (ex); -} - -static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, guint32 flags, - CamelException *ex) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - CamelFolder *new_folder = NULL; - char *short_name, *summary_file, *p; - gboolean selectable; - - if (!imap_folder_exists (imap_store, folder_name, - &selectable, &short_name, ex)) { - if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) - return NULL; - - if (!imap_create (imap_store, folder_name, ex)) - return NULL; - - if (!imap_folder_exists (imap_store, folder_name, - &selectable, &short_name, ex)) - return NULL; - } - - if (!selectable) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - "%s is not a selectable folder", - folder_name); - g_free (short_name); - return NULL; - } - - summary_file = g_strdup_printf ("%s/%s/#summary", - imap_store->storage_path, - folder_name); - p = strrchr (summary_file, '/'); - *p = '\0'; - if (e_mkdir_hier (summary_file, S_IRWXU) == 0) { - *p = '/'; - new_folder = camel_imap_folder_new (store, folder_name, - short_name, summary_file, - ex); - } else { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not create directory %s: %s"), - summary_file, g_strerror (errno)); - } - g_free (summary_file); - g_free (short_name); - - if (camel_exception_is_set (ex)) - return NULL; - - return new_folder; -} - -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - /* INBOX is case-insensitive */ - if (g_strcasecmp (folder_name, "INBOX") == 0) - return g_strdup ("INBOX"); - else - return g_strdup (folder_name); -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup (""); -} - -static CamelFolderInfo * -parse_list_response_as_folder_info (CamelImapStore *imap_store, - const char *response) -{ - CamelFolderInfo *fi; - int flags; - char sep, *dir, *name; - - if (!imap_parse_list_response (response, &flags, &sep, &dir)) - return NULL; - - if (sep) { - name = strrchr (dir, sep); - if (name && !*++name) { - g_free (dir); - return NULL; - } - } - - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = dir; - if (sep && name) - fi->name = g_strdup (name); - else - fi->name = g_strdup (dir); - if (!(flags & IMAP_LIST_FLAG_NOSELECT)) - fi->url = g_strdup_printf ("%s%s", imap_store->base_url, dir); - - return fi; -} - -static CamelFolderInfo * -get_folder_info (CamelStore *store, const char *top, gboolean fast, - gboolean recursive, gboolean subscribed_only, - CamelException *ex) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - CamelURL *url = CAMEL_SERVICE (store)->url; - gboolean need_inbox = FALSE; - int i; - CamelImapResponse *response; - GPtrArray *folders; - const char *name; - char *pattern, *list; - char *status, *p; - CamelFolderInfo *topfi, *fi; - - name = top; - if (!name) { - need_inbox = !subscribed_only; - if (url->path) - name = url->path + 1; - else - name = ""; - } - response = camel_imap_command (imap_store, NULL, ex, - "LIST \"\" \"%s\"", name); - if (!response) - return FALSE; - list = camel_imap_response_extract (response, "LIST", ex); - if (!list) - return FALSE; - topfi = parse_list_response_as_folder_info (imap_store, list); - g_free (list); - if (!topfi) { - topfi = g_new0 (CamelFolderInfo, 1); - topfi->full_name = g_strdup (name); - topfi->name = g_strdup (name); - } - - if (!top && subscribed_only) - pattern = g_strdup (""); - else if (*name) - pattern = g_strdup_printf ("%s%c", name, imap_store->dir_sep); - else - pattern = g_strdup (name); - response = camel_imap_command (imap_store, NULL, ex, - "%s \"\" \"%s%c\"", - subscribed_only ? "LSUB" : "LIST", - pattern, recursive ? '*' : '%'); - g_free (pattern); - if (!response) - return NULL; - - if (subscribed_only) { - g_hash_table_foreach_remove (imap_store->subscribed_folders, - free_sub, NULL); - } - - /* Turn responses into CamelFolderInfo and remove any - * extraneous responses. - */ - folders = g_ptr_array_new (); - for (i = 0; i < response->untagged->len; i++) { - list = response->untagged->pdata[i]; - fi = parse_list_response_as_folder_info (imap_store, list); - if (!fi) - continue; - g_ptr_array_add (folders, fi); - - if (subscribed_only) { - g_hash_table_insert (imap_store->subscribed_folders, - g_strdup (fi->full_name), - GUINT_TO_POINTER (1)); - } - - if (!g_strcasecmp (fi->full_name, "INBOX")) - need_inbox = FALSE; - } - camel_imap_response_free (response); - - /* Add INBOX, if necessary */ - if (need_inbox) { - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = g_strdup ("INBOX"); - fi->name = g_strdup ("INBOX"); - fi->url = g_strdup_printf ("%sINBOX", imap_store->base_url); - - g_ptr_array_add (folders, fi); - } - - if (!fast) { - /* Get read/unread counts */ - for (i = 0; i < folders->len; i++) { - fi = folders->pdata[i]; - if (!fi->url) - continue; - - response = camel_imap_command ( - imap_store, NULL, NULL, - "STATUS \"%s\" (MESSAGES UNSEEN)", - fi->full_name); - if (!response) - continue; - status = camel_imap_response_extract ( - response, "STATUS", NULL); - if (!status) - continue; - - p = e_strstrcase (status, "MESSAGES"); - if (p) - fi->message_count = strtoul (p + 8, NULL, 10); - p = e_strstrcase (status, "UNSEEN"); - if (p) - fi->unread_message_count = strtoul (p + 6, NULL, 10); - g_free (status); - } - } - - /* And assemble */ - camel_folder_info_build (folders, topfi, imap_store->dir_sep, TRUE); - g_ptr_array_free (folders, TRUE); - - /* Remove the top if it's the root of the store. */ - if (!top && !topfi->sibling && !topfi->url) { - fi = topfi; - topfi = topfi->child; - fi->child = NULL; - camel_folder_info_free (fi); - for (fi = topfi; fi; fi = fi->sibling) - fi->parent = NULL; - } - - return topfi; -} - -static gboolean -folder_subscribed (CamelStore *store, const char *folder_name) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - - return g_hash_table_lookup (imap_store->subscribed_folders, - folder_name) != NULL; -} - -static void -subscribe_folder (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - CamelImapResponse *response; - - response = camel_imap_command (imap_store, NULL, ex, - "SUBSCRIBE \"%s\"", folder_name); - if (response) { - g_hash_table_insert (imap_store->subscribed_folders, - g_strdup (folder_name), - GUINT_TO_POINTER (1)); - } - camel_imap_response_free (response); -} - -static void -unsubscribe_folder (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - CamelImapResponse *response; - gpointer key, value; - - response = camel_imap_command (imap_store, NULL, ex, - "UNSUBSCRIBE \"%s\"", folder_name); - if (response) { - g_hash_table_lookup_extended (imap_store->subscribed_folders, - folder_name, key, value); - g_hash_table_remove (imap_store->subscribed_folders, - folder_name); - g_free (key); - } - camel_imap_response_free (response); -} - -static void -imap_keepalive (CamelRemoteStore *store) -{ - CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - CamelImapResponse *response; - - response = camel_imap_command (imap_store, NULL, NULL, "NOOP"); - camel_imap_response_free (response); -} diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h deleted file mode 100644 index 8fd996c420..0000000000 --- a/camel/providers/imap/camel-imap-store.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-store.h : class for an imap store */ - -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_IMAP_STORE_H -#define CAMEL_IMAP_STORE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-remote-store.h" - -#define CAMEL_IMAP_STORE_TYPE (camel_imap_store_get_type ()) -#define CAMEL_IMAP_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_STORE_TYPE, CamelImapStore)) -#define CAMEL_IMAP_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAP_STORE_TYPE, CamelImapStoreClass)) -#define IS_CAMEL_IMAP_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_STORE_TYPE)) - -typedef enum { - IMAP_LEVEL_UNKNOWN, - IMAP_LEVEL_IMAP4, - IMAP_LEVEL_IMAP4REV1 -} CamelImapServerLevel; - -#define IMAP_CAPABILITY_IMAP4 (1 << 0) -#define IMAP_CAPABILITY_IMAP4REV1 (1 << 1) -#define IMAP_CAPABILITY_STATUS (1 << 2) -#define IMAP_CAPABILITY_NAMESPACE (1 << 3) -#define IMAP_CAPABILITY_AUTH_KERBEROS_V4 (1 << 4) -#define IMAP_CAPABILITY_AUTH_GSSAPI (1 << 5) -#define IMAP_CAPABILITY_UIDPLUS (1 << 6) -#define IMAP_CAPABILITY_LITERALPLUS (1 << 7) - -typedef struct { - CamelRemoteStore parent_object; - - CamelFolder *current_folder; - - guint32 command; - - CamelImapServerLevel server_level; - guint32 capabilities; - - gchar dir_sep, *storage_path, *base_url; - - gboolean connected; - - GHashTable *subscribed_folders; -} CamelImapStore; - - -typedef struct { - CamelRemoteStoreClass parent_class; - -} CamelImapStoreClass; - - -/* Standard Camel function */ -CamelType camel_imap_store_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_IMAP_STORE_H */ diff --git a/camel/providers/imap/camel-imap-stream.c b/camel/providers/imap/camel-imap-stream.c deleted file mode 100644 index 4e9ee046d7..0000000000 --- a/camel/providers/imap/camel-imap-stream.c +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#include <config.h> -#include "camel-imap-stream.h" -#include "camel/camel-exception.h" -#include <sys/types.h> -#include <errno.h> -#include <stdlib.h> - -static CamelStreamClass *parent_class = NULL; - -/* Returns the class for a CamelImapStream */ -#define CIS_CLASS(so) CAMEL_IMAP_STREAM_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n); -static int stream_reset (CamelStream *stream); -static gboolean stream_eos (CamelStream *stream); - -static void finalize (CamelObject *object); - -static void -camel_imap_stream_class_init (CamelImapStreamClass *camel_imap_stream_class) -{ - CamelStreamClass *camel_stream_class = - CAMEL_STREAM_CLASS (camel_imap_stream_class); - - parent_class = CAMEL_STREAM_CLASS (camel_type_get_global_classfuncs (camel_stream_get_type ())); - - /* virtual method overload */ - camel_stream_class->read = stream_read; - camel_stream_class->reset = stream_reset; - camel_stream_class->eos = stream_eos; -} - -static void -camel_imap_stream_init (gpointer object, gpointer klass) -{ - CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (object); - - imap_stream->cache = NULL; - imap_stream->cache_ptr = NULL; -} - -CamelType -camel_imap_stream_get_type (void) -{ - static CamelType camel_imap_stream_type = CAMEL_INVALID_TYPE; - - if (camel_imap_stream_type == CAMEL_INVALID_TYPE) { - camel_imap_stream_type = - camel_type_register (camel_stream_get_type (), "CamelImapStream", - sizeof (CamelImapStream), - sizeof (CamelImapStreamClass), - (CamelObjectClassInitFunc) camel_imap_stream_class_init, - NULL, - (CamelObjectInitFunc) camel_imap_stream_init, - (CamelObjectFinalizeFunc) finalize); - } - - return camel_imap_stream_type; -} - -CamelStream * -camel_imap_stream_new (CamelImapFolder *folder, char *command) -{ - CamelImapStream *imap_stream; - - imap_stream = CAMEL_IMAP_STREAM(camel_object_new (camel_imap_stream_get_type ())); - - imap_stream->folder = folder; - camel_object_ref (CAMEL_OBJECT (imap_stream->folder)); - - imap_stream->command = g_strdup (command); - - return CAMEL_STREAM (imap_stream); -} - -static void -finalize (CamelObject *object) -{ - CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (object); - - g_free (imap_stream->cache); - g_free (imap_stream->command); - - if (imap_stream->folder) - camel_object_unref (CAMEL_OBJECT (imap_stream->folder)); -} - -static ssize_t -stream_read (CamelStream *stream, char *buffer, size_t n) -{ - ssize_t nread; - - /* do we want to do any IMAP specific parsing in here? If not, maybe rename to camel-stream-cache? */ - CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (stream); - - if (!imap_stream->cache) { - /* We need to send the IMAP command since this is our first fetch */ - CamelFolder *folder = CAMEL_FOLDER (imap_stream->folder); - CamelException ex; - gchar *result, *p, *q; - gint status, part_len; - - camel_exception_init (&ex); - status = camel_imap_fetch_command (CAMEL_IMAP_STORE (folder->parent_store), - CAMEL_FOLDER (imap_stream->folder), - &result, &ex, "%s\r\n", - imap_stream->command); - /* FIXME: exception is ignored */ - camel_exception_clear (&ex); - - if (!result || status != CAMEL_IMAP_OK) { - /* we got an error, dump this stuff */ - g_free (result); - imap_stream->cache = NULL; - camel_object_unref (CAMEL_OBJECT (imap_stream->folder)); - - return -1; - } - - /* we don't need the folder anymore... */ - camel_object_unref (CAMEL_OBJECT (imap_stream->folder)); - - /* parse out the message part */ - for (p = result; *p && *p != '{' && *p != '"' && *p != '\n'; p++); - switch (*p) { - case '"': - /* a quoted string - section 4.3 */ - p++; - for (q = p; *q && *q != '"' && *q != '\n'; q++); - part_len = (gint) (q - p); - - break; - case '{': - /* a literal string - section 4.3 */ - part_len = atoi (p + 1); - for ( ; *p && *p != '\n'; p++); - if (*p != '\n') { - g_free (result); - return -1; - } - - /* advance to the beginning of the actual data */ - p++; - - /* calculate the new part-length */ - for (q = p; *q && (q - p) <= part_len; q++) { - if (*q == '\n') - part_len--; - } - - /* FIXME: This is a hack for IMAP daemons that send us a UID at the end of each FETCH */ - for ( ; q > p && *(q-1) != '\n'; q--, part_len--); - part_len++; - - break; - default: - /* Bad input */ - g_free (result); - return -1; - } - - imap_stream->cache = g_strndup (p, part_len); - g_free (result); - - imap_stream->cache_ptr = imap_stream->cache; - } - - /* we've already read this stream, so return whats in the cache */ - nread = MIN (n, strlen (imap_stream->cache_ptr)); - - if (nread > 0) { - memcpy (buffer, imap_stream->cache_ptr, nread); - imap_stream->cache_ptr += nread; - } else { - nread = -1; - } - - return nread; -} - -static int -stream_reset (CamelStream *stream) -{ - CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (stream); - - imap_stream->cache_ptr = imap_stream->cache; - - return 1; -} - -static gboolean -stream_eos (CamelStream *stream) -{ - CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (stream); - - return (imap_stream->cache_ptr && strlen (imap_stream->cache_ptr)); -} diff --git a/camel/providers/imap/camel-imap-stream.h b/camel/providers/imap/camel-imap-stream.h deleted file mode 100644 index 88881e7c1f..0000000000 --- a/camel/providers/imap/camel-imap-stream.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#ifndef CAMEL_IMAP_STREAM_H -#define CAMEL_IMAP_STREAM_H - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <camel/camel-stream.h> -#include "camel-imap-folder.h" -#include "camel-imap-store.h" -#include <sys/types.h> - -#define CAMEL_IMAP_STREAM_TYPE (camel_imap_stream_get_type ()) -#define CAMEL_IMAP_STREAM(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_STREAM_TYPE, CamelImapStream)) -#define CAMEL_IMAP_STREAM_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAP_STREAM_TYPE, CamelImapStreamClass)) -#define CAMEL_IS_IMAP_STREAM(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_STREAM_TYPE)) - -typedef struct _CamelImapStream CamelImapStream; -typedef struct _CamelImapStreamClass CamelImapStreamClass; - -struct _CamelImapStream { - CamelStream parent_object; - - CamelImapFolder *folder; - char *command; - char *cache; - char *cache_ptr; -}; - -struct _CamelImapStreamClass { - CamelStreamClass parent_class; - - /* Virtual methods */ -}; - -/* Standard Camel function */ -CamelType camel_imap_stream_get_type (void); - -/* public methods */ -CamelStream *camel_imap_stream_new (CamelImapFolder *folder, char *command); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_IMAP_STREAM_H */ diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c deleted file mode 100644 index ebdf8b9842..0000000000 --- a/camel/providers/imap/camel-imap-summary.c +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: - * Michael Zucchi <notzed@helixcode.com> - * Dan Winship <danw@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "camel-imap-summary.h" -#include <camel/camel-mime-message.h> - -#include <sys/stat.h> -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#define CAMEL_IMAP_SUMMARY_VERSION (0x1000) - -static int summary_header_load (CamelFolderSummary *, FILE *); -static int summary_header_save (CamelFolderSummary *, FILE *); - -static void camel_imap_summary_class_init (CamelImapSummaryClass *klass); -static void camel_imap_summary_init (CamelImapSummary *obj); - -static CamelFolderSummaryClass *camel_imap_summary_parent; - -CamelType -camel_imap_summary_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register( - camel_folder_summary_get_type(), "CamelImapSummary", - sizeof (CamelImapSummary), - sizeof (CamelImapSummaryClass), - (CamelObjectClassInitFunc) camel_imap_summary_class_init, - NULL, - (CamelObjectInitFunc) camel_imap_summary_init, - NULL); - } - - return type; -} - -static void -camel_imap_summary_class_init (CamelImapSummaryClass *klass) -{ - CamelFolderSummaryClass *cfs_class = (CamelFolderSummaryClass *) klass; - - camel_imap_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs (camel_folder_summary_get_type())); - - cfs_class->summary_header_load = summary_header_load; - cfs_class->summary_header_save = summary_header_save; -} - -static void -camel_imap_summary_init (CamelImapSummary *obj) -{ - CamelFolderSummary *s = (CamelFolderSummary *)obj; - - /* subclasses need to set the right instance data sizes */ - s->message_info_size = sizeof(CamelImapMessageInfo); - s->content_info_size = sizeof(CamelImapMessageContentInfo); - - /* and a unique file version */ - s->version += CAMEL_IMAP_SUMMARY_VERSION; -} - -/** - * camel_imap_summary_new: - * @filename: the file to store the summary in. - * @validity: the current UIDVALIDITY value of the folder - * - * This will create a new CamelImapSummary object and read in the - * summary data from disk, if it exists and has the right UIDVALIDITY - * value. - * - * Return value: A new CamelImapSummary object. - **/ -CamelFolderSummary * -camel_imap_summary_new (const char *filename, guint32 validity) -{ - CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY ( - camel_object_new (camel_imap_summary_get_type ())); - CamelImapSummary *imap_summary = (CamelImapSummary *)summary; - - camel_folder_summary_set_build_content (summary, FALSE); - camel_folder_summary_set_filename (summary, filename); - - if (camel_folder_summary_load (summary) == -1) { - if (errno == ENOENT) { - imap_summary->validity = validity; - return summary; - } else { - camel_object_unref ((CamelObject *)summary); - return NULL; - } - } - if (imap_summary->validity != validity) { - camel_folder_summary_clear (summary); - imap_summary->validity = validity; - } - - return summary; -} - - -static int -summary_header_load (CamelFolderSummary *s, FILE *in) -{ - CamelImapSummary *ims = CAMEL_IMAP_SUMMARY (s); - - if (camel_imap_summary_parent->summary_header_load (s, in) == -1) - return -1; - - return camel_folder_summary_decode_uint32 (in, &ims->validity); -} - -static int -summary_header_save (CamelFolderSummary *s, FILE *out) -{ - CamelImapSummary *ims = CAMEL_IMAP_SUMMARY(s); - - if (camel_imap_summary_parent->summary_header_save (s, out) == -1) - return -1; - - return camel_folder_summary_encode_uint32 (out, ims->validity); -} diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h deleted file mode 100644 index 0b844fdd7e..0000000000 --- a/camel/providers/imap/camel-imap-summary.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: - * Michael Zucchi <notzed@helixcode.com> - * Dan Winship <danw@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _CAMEL_IMAP_SUMMARY_H -#define _CAMEL_IMAP_SUMMARY_H - -#include <camel/camel-folder-summary.h> -#include <camel/camel-exception.h> - -#define CAMEL_IMAP_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_imap_summary_get_type (), CamelImapSummary) -#define CAMEL_IMAP_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imap_summary_get_type (), CamelImapSummaryClass) -#define CAMEL_IS_IMAP_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_imap_summary_get_type ()) - -typedef struct _CamelImapSummary CamelImapSummary; -typedef struct _CamelImapSummaryClass CamelImapSummaryClass; - -typedef struct _CamelImapMessageContentInfo { - CamelMessageContentInfo info; - -} CamelImapMessageContentInfo; - -typedef struct _CamelImapMessageInfo { - CamelMessageInfo info; - -} CamelImapMessageInfo; - -struct _CamelImapSummary { - CamelFolderSummary parent; - - guint32 validity; -}; - -struct _CamelImapSummaryClass { - CamelFolderSummaryClass parent_class; - -}; - -guint camel_imap_summary_get_type (void); -CamelFolderSummary *camel_imap_summary_new (const char *filename, - guint32 validity); - -#endif /* ! _CAMEL_IMAP_SUMMARY_H */ - diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c deleted file mode 100644 index b38024ecc6..0000000000 --- a/camel/providers/imap/camel-imap-utils.c +++ /dev/null @@ -1,688 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <time.h> - -#include <gtk/gtk.h> -#include "camel-imap-utils.h" -#include "string-utils.h" -#include <e-sexp.h> -#include "camel/camel-folder-summary.h" - -#define d(x) x - -char * -imap_next_word (const char *buf) -{ - char *word; - - /* skip over current word */ - for (word = (char *)buf; *word && *word != ' '; word++); - - /* skip over white space */ - for ( ; *word && *word == ' '; word++); - - return word; -} - -/** - * imap_parse_list_response: - * @buf: the LIST or LSUB response - * @flags: a pointer to a variable to store the flags in, or %NULL - * @sep: a pointer to a variable to store the hierarchy separator in, or %NULL - * @folder: a pointer to a variable to store the folder name in, or %NULL - * - * Parses a LIST or LSUB response and returns the desired parts of it. - * If @folder is non-%NULL, its value must be freed by the caller. - * - * Return value: whether or not the response was successfully parsed. - **/ -gboolean -imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder) -{ - char *word; - int len; - - if (*buf != '*') - return FALSE; - - word = imap_next_word (buf); - if (g_strncasecmp (word, "LIST", 4) && g_strncasecmp (word, "LSUB", 4)) - return FALSE; - - /* get the flags */ - word = imap_next_word (word); - if (*word != '(') - return FALSE; - - if (flags) - *flags = 0; - - word++; - while (*word != ')') { - len = strcspn (word, " )"); - if (flags) { - if (!g_strncasecmp (word, "\\Noinferiors", len)) - *flags |= IMAP_LIST_FLAG_NOINFERIORS; - else if (!g_strncasecmp (word, "\\Noselect", len)) - *flags |= IMAP_LIST_FLAG_NOSELECT; - else if (!g_strncasecmp (word, "\\Marked", len)) - *flags |= IMAP_LIST_FLAG_MARKED; - else if (!g_strncasecmp (word, "\\Unmarked", len)) - *flags |= IMAP_LIST_FLAG_UNMARKED; - } - - word += len; - while (*word == ' ') - word++; - } - - /* get the directory separator */ - word = imap_next_word (word); - if (!strncmp (word, "NIL", 3)) { - if (sep) - *sep = '\0'; - } else if (*word++ == '"') { - if (*word == '\\') - word++; - if (sep) - *sep = *word; - word++; - if (*word++ != '"') - return FALSE; - } else - return FALSE; - - if (folder) { - /* get the folder name */ - word = imap_next_word (word); - *folder = imap_parse_astring (&word, &len); - return *folder != NULL; - } - - return TRUE; -} - -static ESExpResult * -func_and (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - ESExpResult *r; - - d(fprintf (stderr, "in AND func (argc = %d)\n", argc)); - if (argc > 0) { - char **strings; - int i; - - strings = g_new (char*, argc+1); - strings[argc] = NULL; - - for (i = 0; i < argc; i++) { - GList *list_head = *list; - - d(fprintf (stderr, "\tAND func: %s\n", (*list) ? (char *) (*list)->data : "(null)")); - strings[argc - (i+1)] = (*list) ? (*list)->data : g_strdup (""); - *list = g_list_remove_link (*list, *list); - g_list_free_1 (list_head); - } - - *list = g_list_prepend (*list, g_strjoinv (" ", strings)); - d(fprintf (stderr, "%s\n", (char *) (*list)->data)); - - for (i = 0 ; i < argc; i ++) - g_free (strings[i]); - - g_free (strings); - } - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_or (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - ESExpResult *r; - - d(fprintf (stderr, "in OR func (argc = %d)\n", argc)); - if (argc == 2 && (*list)->data && (*list)->next && (*list)->next->data) { - char **strings; - int i; - - strings = g_new (char*, argc+2); - strings[0] = g_strdup ("OR"); - strings[argc+2 - 1] = NULL; - - for (i = 0; i < 2; i++) { - GList *list_head = *list; - - d(fprintf (stderr, "\tOR func: %s\n", (*list) ? (char *) (*list)->data : "(null)")); - strings[argc - i] = (*list) ? (*list)->data : g_strdup (""); - *list = g_list_remove_link (*list, *list); - g_list_free_1 (list_head); - } - - *list = g_list_prepend (*list, g_strjoinv (" ", strings)); - d(fprintf (stderr, "%s\n", (char *) (*list)->data)); - - for (i = 0 ; i < argc + 2; i ++) - g_free (strings[i]); - - g_free (strings); - } - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_not (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - ESExpResult *r; - - d(fprintf (stderr, "in NOT func\n")); - /* just replace the head of the list with the NOT of it. */ - if (argc > 0) { - char *term = (*list)->data; - - (*list)->data = g_strdup_printf ("NOT %s", term); - d(fprintf (stderr, "%s\n", (char *) (*list)->data)); - g_free (term); - } - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static char *tz_months [] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -static char * -format_date (time_t time, int offset) -{ - struct tm tm; - - time += ((offset / 100) * (60*60)) + (offset % 100)*60; - - d(printf("converting date %s", ctime (&time))); - - memcpy (&tm, gmtime (&time), sizeof (tm)); - - return g_strdup_printf ("%d-%s-%04d", - tm.tm_mday, tz_months[tm.tm_mon], - tm.tm_year + 1900); -} - -static ESExpResult * -func_lt (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - char *type = (*list)->data; - time_t date = (time_t) (argv[1])->value.number; - ESExpResult *r; - - d(fprintf (stderr, "in less-than func: (%d) (%s) (%d)\n", argc, type, (int) date)); - if (argc > 0) { - char *string, *date_str; - - date_str = format_date (date, 0); - - if (!strcmp ("SENT", type)) { - string = g_strdup_printf ("SENTBEFORE \"%s\"", date_str); - } else { - string = g_strdup_printf ("BEFORE \"%s\"", date_str); - } - - (*list)->data = string; - g_free (type); - } - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_gt (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - char *type = (*list)->data; - time_t date = (time_t) (argv[1])->value.number; - ESExpResult *r; - - d(fprintf (stderr, "in greater-than func: (%d) (%s) (%d)\n", argc, type, (int) date)); - if (argc > 0) { - char *string, *date_str; - - date_str = format_date (date, 0); - - if (!strcmp ("SENT", type)) { - string = g_strdup_printf ("SENTSINCE \"%s\"", date_str); - } else { - string = g_strdup_printf ("SINCE \"%s\"", date_str); - } - - (*list)->data = string; - g_free (type); - } - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_eq (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - char *type = (*list)->data; - time_t date = (time_t) (argv[1])->value.number; - ESExpResult *r; - - d(fprintf (stderr, "in equal-to func: (%d) (%s) (%d)\n", argc, type, (int) date)); - if (argc > 0) { - char *string, *date_str; - - date_str = format_date (date, 0); - - if (!strcmp ("SENT", type)) { - string = g_strdup_printf ("SENTON \"%s\"", date_str); - } else { - string = g_strdup_printf ("ON \"%s\"", date_str); - } - - (*list)->data = string; - g_free (type); - } - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_match_all (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - /* match-all doesn't have a IMAP equiv */ - ESExpResult *r; - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - char *value = (*argv)->value.string; - ESExpResult *r; - - if (argc > 0) { - char *string; - - string = g_strdup_printf ("BODY \"%s\"", value); - - *list = g_list_prepend (*list, string); - } - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_header_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - char *header = (argv[0])->value.string; - char *match = (argv[1])->value.string; - ESExpResult *r; - - if (argc == 2) { - char *string; - string = g_strdup_printf ("HEADER %s \"%s\"", header, match); - - *list = g_list_prepend (*list, string); - } - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_user_tag (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - /* FIXME: what do I do here? */ - ESExpResult *r; - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_user_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - /* FIXME: what do I do here? */ - ESExpResult *r; - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_get_sent_date (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - ESExpResult *r; - - *list = g_list_prepend (*list, g_strdup ("SENT")); - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_get_received_date (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - GList **list = data; - ESExpResult *r; - - *list = g_list_prepend (*list, g_strdup ("RECEIVED")); - - r = e_sexp_result_new (ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_get_current_date (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - - r = e_sexp_result_new (ESEXP_RES_INT); - r->value.number = time (NULL); - - return r; -} - -/* builtin functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "and", (ESExpFunc *) func_and, 0 }, - { "or", (ESExpFunc *) func_or, 0 }, - { "not", (ESExpFunc *) func_not, 0 }, - { "<", (ESExpFunc *) func_lt, 0 }, - { ">", (ESExpFunc *) func_gt, 0 }, - { "=", (ESExpFunc *) func_eq, 0 }, - { "match-all", (ESExpFunc *) func_match_all, 0 }, - { "body-contains", (ESExpFunc *) func_body_contains, 0 }, - { "header-contains", (ESExpFunc *) func_header_contains, 0 }, - { "user-tag", (ESExpFunc *) func_user_tag, 1 }, - { "user-flag", (ESExpFunc *) func_user_flag, 1 }, - { "get-sent-date", (ESExpFunc *) func_get_sent_date, 1 }, - { "get-received-date", (ESExpFunc *) func_get_received_date, 1 }, - { "get-current-date", (ESExpFunc *) func_get_current_date, 1 } -}; - -char * -imap_translate_sexp (const char *expression) -{ - ESExp *sexp; - ESExpResult *r; - gchar *retval; - GList *list = NULL; - int i; - - sexp = e_sexp_new (); - - for (i = 0; i < sizeof (symbols) / sizeof (symbols[0]); i++) { - if (symbols[i].type == 1) { - e_sexp_add_ifunction (sexp, 0, symbols[i].name, - (ESExpIFunc *)symbols[i].func, &list); - } else { - e_sexp_add_function (sexp, 0, symbols[i].name, - symbols[i].func, &list); - } - } - - e_sexp_input_text (sexp, expression, strlen (expression)); - - e_sexp_parse (sexp); - - r = e_sexp_eval (sexp); - - gtk_object_unref (GTK_OBJECT (sexp)); - e_sexp_result_free (r); - - if (list->next) { - g_warning ("conversion to IMAP SEARCH string failed"); - retval = NULL; - g_list_foreach (list, (GFunc)g_free, NULL); - } else { - retval = list->data; - } - - g_list_free (list); - - return retval; -} - -char * -imap_create_flag_list (guint32 flags) -{ - GString *gstr; - char *flag_list; - - gstr = g_string_new ("("); - - if (flags & CAMEL_MESSAGE_ANSWERED) - g_string_append (gstr, "\\Answered "); - if (flags & CAMEL_MESSAGE_DELETED) - g_string_append (gstr, "\\Deleted "); - if (flags & CAMEL_MESSAGE_DRAFT) - g_string_append (gstr, "\\Draft "); - if (flags & CAMEL_MESSAGE_FLAGGED) - g_string_append (gstr, "\\Flagged "); - if (flags & CAMEL_MESSAGE_SEEN) - g_string_append (gstr, "\\Seen "); - - if (gstr->str[gstr->len - 1] == ' ') - gstr->str[gstr->len - 1] = ')'; - else - g_string_append_c (gstr, ')'); - - flag_list = gstr->str; - g_string_free (gstr, FALSE); - return flag_list; -} - -guint32 -imap_parse_flag_list (const char *flag_list) -{ - guint32 flags = 0; - int len; - - if (*flag_list++ != '(') - return 0; - - while (*flag_list != ')') { - len = strcspn (flag_list, " )"); - if (!g_strncasecmp (flag_list, "\\Answered", len)) - flags |= CAMEL_MESSAGE_ANSWERED; - else if (!g_strncasecmp (flag_list, "\\Deleted", len)) - flags |= CAMEL_MESSAGE_DELETED; - else if (!g_strncasecmp (flag_list, "\\Draft", len)) - flags |= CAMEL_MESSAGE_DRAFT; - else if (!g_strncasecmp (flag_list, "\\Flagged", len)) - flags |= CAMEL_MESSAGE_FLAGGED; - else if (!g_strncasecmp (flag_list, "\\Seen", len)) - flags |= CAMEL_MESSAGE_SEEN; - - flag_list += len; - if (*flag_list == ' ') - flag_list++; - } - - return flags; -} - -/** - * imap_parse_nstring: - * @str_p: a pointer to a string - * @len: a pointer to an int to return the length in - * - * This parses an "nstring" (NIL, a quoted string, or a literal) - * starting at *@str_p. On success, *@str_p will point to the first - * character after the end of the nstring, and *@len will contain - * the length of the returned string. On failure, *@str_p will be - * set to %NULL. - * - * This assumes that the string is in the form returned by - * camel_imap_command(): that line breaks are indicated by LF rather - * than CRLF. - * - * Return value: the parsed string, or %NULL if a NIL or no string - * was parsed. (In the former case, *@str_p will be %NULL; in the - * latter, it will point to the character after the NIL.) - **/ -char * -imap_parse_nstring (char **str_p, int *len) -{ - char *str = *str_p; - char *out; - - if (!str) - return NULL; - else if (*str == '"') { - char *p; - int size; - - str++; - size = strcspn (str, "\"") + 1; - p = out = g_malloc (size); - - while (*str && *str != '"') { - if (*str == '\\') - str++; - *p++ = *str++; - if (p - out == size) { - out = g_realloc (out, size * 2); - p = out + size; - size *= 2; - } - } - if (*str != '"') { - *str_p = NULL; - g_free (out); - return NULL; - } - *p = '\0'; - *str_p = str + 1; - *len = strlen (out); - return out; - } else if (*str == '{') { - *len = strtoul (str + 1, (char **)&str, 10); - if (*str++ != '}' || *str++ != '\n' || strlen (str) < *len) { - *str_p = NULL; - return NULL; - } - out = g_strndup (str, *len); - *str_p = str + *len; - return out; - } else if (!g_strncasecmp (str, "nil", 3)) { - *str_p += 3; - *len = 0; - return NULL; - } else { - *str_p = NULL; - return NULL; - } -} - -/** - * imap_parse_astring: - * @str_p: a pointer to a string - * @len: a pointer to an int to return the length in - * - * This parses an "astring" (an atom, a quoted string, or a literal) - * starting at *@str_p. On success, *@str_p will point to the first - * character after the end of the astring, and *@len will contain - * the length of the returned string. On failure, *@str_p will be - * set to %NULL. - * - * This assumes that the string is in the form returned by - * camel_imap_command(): that line breaks are indicated by LF rather - * than CRLF. - * - * Return value: the parsed string, or %NULL if no string - * was parsed. (In this case, *@str_p will also be %NULL.) - **/ -char * -imap_parse_astring (char **str_p, int *len) -{ - char *p; - - if (**str_p == '{' || **str_p == '"') - return imap_parse_nstring (str_p, len); - - p = *str_p; - while (isascii ((unsigned char)*p) && - !strchr ("(){ \"\\%*", *p)) - p++; - - *len = p - *str_p; - p = g_strndup (*str_p, *len); - *str_p += *len; - return p; -} diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h deleted file mode 100644 index d0cc05832d..0000000000 --- a/camel/providers/imap/camel-imap-utils.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef CAMEL_IMAP_UTILS_H -#define CAMEL_IMAP_UTILS_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <glib.h> - -char *imap_next_word (const char *buf); - -#define IMAP_LIST_FLAG_NOINFERIORS (1 << 0) -#define IMAP_LIST_FLAG_NOSELECT (1 << 1) -#define IMAP_LIST_FLAG_MARKED (1 << 2) -#define IMAP_LIST_FLAG_UNMARKED (1 << 3) -gboolean imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder); - -char *imap_translate_sexp (const char *expression); - -char *imap_create_flag_list (guint32 flags); -guint32 imap_parse_flag_list (const char *flag_list); - -char *imap_parse_nstring (char **str_p, int *len); -char *imap_parse_astring (char **str_p, int *len); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_IMAP_UTILS_H */ diff --git a/camel/providers/imap/libcamelimap.urls b/camel/providers/imap/libcamelimap.urls deleted file mode 100644 index c301c0ffac..0000000000 --- a/camel/providers/imap/libcamelimap.urls +++ /dev/null @@ -1 +0,0 @@ -imap diff --git a/camel/providers/maildir/.cvsignore b/camel/providers/maildir/.cvsignore deleted file mode 100644 index 2e7b174532..0000000000 --- a/camel/providers/maildir/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile.in -Makefile -.deps -*.lo -*.la -.libs diff --git a/camel/providers/maildir/Makefile.am b/camel/providers/maildir/Makefile.am deleted file mode 100644 index 80b41a2d45..0000000000 --- a/camel/providers/maildir/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelmaildirincludedir = $(includedir)/camel - -lib_LTLIBRARIES = libcamelmaildir.la - -INCLUDES = -I.. -I$(srcdir)/.. -I$(top_srcdir)/intl -I$(top_srcdir)/camel \ - $(GTK_INCLUDEDIR) -I$(includedir) \ - -DG_LOG_DOMAIN=\"camel-maildir-provider\" - -libcamelmaildir_la_SOURCES = \ - camel-maildir-folder.c \ - camel-maildir-provider.c \ - camel-maildir-store.c - -libcamelmaildirinclude_HEADERS = \ - camel-maildir-folder.h \ - camel-maildir-store.h - -libcamelmaildir_la_LDFLAGS = -version-info 0:0:0 - -EXTRA_DIST = diff --git a/camel/providers/maildir/camel-maildir-folder.c b/camel/providers/maildir/camel-maildir-folder.c deleted file mode 100644 index 2cb81f3e81..0000000000 --- a/camel/providers/maildir/camel-maildir-folder.c +++ /dev/null @@ -1,802 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-maildir-folder.c : camel-folder subclass for maildir folders */ - -/* - * - * Copyright (C) 1999 Bertrand Guiheneuf <Bertrand.Guiheneuf@inria.fr> . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * AUTHORS : Jukka Zitting - * - */ - - -#include <config.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <unistd.h> -#include <sys/types.h> -#include <fcntl.h> -#include <dirent.h> -#include <stdio.h> -#include <errno.h> -#include <time.h> -#include <string.h> -#include "camel-maildir-folder.h" -#include "camel-maildir-store.h" -#include "camel-stream-fs.h" -#include "camel-log.h" - -static CamelFolderClass *parent_class=NULL; - -/* Returns the class for a CamelMaildirFolder */ -#define CMAILDIRF_CLASS(so) CAMEL_MAILDIR_FOLDER_CLASS (GTK_OBJECT(so)->klass) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (GTK_OBJECT(so)->klass) -#define CMAILDIRS_CLASS(so) CAMEL_STORE_CLASS (GTK_OBJECT(so)->klass) - -static void _init_with_store (CamelFolder *folder, CamelStore *parent_store, CamelException *ex); -static void _set_name (CamelFolder *folder, const gchar *name, CamelException *ex); -static gboolean _exists (CamelFolder *folder, CamelException *ex); -static gboolean _create (CamelFolder *folder, CamelException *ex); -static gboolean _delete (CamelFolder *folder, gboolean recurse, CamelException *ex); -static gboolean _delete_messages (CamelFolder *folder, CamelException *ex); -static CamelMimeMessage *_get_message (CamelFolder *folder, gint number, CamelException *ex); -static gint _get_message_count (CamelFolder *folder, CamelException *ex); -static void _expunge (CamelFolder *folder, CamelException *ex); -static GList *_list_subfolders (CamelFolder *folder, CamelException *ex); - -/* fs utility functions */ -static DIR * _xopendir (const gchar *path); -static gboolean _xstat (const gchar *path, struct stat *buf); -static gboolean _xmkdir (const gchar *path); -static gboolean _xrename (const gchar *from, const gchar *to); -static gboolean _xunlink (const gchar *path); -static gboolean _xrmdir (const gchar *path); -/* ** */ - -static void -camel_maildir_folder_class_init (CamelMaildirFolderClass *camel_maildir_folder_class) -{ - CamelFolderClass *camel_folder_class = - CAMEL_FOLDER_CLASS (camel_maildir_folder_class); - - parent_class = gtk_type_class (camel_folder_get_type ()); - - /* virtual method definition */ - /* virtual method overload */ - camel_folder_class->init_with_store = _init_with_store; - camel_folder_class->set_name = _set_name; - camel_folder_class->exists = _exists; - camel_folder_class->create = _create; - camel_folder_class->delete = _delete; - camel_folder_class->delete_messages = _delete_messages; - camel_folder_class->expunge = _expunge; - camel_folder_class->get_message = _get_message; - camel_folder_class->get_message_count = _get_message_count; - camel_folder_class->list_subfolders = _list_subfolders; -} - -GtkType -camel_maildir_folder_get_type (void) -{ - static GtkType camel_maildir_folder_type = 0; - - if (!camel_maildir_folder_type) { - GtkTypeInfo camel_maildir_folder_info = - { - "CamelMaildirFolder", - sizeof (CamelMaildirFolder), - sizeof (CamelMaildirFolderClass), - (GtkClassInitFunc) camel_maildir_folder_class_init, - (GtkObjectInitFunc) NULL, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - camel_maildir_folder_type = - gtk_type_unique (CAMEL_FOLDER_TYPE, &camel_maildir_folder_info); - } - - return camel_maildir_folder_type; -} - - - - - - -/** - * CamelMaildirFolder::init_with_store: initializes the folder object - * @folder: folder object to initialize - * @parent_store: parent store object of the folder - * - * Simply tells that the folder can contain messages but not subfolders. - * Perhaps we'll later implement subfolders too... - */ -static void -_init_with_store (CamelFolder *folder, CamelStore *parent_store, CamelException *ex) -{ - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::init_with_store\n"); - g_assert (folder); - g_assert (parent_store); - - /* call parent method */ - parent_class->init_with_store (folder, parent_store, ex); - - folder->can_hold_messages = TRUE; - folder->can_hold_folders = TRUE; - folder->has_summary_capability = FALSE; - - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::init_with_store\n"); -} - -/** - * CamelMaildirFolder::set_name: sets the name of the folder - * @folder: folder object - * @name: name of the folder - * - * Sets the name of the folder object. The existence of a folder with - * the given name is not checked in this function. - */ -static void -_set_name (CamelFolder *folder, const gchar *name, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder; - CamelMaildirStore *maildir_store; - - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::set_name\n"); - g_assert (folder); - g_assert (name); - g_assert (folder->parent_store); - - maildir_folder = CAMEL_MAILDIR_FOLDER (folder); - maildir_store = CAMEL_MAILDIR_STORE (folder->parent_store); - - /* call default implementation */ - parent_class->set_name (folder, name, ex); - - if (maildir_folder->directory_path) - g_free (maildir_folder->directory_path); - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::set_name full_name is %s\n", folder->full_name); - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::set_name toplevel_dir is %s\n", maildir_store->toplevel_dir); - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::set_name separator is %c\n", camel_store_get_separator (folder->parent_store)); - - if (folder->full_name && folder->full_name[0]) - maildir_folder->directory_path = - g_strconcat (maildir_store->toplevel_dir, G_DIR_SEPARATOR_S, - folder->full_name, NULL); - else - maildir_folder->directory_path = g_strdup (maildir_store->toplevel_dir); - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::set_name: name set to %s\n", name); - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::set_name\n"); -} - -/** - * CamelMaildirFolder::exists: tests whether the named maildir exists - * @folder: folder object - * - * A created maildir folder object doesn't necessarily exist yet in the - * filesystem. This function checks whether the maildir exists. - * The structure of the maildir is stated in the maildir.5 manpage. - * - * maildir.5: - * A directory in maildir format has three subdirectories, - * all on the same filesystem: tmp, new, and cur. - * - * Return value: TRUE if the maildir exists, FALSE otherwise - */ -static gboolean -_exists (CamelFolder *folder, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); - static const gchar *dir[3] = { "new", "cur", "tmp" }; - gint i; - struct stat statbuf; - const gchar *maildir; - gchar *path; - gboolean rv = TRUE; - - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::exists\n"); - g_assert (folder); - g_return_val_if_fail (maildir_folder->directory_path, FALSE); - - maildir = maildir_folder->directory_path; - - CAMEL_LOG_FULL_DEBUG ("CamelMailFolder::exists: checking maildir %s\n", - maildir); - - /* check whether the toplevel directory exists */ - rv = _xstat (maildir, &statbuf) && S_ISDIR (statbuf.st_mode); - - /* check whether the maildir subdirectories exist */ - for (i = 0; rv && i < 3; i++) { - path = g_strconcat (maildir, G_DIR_SEPARATOR_S, dir[i], NULL); - - rv = _xstat (path, &statbuf) && S_ISDIR (statbuf.st_mode); - - g_free (path); - } - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::exists: %s\n", - (rv) ? "maildir found" : "maildir not found"); - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::exists\n"); - return rv; -} - -/** - * CamelMaildirFolder::create: creates the named maildir - * @folder: folder object - * - * A created maildir folder object doesn't necessarily exist yet in the - * filesystem. This function creates the maildir if it doesn't yet exist. - * The structure of the maildir is stated in the maildir.5 manpage. - * - * maildir.5: - * A directory in maildir format has three subdirectories, - * all on the same filesystem: tmp, new, and cur. - * - * Return value: TRUE if the maildir existed already or was created, - * FALSE otherwise - */ -static gboolean -_create (CamelFolder *folder, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); - static const gchar *dir[3] = { "new", "cur", "tmp" }; - gint i; - const gchar *maildir; - gchar *path; - gboolean rv = TRUE; - - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::create\n"); - g_assert (folder); - - /* check whether the maildir already exists */ - if (camel_folder_exists (folder, ex)) return TRUE; - - maildir = maildir_folder->directory_path; - - CAMEL_LOG_FULL_DEBUG ("CamelMailFolder::create: creating maildir %s\n", - maildir); - - /* create the toplevel directory */ - rv = _xmkdir (maildir); - - /* create the maildir subdirectories */ - for (i = 0; rv && i < 3; i++) { - path = g_strconcat (maildir, G_DIR_SEPARATOR_S, dir[i], NULL); - - rv = _xmkdir (path); - - g_free (path); - } - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::create: %s\n", - rv ? "maildir created" : "an error occurred"); - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::create\n"); - return rv; -} - -/** - * CamelMaildirFolder::delete: delete the maildir folder - * @folder: the folder object - * @recurse: - * - * This function empties and deletes the maildir folder. The subdirectories - * "tmp", "cur", and "new" are removed first and then the toplevel maildir - * directory is deleted. All files from the directories are deleted as well, - * so you should be careful when using this function. If a subdirectory cannot - * be deleted, then the operation it is stopped. Thus if an error occurs, the - * maildir directory won't be removed, but it might no longer be a valid maildir. - */ -static gboolean -_delete (CamelFolder *folder, gboolean recurse, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); - static const gchar *dir[3] = { "new", "cur", "tmp" }; - gint i; - const gchar *maildir; - gchar *path; - gboolean rv = TRUE; - - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::create\n"); - g_assert (folder); - - /* check whether the maildir already exists */ - if (!camel_folder_exists (folder, ex)) return TRUE; - - maildir = maildir_folder->directory_path; - - CAMEL_LOG_FULL_DEBUG ("CamelMailFolder::delete: deleting maildir %s\n", - maildir); - - /* delete the maildir subdirectories */ - for (i = 0; rv && i < 3; i++) { - path = g_strconcat (maildir, G_DIR_SEPARATOR_S, dir[i], NULL); - - rv = _xrmdir (path); - - g_free (path); - } - - /* create the toplevel directory */ - if (rv) - rv = _xrmdir (maildir); - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::delete: %s\n", - rv ? "maildir deleted" : "an error occurred"); - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::delete\n"); - return rv; -} - -/** - * CamelMaildirFolder::delete_messages: empty the maildir folder - * @folder: the folder object - * - * This function empties the maildir folder. All messages from the - * "cur" subdirectory are deleted. If a message cannot be deleted, then - * it is just skipped and the rest of the messages are still deleted. - * Files with names starting with a dot are skipped as described in the - * maildir.5 manpage. - * - * maildir.5: - * It is a good idea for readers to skip all filenames in new - * and cur starting with a dot. Other than this, readers - * should not attempt to parse filenames. - * - * Return value: FALSE on error and if some messages could not be deleted. - * TRUE otherwise. - */ -static gboolean -_delete_messages (CamelFolder *folder, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); - const gchar *maildir; - gchar *curdir, *file; - DIR *dir_handle; - struct dirent *dir_entry; - gboolean rv = TRUE; - - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::delete_messages\n"); - g_assert (folder); - - /* call default implementation */ - parent_class->delete_messages (folder, ex); - - /* Check if the folder didn't exist */ - if (!camel_folder_exists (folder, ex)) return TRUE; - - maildir = maildir_folder->directory_path; - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::delete_messages: " - "deleting messages from %s\n", maildir); - - /* delete messages from the maildir subdirectory "cur" */ - curdir = g_strconcat (maildir, G_DIR_SEPARATOR_S, "cur", NULL); - - dir_handle = _xopendir (curdir); - if (dir_handle) { - while ((dir_entry = readdir (dir_handle))) { - if (dir_entry->d_name[0] == '.') continue; - file = g_strconcat (curdir, G_DIR_SEPARATOR_S, - dir_entry->d_name, NULL); - - if (!_xunlink (file)) rv = FALSE; - - g_free (file); - } - closedir (dir_handle); - } else - rv = FALSE; - - g_free (curdir); - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::delete_messages: %s\n", - rv ? "messages deleted" : "an error occurred"); - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::delete_messages\n"); - return rv; -} - -/** - * CamelMaildirFolder::get_message: get a message from maildir - * @folder: the folder object - * @number: number of the message within the folder - * - * Return value: the message, NULL on error - */ -static CamelMimeMessage * -_get_message (CamelFolder *folder, gint number, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER(folder); - DIR *dir_handle; - struct dirent *dir_entry; - CamelStream *stream; - CamelMimeMessage *message = NULL; - const gchar *maildir; - gchar *curdir, *file = NULL; - gint count = -1; - - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::get_message\n"); - g_assert(folder); - - /* Check if the folder exists */ - if (!camel_folder_exists (folder, ex)) return NULL; - - maildir = maildir_folder->directory_path; - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::get_message: " - "getting message #%d from %s\n", number, maildir); - - /* Count until the desired message is reached */ - curdir = g_strconcat (maildir, G_DIR_SEPARATOR_S, "cur", NULL); - if ((dir_handle = _xopendir (curdir))) { - while ((count < number) && (dir_entry = readdir (dir_handle))) - if (dir_entry->d_name[0] != '.') count++; - - if (count == number) - file = g_strconcat (curdir, G_DIR_SEPARATOR_S, - dir_entry->d_name, NULL); - - closedir (dir_handle); - } - g_free (curdir); - if (!file) return NULL; - - /* Create the message object */ - message = camel_mime_message_new (); - stream = camel_stream_fs_new_with_name (file, CAMEL_STREAM_FS_READ); - - if (!message || !stream) { - g_free (file); - if (stream) gtk_object_unref (GTK_OBJECT (stream)); - if (message) gtk_object_unref (GTK_OBJECT (message)); - return NULL; - } - - camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (message), - stream); - gtk_object_unref (GTK_OBJECT (stream)); - gtk_object_set_data_full (GTK_OBJECT (message), - "fullpath", file, g_free); - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::get_message: " - "message %p created from %s\n", message, file); - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::get_message\n"); - return message; -} - -/** - * CamelMaildirFolder::get_message_count: count messages in maildir - * @folder: the folder object - * - * Returns the number of messages in the maildir folder. New messages - * are included in this count. - * - * Return value: number of messages in the maildir, -1 on error - */ -static gint -_get_message_count (CamelFolder *folder, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER(folder); - const gchar *maildir; - gchar *newdir, *curdir, *newfile, *curfile; - DIR *dir_handle; - struct dirent *dir_entry; - guint count = 0; - - CAMEL_LOG_FULL_DEBUG ("Entering " - "CamelMaildirFolder::get_message_count\n"); - g_assert(folder); - - /* check if the maildir exists */ - if (!camel_folder_exists (folder, ex)) return -1; - - maildir = maildir_folder->directory_path; - - newdir = g_strconcat (maildir, G_DIR_SEPARATOR_S, "new", NULL); - curdir = g_strconcat (maildir, G_DIR_SEPARATOR_S, "cur", NULL); - - /* Check new messages */ - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::get_message_count: " - "getting new messages from %s\n", newdir); - if ((dir_handle = _xopendir (newdir))) { - while ((dir_entry = readdir (dir_handle))) { - if (dir_entry->d_name[0] == '.') continue; - newfile = g_strconcat (newdir, G_DIR_SEPARATOR_S, - dir_entry->d_name, NULL); - curfile = g_strconcat (curdir, G_DIR_SEPARATOR_S, - dir_entry->d_name, ":2,", NULL); - - _xrename (newfile, curfile); - - g_free (curfile); - g_free (newfile); - } - closedir (dir_handle); - } - - /* Count messages */ - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::get_message_count: " - "counting messages in %s\n", curdir); - if ((dir_handle = _xopendir (curdir))) { - while ((dir_entry = readdir (dir_handle))) - if (dir_entry->d_name[0] != '.') count++; - closedir (dir_handle); - } - - g_free (curdir); - g_free (newdir); - - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::get_message_count: " - " found %d messages\n", count); - CAMEL_LOG_FULL_DEBUG ("Leaving " - "CamelMaildirFolder::get_message_count\n"); - return count; -} - - - - -/** - * CamelMaildirFolder::expunge: expunge messages marked as deleted - * @folder: the folder object - * - * Physically deletes the messages marked as deleted in the folder. - */ -static void -_expunge (CamelFolder *folder, CamelException *ex) -{ - CamelMimeMessage *message; - GList *node; - gchar *fullpath; - - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::expunge\n"); - g_assert(folder); - - /* expunge messages marked for deletion */ - for (node = folder->message_list; node; node = g_list_next(node)) { - message = CAMEL_MIME_MESSAGE (node->data); - if (!message) { - CAMEL_LOG_WARNING ("CamelMaildirFolder::expunge: " - "null message in node %p\n", node); - continue; - } - - if (camel_mime_message_get_flag (message, "DELETED")) { - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::expunge: " - "expunging message #%d\n", - message->message_number); - - /* expunge the message */ - fullpath = gtk_object_get_data (GTK_OBJECT (message), - "fullpath"); - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::expunge: " - "message fullpath is %s\n", - fullpath); - - if (_xunlink (fullpath)) - message->expunged = TRUE; - } else { - CAMEL_LOG_FULL_DEBUG ("CamelMaildirFolder::expunge: " - "skipping message #%d\n", - message->message_number); - } - } - - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::expunge\n"); -} - - - - -/** - * CamelMaildirFolder::list_subfolders: return a list of subfolders - * @folder: the folder object - * - * Returns the names of the maildir subfolders in a list. - * - * Return value: list of subfolder names - */ -static GList * -_list_subfolders (CamelFolder *folder, CamelException *ex) -{ - CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); - const gchar *maildir; - gchar *subdir; - struct stat statbuf; - struct dirent *dir_entry; - DIR *dir_handle; - GList *subfolders = NULL; - - CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::list_subfolders\n"); - g_assert (folder); - - /* check if the maildir exists */ - if (!camel_folder_exists (folder, ex)) return NULL; - - /* scan through the maildir toplevel directory */ - maildir = maildir_folder->directory_path; - if ((dir_handle = _xopendir (maildir))) { - while ((dir_entry = readdir (dir_handle))) { - if (dir_entry->d_name[0] == '.') continue; - if (strcmp (dir_entry->d_name, "new") == 0) continue; - if (strcmp (dir_entry->d_name, "cur") == 0) continue; - if (strcmp (dir_entry->d_name, "tmp") == 0) continue; - - subdir = g_strconcat (maildir, G_DIR_SEPARATOR_S, - dir_entry->d_name, NULL); - - if (_xstat (subdir, &statbuf) - && S_ISDIR (statbuf.st_mode)) - subfolders = - g_list_append ( - subfolders, - g_strdup (dir_entry->d_name)); - - g_free (subdir); - } - closedir (dir_handle); - } - - CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::list_subfolders\n"); - return subfolders; -} - - - - - - - -/* - * fs utility function - * - */ - -static DIR * -_xopendir (const gchar *path) -{ - DIR *handle; - g_assert (path); - - handle = opendir (path); - if (!handle) { - CAMEL_LOG_WARNING ("ERROR: opendir (%s);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - } - - return handle; -} - -static gboolean -_xstat (const gchar *path, struct stat *buf) -{ - gint stat_error; - g_assert (path); - g_assert (buf); - - stat_error = stat (path, buf); - if (stat_error == 0) { - return TRUE; - } else if (errno == ENOENT) { - buf->st_mode = 0; - return TRUE; - } else { - CAMEL_LOG_WARNING ("ERROR: stat (%s, %p);\n", path, buf); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } -} - -static gboolean -_xmkdir (const gchar *path) -{ - g_assert (path); - - if (mkdir (path, S_IRWXU) == -1) { - CAMEL_LOG_WARNING ("ERROR: mkdir (%s, S_IRWXU);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } - - return TRUE; -} - -static gboolean -_xrename (const gchar *from, const gchar *to) -{ - g_assert (from); - g_assert (to); - - if (rename (from, to) == 0) { - return TRUE; - } else { - CAMEL_LOG_WARNING ("ERROR: rename (%s, %s);\n", from, to); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } -} - -static gboolean -_xunlink (const gchar *path) -{ - g_assert (path); - - if (unlink (path) == 0) { - return TRUE; - } else if (errno == ENOENT) { - return TRUE; - } else { - CAMEL_LOG_WARNING ("ERROR: unlink (%s);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } -} - -static gboolean -_xrmdir (const gchar *path) -{ - DIR *dir_handle; - struct dirent *dir_entry; - gchar *file; - struct stat statbuf; - g_assert (path); - - dir_handle = opendir (path); - if (!dir_handle && errno == ENOENT) { - return TRUE; - } else if (!dir_handle) { - CAMEL_LOG_WARNING ("ERROR: opendir (%s);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } - - while ((dir_entry = readdir (dir_handle))) { - file = g_strconcat (path, G_DIR_SEPARATOR_S, dir_entry->d_name, - NULL); - if (_xstat (file, &statbuf) && S_ISREG (statbuf.st_mode)) - _xunlink (file); - g_free (file); - } - - closedir (dir_handle); - - if (rmdir (path) == 0) { - return TRUE; - } else if (errno == ENOENT) { - return TRUE; - } else { - CAMEL_LOG_WARNING ("ERROR: rmdir (%s);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } -} - -/** *** **/ - diff --git a/camel/providers/maildir/camel-maildir-folder.h b/camel/providers/maildir/camel-maildir-folder.h deleted file mode 100644 index 5997da2011..0000000000 --- a/camel/providers/maildir/camel-maildir-folder.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-maildir-folder.h : Abstract class for an email folder */ - -/* - * - * Copyright (C) 1999 Bertrand Guiheneuf <Bertrand.Guiheneuf@inria.fr> . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef CAMEL_MAILDIR_FOLDER_H -#define CAMEL_MAILDIR_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <gtk/gtk.h> -#include "camel-folder.h" -/* #include "camel-store.h" */ - -#define CAMEL_MAILDIR_FOLDER_TYPE (camel_maildir_folder_get_type ()) -#define CAMEL_MAILDIR_FOLDER(obj) (GTK_CHECK_CAST((obj), CAMEL_MAILDIR_FOLDER_TYPE, CamelMaildirFolder)) -#define CAMEL_MAILDIR_FOLDER_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MAILDIR_FOLDER_TYPE, CamelMaildirFolderClass)) -#define IS_CAMEL_MAILDIR_FOLDER(o) (GTK_CHECK_TYPE((o), CAMEL_MAILDIR_FOLDER_TYPE)) - - -typedef struct { - CamelFolder parent_object; - - gchar *directory_path; -} CamelMaildirFolder; - - - -typedef struct { - CamelFolderClass parent_class; - - /* Virtual methods */ - -} CamelMaildirFolderClass; - - -/* public methods */ - -/* Standard Gtk function */ -GtkType camel_maildir_folder_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_MAILDIR_FOLDER_H */ diff --git a/camel/providers/maildir/camel-maildir-provider.c b/camel/providers/maildir/camel-maildir-provider.c deleted file mode 100644 index cd5521adc0..0000000000 --- a/camel/providers/maildir/camel-maildir-provider.c +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-maildir-provider.c: maildir provider registration code */ - -/* - * - * Copyright (C) 1999 Bertrand Guiheneuf <Bertrand.Guiheneuf@inria.fr> . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-maildir-store.h" -#include "camel-provider.h" -#include "camel-log.h" - - -static CamelProvider _maildir_provider = { - (GtkType) 0, - PROVIDER_STORE, - "maildir", - "Maildir provider for Camel", - "This maildir provider is based on the default MH provider of Camel", - (GModule *) NULL -}; - - - -CamelProvider * -camel_provider_module_init () -{ - _maildir_provider.object_type = camel_maildir_store_get_type(); - return &_maildir_provider; -} diff --git a/camel/providers/maildir/camel-maildir-store.c b/camel/providers/maildir/camel-maildir-store.c deleted file mode 100644 index 8f37494003..0000000000 --- a/camel/providers/maildir/camel-maildir-store.c +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-maildir-store.c : class for an maildir store */ - -/* - * - * Copyright (C) 1999 Bertrand Guiheneuf <Bertrand.Guiheneuf@inria.fr> . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "camel-maildir-store.h" -#include "camel-maildir-folder.h" -#include "url-util.h" - -static CamelStoreClass *parent_class=NULL; - -/* Returns the class for a CamelMaildirStore */ -#define CMAILDIRS_CLASS(so) CAMEL_MAILDIR_STORE_CLASS (GTK_OBJECT(so)->klass) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (GTK_OBJECT(so)->klass) -#define CMAILDIRF_CLASS(so) CAMEL_MAILDIR_FOLDER_CLASS (GTK_OBJECT(so)->klass) - -static void _init (CamelStore *store, CamelSession *session, - const gchar *url_name); -static CamelFolder *_get_folder (CamelStore *store, const gchar *folder_name); - -static void -camel_maildir_store_class_init ( - CamelMaildirStoreClass *camel_maildir_store_class) -{ - CamelStoreClass *camel_store_class = - CAMEL_STORE_CLASS (camel_maildir_store_class); - - parent_class = gtk_type_class (camel_store_get_type ()); - - /* virtual method definition */ - /* virtual method overload */ - camel_store_class->init = _init; - camel_store_class->get_folder = _get_folder; -} - -static void -camel_maildir_store_init (gpointer object, gpointer klass) -{ - CamelMaildirStore *maildir_store = CAMEL_MAILDIR_STORE (object); - CamelStore *store = CAMEL_STORE (object); - - store->separator = G_DIR_SEPARATOR; -} - -GtkType -camel_maildir_store_get_type (void) -{ - static GtkType camel_maildir_store_type = 0; - - if (!camel_maildir_store_type) { - GtkTypeInfo camel_maildir_store_info = - { - "CamelMaildirStore", - sizeof (CamelMaildirStore), - sizeof (CamelMaildirStoreClass), - (GtkClassInitFunc) camel_maildir_store_class_init, - (GtkObjectInitFunc) camel_maildir_store_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - camel_maildir_store_type = - gtk_type_unique (CAMEL_STORE_TYPE, - &camel_maildir_store_info); - } - - return camel_maildir_store_type; -} - -static void -_init (CamelStore *store, CamelSession *session, const gchar *url_name) -{ - CamelMaildirStore *maildir_store = CAMEL_MAILDIR_STORE (store); - Gurl *store_url; - g_assert (url_name); - - /* call parent implementation */ - parent_class->init (store, session, url_name); - - /* find the path in the URL*/ - store_url = g_url_new (url_name); - - g_return_if_fail (store_url); - g_return_if_fail (store_url->path); - - maildir_store->toplevel_dir = g_strdup (store_url->path); - - g_url_free (store_url); -} - -static CamelFolder * -_get_folder (CamelStore *store, const gchar *folder_name) -{ - CamelMaildirStore *maildir_store = CAMEL_MAILDIR_STORE (store); - CamelMaildirFolder *new_maildir_folder; - CamelFolder *new_folder; - - new_maildir_folder = gtk_type_new (CAMEL_MAILDIR_FOLDER_TYPE); - new_folder = CAMEL_FOLDER (new_maildir_folder); - - CF_CLASS (new_folder)->init_with_store (new_folder, store, NULL); - CF_CLASS (new_folder)->set_name (new_folder, folder_name, NULL); - - return new_folder; -} diff --git a/camel/providers/maildir/camel-maildir-store.h b/camel/providers/maildir/camel-maildir-store.h deleted file mode 100644 index 1a95ed1436..0000000000 --- a/camel/providers/maildir/camel-maildir-store.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-maildirstore.h : class for an maildir store */ - -/* - * - * Copyright (C) 1999 Bertrand Guiheneuf <Bertrand.Guiheneuf@inria.fr> . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_MAILDIR_STORE_H -#define CAMEL_MAILDIR_STORE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <gtk/gtk.h> -#include "camel-store.h" - -#define CAMEL_MAILDIR_STORE_TYPE (camel_maildir_store_get_type ()) -#define CAMEL_MAILDIR_STORE(obj) (GTK_CHECK_CAST((obj), CAMEL_MAILDIR_STORE_TYPE, CamelMaildirStore)) -#define CAMEL_MAILDIR_STORE_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MAILDIR_STORE_TYPE, CamelMaildirStoreClass)) -#define IS_CAMEL_MAILDIR_STORE(o) (GTK_CHECK_TYPE((o), CAMEL_MAILDIR_STORE_TYPE)) - - -typedef struct { - CamelStore parent_object; - - gchar *toplevel_dir; -} CamelMaildirStore; - - - -typedef struct { - CamelStoreClass parent_class; - - -} CamelMaildirStoreClass; - - -/* public methods */ - -/* Standard Gtk function */ -GtkType camel_maildir_store_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_MAILDIR_STORE_H */ - - diff --git a/camel/providers/mbox/.cvsignore b/camel/providers/mbox/.cvsignore deleted file mode 100644 index fd6b811c68..0000000000 --- a/camel/providers/mbox/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la diff --git a/camel/providers/mbox/Makefile.am b/camel/providers/mbox/Makefile.am deleted file mode 100644 index 073d9830de..0000000000 --- a/camel/providers/mbox/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelmboxincludedir = $(includedir)/camel - - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelmbox.la -provider_DATA = libcamelmbox.urls - -INCLUDES = -I.. \ - -I$(srcdir)/.. \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/libibex \ - -I$(top_srcdir)/e-util \ - -I$(top_srcdir) \ - -I$(includedir) \ - $(GTK_INCLUDEDIR) \ - -DG_LOG_DOMAIN=\"camel-mbox-provider\" - -libcamelmbox_la_SOURCES = \ - camel-mbox-folder.c \ - camel-mbox-provider.c \ - camel-mbox-store.c \ - camel-mbox-summary.c - -libcamelmboxinclude_HEADERS = \ - camel-mbox-folder.h \ - camel-mbox-store.h \ - camel-mbox-summary.h - -libcamelmbox_la_LDFLAGS = -version-info 0:0:0 - -libcamelmbox_la_LIBADD = $(top_builddir)/e-util/libeutil.la $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) -#libcamelmbox_la_LIBADD = $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) - -EXTRA_DIST = libcamelmbox.urls - diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c deleted file mode 100644 index 44dfc7c6a4..0000000000 --- a/camel/providers/mbox/camel-mbox-folder.c +++ /dev/null @@ -1,620 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ -/* camel-mbox-folder.c : Abstract class for an email folder */ - -/* - * Authors: Bertrand Guiheneuf <bertrand@helixcode.com> - * Michael Zucchi <notzed@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright (C) 1999, 2000 Helix Code Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> - -#include <stdlib.h> -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> - -#include "camel-mbox-folder.h" -#include "camel-mbox-store.h" -#include "string-utils.h" -#include "camel-stream-fs.h" -#include "camel-mbox-summary.h" -#include "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) - -static CamelFolderClass *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)) - - -static void mbox_sync(CamelFolder *folder, gboolean expunge, CamelException *ex); -static gint mbox_get_message_count(CamelFolder *folder); -static gint mbox_get_unread_message_count(CamelFolder *folder); -static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, - - CamelException *ex); -static GPtrArray *mbox_get_uids(CamelFolder *folder); -static GPtrArray *mbox_get_summary(CamelFolder *folder); -static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex); - -static void mbox_expunge(CamelFolder *folder, CamelException *ex); - -static const CamelMessageInfo *mbox_get_message_info(CamelFolder *folder, const char *uid); - -static GPtrArray *mbox_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); -static void mbox_search_free(CamelFolder *folder, GPtrArray * result); - -static guint32 mbox_get_message_flags(CamelFolder *folder, const char *uid); -static void mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set); -static gboolean mbox_get_message_user_flag(CamelFolder *folder, const char *uid, const char *name); -static void mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value); -static const char *mbox_get_message_user_tag(CamelFolder *folder, const char *uid, const char *name); -static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); - - -static void mbox_finalize(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); - - parent_class = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs(camel_folder_get_type())); - - /* virtual method definition */ - - /* virtual method overload */ - camel_folder_class->sync = mbox_sync; - camel_folder_class->get_message_count = mbox_get_message_count; - camel_folder_class->get_unread_message_count = mbox_get_unread_message_count; - camel_folder_class->append_message = mbox_append_message; - camel_folder_class->get_uids = mbox_get_uids; - camel_folder_class->free_uids = camel_folder_free_deep; - camel_folder_class->get_summary = mbox_get_summary; - camel_folder_class->free_summary = camel_folder_free_nop; - camel_folder_class->expunge = mbox_expunge; - - camel_folder_class->get_message = mbox_get_message; - - camel_folder_class->search_by_expression = mbox_search_by_expression; - camel_folder_class->search_free = mbox_search_free; - - camel_folder_class->get_message_info = mbox_get_message_info; - - camel_folder_class->get_message_flags = mbox_get_message_flags; - camel_folder_class->set_message_flags = mbox_set_message_flags; - camel_folder_class->get_message_user_flag = mbox_get_message_user_flag; - camel_folder_class->set_message_user_flag = mbox_set_message_user_flag; - camel_folder_class->get_message_user_tag = mbox_get_message_user_tag; - camel_folder_class->set_message_user_tag = mbox_set_message_user_tag; -} - -static void -mbox_init(gpointer object, gpointer klass) -{ - CamelFolder *folder = object; - CamelMboxFolder *mbox_folder = object; - - folder->has_summary_capability = TRUE; - folder->has_search_capability = TRUE; - - folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | - CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT | - CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_USER; - /* FIXME: we don't actually preserve user flags right now. */ - - mbox_folder->summary = NULL; - mbox_folder->search = NULL; -} - -static void -mbox_finalize(CamelObject * object) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(object); - - if (mbox_folder->index) - ibex_close(mbox_folder->index); - - g_free(mbox_folder->folder_file_path); - g_free(mbox_folder->summary_file_path); - g_free(mbox_folder->folder_dir_path); - g_free(mbox_folder->index_file_path); - - camel_folder_change_info_free(mbox_folder->changes); -} - -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_FOLDER_TYPE, "CamelMboxFolder", - sizeof(CamelMboxFolder), - sizeof(CamelMboxFolderClass), - (CamelObjectClassInitFunc) camel_mbox_folder_class_init, - NULL, - (CamelObjectInitFunc) mbox_init, - (CamelObjectFinalizeFunc) mbox_finalize); - } - - return camel_mbox_folder_type; -} - -CamelFolder * -camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex) -{ - CamelFolder *folder; - CamelMboxFolder *mbox_folder; - const char *root_dir_path, *name; - struct stat st; - int forceindex; - - folder = CAMEL_FOLDER (camel_object_new (CAMEL_MBOX_FOLDER_TYPE)); - mbox_folder = (CamelMboxFolder *)folder; - - name = strrchr(full_name, '/'); - if (name) - name++; - else - name = full_name; - - camel_folder_construct(folder, parent_store, full_name, name); - - root_dir_path = camel_mbox_store_get_toplevel_dir(CAMEL_MBOX_STORE(folder->parent_store)); - - mbox_folder->folder_file_path = g_strdup_printf("%s/%s", root_dir_path, full_name); - mbox_folder->summary_file_path = g_strdup_printf("%s/%s-ev-summary", root_dir_path, full_name); - mbox_folder->folder_dir_path = g_strdup_printf("%s/%s.sdb", root_dir_path, full_name); - mbox_folder->index_file_path = g_strdup_printf("%s/%s.ibex", root_dir_path, full_name); - - mbox_folder->changes = camel_folder_change_info_new(); - - /* if we have no index file, force it */ - forceindex = stat(mbox_folder->index_file_path, &st) == -1; - if (flags & CAMEL_STORE_FOLDER_BODY_INDEX) { - - mbox_folder->index = ibex_open(mbox_folder->index_file_path, O_CREAT | O_RDWR, 0600); - if (mbox_folder->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; - } - } else { - /* if we do have an index file, remove it */ - if (forceindex == FALSE) { - unlink(mbox_folder->index_file_path); - } - forceindex = FALSE; - } - /* no summary (disk or memory), and we're proverbially screwed */ - mbox_folder->summary = camel_mbox_summary_new(mbox_folder->summary_file_path, - mbox_folder->folder_file_path, mbox_folder->index); - if (mbox_folder->summary == NULL || camel_mbox_summary_load(mbox_folder->summary, forceindex) == -1) { - camel_exception_set(ex, CAMEL_EXCEPTION_FOLDER_INVALID, /* FIXME: right error code */ - _("Could not create summary")); - camel_object_unref (CAMEL_OBJECT (folder)); - return NULL; - } - - return folder; -} - -static void -mbox_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - - if (expunge) - mbox_expunge(folder, ex); - else { - camel_mbox_summary_sync(mbox_folder->summary, FALSE, mbox_folder->changes, ex); - camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", mbox_folder->changes); - camel_folder_change_info_clear(mbox_folder->changes); - } - - /* save index */ - if (mbox_folder->index) - ibex_save(mbox_folder->index); - if (mbox_folder->summary) - camel_folder_summary_save(CAMEL_FOLDER_SUMMARY(mbox_folder->summary)); -} - -static void -mbox_expunge(CamelFolder *folder, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - - camel_mbox_summary_sync(mbox_folder->summary, TRUE, mbox_folder->changes, ex); - camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", mbox_folder->changes); - camel_folder_change_info_clear(mbox_folder->changes); -} - -static gint -mbox_get_message_count(CamelFolder *folder) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - - g_return_val_if_fail(mbox_folder->summary != NULL, -1); - - return camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(mbox_folder->summary)); -} - -static gint -mbox_get_unread_message_count(CamelFolder *folder) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - CamelMessageInfo *info; - GPtrArray *infolist; - gint i, max, count = 0; - - g_return_val_if_fail(mbox_folder->summary != NULL, -1); - - max = camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(mbox_folder->summary)); - if (max == -1) - return -1; - - infolist = mbox_get_summary(folder); - - for (i = 0; i < infolist->len; i++) { - info = (CamelMessageInfo *) g_ptr_array_index(infolist, i); - if (!(info->flags & CAMEL_MESSAGE_SEEN)) - count++; - } - - return count; -} - -/* FIXME: this may need some tweaking for performance? */ -static void -mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - CamelStream *output_stream = NULL, *filter_stream = NULL; - CamelMimeFilter *filter_from = NULL; - CamelMessageInfo *newinfo; - struct stat st; - off_t seek = -1; - char *xev; - guint32 uid; - char *fromline = NULL; - - if (stat(mbox_folder->folder_file_path, &st) != 0) - goto fail; - - output_stream = camel_stream_fs_new_with_name(mbox_folder->folder_file_path, O_WRONLY|O_APPEND, 0600); - if (output_stream == NULL) - goto fail; - - seek = st.st_size; - - /* assign a new x-evolution header/uid */ - camel_medium_remove_header(CAMEL_MEDIUM(message), "X-Evolution"); - uid = camel_folder_summary_next_uid(CAMEL_FOLDER_SUMMARY(mbox_folder->summary)); - /* important that the header matches exactly 00000000-0000 */ - xev = g_strdup_printf("%08x-%04x", uid, info ? info->flags & 0xFFFF : 0); - camel_medium_add_header(CAMEL_MEDIUM(message), "X-Evolution", xev); - g_free(xev); - - /* we must write this to the non-filtered stream ... */ - fromline = camel_mbox_summary_build_from(CAMEL_MIME_PART(message)->headers); - if (camel_stream_printf(output_stream, seek==0?"%s":"\n%s", fromline) == -1) - goto fail; - - /* and write the content to the filtering stream, that translated '\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(CAMEL_DATA_WRAPPER(message), filter_stream) == -1) - goto fail; - - if (camel_stream_close(filter_stream) == -1) - goto fail; - - /* filter stream ref's the output stream itself, so we need to unref it too */ - camel_object_unref(CAMEL_OBJECT(filter_from)); - camel_object_unref(CAMEL_OBJECT(filter_stream)); - camel_object_unref(CAMEL_OBJECT(output_stream)); - g_free(fromline); - - /* force a summary update - will only update from the new position, if it can */ - if (camel_mbox_summary_update(mbox_folder->summary, seek==0?seek:seek+1, mbox_folder->changes) == 0) { - char uidstr[16]; - - sprintf(uidstr, "%u", uid); - newinfo = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mbox_folder->summary), uidstr); - - if (info && newinfo) { - CamelFlag *flag = info->user_flags; - CamelTag *tag = info->user_tags; - - while (flag) { - camel_flag_set(&(newinfo->user_flags), flag->name, TRUE); - flag = flag->next; - } - - while (tag) { - camel_tag_set(&(newinfo->user_tags), tag->name, tag->value); - tag = tag->next; - } - } - camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", mbox_folder->changes); - camel_folder_change_info_clear(mbox_folder->changes); - } - - return; - - fail: - if (camel_exception_is_set(ex)) { - camel_exception_setv(ex, camel_exception_get_id(ex), - _("Cannot append message to mbox file: %s"), camel_exception_get_description(ex)); - } else { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot append message to mbox file: %s"), g_strerror(errno)); - } - if (filter_stream) { - /*camel_stream_close (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); - - /* make sure the file isn't munged by us */ - if (seek != -1) { - int fd = open(mbox_folder->folder_file_path, O_WRONLY, 0600); - - if (fd != -1) { - ftruncate(fd, st.st_size); - close(fd); - } - } -} - -static GPtrArray * -mbox_get_uids(CamelFolder *folder) -{ - GPtrArray *array; - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - int i, count; - - count = camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(mbox_folder->summary)); - array = g_ptr_array_new(); - g_ptr_array_set_size(array, count); - for (i = 0; i < count; i++) { - CamelMboxMessageInfo *info = - (CamelMboxMessageInfo *) camel_folder_summary_index(CAMEL_FOLDER_SUMMARY(mbox_folder->summary), i); - - array->pdata[i] = g_strdup(info->info.uid); - } - - return array; -} - -static CamelMimeMessage * -mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - CamelStream *message_stream = NULL; - CamelMimeMessage *message = NULL; - CamelMboxMessageInfo *info; - CamelMimeParser *parser = NULL; - char *buffer; - int len; - - /* get the message summary info */ - info = (CamelMboxMessageInfo *) camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mbox_folder->summary), uid); - - if (info == NULL) { - errno = ENOENT; - goto fail; - } - - /* if this has no content, its an error in the library */ - g_assert(info->info.content); - g_assert(info->frompos != -1); - - /* where we read from */ - message_stream = camel_stream_fs_new_with_name(mbox_folder->folder_file_path, O_RDONLY, 0); - if (message_stream == NULL) - 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_stream(parser, message_stream); - camel_object_unref(CAMEL_OBJECT(message_stream)); - camel_mime_parser_scan_from(parser, TRUE); - - camel_mime_parser_seek(parser, info->frompos, SEEK_SET); - if (camel_mime_parser_step(parser, &buffer, &len) != HSCAN_FROM) { - g_warning("File appears truncated"); - goto fail; - } - - if (camel_mime_parser_tell_start_from(parser) != info->frompos) { - /* TODO: This should probably perform a re-sync/etc, and try again? */ - g_warning("Summary doesn't match the folder contents! eek!\n" - " expecting offset %ld got %ld", (long int)info->frompos, - (long int)camel_mime_parser_tell_start_from(parser)); - errno = EINVAL; - goto fail; - } - - message = camel_mime_message_new(); - if (camel_mime_part_construct_from_parser(CAMEL_MIME_PART(message), parser) == -1) { - g_warning("Construction failed"); - goto fail; - } - camel_object_unref(CAMEL_OBJECT(parser)); - - return message; - - fail: - camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s"), g_strerror(errno)); - - if (parser) - camel_object_unref(CAMEL_OBJECT(parser)); - if (message) - camel_object_unref(CAMEL_OBJECT(message)); - - return NULL; -} - -GPtrArray * -mbox_get_summary(CamelFolder *folder) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - - return CAMEL_FOLDER_SUMMARY(mbox_folder->summary)->messages; -} - -/* get a single message info, by uid */ -static const CamelMessageInfo * -mbox_get_message_info(CamelFolder *folder, const char *uid) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - - return camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mbox_folder->summary), uid); -} - -static GPtrArray * -mbox_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - - if (mbox_folder->search == NULL) { - mbox_folder->search = camel_folder_search_new(); - } - - camel_folder_search_set_folder(mbox_folder->search, folder); - if (mbox_folder->summary) { - /* FIXME: dont access summary array directly? */ - camel_folder_search_set_summary(mbox_folder->search, - CAMEL_FOLDER_SUMMARY(mbox_folder->summary)->messages); - } - - camel_folder_search_set_body_index(mbox_folder->search, mbox_folder->index); - - return camel_folder_search_execute_expression(mbox_folder->search, expression, ex); -} - -static void -mbox_search_free(CamelFolder *folder, GPtrArray * result) -{ - CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder); - - camel_folder_search_free_result(mbox_folder->search, result); -} - -static guint32 -mbox_get_message_flags(CamelFolder *folder, const char *uid) -{ - CamelMessageInfo *info; - CamelMboxFolder *mf = CAMEL_MBOX_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, 0); - - return info->flags; -} - -static void -mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set) -{ - CamelMessageInfo *info; - CamelMboxFolder *mf = CAMEL_MBOX_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); - - info->flags = (info->flags & ~flags) | (set & flags) | CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); -} - -static gboolean -mbox_get_message_user_flag(CamelFolder *folder, const char *uid, const char *name) -{ - CamelMessageInfo *info; - CamelMboxFolder *mf = CAMEL_MBOX_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, FALSE); - - return camel_flag_get(&info->user_flags, name); -} - -static void -mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value) -{ - CamelMessageInfo *info; - CamelMboxFolder *mf = CAMEL_MBOX_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); - - camel_flag_set(&info->user_flags, name, value); - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); -} - -static const char *mbox_get_message_user_tag(CamelFolder *folder, const char *uid, const char *name) -{ - CamelMessageInfo *info; - CamelMboxFolder *mf = CAMEL_MBOX_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, FALSE); - - return camel_tag_get(&info->user_tags, name); -} - -static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value) -{ - CamelMessageInfo *info; - CamelMboxFolder *mf = CAMEL_MBOX_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); - - camel_tag_set(&info->user_tags, name, value); - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); -} - - diff --git a/camel/providers/mbox/camel-mbox-folder.h b/camel/providers/mbox/camel-mbox-folder.h deleted file mode 100644 index 73f51a6d85..0000000000 --- a/camel/providers/mbox/camel-mbox-folder.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-folder.h : Abstract class for an email folder */ - -/* - * - * Author : Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 1999 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_MBOX_FOLDER_H -#define CAMEL_MBOX_FOLDER_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <camel/camel-folder.h> -#include <camel/camel-folder-search.h> -#include <libibex/ibex.h> -#include "camel-mbox-summary.h" - -/* #include "camel-store.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 IS_CAMEL_MBOX_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_MBOX_FOLDER_TYPE)) - -typedef struct { - CamelFolder parent_object; - - gchar *folder_file_path; /* contains the messages */ - gchar *summary_file_path; /* contains the messages summary */ - gchar *folder_dir_path; /* contains the subfolders */ - gchar *index_file_path; /* index of body contents */ - - ibex *index; /* index for this folder */ - CamelMboxSummary *summary; - CamelFolderSearch *search; /* used to run searches, we just use the real thing (tm) */ - CamelFolderChangeInfo *changes; /* used to store changes to the folder during processing */ -} CamelMboxFolder; - - - -typedef struct { - CamelFolderClass 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/mbox/camel-mbox-provider.c b/camel/providers/mbox/camel-mbox-provider.c deleted file mode 100644 index bfce8b5ada..0000000000 --- a/camel/providers/mbox/camel-mbox-provider.c +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-provider.c: mbox provider registration code */ - -/* - * Authors : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 2000 HelixCode (www.helixcode.com). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-mbox-store.h" -#include "camel-provider.h" -#include "camel-session.h" -#include "camel-url.h" - -static CamelProvider mbox_provider = { - "mbox", - N_("UNIX mbox-format mail files"), - - N_("For reading mail delivered by the local system, and for " - "storing mail on local disk."), - - "mail", - - CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE, - - CAMEL_URL_NEED_PATH, - - { 0, 0 }, - - NULL -}; - -void -camel_provider_module_init (CamelSession *session) -{ - mbox_provider.object_types[CAMEL_PROVIDER_STORE] = - camel_mbox_store_get_type(); - - mbox_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal); - - camel_session_register_provider (session, &mbox_provider); -} diff --git a/camel/providers/mbox/camel-mbox-store.c b/camel/providers/mbox/camel-mbox-store.c deleted file mode 100644 index e3110ef3d3..0000000000 --- a/camel/providers/mbox/camel-mbox-store.c +++ /dev/null @@ -1,287 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-store.c : class for an mbox store */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. <bertrand@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#include <config.h> - -#include <sys/stat.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#include "camel-mbox-store.h" -#include "camel-mbox-folder.h" -#include "camel-exception.h" -#include "camel-url.h" - -/* Returns the class for a CamelMboxStore */ -#define CMBOXS_CLASS(so) CAMEL_MBOX_STORE_CLASS (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)) - -static char *get_name(CamelService *service, gboolean brief); -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_name, const char *new_name, CamelException *ex); -static char *get_folder_name(CamelStore *store, const char *folder_name, CamelException *ex); -static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, - gboolean fast, gboolean recursive, - gboolean subscribed_only, - 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); - CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_mbox_store_class); - - /* virtual method overload */ - camel_service_class->get_name = get_name; - - camel_store_class->get_folder = get_folder; - camel_store_class->delete_folder = delete_folder; - camel_store_class->rename_folder = rename_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_folder_info = get_folder_info; - camel_store_class->free_folder_info = camel_store_free_folder_info_full; -} - -static void -camel_mbox_store_init (gpointer object, gpointer klass) -{ - CamelStore *store = CAMEL_STORE (object); - - /* mbox names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new (g_str_hash, g_str_equal); -} - -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_STORE_TYPE, "CamelMboxStore", - sizeof (CamelMboxStore), - sizeof (CamelMboxStoreClass), - (CamelObjectClassInitFunc) camel_mbox_store_class_init, - NULL, - (CamelObjectInitFunc) camel_mbox_store_init, - NULL); - } - - return camel_mbox_store_type; -} - -const gchar * -camel_mbox_store_get_toplevel_dir (CamelMboxStore *store) -{ - CamelURL *url = CAMEL_SERVICE (store)->url; - - g_assert (url != NULL); - return url->path; -} - -static CamelFolder * -get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) -{ - char *name; - struct stat st; - - name = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, folder_name); - - if (stat(name, &st) == -1) { - 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; - } - - fd = open(name, O_WRONLY | O_CREAT | O_APPEND, 0600); - 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) -{ - char *name, *name2; - struct stat st; - int status; - - name = g_strdup_printf ("%s%s", CAMEL_SERVICE (store)->url->path, folder_name); - if (stat (name, &st) == -1) { - if (errno == ENOENT) { - /* file doesn't exist - it's kinda like deleting it ;-) */ - g_free (name); - return; - } - - 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; - } - - /* Delete index and summary first, then the main file. */ - name2 = g_strdup_printf ("%s.ibex", name); - status = unlink (name2); - g_free (name2); - if (status == 0 || errno == ENOENT) { - name2 = g_strdup_printf ("%s-ev-summary", name); - status = unlink (name2); - g_free (name2); - } - if (status == 0 || errno == ENOENT) - status = unlink (name); - g_free (name); - - if (status == -1 && errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s':\n%s"), - folder_name, g_strerror (errno)); - } -} - -static int xrename(const char *oldp, const char *newp, const char *prefix, const char *suffix, CamelException *ex) -{ - struct stat st; - char *old = g_strconcat(prefix, oldp, suffix, 0); - char *new = g_strconcat(prefix, newp, suffix, 0); - int ret = -1; - - printf("renaming %s%s to %s%s\n", oldp, suffix, newp, suffix); - - /* FIXME: this has races ... */ - if (!(stat(new, &st) == -1 && errno==ENOENT)) { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename folder %s to %s: destination exists"), - old, new); - } else if (rename(old, new) == 0 || errno==ENOENT) { - ret = 0; - } else if (stat(old, &st) == -1 && errno==ENOENT && stat(new, &st) == 0) { - /* for nfs, check if the rename worked anyway ... */ - ret = 0; - } - - g_free(old); - g_free(new); - return ret; -} - -static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex) -{ - char *path = CAMEL_SERVICE (store)->url->path; - - /* try to rollback failures, has obvious races */ - if (xrename(old, new, path, ".ibex", ex)) { - return; - } - if (xrename(old, new, path, "-ev-summary", ex)) { - xrename(new, old, path, ".ibex", ex); - return; - } - if (xrename(old, new, path, "", ex)) { - xrename(new, old, path, "-ev-summary", ex); - xrename(new, old, path, ".ibex", ex); - } -} - -static char * -get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - /* For now, we don't allow hieararchy. FIXME. */ - if (strchr (folder_name + 1, '/')) { - camel_exception_set (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Mbox folders may not be nested.")); - return NULL; - } - - return *folder_name == '/' ? g_strdup (folder_name) : - g_strdup_printf ("/%s", folder_name); -} - -static char * -get_name (CamelService *service, gboolean brief) -{ - if (brief) - return g_strdup (service->url->path); - else - return g_strdup_printf (_("Local mail file %s"), service->url->path); -} - -static CamelFolderInfo * -get_folder_info (CamelStore *store, const char *top, - gboolean fast, gboolean recursive, - gboolean subscribed_only, - CamelException *ex) -{ - /* FIXME: This is broken, but it corresponds to what was - * there before. - */ - return NULL; -} diff --git a/camel/providers/mbox/camel-mbox-store.h b/camel/providers/mbox/camel-mbox-store.h deleted file mode 100644 index 7b298b67f6..0000000000 --- a/camel/providers/mbox/camel-mbox-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 Helix Code, Inc. <bertrand@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_MBOX_STORE_H -#define CAMEL_MBOX_STORE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-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 IS_CAMEL_MBOX_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_MBOX_STORE_TYPE)) - - -typedef struct { - CamelStore parent_object; - -} CamelMboxStore; - - - -typedef struct { - CamelStoreClass parent_class; - -} CamelMboxStoreClass; - - -/* public methods */ - -/* Standard Camel function */ -CamelType camel_mbox_store_get_type (void); - -const gchar *camel_mbox_store_get_toplevel_dir (CamelMboxStore *store); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_MBOX_STORE_H */ - - diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c deleted file mode 100644 index 8856d37ee8..0000000000 --- a/camel/providers/mbox/camel-mbox-summary.c +++ /dev/null @@ -1,894 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "camel-mbox-summary.h" -#include <camel/camel-mime-message.h> - -#include <sys/stat.h> -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#define io(x) -#define d(x) - -#define CAMEL_MBOX_SUMMARY_VERSION (0x1000) - -struct _CamelMboxSummaryPrivate { -}; - -#define _PRIVATE(o) (((CamelMboxSummary *)(o))->priv) - -static int summary_header_load (CamelFolderSummary *, FILE *); -static int summary_header_save (CamelFolderSummary *, FILE *); - -static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _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 void camel_mbox_summary_class_init (CamelMboxSummaryClass *klass); -static void camel_mbox_summary_init (CamelMboxSummary *obj); -static void camel_mbox_summary_finalise (CamelObject *obj); - -static CamelFolderSummaryClass *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_folder_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; - - camel_mbox_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_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;*/ -} - -static void -camel_mbox_summary_init(CamelMboxSummary *obj) -{ - struct _CamelMboxSummaryPrivate *p; - struct _CamelFolderSummary *s = (CamelFolderSummary *)obj; - - p = _PRIVATE(obj) = g_malloc0(sizeof(*p)); - - /* 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); - - g_free(mbs->folder_path); -} - -/** - * 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, ibex *index) -{ - CamelMboxSummary *new = CAMEL_MBOX_SUMMARY(camel_object_new(camel_mbox_summary_get_type())); - - if (new) { - /* ?? */ - camel_folder_summary_set_build_content(CAMEL_FOLDER_SUMMARY(new), TRUE); - camel_folder_summary_set_filename(CAMEL_FOLDER_SUMMARY(new), filename); - new->folder_path = g_strdup(mbox_name); - new->index = index; - } - return new; -} - -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_folder_summary_decode_uint32(in, &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_folder_summary_encode_uint32(out, mbs->folder_size); -} - -static int -header_evolution_decode(const char *in, guint32 *uid, guint32 *flags) -{ - char *header; - - if (in && (header = header_token_decode(in))) { - if (strlen (header) == strlen ("00000000-0000") - && sscanf (header, "%08x-%04x", uid, flags) == 2) { - g_free(header); - return *uid; - } - g_free(header); - } - - return -1; -} - -static char * -header_evolution_encode(guint32 uid, guint32 flags) -{ - return g_strdup_printf("%08x-%04x", uid, flags & 0xffff); -} - -static CamelMessageInfo * -message_info_new(CamelFolderSummary *s, struct _header_raw *h) -{ - CamelMessageInfo *mi; - - mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new(s, h); - if (mi) { - const char *xev; - guint32 uid, flags; - CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi; - - xev = header_raw_find(&h, "X-Evolution", NULL); - if (xev && header_evolution_decode(xev, &uid, &flags) != -1) { - g_free(mi->uid); - mi->uid = g_strdup_printf("%u", uid); - if (camel_folder_summary_uid(s, mi->uid)) { - g_free(mi->uid); - mi->uid = camel_folder_summary_next_uid_string(s); - } else { - /* so we dont get clashes later on */ - camel_folder_summary_set_uid(s, uid+1); - } - mi->flags = flags; - } else { - /* to indicate it has no xev header? */ - mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV; - mi->uid = g_strdup_printf("%u", camel_folder_summary_next_uid(s)); - } - mbi->frompos = -1; - } - - return mi; -} - -static CamelMessageInfo * -message_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp) -{ - CamelMessageInfo *mi; - CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s); - - 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); - - /* do we want to index this message as we add it, as well? */ - if (mbs->index - && (mbs->index_force - || (mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0 - || !ibex_contains_name(mbs->index, mi->uid))) { - camel_folder_summary_set_index(s, mbs->index); - } else { - camel_folder_summary_set_index(s, NULL); - } - } - - 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) { - guint32 position; - CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi; - - camel_folder_summary_decode_uint32(in, &position); - mbi->frompos = position; - } - - return mi; -} - -static int -message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi) -{ - CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi; - - io(printf("saving mbox message info\n")); - - ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_save(s, out, mi); - - return camel_folder_summary_encode_uint32(out, mbi->frompos); -} - -static int -summary_rebuild(CamelMboxSummary *mbs, off_t offset) -{ - CamelFolderSummary *s = CAMEL_FOLDER_SUMMARY(mbs); - CamelMimeParser *mp; - int fd; - int ok = 0; - - fd = open(mbs->folder_path, O_RDONLY); - if (fd == -1) { - printf("%s failed to open: %s", mbs->folder_path, strerror(errno)); - return -1; - } - - 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) == HSCAN_FROM) { - if (camel_mime_parser_tell_start_from(mp) != offset) { - g_warning ("The next message didn't start where I expected\nbuilding summary from start"); - camel_mime_parser_drop_step(mp); - offset = 0; - camel_mime_parser_seek(mp, offset, SEEK_SET); - camel_folder_summary_clear(CAMEL_FOLDER_SUMMARY(mbs)); - } else { - camel_mime_parser_unstep(mp); - } - } else { - camel_object_unref(CAMEL_OBJECT(mp)); - /* end of file - no content? */ - return -1; - } - } - - while (camel_mime_parser_step(mp, NULL, NULL) == HSCAN_FROM) { - CamelMessageInfo *info; - - info = camel_folder_summary_add_from_parser(CAMEL_FOLDER_SUMMARY(mbs), mp); - if (info == NULL) { - printf ("Could not build info from file?\n"); - ok = -1; - break; - } - - g_assert(camel_mime_parser_step(mp, NULL, NULL) == HSCAN_FROM_END); - } - - camel_object_unref(CAMEL_OBJECT (mp)); - - /* update the file size/mtime in the summary */ - if (ok != -1) { - struct stat st; - - if (stat(mbs->folder_path, &st) == 0) { - mbs->folder_size = st.st_size; - s->time = st.st_mtime; - } - } - - return ok; -} - -int -camel_mbox_summary_update(CamelMboxSummary *mbs, off_t offset, CamelFolderChangeInfo *changeinfo) -{ - int ret, i, count; - CamelFolderSummary *s = (CamelFolderSummary *)mbs; - - /* we use the diff function of the change_info to build the update list. */ - for (i = 0; i < camel_folder_summary_count(s); i++) { - CamelMessageInfo *mi = camel_folder_summary_index(s, i); - - camel_folder_change_info_add_source(changeinfo, mi->uid); - } - - /* do the actual work */ - mbs->index_force = FALSE; - ret = summary_rebuild(mbs, offset); - - count = camel_folder_summary_count(s); - for (i = 0; i < count; i++) { - CamelMessageInfo *mi = camel_folder_summary_index(s, i); - camel_folder_change_info_add_update(changeinfo, mi->uid); - } - camel_folder_change_info_build_diff(changeinfo); - -#if 0 -#warning "Saving full summary and index after every summarisation is slow ..." - if (ret != -1) { - if (camel_folder_summary_save((CamelFolderSummary *)mbs) == -1) - g_warning("Could not save summary: %s", strerror(errno)); - if (mbs->index) - ibex_save(mbs->index); - } -#endif - return ret; -} - -int -camel_mbox_summary_load(CamelMboxSummary *mbs, int forceindex) -{ - CamelFolderSummary *s = CAMEL_FOLDER_SUMMARY(mbs); - struct stat st; - int ret = 0; - off_t minstart; - - mbs->index_force = forceindex; - - /* is the summary out of date? */ - if (stat(mbs->folder_path, &st) == -1) { - camel_folder_summary_clear(s); - printf("Cannot summarise folder: '%s': %s\n", mbs->folder_path, strerror(errno)); - return -1; - } - - if (forceindex || camel_folder_summary_load(s) == -1) { - camel_folder_summary_clear(s); - ret = summary_rebuild(mbs, 0); - } else { - minstart = st.st_size; -#if 0 - /* find out the first unindexed message ... */ - /* TODO: For this to work, it has to check that the message is - indexable, and contains content ... maybe it cannot be done - properly? */ - for (i = 0; i < camel_folder_summary_count(s); i++) { - CamelMessageInfo *mi = camel_folder_summary_index(s, i); - - if (mbs->index && !ibex_contains_name(mbs->index, mi->uid)) { - minstart = ((CamelMboxMessageInfo *) mi)->frompos; - printf("Found unindexed message: %s\n", mi->uid); - break; - } - } -#endif - /* is the summary uptodate? */ - if (st.st_size == mbs->folder_size && st.st_mtime == s->time) { - if (minstart < st.st_size) { - /* FIXME: Only clear the messages and reindex from this point forward */ - camel_folder_summary_clear(s); - ret = summary_rebuild(mbs, 0); - } - } else { - if (mbs->folder_size < st.st_size) { - if (minstart < mbs->folder_size) { - /* FIXME: only make it rebuild as necessary */ - camel_folder_summary_clear(s); - ret = summary_rebuild(mbs, 0); - } else { - ret = summary_rebuild(mbs, mbs->folder_size); - /* If that fails, it might be because a message was changed - * rather than appended... so try again from the beginning. - */ - if (ret == -1) { - camel_folder_summary_clear(s); - ret = summary_rebuild(mbs, 0); - } - } - } else { - camel_folder_summary_clear(s); - ret = summary_rebuild(mbs, 0); - } - } - } - - if (ret != -1) { - mbs->folder_size = st.st_size; - s->time = st.st_mtime; - if (camel_folder_summary_save(s) == -1) - g_warning("Could not save summary: %s", strerror(errno)); - if (mbs->index) - ibex_save(mbs->index); - } - - return ret; -} - -static int -header_write(int fd, struct _header_raw *header, char *xevline) -{ - struct iovec iv[4]; - int outlen = 0, len; - - iv[1].iov_base = ":"; - iv[1].iov_len = 1; - iv[3].iov_base = "\n"; - iv[3].iov_len = 1; - - while (header) { - if (strcasecmp(header->name, "X-Evolution")) { - iv[0].iov_base = header->name; - iv[0].iov_len = strlen(header->name); - iv[2].iov_base = header->value; - iv[2].iov_len = strlen(header->value); - - do { - len = writev(fd, iv, 4); - } while (len == -1 && errno == EINTR); - - if (len == -1) - return -1; - outlen += len; - } - header = header->next; - } - - iv[0].iov_base = "X-Evolution: "; - iv[0].iov_len = strlen(iv[0].iov_base); - iv[1].iov_base = xevline; - iv[1].iov_len = strlen(xevline); - iv[2].iov_base = "\n\n"; - iv[2].iov_len = 2; - - do { - len = writev(fd, iv, 3); - } while (len == -1 && errno == EINTR); - - if (len == -1) - return -1; - - outlen += 1; - - d(printf("Wrote %d bytes of headers\n", outlen)); - - return outlen; -} - -static int -copy_block(int fromfd, int tofd, off_t start, size_t bytes) -{ - char buffer[4096]; - int written = 0; - - d(printf("writing %d bytes ... ", bytes)); - - if (lseek(fromfd, start, SEEK_SET) != start) - return -1; - - while (bytes > 0) { - int toread, towrite; - - toread = bytes; - if (bytes > 4096) - toread = 4096; - else - toread = bytes; - do { - towrite = read(fromfd, buffer, toread); - } while (towrite == -1 && errno == EINTR); - - if (towrite == -1) - return -1; - - /* check for 'end of file' */ - if (towrite == 0) { - d(printf("end of file?\n")); - break; - } - - do { - toread = write(tofd, buffer, towrite); - } while (toread == -1 && errno == EINTR); - - if (toread == -1) - return -1; - - written += toread; - bytes -= toread; - } - - d(printf("written %d bytes\n", written)); - - return written; -} - -static char *tz_months[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -static char *tz_days[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -/* tries to build a From line, based on message headers */ -char * -camel_mbox_summary_build_from(struct _header_raw *header) -{ - GString *out = g_string_new("From "); - char *ret; - const char *tmp; - time_t thetime; - int offset; - struct tm tm; - - tmp = header_raw_find(&header, "Sender", NULL); - if (tmp == NULL) - tmp = header_raw_find(&header, "From", NULL); - if (tmp != NULL) { - struct _header_address *addr = header_address_decode(tmp); - - tmp = NULL; - if (addr) { - if (addr->type == HEADER_ADDRESS_NAME) { - g_string_append(out, addr->v.addr); - tmp = ""; - } - header_address_unref(addr); - } - } - if (tmp == NULL) { - g_string_append(out, "unknown@nodomain.now.au"); - } - - /* try use the received header to get the date */ - tmp = header_raw_find(&header, "Received", NULL); - if (tmp) { - tmp = strrchr(tmp, ';'); - if (tmp) - tmp++; - } - - /* if there isn't one, try the Date field */ - if (tmp == NULL) - tmp = header_raw_find(&header, "Date", NULL); - - thetime = header_decode_date(tmp, &offset); - - thetime += ((offset / 100) * (60 * 60)) + (offset % 100) * 60; - - /* a pseudo, but still bogus attempt at thread safing the function */ - /*memcpy(&tm, gmtime(&thetime), sizeof(tm));*/ - gmtime_r(&thetime, &tm); - - g_string_sprintfa(out, " %s %s %d %02d:%02d:%02d %4d\n", - tz_days[tm.tm_wday], - tz_months[tm.tm_mon], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900); - - ret = out->str; - g_string_free(out, FALSE); - return ret; -} - -int -camel_mbox_summary_sync(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex) -{ - CamelMimeParser *mp = NULL; - int i, count; - CamelMboxMessageInfo *info; - CamelFolderSummary *s = CAMEL_FOLDER_SUMMARY(mbs); - int fd = -1, fdout = -1; - off_t offset = 0; - char *tmpname = NULL; - char *buffer, *xevnew = NULL; - const char *xev; - int len; - guint32 uid, flags; - int quick = TRUE, work = FALSE; - struct stat st; - char *fromline; - - /* make sure we're in sync, after this point we at least have a complete list of id's */ - count = camel_folder_summary_count (s); - if (count > 0) { - CamelMessageInfo *mi = camel_folder_summary_index(s, count - 1); - camel_mbox_summary_update(mbs, mi->content->endpos, changeinfo); - } else { - camel_mbox_summary_update(mbs, 0, changeinfo); - } - - /* check if we have any work to do */ - d(printf("Performing sync, %d messages in inbox\n", count)); - for (i = 0; quick && i < count; i++) { - info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i); - if ((expunge && (info->info.flags & CAMEL_MESSAGE_DELETED)) || - (info->info.flags & CAMEL_MESSAGE_FOLDER_NOXEV)) - quick = FALSE; - else - work |= (info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0; - } - - d(printf("Options: %s %s %s\n", expunge ? "expunge" : "", quick ? "quick" : "", work ? "Work" : "")); - - if (quick && !work) - return 0; - - fd = open(mbs->folder_path, O_RDWR); - if (fd == -1) { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open summary %s"), mbs->folder_path); - return -1; - } - - mp = camel_mime_parser_new(); - camel_mime_parser_scan_from(mp, TRUE); - camel_mime_parser_init_with_fd(mp, fd); - - if (!quick) { - tmpname = alloca(strlen (mbs->folder_path) + 5); - sprintf(tmpname, "%s.tmp", mbs->folder_path); - d(printf("Writing tmp file to %s\n", tmpname)); - retry_out: - fdout = open(tmpname, O_WRONLY|O_CREAT|O_EXCL, 0600); - if (fdout == -1) { - if (errno == EEXIST) - if (unlink(tmpname) != -1) - goto retry_out; - - tmpname = NULL; - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot open temporary mailbox: %s"), strerror(errno)); - goto error; - } - } - - for (i = 0; i < count; i++) { - off_t frompos, bodypos, lastpos; - /* This has to be an int, not an off_t, because that's - * what camel_mime_parser_header returns... FIXME. - */ - int xevoffset; - - info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i); - - g_assert(info); - - d(printf("Looking at message %s\n", info->info.uid)); - - if (expunge && info->info.flags & CAMEL_MESSAGE_DELETED) { - d(printf("Deleting %s\n", info->info.uid)); - - g_assert(!quick); - offset -= (info->info.content->endpos - info->frompos); - if (mbs->index) - ibex_unindex(mbs->index, info->info.uid); - /* remove it from teh change list */ - camel_folder_change_info_remove_uid(changeinfo, info->info.uid); - camel_folder_summary_remove(s, (CamelMessageInfo *)info); - count--; - i--; - info = NULL; - } else if (info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) { - int xevok = FALSE; - - d(printf("Updating header for %s flags = %08x\n", info->info.uid, info->info.flags)); - - /* find the next message, header parts */ - camel_mime_parser_seek(mp, info->frompos, SEEK_SET); - if (camel_mime_parser_step(mp, &buffer, &len) != HSCAN_FROM) { - g_warning("camel_mime_parser_step failed (1)"); - goto error; - } - - if (camel_mime_parser_tell_start_from (mp) != info->frompos) { - g_warning("Summary/mbox mismatch, aborting sync"); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Summary mismatch, aborting sync")); - goto error; - } - - if (camel_mime_parser_step (mp, &buffer, &len) == HSCAN_FROM_END) { - g_warning("camel_mime_parser_step failed (2)"); - goto error; - } - - /* Check if the X-Evolution header is valid. */ - - xev = camel_mime_parser_header(mp, "X-Evolution", &xevoffset); - if (xev && header_evolution_decode (xev, &uid, &flags) != -1) - xevok = TRUE; - - xevnew = header_evolution_encode(strtoul (info->info.uid, NULL, 10), info->info.flags & 0xffff); - if (quick) { - if (!xevok) { - g_warning("The summary told me I had an X-Evolution header, but i dont!"); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Summary mismatch, X-Evolution header missing")); - goto error; - } - buffer = g_strdup_printf("X-Evolution: %s", xevnew); - lastpos = lseek(fd, 0, SEEK_CUR); - lseek(fd, xevoffset, SEEK_SET); - do { - len = write(fd, buffer, strlen (buffer)); - } while (len == -1 && errno == EINTR); - lseek(fd, lastpos, SEEK_SET); - g_free(buffer); - if (len == -1) { - goto error; - } - } else { - frompos = lseek(fdout, 0, SEEK_CUR); - fromline = camel_mbox_summary_build_from(camel_mime_parser_headers_raw (mp)); - write(fdout, fromline, strlen(fromline)); - g_free(fromline); - if (header_write(fdout, camel_mime_parser_headers_raw(mp), xevnew) == -1) { - d(printf("Error writing to tmp mailbox\n")); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Error writing to temp mailbox: %s"), - strerror(errno)); - goto error; - } - bodypos = lseek(fdout, 0, SEEK_CUR); - d(printf("pos = %d, endpos = %d, bodypos = %d\n", - (int) info->info.content->pos, - (int) info->info.content->endpos, - (int) info->info.content->bodypos)); - if (copy_block(fd, fdout, info->info.content->bodypos, - info->info.content->endpos - info->info.content->bodypos) == -1) { - g_warning("Cannot copy data to output fd"); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot copy data to output file: %s"), - strerror (errno)); - goto error; - } - info->frompos = frompos; - offset = bodypos - info->info.content->bodypos; - } - info->info.flags &= 0xffff; - g_free(xevnew); - xevnew = NULL; - camel_mime_parser_drop_step(mp); - camel_mime_parser_drop_step(mp); - } else { - if (!quick) { - if (copy_block(fd, fdout, info->frompos, - info->info.content->endpos - info->frompos) == -1) { - g_warning("Cannot copy data to output fd"); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot copy data to output file: %s"), - strerror(errno)); - goto error; - } - /* update from pos here? */ - info->frompos += offset; - } else { - d(printf("Nothing to do for this message\n")); - } - } - if (!quick && info != NULL && offset != 0) { - d(printf("offsetting content: %d\n", (int)offset)); - camel_folder_summary_offset_content(info->info.content, offset); - d(printf("pos = %d, endpos = %d, bodypos = %d\n", - (int) info->info.content->pos, - (int) info->info.content->endpos, - (int) info->info.content->bodypos)); - } - } - - 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"), - mbs->folder_path, strerror(errno)); - goto error; - } - - if (!quick) { - 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"), - strerror(errno)); - goto error; - } - - if (rename(tmpname, mbs->folder_path) == -1) { - g_warning("Cannot rename folder: %s", strerror(errno)); - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename folder: %s"), - strerror(errno)); - goto error; - } - tmpname = NULL; - - if (mbs->index) - ibex_save(mbs->index); - } - - if (stat(mbs->folder_path, &st) == -1) { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Unknown error: %s"), - strerror(errno)); - goto error; - } - - camel_folder_summary_touch(s); - s->time = st.st_mtime; - mbs->folder_size = st.st_size; - camel_folder_summary_save(s); - - camel_object_unref(CAMEL_OBJECT(mp)); - - return 0; - error: - if (fd != -1) - close(fd); - - if (fdout != -1) - close(fdout); - - g_free(xevnew); - - if (tmpname) - unlink(tmpname); - if (mp) - camel_object_unref(CAMEL_OBJECT(mp)); - - return -1; -} - - - - - diff --git a/camel/providers/mbox/camel-mbox-summary.h b/camel/providers/mbox/camel-mbox-summary.h deleted file mode 100644 index f90acc4f35..0000000000 --- a/camel/providers/mbox/camel-mbox-summary.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _CAMEL_MBOX_SUMMARY_H -#define _CAMEL_MBOX_SUMMARY_H - -#include <camel/camel-folder-summary.h> -#include <camel/camel-folder.h> -#include <camel/camel-exception.h> -#include <libibex/ibex.h> - -#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 IS_CAMEL_MBOX_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_mbox_summary_get_type ()) - -typedef struct _CamelMboxSummary CamelMboxSummary; -typedef struct _CamelMboxSummaryClass CamelMboxSummaryClass; - -/* extra summary flags */ -enum { - CAMEL_MESSAGE_FOLDER_NOXEV = 1<<17, -}; - -typedef struct _CamelMboxMessageContentInfo { - CamelMessageContentInfo info; -} CamelMboxMessageContentInfo; - -typedef struct _CamelMboxMessageInfo { - CamelMessageInfo info; - - off_t frompos; -} CamelMboxMessageInfo; - -struct _CamelMboxSummary { - CamelFolderSummary parent; - - struct _CamelMboxSummaryPrivate *priv; - - char *folder_path; /* name of matching folder */ - size_t folder_size; /* size of the mbox file, last sync */ - - ibex *index; - int index_force; /* do we force index during creation? */ -}; - -struct _CamelMboxSummaryClass { - CamelFolderSummaryClass parent_class; -}; - -guint camel_mbox_summary_get_type (void); -CamelMboxSummary *camel_mbox_summary_new (const char *filename, const char *mbox_name, ibex *index); - -/* load/check the summary */ -int camel_mbox_summary_load(CamelMboxSummary *mbs, int forceindex); -/* incremental update */ -int camel_mbox_summary_update(CamelMboxSummary *mbs, off_t offset, CamelFolderChangeInfo *changeinfo); -/* perform a folder sync or expunge, if needed */ -int camel_mbox_summary_sync (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); -/* generate a From line from headers */ -char *camel_mbox_summary_build_from(struct _header_raw *header); - -#endif /* ! _CAMEL_MBOX_SUMMARY_H */ - diff --git a/camel/providers/mbox/libcamelmbox.urls b/camel/providers/mbox/libcamelmbox.urls deleted file mode 100644 index e021190356..0000000000 --- a/camel/providers/mbox/libcamelmbox.urls +++ /dev/null @@ -1 +0,0 @@ -mbox diff --git a/camel/providers/mh/.cvsignore b/camel/providers/mh/.cvsignore deleted file mode 100644 index fd6b811c68..0000000000 --- a/camel/providers/mh/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la diff --git a/camel/providers/mh/Makefile.am b/camel/providers/mh/Makefile.am deleted file mode 100644 index 62f447171b..0000000000 --- a/camel/providers/mh/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelmhincludedir = $(includedir)/camel - - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelmh.la -provider_DATA = libcamelmh.urls - -INCLUDES = -I.. \ - -I$(srcdir)/.. \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/libibex \ - -I$(top_srcdir)/e-util \ - -I$(top_srcdir) \ - -I$(includedir) \ - $(GTK_INCLUDEDIR) \ - -DG_LOG_DOMAIN=\"camel-mh-provider\" - -libcamelmh_la_SOURCES = \ - camel-mh-folder.c \ - camel-mh-provider.c \ - camel-mh-store.c \ - camel-mh-summary.c - -libcamelmhinclude_HEADERS = \ - camel-mh-folder.h \ - camel-mh-store.h \ - camel-mh-summary.h - -libcamelmh_la_LDFLAGS = -version-info 0:0:0 - -libcamelmh_la_LIBADD = $(top_builddir)/e-util/libeutil.la $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) -#libcamelmh_la_LIBADD = $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) - -EXTRA_DIST = libcamelmh.urls - diff --git a/camel/providers/mh/camel-mh-folder.c b/camel/providers/mh/camel-mh-folder.c deleted file mode 100644 index a56de4a9c1..0000000000 --- a/camel/providers/mh/camel-mh-folder.c +++ /dev/null @@ -1,534 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ -/* camel-mh-folder.c : Abstract class for an email folder */ - -/* - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * Copyright (C) 1999, 2000 Helix Code Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> - -#include <stdlib.h> -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> - -#include "camel-mh-folder.h" -#include "camel-mh-store.h" -#include "string-utils.h" -#include "camel-stream-fs.h" -#include "camel-mh-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) - -static CamelFolderClass *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 void mh_sync(CamelFolder * folder, gboolean expunge, CamelException * ex); -static gint mh_get_message_count(CamelFolder * folder); -static gint mh_get_unread_message_count(CamelFolder * folder); -static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, CamelException * ex); -static GPtrArray *mh_get_uids(CamelFolder * folder); -static GPtrArray *mh_get_summary(CamelFolder * folder); -static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex); - -static void mh_expunge(CamelFolder * folder, CamelException * ex); - -static const CamelMessageInfo *mh_get_message_info(CamelFolder * folder, const char *uid); - -static GPtrArray *mh_search_by_expression(CamelFolder * folder, const char *expression, CamelException * ex); -static void mh_search_free(CamelFolder *folder, GPtrArray *result); - -static guint32 mh_get_message_flags(CamelFolder * folder, const char *uid); -static void mh_set_message_flags(CamelFolder * folder, const char *uid, guint32 flags, guint32 set); -static gboolean mh_get_message_user_flag(CamelFolder * folder, const char *uid, const char *name); -static void mh_set_message_user_flag(CamelFolder * folder, const char *uid, const char *name, gboolean value); -static const char *mh_get_message_user_tag(CamelFolder *folder, const char *uid, const char *name); -static void mh_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); - -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); - - parent_class = CAMEL_FOLDER_CLASS (camel_type_get_global_classfuncs(camel_folder_get_type())); - - /* virtual method definition */ - - /* virtual method overload */ - camel_folder_class->sync = mh_sync; - camel_folder_class->get_message_count = mh_get_message_count; - camel_folder_class->get_unread_message_count = mh_get_unread_message_count; - camel_folder_class->append_message = mh_append_message; - camel_folder_class->get_uids = mh_get_uids; - camel_folder_class->free_uids = camel_folder_free_deep; - camel_folder_class->get_summary = mh_get_summary; - camel_folder_class->free_summary = camel_folder_free_nop; - camel_folder_class->expunge = mh_expunge; - - camel_folder_class->get_message = mh_get_message; - - camel_folder_class->search_by_expression = mh_search_by_expression; - camel_folder_class->search_free = mh_search_free; - - camel_folder_class->get_message_info = mh_get_message_info; - - camel_folder_class->get_message_flags = mh_get_message_flags; - camel_folder_class->set_message_flags = mh_set_message_flags; - camel_folder_class->get_message_user_flag = mh_get_message_user_flag; - camel_folder_class->set_message_user_flag = mh_set_message_user_flag; - camel_folder_class->get_message_user_tag = mh_get_message_user_tag; - camel_folder_class->set_message_user_tag = mh_set_message_user_tag; -} - -static void mh_init(gpointer object, gpointer klass) -{ - CamelFolder *folder = object; - CamelMhFolder *mh_folder = object; - - folder->has_summary_capability = TRUE; - folder->has_search_capability = TRUE; - - folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | - CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT | - CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_USER; - - mh_folder->summary = NULL; - mh_folder->search = NULL; - mh_folder->changes = camel_folder_change_info_new(); -} - -static void mh_finalize(CamelObject * object) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(object); - - if (mh_folder->index) - ibex_close(mh_folder->index); - - g_free(mh_folder->folder_file_path); - g_free(mh_folder->summary_file_path); - g_free(mh_folder->folder_dir_path); - g_free(mh_folder->index_file_path); - camel_folder_change_info_free(mh_folder->changes); -} - -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_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; - CamelMhFolder *mh_folder; - const char *root_dir_path, *name; - int forceindex; - struct stat st; - - folder = CAMEL_FOLDER (camel_object_new(CAMEL_MH_FOLDER_TYPE)); - mh_folder = (CamelMhFolder *)folder; - - name = strrchr(full_name, '/'); - if (name) - name++; - else - name = full_name; - camel_folder_construct (folder, parent_store, full_name, name); - - root_dir_path = camel_mh_store_get_toplevel_dir(CAMEL_MH_STORE(folder->parent_store)); - - mh_folder->folder_file_path = g_strdup_printf("%s/%s", root_dir_path, full_name); - mh_folder->summary_file_path = g_strdup_printf("%s/%s/ev-summary", root_dir_path, full_name); - mh_folder->folder_dir_path = g_strdup_printf("%s/%s", root_dir_path, full_name); - mh_folder->index_file_path = g_strdup_printf("%s/%s/ev-index.ibex", root_dir_path, full_name); - - /* if we have no index file, force it */ - forceindex = stat(mh_folder->index_file_path, &st) == -1; - /* check if we need to setup an index */ - if (flags & CAMEL_STORE_FOLDER_BODY_INDEX) { - mh_folder->index = ibex_open(mh_folder->index_file_path, O_CREAT | O_RDWR, 0600); - if (mh_folder->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; - } - } else { - /* if we do have an index file, remove it */ - if (forceindex == FALSE) { - unlink(mh_folder->index_file_path); - } - forceindex = FALSE; - } - - /* no summary (disk or memory), and we're proverbially screwed */ - mh_folder->summary = camel_mh_summary_new(mh_folder->summary_file_path, - mh_folder->folder_file_path, - mh_folder->index); - - if (camel_mh_summary_load(mh_folder->summary, forceindex) == -1) { - camel_exception_set(ex, CAMEL_EXCEPTION_FOLDER_INVALID, /* FIXME: right error code */ - _("Could not load or create summary")); - camel_object_unref (CAMEL_OBJECT (folder)); - return NULL; - } - - return folder; -} - -static void mh_sync(CamelFolder * folder, gboolean expunge, CamelException * ex) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - - if (expunge) - mh_expunge(folder, ex); - else { - camel_mh_summary_sync(mh_folder->summary, FALSE, mh_folder->changes, ex); - camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", mh_folder->changes); - camel_folder_change_info_clear(mh_folder->changes); - } - - /* save index */ - if (mh_folder->index) - ibex_save(mh_folder->index); - if (mh_folder->summary) - camel_folder_summary_save(CAMEL_FOLDER_SUMMARY(mh_folder->summary)); -} - -static void mh_expunge(CamelFolder * folder, CamelException * ex) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - - camel_mh_summary_sync(mh_folder->summary, TRUE, mh_folder->changes, ex); - camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", mh_folder->changes); - camel_folder_change_info_clear(mh_folder->changes); -} - -static gint mh_get_message_count(CamelFolder * folder) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - - g_return_val_if_fail(mh_folder->summary != NULL, -1); - - return camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(mh_folder->summary)); -} - -static gint mh_get_unread_message_count(CamelFolder * folder) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - CamelMessageInfo *info; - GPtrArray *infolist; - gint i, count = 0; - - g_return_val_if_fail(mh_folder->summary != NULL, -1); - - infolist = mh_get_summary(folder); - - for (i = 0; i < infolist->len; i++) { - info = (CamelMessageInfo *) g_ptr_array_index(infolist, i); - if (!(info->flags & CAMEL_MESSAGE_SEEN)) - count++; - } - - return count; -} - -static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, CamelException * ex) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - CamelStream *output_stream = NULL; - char *name = NULL; - char *uid = NULL; - CamelMessageInfo *newinfo; - - /* FIXME: probably needs additional locking */ - - /* keep trying uid's until we find one thats ok */ - do { - g_free(uid); - g_free(name); - uid = camel_folder_summary_next_uid_string((CamelFolderSummary *)mh_folder->summary); - name = g_strdup_printf("%s/%s", mh_folder->folder_file_path, uid); - output_stream = camel_stream_fs_new_with_name(name, O_WRONLY|O_CREAT|O_EXCL, 0600); - } while (output_stream == NULL && errno == EEXIST); - - if (output_stream == NULL) - goto fail; - - /* write the message */ - if (camel_data_wrapper_write_to_stream(CAMEL_DATA_WRAPPER(message), output_stream) == -1) - goto fail; - - if (camel_stream_close(output_stream) == -1) - goto fail; - - /* index/summarise the message. Yes this re-reads it, its just simpler */ - camel_mh_summary_add(mh_folder->summary, uid, TRUE); - - if (info - && (newinfo = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mh_folder->summary), uid))) { - CamelFlag *flag = info->user_flags; - CamelTag *tag = info->user_tags; - - newinfo->flags = info->flags; - while (flag) { - camel_flag_set(&newinfo->user_flags, flag->name, TRUE); - flag = flag->next; - } - while (tag) { - camel_tag_set(&newinfo->user_tags, tag->name, tag->value); - tag = tag->next; - } - } - - camel_folder_change_info_add_uid(mh_folder->changes, uid); - camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", mh_folder->changes); - camel_folder_change_info_clear(mh_folder->changes); - g_free(name); - g_free(uid); - return; - -fail: - if (camel_exception_is_set(ex)) { - camel_exception_setv(ex, camel_exception_get_id(ex), - _("Cannot append message to mh folder: %s"), camel_exception_get_description(ex)); - } else { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot append message to mh folder: %s"), g_strerror(errno)); - } - if (output_stream) - camel_object_unref(CAMEL_OBJECT(output_stream)); - if (name) { - unlink(name); - g_free(name); - } - g_free(uid); -} - -static GPtrArray *mh_get_uids(CamelFolder * folder) -{ - GPtrArray *array; - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - int i, count; - - count = camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(mh_folder->summary)); - array = g_ptr_array_new(); - g_ptr_array_set_size(array, count); - for (i = 0; i < count; i++) { - CamelMessageInfo *info = - camel_folder_summary_index(CAMEL_FOLDER_SUMMARY(mh_folder->summary), i); - - array->pdata[i] = g_strdup(info->uid); - } - - return array; -} - -static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - CamelStream *message_stream = NULL; - CamelMimeMessage *message = NULL; - CamelMessageInfo *info; - char *name; - - name = g_strdup_printf("%s/%s", mh_folder->folder_file_path, uid); - - /* get the message summary info */ - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mh_folder->summary), uid); - - if (info == NULL) { - errno = ENOENT; - goto fail; - } - - message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0); - - /* where we read from */ - if (message_stream == NULL) - goto fail; - - message = camel_mime_message_new(); - if (camel_data_wrapper_construct_from_stream(CAMEL_DATA_WRAPPER(message), message_stream) == -1) { - g_warning("Construction failed"); - errno = EINVAL; - goto fail; - } - camel_object_unref(CAMEL_OBJECT(message_stream)); - g_free(name); - - return message; - -fail: - camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), - name, g_strerror(errno)); - - if (message_stream) - camel_object_unref(CAMEL_OBJECT(message_stream)); - - if (message) - camel_object_unref(CAMEL_OBJECT(message)); - - g_free(name); - - return NULL; -} - -GPtrArray *mh_get_summary(CamelFolder * folder) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - - return CAMEL_FOLDER_SUMMARY(mh_folder->summary)->messages; -} - -/* get a single message info, by uid */ -static const CamelMessageInfo *mh_get_message_info(CamelFolder * folder, const char *uid) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - - return camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mh_folder->summary), uid); -} - -static GPtrArray *mh_search_by_expression(CamelFolder * folder, const char *expression, CamelException * ex) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); - - if (mh_folder->search == NULL) { - mh_folder->search = camel_folder_search_new(); - } - - camel_folder_search_set_folder(mh_folder->search, folder); - if (mh_folder->summary) { - /* FIXME: dont access summary array directly? */ - camel_folder_search_set_summary(mh_folder->search, - CAMEL_FOLDER_SUMMARY(mh_folder->summary)->messages); - } - - camel_folder_search_set_body_index(mh_folder->search, mh_folder->index); - - return camel_folder_search_execute_expression(mh_folder->search, expression, ex); -} - -static void mh_search_free(CamelFolder *folder, GPtrArray *result) -{ - CamelMhFolder *mh_folder = CAMEL_MH_FOLDER (folder); - - camel_folder_search_free_result(mh_folder->search, result); -} - -static guint32 mh_get_message_flags(CamelFolder * folder, const char *uid) -{ - CamelMessageInfo *info; - CamelMhFolder *mf = CAMEL_MH_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, 0); - - return info->flags; -} - -static void mh_set_message_flags(CamelFolder * folder, const char *uid, guint32 flags, guint32 set) -{ - CamelMessageInfo *info; - CamelMhFolder *mf = CAMEL_MH_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); - - info->flags = (info->flags & ~flags) | (set & flags) | CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - - camel_object_trigger_event (CAMEL_OBJECT(folder), "message_changed", (char *) uid); -} - -static gboolean mh_get_message_user_flag(CamelFolder * folder, const char *uid, const char *name) -{ - CamelMessageInfo *info; - CamelMhFolder *mf = CAMEL_MH_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, FALSE); - - return camel_flag_get(&info->user_flags, name); -} - -static void mh_set_message_user_flag(CamelFolder * folder, const char *uid, const char *name, gboolean value) -{ - CamelMessageInfo *info; - CamelMhFolder *mf = CAMEL_MH_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); - - camel_flag_set(&info->user_flags, name, value); - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - camel_object_trigger_event (CAMEL_OBJECT(folder), "message_changed", (char *) uid); -} - -static const char *mh_get_message_user_tag(CamelFolder *folder, const char *uid, const char *name) -{ - CamelMessageInfo *info; - CamelMhFolder *mf = CAMEL_MH_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, FALSE); - - return camel_tag_get(&info->user_tags, name); -} - -static void mh_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value) -{ - CamelMessageInfo *info; - CamelMhFolder *mf = CAMEL_MH_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); - - camel_tag_set(&info->user_tags, name, value); - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); -} diff --git a/camel/providers/mh/camel-mh-folder.h b/camel/providers/mh/camel-mh-folder.h deleted file mode 100644 index ddfdf2b4aa..0000000000 --- a/camel/providers/mh/camel-mh-folder.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mh-folder.h : MH folder. */ - -/* - * - * Authors: - * Michael Zucchi <notzed@helixcode.com> - * - * Copyright (C) 1999 Helix Code Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_MH_FOLDER_H -#define CAMEL_MH_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus } */ -#include <camel/camel-folder.h> -#include <camel/camel-folder-search.h> -#include <libibex/ibex.h> -#include "camel-mh-summary.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 IS_CAMEL_MH_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_MH_FOLDER_TYPE)) - -typedef struct { - CamelFolder parent_object; - - gchar *folder_file_path; /* contains the messages */ - gchar *summary_file_path; /* contains the messages summary */ - gchar *folder_dir_path; /* contains the subfolders */ - gchar *index_file_path; /* index of body contents */ - - ibex *index; /* index for this folder */ - CamelMhSummary *summary; - CamelFolderSearch *search; /* used to run searches, we just use the real thing (tm) */ - CamelFolderChangeInfo *changes; /* mass changes to the folder */ -} CamelMhFolder; - -typedef struct { - CamelFolderClass 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/mh/camel-mh-provider.c b/camel/providers/mh/camel-mh-provider.c deleted file mode 100644 index 74329a3203..0000000000 --- a/camel/providers/mh/camel-mh-provider.c +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-provider.c: mbox provider registration code */ - -/* - * Authors : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright (C) 2000 HelixCode (www.helixcode.com). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-mh-store.h" -#include "camel-provider.h" -#include "camel-session.h" -#include "camel-url.h" - -static CamelProvider mh_provider = { - "mh", - N_("UNIX MH-format mail directories"), - - N_("For storing local mail in MH-like mail directories"), - - "mail", - - CAMEL_PROVIDER_IS_STORAGE, - - CAMEL_URL_NEED_PATH, - - {0, 0}, - - NULL -}; - -void camel_provider_module_init(CamelSession * session) -{ - mh_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mh_store_get_type(); - - mh_provider.service_cache = g_hash_table_new(camel_url_hash, camel_url_equal); - - camel_session_register_provider(session, &mh_provider); -} diff --git a/camel/providers/mh/camel-mh-store.c b/camel/providers/mh/camel-mh-store.c deleted file mode 100644 index 0a6da11162..0000000000 --- a/camel/providers/mh/camel-mh-store.c +++ /dev/null @@ -1,228 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mbox-store.c : class for an mbox store */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> - -#include <sys/stat.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#include "camel-mh-store.h" -#include "camel-mh-folder.h" -#include "camel-exception.h" -#include "camel-url.h" - -/* 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 char *get_name(CamelService * service, gboolean brief); -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_name, const char *new_name, CamelException *ex); -static char *get_folder_name(CamelStore * store, const char *folder_name, CamelException * ex); -static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, - gboolean fast, gboolean recursive, - gboolean subscribed_only, - 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); - - /* virtual method overload */ - camel_service_class->get_name = get_name; - - camel_store_class->get_folder = get_folder; - camel_store_class->delete_folder = delete_folder; - camel_store_class->rename_folder = rename_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_folder_info = get_folder_info; - camel_store_class->free_folder_info = camel_store_free_folder_info_full; -} - -static void camel_mh_store_init(CamelObject * object) -{ - CamelStore *store = CAMEL_STORE(object); - - /* mh names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new(g_str_hash, g_str_equal); -} - -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_STORE_TYPE, "CamelMhStore", - sizeof(CamelMhStore), - sizeof(CamelMhStoreClass), - (CamelObjectClassInitFunc) camel_mh_store_class_init, - NULL, - (CamelObjectInitFunc) camel_mh_store_init, - NULL); - } - - return camel_mh_store_type; -} - -const gchar *camel_mh_store_get_toplevel_dir(CamelMhStore * store) -{ - CamelURL *url = CAMEL_SERVICE(store)->url; - - g_assert(url != NULL); - return url->path; -} - -static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex) -{ - char *name; - struct stat st; - - name = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, 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; - } - printf("creating ...\n"); - - 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; - } - printf("created ok?\n"); - - } 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 void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex) -{ - char *name; - struct stat st; - char *str; - - name = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, folder_name); - if (stat(name, &st) == -1) { - if (errno != ENOENT) - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s': %s"), - folder_name, strerror(errno)); - } else { - /* this will 'fail' if there are still messages in the directory - - but only the metadata is lost */ - str = g_strdup_printf("%s/ev-summary", name); - unlink(str); - g_free(str); - str = g_strdup_printf("%s/ev-index.ibex", name); - unlink(str); - g_free(str); - if (rmdir(name) == -1) { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not delete folder `%s': %s"), - folder_name, strerror(errno)); - } - } - g_free(name); -} - -static void rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex) -{ - char *old, *new; - struct stat st; - - old = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, old_name); - new = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, new_name); - if (stat(new, &st) == -1 && errno == ENOENT) { - if (stat(old, &st) == 0 && S_ISDIR(st.st_mode)) { - if (rename(old, new) != 0) { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename folder `%s': %s"), old_name, strerror(errno)); - } - } else { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename folder `%s': %s"), old_name, strerror(errno)); - } - } else { - camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not rename folder `%s': %s exists"), old_name, new_name); - } -} - -static char *get_folder_name(CamelStore * store, const char *folder_name, CamelException * ex) -{ - /* For now, we don't allow hieararchy. FIXME. */ - if (strchr(folder_name + 1, '/')) { - camel_exception_set(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, _("MH folders may not be nested.")); - return NULL; - } - - return *folder_name == '/' ? g_strdup(folder_name) : g_strdup_printf("/%s", folder_name); -} - -static char *get_name(CamelService * service, gboolean brief) -{ - if (brief) - return g_strdup(service->url->path); - else - return g_strdup_printf(_("Local mail directory %s"), service->url->path); -} - - -static CamelFolderInfo * -get_folder_info (CamelStore *store, const char *top, - gboolean fast, gboolean recursive, - gboolean subscribed_only, - CamelException *ex) -{ - /* FIXME: This is broken, but it corresponds to what was - * there before. - */ - return NULL; -} diff --git a/camel/providers/mh/camel-mh-store.h b/camel/providers/mh/camel-mh-store.h deleted file mode 100644 index e2e2bbb656..0000000000 --- a/camel/providers/mh/camel-mh-store.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mh-store.h : class for an mh store */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_MH_STORE_H -#define CAMEL_MH_STORE_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus } */ -#include "camel-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 IS_CAMEL_MH_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_MH_STORE_TYPE)) - -typedef struct { - CamelStore parent_object; - -} CamelMhStore; - -typedef struct { - CamelStoreClass parent_class; - -} CamelMhStoreClass; - -/* public methods */ - -/* Standard Camel function */ -CamelType camel_mh_store_get_type(void); - -const gchar *camel_mh_store_get_toplevel_dir(CamelMhStore * store); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CAMEL_MH_STORE_H */ diff --git a/camel/providers/mh/camel-mh-summary.c b/camel/providers/mh/camel-mh-summary.c deleted file mode 100644 index c757a9a0a9..0000000000 --- a/camel/providers/mh/camel-mh-summary.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code 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 the GNU Library 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 Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "camel-mh-summary.h" -#include <camel/camel-mime-message.h> - -#include <sys/stat.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> - -#define d(x) - -#define CAMEL_MH_SUMMARY_VERSION (0x2000) - -static CamelMessageInfo *message_info_new(CamelFolderSummary *, struct _header_raw *); - -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 CamelFolderSummaryClass *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_folder_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; - - parent_class = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs(camel_folder_summary_get_type ())); - - /* override methods */ - sklass->message_info_new = message_info_new; -} - -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->mh_path); - 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, ibex *index) -{ - CamelMhSummary *o = (CamelMhSummary *)camel_object_new(camel_mh_summary_get_type ()); - - camel_folder_summary_set_build_content((CamelFolderSummary *)o, TRUE); - camel_folder_summary_set_filename((CamelFolderSummary *)o, filename); - o->mh_path = g_strdup(mhdir); - o->index = index; - return o; -} - -static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _header_raw *h) -{ - CamelMessageInfo *mi; - CamelMhSummary *mhs = (CamelMhSummary *)s; - - mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new(s, h); - if (mi) { - /* it only ever indexes 1 message at a time */ - mi->uid = g_strdup(mhs->priv->current_uid); - } - - return mi; -} - -int camel_mh_summary_load(CamelMhSummary * mhs, int forceindex) -{ - CamelFolderSummary *s = CAMEL_FOLDER_SUMMARY(mhs); - - d(printf("loading summary ...\n")); - - if (forceindex || camel_folder_summary_load(s) == -1) { - camel_folder_summary_clear(s); - } - return camel_mh_summary_check(mhs, forceindex); -} - -int camel_mh_summary_add(CamelMhSummary * mhs, const char *name, int forceindex) -{ - char *filename = g_strdup_printf("%s/%s", mhs->mh_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 (mhs->index && (forceindex || !ibex_contains_name(mhs->index, (char *)name))) { - d(printf("forcing indexing of message content\n")); - camel_folder_summary_set_index((CamelFolderSummary *)mhs, mhs->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, CamelMhSummary *mhs) -{ - d(printf("removing message %s from summary\n", key)); - if (mhs->index) - ibex_unindex(mhs->index, info->uid); - camel_folder_summary_remove((CamelFolderSummary *)mhs, info); -} - -int camel_mh_summary_check(CamelMhSummary * mhs, int forceindex) -{ - DIR *dir; - struct dirent *d; - char *p, c; - CamelMessageInfo *info; - GHashTable *left; - int i, count; - - 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(mhs->mh_path); - if (dir == 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 *)mhs); - for (i=0;i<count;i++) { - info = camel_folder_summary_index((CamelFolderSummary *)mhs, i); - if (info) { - g_hash_table_insert(left, info->uid, 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 *)mhs, d->d_name); - if (info == NULL || (mhs->index && (!ibex_contains_name(mhs->index, d->d_name)))) { - /* need to add this file to the summary */ - if (info != NULL) { - g_hash_table_remove(left, info->uid); - camel_folder_summary_remove((CamelFolderSummary *)mhs, info); - } - camel_mh_summary_add(mhs, d->d_name, forceindex); - } else { - g_hash_table_remove(left, info->uid); - } - } - } - closedir(dir); - g_hash_table_foreach(left, (GHFunc)remove_summary, mhs); - g_hash_table_destroy(left); - - /* force a save of the index, just to make sure */ - /* note this could be expensive so possibly shouldn't be here - as such */ - if (mhs->index) { - ibex_save(mhs->index); - } - - return 0; -} - -/* sync the summary with the ondisk files. - It doesnt store the state in the file, the summary only, == MUCH faster */ -int camel_mh_summary_sync(CamelMhSummary * mhs, int expunge, CamelFolderChangeInfo *changes, CamelException *ex) -{ - int count, i; - CamelMessageInfo *info; - char *name; - - printf("summary_sync(expunge=%s)\n", expunge?"true":"false"); - - if (mhs->index) { - ibex_save(mhs->index); - } - if (!expunge) - return 0; - - count = camel_folder_summary_count((CamelFolderSummary *)mhs); - for (i=count-1;i>=0;i--) { - info = camel_folder_summary_index((CamelFolderSummary *)mhs, i); - if (info && info->flags & CAMEL_MESSAGE_DELETED) { - name = g_strdup_printf("%s/%s", mhs->mh_path, info->uid); - d(printf("deleting %s\n", name)); - if (unlink(name) == 0 || errno==ENOENT) { - camel_folder_change_info_remove_uid(changes, info->uid); - camel_folder_summary_remove((CamelFolderSummary *)mhs, info); - } - } - } - return 0; -} - diff --git a/camel/providers/mh/camel-mh-summary.h b/camel/providers/mh/camel-mh-summary.h deleted file mode 100644 index 81aa91b418..0000000000 --- a/camel/providers/mh/camel-mh-summary.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code 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 the GNU Library 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 Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _CAMEL_MH_SUMMARY_H -#define _CAMEL_MH_SUMMARY_H - -#include <camel/camel-folder-summary.h> -#include <camel/camel-folder.h> -#include <camel/camel-exception.h> -#include <libibex/ibex.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 IS_CAMEL_MH_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_mh_summary_get_type ()) - -typedef struct _CamelMhSummary CamelMhSummary; -typedef struct _CamelMhSummaryClass CamelMhSummaryClass; - -struct _CamelMhSummary { - CamelFolderSummary parent; - struct _CamelMhSummaryPrivate *priv; - - char *mh_path; - ibex *index; -}; - -struct _CamelMhSummaryClass { - CamelFolderSummaryClass parent_class; - - /* virtual methods */ - - /* signals */ -}; - -CamelType camel_mh_summary_get_type (void); -CamelMhSummary *camel_mh_summary_new (const char *filename, const char *mhdir, ibex *index); - -/* methods */ -int camel_mh_summary_load(CamelMhSummary * mhs, int forceindex); -int camel_mh_summary_check(CamelMhSummary * mhs, int forceindex); -int camel_mh_summary_add(CamelMhSummary * mhs, const char *name, int forceindex); -int camel_mh_summary_sync(CamelMhSummary * mhs, int expunge, CamelFolderChangeInfo *changes, CamelException *ex); - -#endif /* ! _CAMEL_MH_SUMMARY_H */ - diff --git a/camel/providers/mh/libcamelmh.urls b/camel/providers/mh/libcamelmh.urls deleted file mode 100644 index 372daaa98f..0000000000 --- a/camel/providers/mh/libcamelmh.urls +++ /dev/null @@ -1 +0,0 @@ -mh diff --git a/camel/providers/nntp/.cvsignore b/camel/providers/nntp/.cvsignore deleted file mode 100644 index 1f5b9d35fb..0000000000 --- a/camel/providers/nntp/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la -test-newsrc diff --git a/camel/providers/nntp/Makefile.am b/camel/providers/nntp/Makefile.am deleted file mode 100644 index 4b686735e3..0000000000 --- a/camel/providers/nntp/Makefile.am +++ /dev/null @@ -1,53 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelnntpincludedir = $(includedir)/camel - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelnntp.la -provider_DATA = libcamelnntp.urls - -INCLUDES = -I../.. \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/libibex \ - -I$(top_srcdir)/e-util \ - -I$(top_srcdir) \ - -I$(includedir) \ - $(GTK_INCLUDEDIR) \ - -DG_LOG_DOMAIN=\"camel-nntp-provider\" - -libcamelnntp_la_SOURCES = \ - camel-nntp-auth.c \ - camel-nntp-folder.c \ - camel-nntp-grouplist.c \ - camel-nntp-newsrc.c \ - camel-nntp-provider.c \ - camel-nntp-store.c \ - camel-nntp-utils.c - -libcamelnntpinclude_HEADERS = \ - camel-nntp-auth.h \ - camel-nntp-folder.h \ - camel-nntp-grouplist.h \ - camel-nntp-newsrc.h \ - camel-nntp-resp-codes.h \ - camel-nntp-store.h \ - camel-nntp-types.h \ - camel-nntp-utils.h - -libcamelnntp_la_LDFLAGS = -version-info 0:0:0 - -EXTRA_DIST = libcamelnntp.urls - -#noinst_PROGRAMS = test-newsrc - -#LDADD = \ - #$(top_builddir)/camel/libcamel.la \ - #$(top_builddir)/e-util/libeutil.la \ - #$(top_builddir)/libibex/libibex.la \ - #$(GNOME_LIBDIR) \ - #$(GNOMEUI_LIBS) $(INTLLIBS) $(EXTRA_GNOME_LIBS) -# $(BONOBO_LIBS) - -#test_newsrc_LDADD = libcamelnntp.la $(LDADD) diff --git a/camel/providers/nntp/camel-nntp-auth.c b/camel/providers/nntp/camel-nntp-auth.c deleted file mode 100644 index 1f1e6ab2d8..0000000000 --- a/camel/providers/nntp/camel-nntp-auth.c +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-auth.c : authentication for nntp */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. <toshok@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#include <camel-nntp-auth.h> -#include <camel-nntp-store.h> -#include <camel-nntp-resp-codes.h> -#include <camel-exception.h> -#include <camel-session.h> - -int -camel_nntp_auth_authenticate (CamelNNTPStore *store, CamelException *ex) -{ - CamelService *service = CAMEL_SERVICE (store); - CamelSession *session = camel_service_get_session (service); - int resp; - - if (!service->url->authmech && !service->url->passwd) { - gchar *prompt; - - prompt = g_strdup_printf (_("Please enter the NNTP password for %s@%s"), - service->url->user, service->url->host); - service->url->passwd = - camel_session_query_authenticator (session, - CAMEL_AUTHENTICATOR_ASK, prompt, - TRUE, service, "password", ex); - g_free (prompt); - - if (!service->url->passwd) { - camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, - "You didn\'t enter a password."); - resp = 666; - goto done; - } - } - - /* first send username */ - resp = camel_nntp_command (store, ex, NULL, "AUTHINFO USER %s", service->url->user); - - if (resp == NNTP_AUTH_REJECTED) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Server rejected username")); - goto done; - - } - else if (resp != NNTP_AUTH_CONTINUE) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Failed to send username to server")); - goto done; - } - - /* then send the username if the server asks for it */ - resp = camel_nntp_command (store, ex, NULL, "AUTHINFO PASS %s", service->url->passwd); - - if (resp == NNTP_AUTH_REJECTED) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Server rejected username/password")); - goto done; - } - - done: - - if (service->url->passwd) { - /* let's be paranoid */ - memset (service->url->passwd, 0, strlen (service->url->passwd)); - g_free (service->url->passwd); - service->url->passwd = NULL; - } - return resp; -} diff --git a/camel/providers/nntp/camel-nntp-auth.h b/camel/providers/nntp/camel-nntp-auth.h deleted file mode 100644 index 2708d9d335..0000000000 --- a/camel/providers/nntp/camel-nntp-auth.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-auth.h : authentication for nntp */ - -/* - * - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 1999 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_NNTP_AUTH_H -#define CAMEL_NNTP_AUTH_H 1 - -#include <camel-nntp-store.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -int camel_nntp_auth_authenticate (CamelNNTPStore *store, CamelException *ex); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_NNTP_AUTH_H */ diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c deleted file mode 100644 index e4d53d779f..0000000000 --- a/camel/providers/nntp/camel-nntp-folder.c +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-folder.c : Abstract class for an email folder */ - -/* - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 2000 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#include <config.h> - -#include <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-folder-summary.h" -#include "camel-nntp-resp-codes.h" -#include "camel-nntp-store.h" -#include "camel-nntp-folder.h" -#include "camel-nntp-store.h" -#include "camel-nntp-utils.h" - -#include "string-utils.h" -#include "camel-stream-mem.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-folder-summary.h" - -#include "camel-exception.h" - -static CamelFolderClass *parent_class=NULL; - -/* Returns the class for a CamelNNTPFolder */ -#define CNNTPF_CLASS(so) CAMEL_NNTP_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CNNTPS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - - -static void -nntp_folder_sync (CamelFolder *folder, gboolean expunge, - CamelException *ex) -{ - CamelNNTPStore *store; - - camel_folder_summary_save (CAMEL_NNTP_FOLDER(folder)->summary); - - store = CAMEL_NNTP_STORE (camel_folder_get_parent_store (folder)); - - if (store->newsrc) - camel_nntp_newsrc_write (store->newsrc); -} - -static gint -nntp_folder_get_message_count (CamelFolder *folder) -{ - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER(folder); - - g_assert (folder); - g_assert (nntp_folder->summary); - - return camel_folder_summary_count(nntp_folder->summary); -} - -static guint32 -nntp_folder_get_message_flags (CamelFolder *folder, const char *uid) -{ - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); - CamelMessageInfo *info = camel_folder_summary_uid (nntp_folder->summary, uid); - - return info->flags; -} - -static void -nntp_folder_set_message_flags (CamelFolder *folder, const char *uid, - guint32 flags, guint32 set) -{ - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); - CamelMessageInfo *info = camel_folder_summary_uid (nntp_folder->summary, uid); - - info->flags = set; - - if (set & CAMEL_MESSAGE_SEEN) { - int article_num; - CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (camel_folder_get_parent_store (folder)); - - sscanf (uid, "%d", &article_num); - - camel_nntp_newsrc_mark_article_read (nntp_store->newsrc, - folder->name, - article_num); - } - - camel_folder_summary_touch (nntp_folder->summary); -} - -static CamelMimeMessage * -nntp_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex) -{ - CamelStream *message_stream = NULL; - CamelMimeMessage *message = NULL; - CamelStore *parent_store; - char *buf; - int buf_len; - int buf_alloc; - int status; - gboolean done; - char *message_id; - - /* get the parent store */ - parent_store = camel_folder_get_parent_store (folder); - - message_id = strchr (uid, ',') + 1; - status = camel_nntp_command (CAMEL_NNTP_STORE( parent_store ), ex, NULL, "ARTICLE %s", message_id); - - /* if the message_id was not found, raise an exception and return */ - if (status == NNTP_NO_SUCH_ARTICLE) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("Message %s not found."), - message_id); - return NULL; - } - else if (status != NNTP_ARTICLE_FOLLOWS) { - /* XXX */ - g_warning ("weird nntp error %d\n", status); - return NULL; - } - - /* XXX ick ick ick. read the entire message into a buffer and - then create a stream_mem for it. */ - buf_alloc = 2048; - buf_len = 0; - buf = g_malloc(buf_alloc); - done = FALSE; - - buf[0] = 0; - - while (!done) { - int line_length; - char *line; - - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (parent_store), &line, ex) < 0) { - g_warning ("recv_line failed while building message\n"); - break; - } - - /* XXX check exception */ - - line_length = strlen ( line ); - - if (!strcmp(line, ".")) { - done = TRUE; - g_free (line); - } - else { - if (buf_len + line_length > buf_alloc) { - buf_alloc *= 2; - buf = g_realloc (buf, buf_alloc); - } - strcat(buf, line); - strcat(buf, "\n"); - buf_len += strlen(line) + 1; - g_free (line); - } - } - - /* create a stream bound to the message */ - message_stream = camel_stream_mem_new_with_buffer(buf, buf_len); - - message = camel_mime_message_new (); - camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER(message), message_stream); - - camel_object_unref (CAMEL_OBJECT (message_stream)); - -#if 0 - gtk_signal_connect (CAMEL_OBJECT (message), "message_changed", message_changed, folder); -#endif - - g_free (buf); - - return message; -} - -static GPtrArray * -nntp_folder_get_uids (CamelFolder *folder) -{ - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); - GPtrArray *out; - CamelMessageInfo *message_info; - int i; - int count = camel_folder_summary_count (nntp_folder->summary); - - out = g_ptr_array_new (); - g_ptr_array_set_size (out, count); - - for (i = 0; i < count; i++) { - message_info = camel_folder_summary_index (nntp_folder->summary, i); - out->pdata[i] = g_strdup (message_info->uid); - } - - return out; -} - -static GPtrArray * -nntp_folder_get_summary (CamelFolder *folder) -{ - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); - - return nntp_folder->summary->messages; -} - -static GPtrArray* -nntp_folder_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex) -{ - g_assert (0); - return NULL; -} - -static const CamelMessageInfo* -nntp_folder_get_message_info (CamelFolder *folder, const char *uid) -{ - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); - - return camel_folder_summary_uid (nntp_folder->summary, uid); -} - -static void -nntp_folder_finalize (CamelObject *object) -{ - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (object); - - g_free (nntp_folder->summary_file_path); -} - -static void -camel_nntp_folder_class_init (CamelNNTPFolderClass *camel_nntp_folder_class) -{ - CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_nntp_folder_class); - - parent_class = CAMEL_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_folder_get_type ())); - - /* virtual method definition */ - - /* virtual method overload */ - camel_folder_class->sync = nntp_folder_sync; - camel_folder_class->get_message_count = nntp_folder_get_message_count; - camel_folder_class->set_message_flags = nntp_folder_set_message_flags; - camel_folder_class->get_message_flags = nntp_folder_get_message_flags; - camel_folder_class->get_message = nntp_folder_get_message; - camel_folder_class->get_uids = nntp_folder_get_uids; - camel_folder_class->free_uids = camel_folder_free_deep; - camel_folder_class->get_summary = nntp_folder_get_summary; - camel_folder_class->free_summary = camel_folder_free_nop; - camel_folder_class->search_by_expression = nntp_folder_search_by_expression; - camel_folder_class->get_message_info = nntp_folder_get_message_info; -} - -CamelType -camel_nntp_folder_get_type (void) -{ - static CamelType camel_nntp_folder_type = CAMEL_INVALID_TYPE; - - if (camel_nntp_folder_type == CAMEL_INVALID_TYPE) { - camel_nntp_folder_type = camel_type_register (CAMEL_FOLDER_TYPE, "CamelNNTPFolder", - sizeof (CamelNNTPFolder), - sizeof (CamelNNTPFolderClass), - (CamelObjectClassInitFunc) camel_nntp_folder_class_init, - NULL, - (CamelObjectInitFunc) NULL, - (CamelObjectFinalizeFunc) nntp_folder_finalize); - } - - return camel_nntp_folder_type; -} - -CamelFolder * -camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelException *ex) -{ - CamelFolder *folder = CAMEL_FOLDER (camel_object_new (CAMEL_NNTP_FOLDER_TYPE)); - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); - const gchar *root_dir_path; - - camel_folder_construct (folder, parent, folder_name, folder_name); - folder->has_summary_capability = TRUE; - - root_dir_path = camel_nntp_store_get_toplevel_dir (CAMEL_NNTP_STORE(folder->parent_store)); - nntp_folder->summary_file_path = g_strdup_printf ("%s/%s-ev-summary", - root_dir_path, - folder->name); - - nntp_folder->summary = camel_folder_summary_new (); - camel_folder_summary_set_filename (nntp_folder->summary, - nntp_folder->summary_file_path); - - if (-1 == camel_folder_summary_load (nntp_folder->summary)) { - /* Bad or nonexistant summary file */ - camel_nntp_get_headers (CAMEL_FOLDER( folder )->parent_store, - nntp_folder, ex); - if (camel_exception_get_id (ex)) { - camel_object_unref (CAMEL_OBJECT (folder)); - return NULL; - } - - /* XXX check return value */ - camel_folder_summary_save (nntp_folder->summary); - } - - return folder; -} diff --git a/camel/providers/nntp/camel-nntp-folder.h b/camel/providers/nntp/camel-nntp-folder.h deleted file mode 100644 index eed946fb5c..0000000000 --- a/camel/providers/nntp/camel-nntp-folder.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-folder.h : NNTP group (folder) support. */ - -/* - * - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 2000 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_NNTP_FOLDER_H -#define CAMEL_NNTP_FOLDER_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-folder.h" - -/* #include "camel-store.h" */ - -#define CAMEL_NNTP_FOLDER_TYPE (camel_nntp_folder_get_type ()) -#define CAMEL_NNTP_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_NNTP_FOLDER_TYPE, CamelNNTPFolder)) -#define CAMEL_NNTP_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_NNTP_FOLDER_TYPE, CamelNNTPFolderClass)) -#define IS_CAMEL_NNTP_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_NNTP_FOLDER_TYPE)) - - -typedef struct { - CamelFolder parent_object; - - gchar *summary_file_path; /* contains the messages summary */ - CamelFolderSummary *summary; -} CamelNNTPFolder; - - - -typedef struct { - CamelFolderClass parent_class; - - /* Virtual methods */ - -} CamelNNTPFolderClass; - - -/* public methods */ - -/* Standard Camel function */ -CamelType camel_nntp_folder_get_type (void); - -CamelFolder *camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelException *ex); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_NNTP_FOLDER_H */ diff --git a/camel/providers/nntp/camel-nntp-grouplist.c b/camel/providers/nntp/camel-nntp-grouplist.c deleted file mode 100644 index d7ee85d182..0000000000 --- a/camel/providers/nntp/camel-nntp-grouplist.c +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-grouplist.c : getting/updating the list of newsgroups on the server. */ - -/* - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 2000 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include <errno.h> -#include <string.h> - -#include "camel-exception.h" -#include "camel-nntp-grouplist.h" -#include "camel-nntp-resp-codes.h" - -static CamelNNTPGroupList * -camel_nntp_get_grouplist_from_server (CamelNNTPStore *store, CamelException *ex) -{ - int status; - gboolean done = FALSE; - CamelNNTPGroupList *list; - - status = camel_nntp_command (store, ex, NULL, - "LIST"); - - if (status != NNTP_LIST_FOLLOWS) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not get group list from server.")); - return NULL; - } - - list = g_new0 (CamelNNTPGroupList, 1); - list->time = time (NULL); - - while (!done) { - char *line; - - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, ex) < 0) - return list; - - if (*line == '.') { - done = TRUE; - } - else { - CamelNNTPGroupListEntry *entry = g_new (CamelNNTPGroupListEntry, 1); - char **split_line = g_strsplit (line, " ", 4); - - entry->group_name = g_strdup (split_line[0]); - entry->high = atoi (split_line[1]); - entry->low = atoi (split_line[2]); - - g_strfreev (split_line); - - list->group_list = g_list_append (list->group_list, entry); - } - } - - return list; -} - -static CamelNNTPGroupList* -camel_nntp_get_grouplist_from_file (CamelNNTPStore *store, CamelException *ex) -{ - gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(store)); - gchar *grouplist_file = g_strdup_printf ("%s/grouplist", root_dir); - CamelNNTPGroupList *list; - FILE *fp; - char buf[300]; - unsigned long time; - - g_free (root_dir); - fp = fopen (grouplist_file, "r"); - g_free (grouplist_file); - - if (fp == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Unable to load grouplist file for %s: %s"), - CAMEL_SERVICE(store)->url->host, - strerror(errno)); - return NULL; - } - - /* read the time */ - if (!fgets (buf, 300, fp)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Unable to load grouplist file for %s: %s"), - CAMEL_SERVICE(store)->url->host, - strerror(errno)); - fclose (fp); - return NULL; - } - - - list = g_new0 (CamelNNTPGroupList, 1); - list->store = store; - sscanf (buf, "%lu", &time); - list->time = time; - - while (fgets (buf, 300, fp)) { - CamelNNTPGroupListEntry *entry = g_new (CamelNNTPGroupListEntry, 1); - char **split_line = g_strsplit (buf, " ", 4); - - entry->group_name = g_strdup (split_line[0]); - entry->high = atoi (split_line[1]); - entry->low = atoi (split_line[2]); - - g_strfreev (split_line); - - list->group_list = g_list_append (list->group_list, entry); - } - - fclose (fp); - - return list; -} - -static void -save_entry (CamelNNTPGroupListEntry *entry, FILE *fp) -{ - fprintf (fp, "%s %d %d\n", entry->group_name, entry->low, entry->high); -} - -void -camel_nntp_grouplist_save (CamelNNTPGroupList *group_list, CamelException *ex) -{ - FILE *fp; - gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(group_list->store)); - gchar *grouplist_file = g_strdup_printf ("%s/grouplist", root_dir); - - g_free (root_dir); - fp = fopen (grouplist_file, "w"); - g_free (grouplist_file); - - if (fp == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Unable to save grouplist file for %s: %s"), - CAMEL_SERVICE(group_list->store)->url->host, - strerror(errno)); - return; - } - - fprintf (fp, "%lu\n", (long)group_list->time); - - g_list_foreach (group_list->group_list, (GFunc)save_entry, fp); - - fclose (fp); -} - -static void -free_entry (CamelNNTPGroupListEntry *entry, void *data) -{ - g_free (entry->group_name); - g_free (entry); -} - -void -camel_nntp_grouplist_free (CamelNNTPGroupList *group_list) -{ - g_return_if_fail (group_list); - - g_list_foreach (group_list->group_list, (GFunc)free_entry, NULL); - - g_free (group_list); -} - -CamelNNTPGroupList* -camel_nntp_grouplist_fetch (CamelNNTPStore *store, CamelException *ex) -{ - CamelNNTPGroupList *list; - - list = camel_nntp_get_grouplist_from_file (store, ex); - - printf ("camel_nntp_get_grouplist_from_file returned %p\n", list); - - if (!list) { - camel_exception_clear (ex); - - list = camel_nntp_get_grouplist_from_server (store, ex); - - if (!list) { - camel_nntp_grouplist_free (list); - } - else { - list->store = store; - camel_nntp_grouplist_save (list, ex); - return list; - } - } - - return list; -} - -gint -camel_nntp_grouplist_update (CamelNNTPGroupList *group_list, CamelException *ex) -{ - return 0; -} diff --git a/camel/providers/nntp/camel-nntp-grouplist.h b/camel/providers/nntp/camel-nntp-grouplist.h deleted file mode 100644 index 67c74d5dc2..0000000000 --- a/camel/providers/nntp/camel-nntp-grouplist.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-grouplist.h : getting/updating the list of newsgroups on the server. */ - -/* - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 2000 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_NNTP_GROUPLIST_H -#define CAMEL_NNTP_GROUPLIST_H 1 - -#include <time.h> -#include "camel-nntp-store.h" - -struct CamelNNTPGroupListEntry { - char *group_name; - guint32 low; - guint32 high; - guint32 flags; -}; - -struct CamelNNTPGroupList { - CamelNNTPStore *store; - time_t time; - GList *group_list; -}; - -CamelNNTPGroupList* camel_nntp_grouplist_fetch (CamelNNTPStore *store, CamelException *ex); -gint camel_nntp_grouplist_update (CamelNNTPGroupList *group_list, CamelException *ex); -void camel_nntp_grouplist_save (CamelNNTPGroupList *group_list, CamelException *ex); -void camel_nntp_grouplist_free (CamelNNTPGroupList *group_list); - -#endif /* CAMEL_NNTP_GROUPLIST_H */ diff --git a/camel/providers/nntp/camel-nntp-newsrc.c b/camel/providers/nntp/camel-nntp-newsrc.c deleted file mode 100644 index b474dd3a40..0000000000 --- a/camel/providers/nntp/camel-nntp-newsrc.c +++ /dev/null @@ -1,573 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-newsrc.c - .newsrc parsing/regurgitating code */ -/* - * - * Copyright (C) 2000 Helix Code, Inc. <toshok@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <glib.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include "camel-nntp-newsrc.h" -#include <camel/camel-folder-summary.h> - -typedef struct { - guint low; - guint high; -} ArticleRange; - -typedef struct { - char *name; - GArray *ranges; - gboolean subscribed; -} NewsrcGroup; - -struct CamelNNTPNewsrc { - gchar *filename; - GHashTable *groups; - gboolean dirty; -} ; - -static NewsrcGroup * -camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, const char *group_name, gboolean subscribed) -{ - NewsrcGroup *new_group = g_malloc(sizeof(NewsrcGroup)); - - new_group->name = g_strdup(group_name); - new_group->subscribed = subscribed; - new_group->ranges = g_array_new (FALSE, FALSE, sizeof (ArticleRange)); - - g_hash_table_insert (newsrc->groups, new_group->name, new_group); - - newsrc->dirty = TRUE; - - return new_group; -} - -static int -camel_nntp_newsrc_group_get_highest_article_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *group) -{ - if (!group || group->ranges->len == 0) - return 0; - - return g_array_index(group->ranges, ArticleRange, group->ranges->len - 1).high; -} - -static int -camel_nntp_newsrc_group_get_num_articles_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *group) -{ - int i; - int count = 0; - - if (group == NULL) - return 0; - - for (i = 0; i < group->ranges->len; i ++) - count += (g_array_index(group->ranges, ArticleRange, i).high - - g_array_index(group->ranges, ArticleRange, i).low) + 1; - - return count; -} - - -static void -camel_nntp_newsrc_group_mark_range_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *group, long low, long high) -{ - int i; - - if (group->ranges->len == 1 - && g_array_index (group->ranges, ArticleRange, 0).low == 0 - && g_array_index (group->ranges, ArticleRange, 0).high == 0) { - g_array_index (group->ranges, ArticleRange, 0).low = low; - g_array_index (group->ranges, ArticleRange, 0).high = high; - - newsrc->dirty = TRUE; - } - else { - ArticleRange tmp_range; - - for (i = 0; i < group->ranges->len; i ++) { - guint range_low = g_array_index (group->ranges, ArticleRange, i).low; - guint range_high = g_array_index (group->ranges, ArticleRange, i).high; - - /* if it's already part of a range, return immediately. */ - if (low >= range_low && - low <= range_high && - high >= range_low && - high <= range_high) { - return; - } - /* if we have a new lower bound for this range, set it. */ - else if (low <= range_low - && high >= range_low - && high <= range_high) { - g_array_index (group->ranges, ArticleRange, i).low = low; - newsrc->dirty = TRUE; - return; - } - /* if we have a new upper bound for this range, set it. */ - else if (high >= range_high - && low >= range_low - && low <= range_high) { - g_array_index (group->ranges, ArticleRange, i).high = high; - newsrc->dirty = TRUE; - return; - } - /* if we would be inserting another range that - starts one index higher than an existing - one, make the upper value of the existing - range the upper value of the new one. */ - else if (low == range_high + 1) { - g_array_index (group->ranges, ArticleRange, i).high = high; - newsrc->dirty = TRUE; - return; - } - /* if we would be inserting another range that - ends one index lower than an existing one, - group the existing range by setting its low - to the new low */ - else if (high == range_low - 1) { - g_array_index (group->ranges, ArticleRange, i).low = low; - newsrc->dirty = TRUE; - return; - } - /* if the range lies entirely outside another - range, doesn't coincide with it's - endpoints, and has lower values, insert it - into the middle of the list. */ - else if (low < range_low - && high < range_low) { - tmp_range.low = low; - tmp_range.high = high; - - group->ranges = g_array_insert_val (group->ranges, i, tmp_range); - newsrc->dirty = TRUE; - - return; - } - } - - /* if we made it here, the range needs to go at the end */ - tmp_range.low = low; - tmp_range.high = high; - group->ranges = g_array_append_val (group->ranges, tmp_range); - newsrc->dirty = TRUE; - } -} - -int -camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, const char *group_name) -{ - NewsrcGroup *group; - - group = g_hash_table_lookup (newsrc->groups, group_name); - - return camel_nntp_newsrc_group_get_highest_article_read (newsrc, group); -} - -int -camel_nntp_newsrc_get_num_articles_read (CamelNNTPNewsrc *newsrc, const char *group_name) -{ - NewsrcGroup *group; - - group = g_hash_table_lookup (newsrc->groups, group_name); - - return camel_nntp_newsrc_group_get_num_articles_read (newsrc, group); -} - -void -camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, const char *group_name, int num) -{ - camel_nntp_newsrc_mark_range_read (newsrc, group_name, num, num); -} - -void -camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, const char *group_name, long low, long high) -{ - NewsrcGroup *group; - - /* swap them if they're in the wrong order. */ - if (low > high) { - long tmp; - - tmp = high; - high = low; - low = tmp; - } - - group = g_hash_table_lookup (newsrc->groups, group_name); - - camel_nntp_newsrc_group_mark_range_read (newsrc, group, low, high); -} - -gboolean -camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, const char *group_name, long num) -{ - int i; - NewsrcGroup *group; - - group = g_hash_table_lookup (newsrc->groups, group_name); - - for (i = 0; i < group->ranges->len; i++) { - if (num >= g_array_index (group->ranges, ArticleRange, i).low && - num <= g_array_index (group->ranges, ArticleRange, i).high) { - return TRUE; - } - } - - return FALSE; -} - -gboolean -camel_nntp_newsrc_group_is_subscribed (CamelNNTPNewsrc *newsrc, const char *group_name) -{ - NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name); - - if (group) { - return group->subscribed; - } - else { - return FALSE; - } -} - -void -camel_nntp_newsrc_subscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name) -{ - NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name); - - if (group) { - if (!group->subscribed) - newsrc->dirty = TRUE; - group->subscribed = TRUE; - } - else { - camel_nntp_newsrc_group_add (newsrc, group_name, TRUE); - } -} - -void -camel_nntp_newsrc_unsubscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name) -{ - NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name); - - if (group) { - if (group->subscribed) - newsrc->dirty = TRUE; - group->subscribed = FALSE; - } - else { - camel_nntp_newsrc_group_add (newsrc, group_name, FALSE); - } -} - -struct newsrc_ptr_array { - GPtrArray *ptr_array; - gboolean subscribed_only; -}; - -static void -get_group_foreach (char *group_name, NewsrcGroup *group, struct newsrc_ptr_array *npa) -{ - if (group->subscribed || !npa->subscribed_only) { - g_ptr_array_add (npa->ptr_array, group_name); - } -} - -GPtrArray * -camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc) -{ - struct newsrc_ptr_array npa; - - g_return_val_if_fail (newsrc, NULL); - - npa.ptr_array = g_ptr_array_new(); - npa.subscribed_only = TRUE; - - g_hash_table_foreach (newsrc->groups, - (GHFunc)get_group_foreach, &npa); - - return npa.ptr_array; -} - -GPtrArray * -camel_nntp_newsrc_get_all_group_names (CamelNNTPNewsrc *newsrc) -{ - struct newsrc_ptr_array npa; - - g_return_val_if_fail (newsrc, NULL); - - npa.ptr_array = g_ptr_array_new(); - npa.subscribed_only = FALSE; - - g_hash_table_foreach (newsrc->groups, - (GHFunc)get_group_foreach, &npa); - - return npa.ptr_array; -} - -void -camel_nntp_newsrc_free_group_names (CamelNNTPNewsrc *newsrc, GPtrArray *group_names) -{ - g_ptr_array_free (group_names, TRUE); -} - -struct newsrc_fp { - CamelNNTPNewsrc *newsrc; - FILE *fp; -}; - -static void -camel_nntp_newsrc_write_group_line(gpointer key, NewsrcGroup *group, struct newsrc_fp *newsrc_fp) -{ - CamelNNTPNewsrc *newsrc; - FILE *fp; - int i; - - fp = newsrc_fp->fp; - newsrc = newsrc_fp->newsrc; - - fprintf (fp, "%s%c", group->name, group->subscribed ? ':' : '!'); - - if (group->ranges->len == 1 - && g_array_index (group->ranges, ArticleRange, 0).low == 0 - && g_array_index (group->ranges, ArticleRange, 0).high == 0) { - fprintf (fp, "\n"); - - return; /* special case since our parsing code will insert this - bogus range if there were no read articles. The code - to add a range is smart enough to remove this one if we - ever mark an article read, but we still need to deal with - it if that code doesn't get hit. */ - } - - fprintf (fp, " "); - - for (i = 0; i < group->ranges->len; i ++) { - char range_buffer[100]; - guint low = g_array_index (group->ranges, ArticleRange, i).low; - guint high = g_array_index (group->ranges, ArticleRange, i).high; - - if (low == high) - sprintf(range_buffer, "%d", low); - else if (low == high - 1) - sprintf(range_buffer, "%d,%d", low, high); - else - sprintf(range_buffer, "%d-%d", low, high); - - if (i != group->ranges->len - 1) - strcat(range_buffer, ","); - - fprintf (fp, range_buffer); - } - - fprintf (fp, "\n"); -} - -void -camel_nntp_newsrc_write_to_file(CamelNNTPNewsrc *newsrc, FILE *fp) -{ - struct newsrc_fp newsrc_fp; - - g_return_if_fail (newsrc); - - newsrc_fp.newsrc = newsrc; - newsrc_fp.fp = fp; - - g_hash_table_foreach (newsrc->groups, - (GHFunc)camel_nntp_newsrc_write_group_line, - &newsrc_fp); -} - -void -camel_nntp_newsrc_write(CamelNNTPNewsrc *newsrc) -{ - FILE *fp; - - g_return_if_fail (newsrc); - - if (!newsrc->dirty) - return; - - if ((fp = fopen(newsrc->filename, "w")) == NULL) { - g_warning ("Couldn't open newsrc file '%s'.\n", newsrc->filename); - return; - } - - camel_nntp_newsrc_write_to_file(newsrc, fp); - - newsrc->dirty = FALSE; - - fclose(fp); -} - -static void -camel_nntp_newsrc_parse_line(CamelNNTPNewsrc *newsrc, char *line) -{ - char *p, *comma, *dash; - gboolean is_subscribed; - NewsrcGroup *group; - - p = strchr(line, ':'); - - if (p) { - is_subscribed = TRUE; - } - else { - p = strchr(line, '!'); - if (p) - is_subscribed = FALSE; - else - return; /* bogus line. */ - } - - *p++ = '\0'; - - group = camel_nntp_newsrc_group_add (newsrc, line, is_subscribed); - - do { - guint high, low; - - comma = strchr(p, ','); - - if (comma) - *comma = '\0'; - - dash = strchr(p, '-'); - - if (!dash) { /* there wasn't a dash. must be just one number */ - high = low = atol(p); - } - else { /* there was a dash. */ - *dash = '\0'; - low = atol(p); - *dash = '-'; - p = dash + 1; - high = atol(p); - } - - camel_nntp_newsrc_group_mark_range_read (newsrc, group, low, high); - - if (comma) { - *comma = ','; - p = comma + 1; - } - - } while(comma); -} - -static char* -get_line (char *buf, char **p) -{ - char *l; - char *line; - - g_assert (*p == NULL || **p == '\n' || **p == '\0'); - - if (*p == NULL) { - *p = buf; - - if (**p == '\0') - return NULL; - } - else { - if (**p == '\0') - return NULL; - - (*p) ++; - - /* if we just incremented to the end of the buffer, return NULL */ - if (**p == '\0') - return NULL; - } - - l = strchr (*p, '\n'); - if (l) { - *l = '\0'; - line = g_strdup (*p); - *l = '\n'; - *p = l; - } - else { - /* we're at the last line (which isn't terminated by a \n, btw) */ - line = g_strdup (*p); - (*p) += strlen (*p); - } - - return line; -} - -CamelNNTPNewsrc * -camel_nntp_newsrc_read_for_server (const char *server) -{ - int fd; - char buf[1024]; - char *file_contents, *line, *p; - char *filename; - CamelNNTPNewsrc *newsrc; - int newsrc_len; - int len_read = 0; - struct stat sb; - - filename = g_strdup_printf ("%s/.newsrc-%s", g_get_home_dir(), server); - - newsrc = g_new0(CamelNNTPNewsrc, 1); - newsrc->filename = filename; - newsrc->groups = g_hash_table_new (g_str_hash, g_str_equal); - - if ((fd = open(filename, O_RDONLY)) == -1) { - g_warning ("~/.newsrc-%s not present.\n", server); - return newsrc; - } - - if (fstat (fd, &sb) == -1) { - g_warning ("failed fstat on ~/.newsrc-%s: %s\n", server, strerror(errno)); - return newsrc; - } - newsrc_len = sb.st_size; - - file_contents = g_malloc (newsrc_len + 1); - - while (len_read < newsrc_len) { - int c = read (fd, buf, sizeof (buf)); - - if (c == -1) - break; - - memcpy (&file_contents[len_read], buf, c); - len_read += c; - } - file_contents [len_read] = 0; - - p = NULL; - while ((line = get_line (file_contents, &p))) { - camel_nntp_newsrc_parse_line(newsrc, line); - g_free (line); - } - - close (fd); - g_free (file_contents); - - return newsrc; -} diff --git a/camel/providers/nntp/camel-nntp-newsrc.h b/camel/providers/nntp/camel-nntp-newsrc.h deleted file mode 100644 index 652e3edbce..0000000000 --- a/camel/providers/nntp/camel-nntp-newsrc.h +++ /dev/null @@ -1,34 +0,0 @@ - -#ifndef _CAMEL_NNTP_NEWSRC_H_ -#define _CAMEL_NNTP_NEWSRC_H_ - -#include <stdio.h> -#include "glib.h" - -typedef struct CamelNNTPNewsrc CamelNNTPNewsrc; - -int camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, const char *group_name); -int camel_nntp_newsrc_get_num_articles_read (CamelNNTPNewsrc *newsrc, const char *group_name); -void camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, - const char *group_name, int num); -void camel_nntp_newsrc_mark_range_read (CamelNNTPNewsrc *newsrc, - const char *group_name, long low, long high); - -gboolean camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, - const char *group_name, long num); - -gboolean camel_nntp_newsrc_group_is_subscribed (CamelNNTPNewsrc *newsrc, const char *group_name); -void camel_nntp_newsrc_subscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name); -void camel_nntp_newsrc_unsubscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name); - -GPtrArray* camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc); -GPtrArray* camel_nntp_newsrc_get_all_group_names (CamelNNTPNewsrc *newsrc); -void camel_nntp_newsrc_free_group_names (CamelNNTPNewsrc *newsrc, GPtrArray *group_names); - -void camel_nntp_newsrc_write_to_file (CamelNNTPNewsrc *newsrc, FILE *fp); -void camel_nntp_newsrc_write (CamelNNTPNewsrc *newsrc); -CamelNNTPNewsrc *camel_nntp_newsrc_read_for_server (const char *server); - -#endif /* _CAMEL_NNTP_NEWSRC_H_ */ - - diff --git a/camel/providers/nntp/camel-nntp-provider.c b/camel/providers/nntp/camel-nntp-provider.c deleted file mode 100644 index 76ac521ec6..0000000000 --- a/camel/providers/nntp/camel-nntp-provider.c +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-provider.c: nntp provider registration code */ - -/* - * Authors : - * Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-nntp-store.h" -#include "camel-provider.h" -#include "camel-session.h" - -static void add_hash (guint *hash, char *s); -static guint nntp_url_hash (gconstpointer key); -static gint check_equal (char *s1, char *s2); -static gint nntp_url_equal (gconstpointer a, gconstpointer b); - -static CamelProvider news_provider = { - "nntp", - N_("USENET news"), - - N_("This is a provider for reading from and posting to" - "USENET newsgroups."), - - "news", - - CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_STORAGE, - - CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_USER | - CAMEL_URL_ALLOW_PASSWORD | CAMEL_URL_ALLOW_AUTH, - - { 0, 0 }, - - NULL -}; - -void -camel_provider_module_init (CamelSession *session) -{ - news_provider.object_types[CAMEL_PROVIDER_STORE] = - camel_nntp_store_get_type(); - - news_provider.service_cache = g_hash_table_new (nntp_url_hash, nntp_url_equal); - - camel_session_register_provider (session, &news_provider); -} - -static void -add_hash (guint *hash, char *s) -{ - if (s) - *hash ^= g_str_hash(s); -} - -static guint -nntp_url_hash (gconstpointer key) -{ - const CamelURL *u = (CamelURL *)key; - guint hash = 0; - - add_hash (&hash, u->user); - add_hash (&hash, u->host); - hash ^= u->port; - - return hash; -} - -static gint -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 gint -nntp_url_equal (gconstpointer a, gconstpointer b) -{ - const CamelURL *u1 = a, *u2 = b; - - return check_equal (u1->user, u2->user) - && check_equal (u1->host, u2->host) - && u1->port == u2->port; -} diff --git a/camel/providers/nntp/camel-nntp-resp-codes.h b/camel/providers/nntp/camel-nntp-resp-codes.h deleted file mode 100644 index 8b9dc8ff6c..0000000000 --- a/camel/providers/nntp/camel-nntp-resp-codes.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-resp-codes.h : #defines for all the response codes we care about */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. <toshok@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_NNTP_RESP_CODES_H -#define CAMEL_NNTP_RESP_CODES_H 1 - -#define CAMEL_NNTP_OK(x) ((x) < 400) -#define CAMEL_NNTP_ERR(x) (!CAMEL_NNTP_OK(x) && (x) < 500) -#define CAMEL_NNTP_FAIL(x) (!CAMEL_NNTP_OK(x) && !CAMEL_NNTP_ERR(x)) - -#define NNTP_GREETING_POSTING_OK 200 -#define NNTP_GREETING_NO_POSTING 201 - -#define NNTP_GROUP_SELECTED 211 -#define NNTP_LIST_FOLLOWS 215 -#define NNTP_ARTICLE_FOLLOWS 220 -#define NNTP_HEAD_FOLLOWS 221 -#define NNTP_DATA_FOLLOWS 224 -#define NNTP_NEW_ARTICLE_LIST_FOLLOWS 230 -#define NNTP_NEW_GROUP_LIST_FOLLOWS 231 - -#define NNTP_NO_SUCH_GROUP 411 -#define NNTP_NO_SUCH_ARTICLE 430 - -/* authentication */ -#define NNTP_AUTH_ACCEPTED 281 -#define NNTP_AUTH_CONTINUE 381 -#define NNTP_AUTH_REQUIRED 480 -#define NNTP_AUTH_REJECTED 482 - -#define NNTP_PROTOCOL_ERROR 666 - -#endif /* CAMEL_NNTP_RESP_CODES_H */ diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c deleted file mode 100644 index ff9e7a989a..0000000000 --- a/camel/providers/nntp/camel-nntp-store.c +++ /dev/null @@ -1,870 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-store.c : class for an nntp store */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. <toshok@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> - -#include <dirent.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "libgnome/libgnome.h" - -#include "camel-nntp-resp-codes.h" -#include "camel-folder-summary.h" -#include "camel-nntp-store.h" -#include "camel-nntp-grouplist.h" -#include "camel-nntp-folder.h" -#include "camel-nntp-auth.h" -#include "camel-exception.h" -#include "camel-url.h" -#include "string-utils.h" - -#include <gal/util/e-util.h> - -#define NNTP_PORT 119 - -#define DUMP_EXTENSIONS - -/* define if you want the subscribe ui to show folders in tree form */ -/* #define INFO_AS_TREE */ - -static CamelRemoteStoreClass *remote_store_class = NULL; - -static CamelServiceClass *service_class = NULL; - -/* Returns the class for a CamelNNTPStore */ -#define CNNTPS_CLASS(so) CAMEL_NNTP_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -#define CNNTPF_CLASS(so) CAMEL_NNTP_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) - -static gboolean ensure_news_dir_exists (CamelNNTPStore *store); - -static void -camel_nntp_store_get_extensions (CamelNNTPStore *store, CamelException *ex) -{ - store->extensions = 0; - - if (camel_nntp_command (store, ex, NULL, "LIST EXTENSIONS") == NNTP_LIST_FOLLOWS) { - gboolean done = FALSE; - CamelException ex; - - camel_exception_init (&ex); - - while (!done) { - char *line; - - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, &ex) < 0) - break; /* XXX */ - - if (*line == '.') { - done = TRUE; - } - else { -#define CHECK_EXT(name,val) if (!strcasecmp (line, (name))) store->extensions |= (val) - - CHECK_EXT ("SEARCH", CAMEL_NNTP_EXT_SEARCH); - CHECK_EXT ("SETGET", CAMEL_NNTP_EXT_SETGET); - CHECK_EXT ("OVER", CAMEL_NNTP_EXT_OVER); - CHECK_EXT ("XPATTEXT", CAMEL_NNTP_EXT_XPATTEXT); - CHECK_EXT ("XACTIVE", CAMEL_NNTP_EXT_XACTIVE); - CHECK_EXT ("LISTMOTD", CAMEL_NNTP_EXT_LISTMOTD); - CHECK_EXT ("LISTSUBSCR", CAMEL_NNTP_EXT_LISTSUBSCR); - CHECK_EXT ("LISTPNAMES", CAMEL_NNTP_EXT_LISTPNAMES); - -#undef CHECK_EXT - } - - g_free (line); - } - } - -#ifdef DUMP_EXTENSIONS - g_print ("NNTP Extensions:"); -#define DUMP_EXT(name,val) if (store->extensions & (val)) g_print (" %s", name); - DUMP_EXT ("SEARCH", CAMEL_NNTP_EXT_SEARCH); - DUMP_EXT ("SETGET", CAMEL_NNTP_EXT_SETGET); - DUMP_EXT ("OVER", CAMEL_NNTP_EXT_OVER); - DUMP_EXT ("XPATTEXT", CAMEL_NNTP_EXT_XPATTEXT); - DUMP_EXT ("XACTIVE", CAMEL_NNTP_EXT_XACTIVE); - DUMP_EXT ("LISTMOTD", CAMEL_NNTP_EXT_LISTMOTD); - DUMP_EXT ("LISTSUBSCR", CAMEL_NNTP_EXT_LISTSUBSCR); - DUMP_EXT ("LISTPNAMES", CAMEL_NNTP_EXT_LISTPNAMES); - g_print ("\n"); -#undef DUMP_EXT -#endif -} - -static void -camel_nntp_store_get_overview_fmt (CamelNNTPStore *store, CamelException *ex) -{ - int status; - int i; - gboolean done = FALSE; - - status = camel_nntp_command (store, ex, NULL, - "LIST OVERVIEW.FMT"); - - if (status != NNTP_LIST_FOLLOWS) { - if (store->extensions & CAMEL_NNTP_EXT_OVER) { - /* if we can't get the overview format, we should - disable OVER support */ - g_warning ("server reported support of OVER but LIST OVERVIEW.FMT failed." - " disabling OVER.\n"); - store->extensions &= ~CAMEL_NNTP_EXT_OVER; - return; - } - } - else { - if (!(store->extensions & CAMEL_NNTP_EXT_OVER)) { - g_warning ("server didn't report support of OVER but LIST OVERVIEW.FMT worked." - " enabling OVER.\n"); - store->extensions |= CAMEL_NNTP_EXT_OVER; - } - } - - /* start at 1 because the article number is always first */ - store->num_overview_fields = 1; - - for (i = 0; i < CAMEL_NNTP_OVER_LAST; i ++) { - store->overview_field [i].index = -1; - } - - while (!done) { - char *line; - - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, ex) < 0) - break; /* XXX */ - - if (*line == '.') { - done = TRUE; - } - else { - CamelNNTPOverField *over_field = NULL; - char *colon = NULL;; - - if (!strncasecmp (line, "From:", 5)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_FROM ]; - over_field->index = store->num_overview_fields; - colon = line + 5; - } - else if (!strncasecmp (line, "Subject:", 7)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_SUBJECT ]; - over_field->index = store->num_overview_fields; - colon = line + 7; - } - else if (!strncasecmp (line, "Date:", 5)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_DATE ]; - over_field->index = store->num_overview_fields; - colon = line + 5; - } - else if (!strncasecmp (line, "Message-ID:", 11)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_MESSAGE_ID ]; - over_field->index = store->num_overview_fields; - colon = line + 11; - } - else if (!strncasecmp (line, "References:", 11)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_REFERENCES ]; - over_field->index = store->num_overview_fields; - colon = line + 11; - } - else if (!strncasecmp (line, "Bytes:", 6)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_BYTES ]; - over_field->index = store->num_overview_fields; - colon = line + 11; - } - - if (colon && !strncmp (colon + 1, "full", 4)) - over_field->full = TRUE; - - store->num_overview_fields ++; - } - - g_free (line); - } - - for (i = 0; i < CAMEL_NNTP_OVER_LAST; i ++) { - if (store->overview_field [i].index == -1) { - g_warning ("server's OVERVIEW.FMT doesn't support minimum set we require," - " disabling OVER support.\n"); - store->extensions &= ~CAMEL_NNTP_EXT_OVER; - } - } -} - -static gboolean -nntp_store_connect (CamelService *service, CamelException *ex) -{ - char *buf; - int resp_code; - CamelNNTPStore *store = CAMEL_NNTP_STORE (service); - - if (!ensure_news_dir_exists(store)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open directory for news server: %s"), - strerror (errno)); - return FALSE; - } - - if (CAMEL_SERVICE_CLASS (remote_store_class)->connect (service, ex) == FALSE) - return FALSE; - - /* Read the greeting */ - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (service), &buf, ex) < 0) { - return FALSE; - } - - /* check if posting is allowed. */ - resp_code = atoi (buf); - if (resp_code == NNTP_GREETING_POSTING_OK) { - g_print ("posting allowed\n"); - store->posting_allowed = TRUE; - } - else if (resp_code == NNTP_GREETING_NO_POSTING) { - g_print ("no posting allowed\n"); - store->posting_allowed = FALSE; - } - else { - g_warning ("unexpected server greeting code %d, no posting allowed\n", resp_code); - store->posting_allowed = FALSE; - } - - g_free (buf); - - /* get a list of extensions that the server supports */ - camel_nntp_store_get_extensions (store, ex); - - /* try to get the overview.fmt */ - camel_nntp_store_get_overview_fmt (store, ex); - - return TRUE; -} - -static gboolean -nntp_store_disconnect (CamelService *service, gboolean clean, CamelException *ex) -{ - CamelNNTPStore *store = CAMEL_NNTP_STORE (service); - - if (clean) - camel_nntp_command (store, ex, NULL, "QUIT"); - - if (store->newsrc) - camel_nntp_newsrc_write (store->newsrc); - - if (!service_class->disconnect (service, clean, ex)) - return FALSE; - - return TRUE; -} - -static char * -nntp_store_get_name (CamelService *service, gboolean brief) -{ - if (brief) - return g_strdup_printf ("%s", service->url->host); - else - return g_strdup_printf (_("USENET News via %s"), service->url->host); - -} - -static CamelServiceAuthType password_authtype = { - N_("Password"), - - N_("This option will authenticate with the NNTP server using a " - "plaintext password."), - - "", - TRUE -}; - -static GList * -nntp_store_query_auth_types_generic (CamelService *service, CamelException *ex) -{ - GList *prev; - - prev = CAMEL_SERVICE_CLASS (remote_store_class)->query_auth_types_generic (service, ex); - return g_list_prepend (prev, &password_authtype); -} - -static GList * -nntp_store_query_auth_types_connected (CamelService *service, CamelException *ex) -{ - g_warning ("nntp::query_auth_types_connected: not implemented. Defaulting."); - /* FIXME: use the classfunc instead of the local? */ - return nntp_store_query_auth_types_generic (service, ex); -} - -static CamelFolder * -nntp_store_get_folder (CamelStore *store, const gchar *folder_name, - guint32 flags, CamelException *ex) -{ - CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); - - printf ("get_folder called on folder_name=%s\n", folder_name); - - /* if we haven't already read our .newsrc, read it now */ - if (!nntp_store->newsrc) - nntp_store->newsrc = - camel_nntp_newsrc_read_for_server (CAMEL_SERVICE(store)->url->host); - - if (!nntp_store->newsrc) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Unable to open or create .newsrc file for %s: %s"), - CAMEL_SERVICE(store)->url->host, - strerror(errno)); - return NULL; - } - - return camel_nntp_folder_new (store, folder_name, ex); -} - -#ifdef INFO_AS_TREE -static void -build_folder_info (CamelNNTPStore *nntp_store, CamelFolderInfo **root, - CamelFolderInfo *parent, CamelNNTPGroupListEntry *entry, - char *prefix, char *suffix, - GHashTable *name_to_info) -{ - CamelURL *url = CAMEL_SERVICE (nntp_store)->url; - char *dot; - if ((dot = strchr (suffix, '.'))) { - /* it's an internal node, figure out the next node in - the chain */ - CamelFolderInfo *node; - char *node_name, *node_full_name; - - node_name = g_malloc0 (dot - suffix + 1); - strncpy (node_name, suffix, dot - suffix); - node_full_name = g_strdup_printf ("%s.%s", prefix, node_name); - - node = g_hash_table_lookup (name_to_info, node_full_name); - if (!node) { - /* we need to add one */ - node = g_new0 (CamelFolderInfo, 1); - node->name = g_strdup (node_name); - node->full_name = g_strdup (node_full_name); - node->url = NULL; - node->message_count = -1; - node->unread_message_count = -1; - - if (parent) { - if (parent->child) { - node->sibling = parent->child; - parent->child = node; - } - else { - parent->child = node; - } - } - else { - if (*root) { - *root = node; - } - else { - node->sibling = *root; - *root = node; - } - } - - g_hash_table_insert (name_to_info, node_full_name, node); - } - - build_folder_info (nntp_store, root, node, entry, node_full_name, dot + 1, name_to_info); - } - else { - /* it's a leaf node, make the CamelFolderInfo and - append it to @parent's list of children. */ - CamelFolderInfo *new_group; - - new_group = g_new0 (CamelFolderInfo, 1); - new_group->name = g_strdup (entry->group_name); - new_group->full_name = g_strdup (entry->group_name); - new_group->url = g_strdup_printf ("nntp://%s%s%s/%s", - url->user ? url->user : "", - url->user ? "@" : "", - url->host, (char *)entry->group_name); - - new_group->message_count = entry->high - entry->low; - new_group->unread_message_count = (new_group->message_count - - camel_nntp_newsrc_get_num_articles_read (nntp_store->newsrc, entry->group_name)); - - if (parent) { - if (parent->child) { - new_group->sibling = parent->child; - parent->child = new_group; - } - else { - parent->child = new_group; - } - } - else { - if (*root) { - *root = new_group; - } - else { - new_group->sibling = *root; - *root = new_group; - } - } - } -} -#endif - -static CamelFolderInfo * -build_folder_info_from_grouplist (CamelNNTPStore *nntp_store, const char *top) -{ - GList *g; - CamelFolderInfo *groups = NULL; -#ifdef INFO_AS_TREE - GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal); -#else - CamelFolderInfo *last = NULL, *fi; - CamelURL *url = CAMEL_SERVICE (nntp_store)->url; -#endif - - for (g = nntp_store->group_list->group_list; g; g = g_list_next (g)) { - CamelNNTPGroupListEntry *entry = g->data; - - if (!top || !strncmp (top, entry->group_name, strlen (top))) { -#ifdef INFO_AS_TREE - build_folder_info (nntp_store, &groups, NULL, entry, - "", entry->group_name, hash); -#else - - fi = g_new0 (CamelFolderInfo, 1); - fi->name = g_strdup (entry->group_name); - fi->full_name = g_strdup (entry->group_name); - fi->url = g_strdup_printf ("nntp://%s%s%s/%s", - url->user ? url->user : "", - url->user ? "@" : "", - url->host, (char *)entry->group_name); - - fi->message_count = entry->high - entry->low; - fi->unread_message_count = (fi->message_count - - camel_nntp_newsrc_get_num_articles_read ( - nntp_store->newsrc, entry->group_name)); - - if (last) - last->sibling = fi; - else - groups = fi; - last = fi; -#endif - } - } - - return groups; -} - -static CamelFolderInfo * -nntp_store_get_folder_info (CamelStore *store, const char *top, - gboolean fast, gboolean recursive, - gboolean subscribed_only, - CamelException *ex) -{ - CamelURL *url = CAMEL_SERVICE (store)->url; - CamelNNTPStore *nntp_store = (CamelNNTPStore *)store; - GPtrArray *names; - CamelFolderInfo *groups = NULL, *last = NULL, *fi; - int i; - - /* if we haven't already read our .newsrc, read it now */ - if (!nntp_store->newsrc) - nntp_store->newsrc = - camel_nntp_newsrc_read_for_server (CAMEL_SERVICE(store)->url->host); - - if (!nntp_store->newsrc) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Unable to open or create .newsrc file for %s: %s"), - CAMEL_SERVICE(store)->url->host, - strerror(errno)); - return NULL; - } - - if (!subscribed_only) { - if (!nntp_store->group_list) - nntp_store->group_list = camel_nntp_grouplist_fetch (nntp_store, ex); - if (camel_exception_is_set (ex)) { - return NULL; - } - else { - fi = build_folder_info_from_grouplist (nntp_store, top); - return fi; - } - } - - if (top == NULL) { - /* return the list of groups */ - names = camel_nntp_newsrc_get_subscribed_group_names (nntp_store->newsrc); - for (i = 0; i < names->len; i++) { - fi = g_new0 (CamelFolderInfo, 1); - fi->name = g_strdup (names->pdata[i]); - fi->full_name = g_strdup (names->pdata[i]); - fi->url = g_strdup_printf ("nntp://%s%s%s/%s", - url->user ? url->user : "", - url->user ? "@" : "", - url->host, (char *)names->pdata[i]); - /* FIXME */ - fi->message_count = fi->unread_message_count = -1; - - if (last) - last->sibling = fi; - else - groups = fi; - last = fi; - } - camel_nntp_newsrc_free_group_names (nntp_store->newsrc, names); - - return groups; - } - else { - /* getting a specific group */ - - fi = g_new0 (CamelFolderInfo, 1); - fi->name = g_strdup (top); - fi->full_name = g_strdup (top); - fi->url = g_strdup_printf ("nntp://%s/%s", url->host, top); - /* FIXME */ - fi->message_count = fi->unread_message_count = -1; - - return fi; - } -} - -static char * -nntp_store_get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup (""); -} - -static gboolean -nntp_store_folder_subscribed (CamelStore *store, const char *folder_name) -{ - CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); - - return camel_nntp_newsrc_group_is_subscribed (nntp_store->newsrc, folder_name); -} - -static void -nntp_store_subscribe_folder (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); - - camel_nntp_newsrc_subscribe_group (nntp_store->newsrc, folder_name); -} - -static void -nntp_store_unsubscribe_folder (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); - - camel_nntp_newsrc_unsubscribe_group (nntp_store->newsrc, folder_name); -} - -static void -finalize (CamelObject *object) -{ - CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (object); - if (nntp_store->newsrc) - camel_nntp_newsrc_write (nntp_store->newsrc); -} - -static void -camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class) -{ - CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_nntp_store_class); - CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_nntp_store_class); - - remote_store_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs - (camel_remote_store_get_type ())); - - service_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ())); - - /* virtual method overload */ - camel_service_class->connect = nntp_store_connect; - camel_service_class->disconnect = nntp_store_disconnect; - camel_service_class->query_auth_types_generic = nntp_store_query_auth_types_generic; - camel_service_class->query_auth_types_connected = nntp_store_query_auth_types_connected; - camel_service_class->get_name = nntp_store_get_name; - - camel_store_class->get_folder = nntp_store_get_folder; - camel_store_class->get_root_folder_name = nntp_store_get_root_folder_name; - camel_store_class->get_folder_info = nntp_store_get_folder_info; - camel_store_class->free_folder_info = camel_store_free_folder_info_full; - - camel_store_class->folder_subscribed = nntp_store_folder_subscribed; - camel_store_class->subscribe_folder = nntp_store_subscribe_folder; - camel_store_class->unsubscribe_folder = nntp_store_unsubscribe_folder; -} - - - -static void -camel_nntp_store_init (gpointer object, gpointer klass) -{ - CamelRemoteStore *remote_store = CAMEL_REMOTE_STORE (object); - CamelStore *store = CAMEL_STORE (object); - - remote_store->default_port = NNTP_PORT; - - store->flags = CAMEL_STORE_SUBSCRIPTIONS; -} - -CamelType -camel_nntp_store_get_type (void) -{ - static CamelType camel_nntp_store_type = CAMEL_INVALID_TYPE; - - if (camel_nntp_store_type == CAMEL_INVALID_TYPE) { - camel_nntp_store_type = camel_type_register (CAMEL_REMOTE_STORE_TYPE, "CamelNNTPStore", - sizeof (CamelNNTPStore), - sizeof (CamelNNTPStoreClass), - (CamelObjectClassInitFunc) camel_nntp_store_class_init, - NULL, - (CamelObjectInitFunc) camel_nntp_store_init, - (CamelObjectFinalizeFunc) finalize); - } - - return camel_nntp_store_type; -} - - -/** - * camel_nntp_command: Send a command to a NNTP server. - * @store: the NNTP store - * @ret: a pointer to return the full server response in - * @fmt: a printf-style format string, followed by arguments - * - * This command sends the command specified by @fmt and the following - * arguments to the connected NNTP store specified by @store. It then - * reads the server's response and parses out the status code. If - * the caller passed a non-NULL pointer for @ret, camel_nntp_command - * will set it to point to an buffer containing the rest of the - * response from the NNTP server. (If @ret was passed but there was - * no extended response, @ret will be set to NULL.) The caller must - * free this buffer when it is done with it. - * - * Return value: the response code of the nntp command. - **/ -static int -camel_nntp_command_send_recv (CamelNNTPStore *store, CamelException *ex, char **ret, char *cmd) -{ - char *respbuf; - int resp_code; - gboolean again; - - do { - again = FALSE; - - /* Send the command */ - if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex, cmd) < 0) { - return NNTP_PROTOCOL_ERROR; - } - - /* Read the response */ - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0) { - if (ret) - *ret = g_strdup (g_strerror (errno)); - return NNTP_PROTOCOL_ERROR; - } - - resp_code = atoi (respbuf); - - /* this is kind of a gross hack, but since an auth challenge - can pop up at any time, and we want to shield this from our - callers, we handle authentication here. */ - if (resp_code == NNTP_AUTH_REQUIRED) { - resp_code = camel_nntp_auth_authenticate (store, ex); - if (resp_code != NNTP_AUTH_ACCEPTED) { - return resp_code; - } - - /* need to resend our command here */ - again = TRUE; - } - } while (again); - - if (ret) { - *ret = strchr (respbuf, ' '); - if (*ret) - *ret = g_strdup (*ret + 1); - } - g_free (respbuf); - - return resp_code; -} - -int -camel_nntp_command (CamelNNTPStore *store, CamelException *ex, char **ret, char *fmt, ...) -{ - char *cmdbuf; - va_list ap; - int resp_code; - char *real_fmt; - - real_fmt = g_strdup_printf ("%s\r\n", fmt); - - va_start (ap, fmt); - cmdbuf = g_strdup_vprintf (real_fmt, ap); - va_end (ap); - - g_free (real_fmt); - - resp_code = camel_nntp_command_send_recv (store, ex, ret, cmdbuf); - - g_free (cmdbuf); - - return resp_code; -} - -void -camel_nntp_store_subscribe_group (CamelStore *store, - const gchar *group_name) -{ - gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(store)); - char *ret = NULL; - CamelException *ex = camel_exception_new(); - - if (camel_exception_get_id (ex)) { - g_free (root_dir); - camel_exception_free (ex); - return; - } - - if (camel_nntp_command ( CAMEL_NNTP_STORE (store), - ex, &ret, "GROUP %s", group_name) == NNTP_GROUP_SELECTED) { - /* we create an empty summary file here, so that when - the group is opened we'll know we need to build it. */ - gchar *summary_file; - int fd; - summary_file = g_strdup_printf ("%s/%s-ev-summary", root_dir, group_name); - - fd = open (summary_file, O_CREAT | O_RDWR, 0666); - close (fd); - - g_free (summary_file); - } - if (ret) g_free (ret); - - g_free (root_dir); - camel_exception_free (ex); -} - -void -camel_nntp_store_unsubscribe_group (CamelStore *store, - const gchar *group_name) -{ - gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(store)); - gchar *summary_file; - - summary_file = g_strdup_printf ("%s/%s-ev-summary", root_dir, group_name); - if (g_file_exists (summary_file)) - unlink (summary_file); - g_free (summary_file); - - g_free (root_dir); -} - -GList * -camel_nntp_store_list_subscribed_groups(CamelStore *store) -{ - GList *group_name_list = NULL; - struct stat stat_buf; - gint stat_error = 0; - gchar *entry_name; - gchar *full_entry_name; - gchar *real_group_name; - struct dirent *dir_entry; - DIR *dir_handle; - gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(store)); - - dir_handle = opendir (root_dir); - g_return_val_if_fail (dir_handle, NULL); - - /* read the first entry in the directory */ - dir_entry = readdir (dir_handle); - while ((stat_error != -1) && (dir_entry != NULL)) { - - /* get the name of the next entry in the dir */ - entry_name = dir_entry->d_name; - full_entry_name = g_strdup_printf ("%s/%s", root_dir, entry_name); - stat_error = stat (full_entry_name, &stat_buf); - g_free (full_entry_name); - - /* is it a normal file ending in -ev-summary ? */ - if ((stat_error != -1) && S_ISREG (stat_buf.st_mode)) { - gboolean summary_suffix_found; - - real_group_name = string_prefix (entry_name, "-ev-summary", - &summary_suffix_found); - - if (summary_suffix_found) - /* add the folder name to the list */ - group_name_list = g_list_append (group_name_list, - real_group_name); - } - /* read next entry */ - dir_entry = readdir (dir_handle); - } - - closedir (dir_handle); - - return group_name_list; -} - -gchar * -camel_nntp_store_get_toplevel_dir (CamelNNTPStore *store) -{ - CamelURL *url = CAMEL_SERVICE (store)->url; - char *top_dir; - - g_assert(url != NULL); - - top_dir = g_strdup_printf( "%s/evolution/news/%s", - g_get_home_dir (), - url->host ); - - return top_dir; -} - -static gboolean -ensure_news_dir_exists (CamelNNTPStore *store) -{ - gchar *dir = camel_nntp_store_get_toplevel_dir (store); - - if (access (dir, F_OK) == 0) { - g_free (dir); - return TRUE; - } - - if (e_mkdir_hier (dir, S_IRWXU) == -1) { - g_free (dir); - return FALSE; - } - - return TRUE; -} diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h deleted file mode 100644 index 0566967fd7..0000000000 --- a/camel/providers/nntp/camel-nntp-store.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-store.h : class for an nntp store */ - -/* - * - * Copyright (C) 2000 Helix Code, Inc. <toshok@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_NNTP_STORE_H -#define CAMEL_NNTP_STORE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-remote-store.h" -#include "camel-nntp-newsrc.h" -#include "camel-nntp-types.h" - -#define CAMEL_NNTP_STORE_TYPE (camel_nntp_store_get_type ()) -#define CAMEL_NNTP_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_NNTP_STORE_TYPE, CamelNNTPStore)) -#define CAMEL_NNTP_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_NNTP_STORE_TYPE, CamelNNTPStoreClass)) -#define IS_CAMEL_NNTP_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_NNTP_STORE_TYPE)) - - -enum { - CAMEL_NNTP_OVER_FROM, - CAMEL_NNTP_OVER_SUBJECT, - CAMEL_NNTP_OVER_DATE, - CAMEL_NNTP_OVER_MESSAGE_ID, - CAMEL_NNTP_OVER_REFERENCES, - CAMEL_NNTP_OVER_BYTES, - - CAMEL_NNTP_OVER_LAST -}; - -struct CamelNNTPOverField { - int index; - gboolean full; /* full in the OVER sense - the field name - precedes the ':' in the XOVER list. */ -}; - -struct CamelNNTPStore { - CamelRemoteStore parent_object; - -#define CAMEL_NNTP_EXT_SEARCH (1<<0) -#define CAMEL_NNTP_EXT_SETGET (1<<1) -#define CAMEL_NNTP_EXT_OVER (1<<2) -#define CAMEL_NNTP_EXT_XPATTEXT (1<<3) -#define CAMEL_NNTP_EXT_XACTIVE (1<<4) -#define CAMEL_NNTP_EXT_LISTMOTD (1<<5) -#define CAMEL_NNTP_EXT_LISTSUBSCR (1<<6) -#define CAMEL_NNTP_EXT_LISTPNAMES (1<<7) - guint32 extensions; - - gboolean posting_allowed; - - int num_overview_fields; - CamelNNTPOverField overview_field[ CAMEL_NNTP_OVER_LAST ]; - - CamelNNTPNewsrc *newsrc; - CamelNNTPGroupList *group_list; - -}; - -struct CamelNNTPStoreClass { - CamelRemoteStoreClass parent_class; - -}; - - -/* public methods */ -void camel_nntp_store_open (CamelNNTPStore *store, CamelException *ex); -void camel_nntp_store_close (CamelNNTPStore *store, gboolean expunge, - CamelException *ex); - -void camel_nntp_store_subscribe_group (CamelStore *store, const gchar *group_name); -void camel_nntp_store_unsubscribe_group (CamelStore *store, const gchar *group_name); -GList *camel_nntp_store_list_subscribed_groups(CamelStore *store); - -gchar *camel_nntp_store_get_toplevel_dir (CamelNNTPStore *store); - -/* support functions */ -int camel_nntp_command (CamelNNTPStore *store, CamelException *ex, char **ret, char *fmt, ...); - -/* Standard Camel function */ -CamelType camel_nntp_store_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_NNTP_STORE_H */ - - diff --git a/camel/providers/nntp/camel-nntp-types.h b/camel/providers/nntp/camel-nntp-types.h deleted file mode 100644 index b1d91779b1..0000000000 --- a/camel/providers/nntp/camel-nntp-types.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-grouplist.h : getting/updating the list of newsgroups on the server. */ - -/* - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 2000 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_NNTP_TYPES_H -#define CAMEL_NNTP_TYPES_H 1 - -typedef struct CamelNNTPGroupList CamelNNTPGroupList; -typedef struct CamelNNTPGroupListEntry CamelNNTPGroupListEntry; -typedef struct CamelNNTPOverField CamelNNTPOverField; -typedef struct CamelNNTPStore CamelNNTPStore; -typedef struct CamelNNTPStoreClass CamelNNTPStoreClass; - -#endif /* CAMEL_NNTP_TYPES_H */ diff --git a/camel/providers/nntp/camel-nntp-utils.c b/camel/providers/nntp/camel-nntp-utils.c deleted file mode 100644 index e8ee9bb112..0000000000 --- a/camel/providers/nntp/camel-nntp-utils.c +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-utils.c : utilities used by the nntp code. */ - -/* - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 2000 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "camel-folder-summary.h" -#include "camel-nntp-resp-codes.h" -#include "camel-nntp-folder.h" -#include "camel-nntp-store.h" -#include "camel-nntp-utils.h" -#include "camel-stream-mem.h" -#include "camel-exception.h" - -#include <stdlib.h> -#include <string.h> - -static void -get_XOVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder, - int first_message, int last_message, CamelException *ex) -{ - int status; - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); - - status = camel_nntp_command (nntp_store, ex, NULL, - "XOVER %d-%d", - first_message, - last_message); - - if (status == NNTP_DATA_FOLLOWS) { - gboolean done = FALSE; - - while (!done) { - char *line; - - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (nntp_store), &line, ex) < 0) { - g_warning ("failed to recv_line while building OVER header list\n"); - break; - } - - if (*line == '.') { - done = TRUE; - g_print ("done\n"); - } - else { - CamelMessageInfo *new_info = g_new0(CamelMessageInfo, 1); - char **split_line = g_strsplit (line, "\t", 7); - char *subject, *from, *date, *message_id, *bytes; - - subject = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_SUBJECT].index]; - from = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_FROM].index]; - date = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_DATE].index]; - message_id = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_MESSAGE_ID].index]; - bytes = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_BYTES].index]; - - /* if the overview format flagged this - field as "full", skip over the - preceding field name and colon */ - if (nntp_store->overview_field [ CAMEL_NNTP_OVER_SUBJECT ].full) - subject += strlen ("Subject:"); - if (nntp_store->overview_field [ CAMEL_NNTP_OVER_FROM ].full) - from += strlen ("From:"); - if (nntp_store->overview_field [ CAMEL_NNTP_OVER_DATE ].full) - date += strlen ("Date:"); - if (nntp_store->overview_field [ CAMEL_NNTP_OVER_MESSAGE_ID ].full) - message_id += strlen ("Message-ID:"); - if (nntp_store->overview_field [ CAMEL_NNTP_OVER_BYTES ].full) - bytes += strlen ("Bytes:"); - - new_info->subject = g_strdup(subject); - new_info->from = g_strdup(from); - new_info->to = g_strdup(folder->name); - new_info->date_sent = header_decode_date(date, NULL); -#if 0 - /* XXX do we need to fill in both dates? */ - new_info->headers.date_received = g_strdup(date); -#endif - new_info->size = atoi(bytes); - new_info->uid = g_strdup_printf ("%s,%s", split_line[0], message_id); - new_info->message_id = g_strdup(message_id); - - if (camel_nntp_newsrc_article_is_read (nntp_store->newsrc, - folder->name, - atoi (split_line[0]))) - new_info->flags |= CAMEL_MESSAGE_SEEN; - - camel_folder_summary_add (nntp_folder->summary, new_info); - g_strfreev (split_line); - } - g_free (line); - } - } - else { - /* XXX */ - g_warning ("weird nntp response for XOVER: %d\n", status); - } -} - -#if 0 -static GArray* -get_HEAD_headers(CamelNNTPStore *nntp_store, CamelFolder *folder, - int first_message, int last_message, CamelException *ex) -{ - int i; - int status; - - for (i = first_message; i < last_message; i ++) { - status = camel_nntp_command (nntp_store, ex, NULL, - "HEAD %d", i); - - if (status == NNTP_HEAD_FOLLOWS) { - gboolean done = FALSE; - char *buf; - int buf_len; - int buf_alloc; - int h; - CamelStream *header_stream; - GArray *header_array; - CamelStream *nntp_istream; - CamelMessageInfo *new_info = g_new0(CamelMessageInfo, 1); - - buf_alloc = 2048; - buf_len = 0; - buf = g_malloc(buf_alloc); - done = FALSE; - - buf[0] = 0; - - nntp_istream = nntp_store->istream; - - while (!done) { - char *line; - int line_length; - - line = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER ( nntp_istream )); - line_length = strlen ( line ); - - if (*line == '.') { - done = TRUE; - } - else { - if (buf_len + line_length > buf_alloc) { - buf_alloc *= 2; - buf = g_realloc (buf, buf_alloc); - } - strcat(buf, line); - strcat(buf, "\n"); - buf_len += strlen(line); - g_free (line); - } - } - - /* create a stream from which to parse the headers */ - header_stream = camel_stream_mem_new_with_buffer(buf, - buf_len, - CAMEL_STREAM_MEM_READ); - - header_array = get_header_array_from_stream (header_stream); - - memset (&info, 0, sizeof(info)); - - for (h = 0; h < header_array->len; h ++) { - Rfc822Header *header = &((Rfc822Header*)header_array->data)[h]; - if (!g_strcasecmp(header->name, "From")) - new_info->from = g_strdup(header->value); - else if (!g_strcasecmp(header->name, "To")) - new_info->to = g_strdup(header->value); - else if (!g_strcasecmp(header->name, "Subject")) - new_info->subject = g_strdup(header->value); - else if (!g_strcasecmp(header->name, "Message-ID")) { - new_info->uid = g_strdup_printf("%d,%s", i, header->value); - new_info->message_id = g_strdup(header->value); - } - else if (!g_strcasecmp(header->name, "Date")) { - new_info->date_sent = header_decode_date (header->value); -#if 0 - new_info->date_sent = g_strdup(header->value); - new_info->date_received = g_strdup(header->value); -#endif - } - } - - camel_folder_summary_add (nntp_folder->summary, new_info); - } - else if (status == CAMEL_NNTP_FAIL) { - /* nasty things are afoot */ - g_warning ("failure doing HEAD\n"); - break; - } - } -} -#endif - -void -camel_nntp_get_headers (CamelStore *store, - CamelNNTPFolder *nntp_folder, - CamelException *ex) -{ - CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); - CamelFolder *folder = CAMEL_FOLDER (nntp_folder); - char *ret; - int first_message, nb_message, last_message; - int status; - - status = camel_nntp_command (nntp_store, ex, &ret, - "GROUP %s", folder->name); - - sscanf (ret, "%d %d %d", &nb_message, &first_message, &last_message); - g_free (ret); - - if (status == NNTP_NO_SUCH_GROUP) { - /* XXX throw invalid group exception */ - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID, - "group %s not found on server", - folder->name); - return; - } - - - if (nntp_store->extensions & CAMEL_NNTP_EXT_OVER) { - get_XOVER_headers (nntp_store, folder, first_message, last_message, ex); - } - else { - g_warning ("need to fix get_HEAD_headers\n"); -#if 0 - get_HEAD_headers (nntp_store, folder, first_message, last_message, ex); -#endif - } -} diff --git a/camel/providers/nntp/camel-nntp-utils.h b/camel/providers/nntp/camel-nntp-utils.h deleted file mode 100644 index f28697c744..0000000000 --- a/camel/providers/nntp/camel-nntp-utils.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-utils.h : Utilities for the NNTP provider */ - -/* - * - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 1999 Helix Code . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_NNTP_UTILS_H -#define CAMEL_NNTP_UTILS_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -void camel_nntp_get_headers (CamelStore *store, CamelNNTPFolder *nntp_folder, CamelException *ex); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_NNTP_UTILS_H */ diff --git a/camel/providers/nntp/libcamelnntp.urls b/camel/providers/nntp/libcamelnntp.urls deleted file mode 100644 index dee2e70f14..0000000000 --- a/camel/providers/nntp/libcamelnntp.urls +++ /dev/null @@ -1,2 +0,0 @@ -news -nntp diff --git a/camel/providers/nntp/test-newsrc.c b/camel/providers/nntp/test-newsrc.c deleted file mode 100644 index c4b985e565..0000000000 --- a/camel/providers/nntp/test-newsrc.c +++ /dev/null @@ -1,10 +0,0 @@ -#include <stdio.h> -#include <glib.h> -#include "camel-nntp-newsrc.h" - -int -main(int argc, char *argv[]) -{ - CamelNNTPNewsrc *newsrc = camel_nntp_newsrc_read_for_server (argv[1]); - camel_nntp_newsrc_write_to_file (newsrc, stdout); -} diff --git a/camel/providers/pop3/.cvsignore b/camel/providers/pop3/.cvsignore deleted file mode 100644 index 7d926a5545..0000000000 --- a/camel/providers/pop3/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile -Makefile.in -.libs -.deps -*.lo -*.la diff --git a/camel/providers/pop3/Makefile.am b/camel/providers/pop3/Makefile.am deleted file mode 100644 index 608e640cd9..0000000000 --- a/camel/providers/pop3/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelpop3includedir = $(includedir)/camel - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelpop3.la -provider_DATA = libcamelpop3.urls - -INCLUDES = \ - -I.. \ - -I$(srcdir)/.. \ - -I$(srcdir)/../../.. \ - -I$(includedir) \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/e-util \ - $(KRB4_CFLAGS) \ - $(GTK_INCLUDEDIR) \ - -DG_LOG_DOMAIN=\"camel-pop3-provider\" - -libcamelpop3_la_SOURCES = \ - camel-pop3-folder.c \ - camel-pop3-provider.c \ - camel-pop3-store.c - -libcamelpop3include_HEADERS = \ - camel-pop3-folder.h \ - camel-pop3-store.h - - -libcamelpop3_la_LDFLAGS = $(KRB4_LDFLAGS) -version-info 0:0:0 - -libcamelpop3_la_LIBADD = $(top_builddir)/e-util/libeutil.la $(UNICODE_LIBS) - -EXTRA_DIST = libcamelpop3.urls diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c deleted file mode 100644 index 5cc0609e01..0000000000 --- a/camel/providers/pop3/camel-pop3-folder.c +++ /dev/null @@ -1,332 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-pop3-folder.c : class for a pop3 folder */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "camel-pop3-folder.h" -#include "camel-pop3-store.h" -#include "camel-exception.h" -#include "camel-stream-mem.h" -#include "camel-stream-filter.h" -#include "camel-mime-message.h" - -#include <stdlib.h> -#include <string.h> - -#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(o))) -static CamelFolderClass *parent_class; - -static void pop3_finalize (CamelObject *object); - -static void pop3_refresh_info (CamelFolder *folder, CamelException *ex); -static void pop3_sync (CamelFolder *folder, gboolean expunge, - CamelException *ex); - -static gint pop3_get_message_count (CamelFolder *folder); -static GPtrArray *pop3_get_uids (CamelFolder *folder); -static CamelMimeMessage *pop3_get_message (CamelFolder *folder, - const char *uid, - CamelException *ex); -static void pop3_set_message_flags (CamelFolder *folder, const char *uid, - guint32 flags, guint32 set); - -static GPtrArray *parse_listing (int count, char *data); - -static void -camel_pop3_folder_class_init (CamelPop3FolderClass *camel_pop3_folder_class) -{ - CamelFolderClass *camel_folder_class = - CAMEL_FOLDER_CLASS (camel_pop3_folder_class); - - parent_class = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ())); - - /* virtual method overload */ - camel_folder_class->refresh_info = pop3_refresh_info; - camel_folder_class->sync = pop3_sync; - - camel_folder_class->get_message_count = pop3_get_message_count; - camel_folder_class->get_uids = pop3_get_uids; - camel_folder_class->free_uids = camel_folder_free_nop; - - camel_folder_class->get_message = pop3_get_message; - camel_folder_class->set_message_flags = pop3_set_message_flags; -} - -static void -camel_pop3_folder_init (gpointer object) -{ - CamelFolder *folder = CAMEL_FOLDER (object); - CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (object); - - folder->has_summary_capability = FALSE; - folder->has_search_capability = FALSE; - - pop3_folder->uids = NULL; - pop3_folder->flags = NULL; -} - -CamelType -camel_pop3_folder_get_type (void) -{ - static CamelType camel_pop3_folder_type = CAMEL_INVALID_TYPE; - - if (!camel_pop3_folder_type) { - camel_pop3_folder_type = camel_type_register (CAMEL_FOLDER_TYPE, "CamelPop3Folder", - sizeof (CamelPop3Folder), - sizeof (CamelPop3FolderClass), - (CamelObjectClassInitFunc) camel_pop3_folder_class_init, - NULL, - (CamelObjectInitFunc) camel_pop3_folder_init, - (CamelObjectFinalizeFunc) pop3_finalize); - } - - return camel_pop3_folder_type; -} - -void -pop3_finalize (CamelObject *object) -{ - CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (object); - - camel_folder_free_deep (NULL, pop3_folder->uids); - g_free (pop3_folder->flags); -} - -CamelFolder * -camel_pop3_folder_new (CamelStore *parent, CamelException *ex) -{ - CamelFolder *folder; - - folder = CAMEL_FOLDER (camel_object_new (CAMEL_POP3_FOLDER_TYPE)); - camel_folder_construct (folder, parent, "inbox", "inbox"); - - camel_folder_refresh_info (folder, ex); - if (camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (folder)); - folder = NULL; - } - - return folder; -} - -static void -pop3_refresh_info (CamelFolder *folder, CamelException *ex) -{ - GPtrArray *uids; - int status, count; - char *data; - CamelPop3Folder *pop3_folder = (CamelPop3Folder *) folder; - CamelPop3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store); - - status = camel_pop3_command (pop3_store, &data, ex, "STAT"); - if (status != CAMEL_POP3_OK) - return; - - count = atoi (data); - g_free (data); - - if (pop3_store->supports_uidl != FALSE) { - status = camel_pop3_command (pop3_store, NULL, ex, "UIDL"); - switch (status) { - case CAMEL_POP3_ERR: - pop3_store->supports_uidl = FALSE; - break; - case CAMEL_POP3_FAIL: - return; - } - } - - if (pop3_store->supports_uidl == FALSE) { - int i; - - uids = g_ptr_array_new (); - g_ptr_array_set_size (uids, count); - - for (i = 0; i < count; i++) - uids->pdata[i] = g_strdup_printf ("%d", i + 1); - } else { - data = camel_pop3_command_get_additional_data (pop3_store, ex); - if (camel_exception_is_set (ex)) - return; - - uids = parse_listing (count, data); - g_free (data); - - if (!uids) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not open folder: " - "message listing was " - "incomplete.")); - return; - } - } - - pop3_folder->uids = uids; - pop3_folder->flags = g_new0 (guint32, uids->len); -} - -static void -pop3_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - CamelPop3Folder *pop3_folder; - CamelPop3Store *pop3_store; - int i, status; - char *resp; - - if (!expunge) - return; - - pop3_folder = CAMEL_POP3_FOLDER (folder); - pop3_store = CAMEL_POP3_STORE (folder->parent_store); - - for (i = 0; i < pop3_folder->uids->len; i++) { - if (pop3_folder->flags[i] & CAMEL_MESSAGE_DELETED) { - status = camel_pop3_command (pop3_store, &resp, ex, - "DELE %d", i + 1); - if (status != CAMEL_POP3_OK) - return; - } - } - - camel_pop3_store_expunge (pop3_store, ex); -} - - -static GPtrArray * -parse_listing (int count, char *data) -{ - GPtrArray *ans; - char *p; - int index, len; - - ans = g_ptr_array_new (); - g_ptr_array_set_size (ans, count); - - p = data; - while (*p) { - index = strtoul (p, &p, 10); - len = strcspn (p, "\n"); - if (index <= count && *p == ' ') - ans->pdata[index - 1] = g_strndup (p + 1, len - 1); - p += len; - if (*p == '\n') - p++; - } - - for (index = 0; index < count; index++) { - if (ans->pdata[index] == NULL) { - g_ptr_array_free (ans, TRUE); - return NULL; - } - } - - return ans; -} - -static int -uid_to_number (CamelPop3Folder *pop3_folder, const char *uid) -{ - int i; - - for (i = 0; i < pop3_folder->uids->len; i++) { - if (!strcmp (uid, pop3_folder->uids->pdata[i])) - return i + 1; - } - - return -1; -} - - -static CamelMimeMessage * -pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex) -{ - int status, num; - char *result, *body; - CamelStream *msgstream; - CamelMimeMessage *msg; - - num = uid_to_number (CAMEL_POP3_FOLDER (folder), uid); - if (num == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("No message with uid %s"), uid); - return NULL; - } - - status = camel_pop3_command (CAMEL_POP3_STORE (folder->parent_store), - &result, ex, "RETR %d", num); - if (status != CAMEL_POP3_OK) - return NULL; - g_free (result); - - body = camel_pop3_command_get_additional_data (CAMEL_POP3_STORE (folder->parent_store), ex); - if (!body) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Could not retrieve message from POP " - "server %s: %s"), service->url->host, - camel_exception_get_description (ex)); - return NULL; - } - - msgstream = camel_stream_mem_new_with_buffer (body, strlen (body)); - g_free (body); - - msg = camel_mime_message_new (); - camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), - CAMEL_STREAM (msgstream)); - - camel_object_unref (CAMEL_OBJECT (msgstream)); - - return msg; -} - -static void -pop3_set_message_flags (CamelFolder *folder, const char *uid, - guint32 flags, guint32 set) -{ - CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder); - int num; - - num = uid_to_number (pop3_folder, uid); - if (num == -1) - return; - - pop3_folder->flags[num - 1] = - (pop3_folder->flags[num] & ~flags) | (set & flags); -} - -static gint -pop3_get_message_count (CamelFolder *folder) -{ - CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder); - - return pop3_folder->uids->len; -} - -static GPtrArray * -pop3_get_uids (CamelFolder *folder) -{ - CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder); - - return pop3_folder->uids; -} diff --git a/camel/providers/pop3/camel-pop3-folder.h b/camel/providers/pop3/camel-pop3-folder.h deleted file mode 100644 index b4cfd469b6..0000000000 --- a/camel/providers/pop3/camel-pop3-folder.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-pop3-folder.h : Class for a POP3 folder */ - -/* - * Author: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_POP3_FOLDER_H -#define CAMEL_POP3_FOLDER_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-folder.h" - -#define CAMEL_POP3_FOLDER_TYPE (camel_pop3_folder_get_type ()) -#define CAMEL_POP3_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_POP3_FOLDER_TYPE, CamelPop3Folder)) -#define CAMEL_POP3_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_POP3_FOLDER_TYPE, CamelPop3FolderClass)) -#define IS_CAMEL_POP3_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_POP3_FOLDER_TYPE)) - - -typedef struct { - CamelFolder parent_object; - - GPtrArray *uids; - guint32 *flags; - -} CamelPop3Folder; - - - -typedef struct { - CamelFolderClass parent_class; - - /* Virtual methods */ - -} CamelPop3FolderClass; - - -/* public methods */ -CamelFolder *camel_pop3_folder_new (CamelStore *parent, CamelException *ex); - -/* Standard Camel function */ -CamelType camel_pop3_folder_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_POP3_FOLDER_H */ diff --git a/camel/providers/pop3/camel-pop3-provider.c b/camel/providers/pop3/camel-pop3-provider.c deleted file mode 100644 index 5af0dad73c..0000000000 --- a/camel/providers/pop3/camel-pop3-provider.c +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-pop3-provider.c: pop3 provider registration code */ - -/* - * Authors : - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-pop3-store.h" -#include "camel-provider.h" -#include "camel-session.h" -#include "camel-url.h" - -static CamelProvider pop3_provider = { - "pop", - N_("POP"), - - N_("For connecting to POP servers. The POP protocol can also " - "be used to retrieve mail from certain web mail providers " - "and proprietary email systems."), - - "mail", - - CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE, - - CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH, - - { 0, 0 }, - - NULL -}; - -void -camel_provider_module_init (CamelSession *session) -{ - pop3_provider.object_types[CAMEL_PROVIDER_STORE] = - camel_pop3_store_get_type(); - - pop3_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal); - - camel_session_register_provider (session, &pop3_provider); -} diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c deleted file mode 100644 index bdcf7996e3..0000000000 --- a/camel/providers/pop3/camel-pop3-store.c +++ /dev/null @@ -1,700 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-pop3-store.c : class for a pop3 store */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#ifdef HAVE_KRB4 -/* Specified nowhere */ -#define KPOP_PORT 1109 - -#include <krb.h> -/* MIT krb4 des.h #defines _. Sigh. We don't need it. */ -#undef _ - -#ifdef NEED_KRB_SENDAUTH_PROTO -extern int krb_sendauth(long options, int fd, KTEXT ticket, char *service, - char *inst, char *realm, unsigned KRB4_32 checksum, - MSG_DAT *msg_data, CREDENTIALS *cred, - Key_schedule schedule, struct sockaddr_in *laddr, - struct sockaddr_in *faddr, char *version); -#endif -#endif - -#include "camel-pop3-store.h" -#include "camel-pop3-folder.h" -#include "camel-stream-buffer.h" -#include "camel-stream-fs.h" -#include "camel-session.h" -#include "camel-exception.h" -#include "camel-url.h" -#include "e-util/md5-utils.h" - -/* Specified in RFC 1939 */ -#define POP3_PORT 110 - -static CamelRemoteStoreClass *parent_class = NULL; - -static void finalize (CamelObject *object); - -static gboolean pop3_connect (CamelService *service, CamelException *ex); -static gboolean pop3_disconnect (CamelService *service, gboolean clean, CamelException *ex); -static GList *query_auth_types_connected (CamelService *service, CamelException *ex); -static GList *query_auth_types_generic (CamelService *service, CamelException *ex); - -static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - guint32 flags, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); - -static int pop3_get_response (CamelPop3Store *store, char **ret, CamelException *ex); - - -static void -camel_pop3_store_class_init (CamelPop3StoreClass *camel_pop3_store_class) -{ - CamelServiceClass *camel_service_class = - CAMEL_SERVICE_CLASS (camel_pop3_store_class); - CamelStoreClass *camel_store_class = - CAMEL_STORE_CLASS (camel_pop3_store_class); - /*CamelRemoteStoreClass *camel_remote_store_class = - * CAMEL_STORE_CLASS (camel_pop3_store_class); - */ - - parent_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs - (camel_remote_store_get_type ())); - - /* virtual method overload */ - camel_service_class->query_auth_types_connected = query_auth_types_connected; - camel_service_class->query_auth_types_generic = query_auth_types_generic; - camel_service_class->connect = pop3_connect; - camel_service_class->disconnect = pop3_disconnect; - - camel_store_class->get_folder = get_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; -} - - - -static void -camel_pop3_store_init (gpointer object, gpointer klass) -{ - CamelRemoteStore *remote_store = CAMEL_REMOTE_STORE (object); - - remote_store->default_port = 110; -} - -CamelType -camel_pop3_store_get_type (void) -{ - static CamelType camel_pop3_store_type = CAMEL_INVALID_TYPE; - - if (!camel_pop3_store_type) { - camel_pop3_store_type = camel_type_register (CAMEL_REMOTE_STORE_TYPE, "CamelPop3Store", - sizeof (CamelPop3Store), - sizeof (CamelPop3StoreClass), - (CamelObjectClassInitFunc) camel_pop3_store_class_init, - NULL, - (CamelObjectInitFunc) camel_pop3_store_init, - finalize); - } - - return camel_pop3_store_type; -} - -static void -finalize (CamelObject *object) -{ - CamelPop3Store *pop3_store = CAMEL_POP3_STORE (object); - - if (pop3_store->apop_timestamp) - g_free (pop3_store->apop_timestamp); -} - -static CamelServiceAuthType password_authtype = { - N_("Password"), - - N_("This option will connect to the POP server using a plaintext " - "password. This is the only option supported by many POP servers."), - - "", - TRUE -}; - -static CamelServiceAuthType apop_authtype = { - "APOP", - - N_("This option will connect to the POP server using an encrypted " - "password via the APOP protocol. This may not work for all users " - "even on servers that claim to support it."), - - "+APOP", - TRUE -}; - -#ifdef HAVE_KRB4 -static CamelServiceAuthType kpop_authtype = { - "Kerberos 4 (KPOP)", - - N_("This will connect to the POP server and use Kerberos 4 " - "to authenticate to it."), - - "+KPOP", - FALSE -}; -#endif - -static gboolean -connect_to_server (CamelService *service, /*gboolean real, */CamelException *ex) -{ - CamelPop3Store *store = CAMEL_POP3_STORE (service); - char *buf, *apoptime, *apopend; - gint status; -#ifdef HAVE_KRB4 - gboolean kpop = service->url->authmech && - !strcmp (service->url->authmech, "+KPOP"); -#endif - -#ifdef HAVE_KRB4 - if (kpop) { - KTEXT_ST ticket_st; - MSG_DAT msg_data; - CREDENTIALS cred; - Key_schedule schedule; - char *hostname; - struct hostent *h; - int fd; - - /* Need to copy hostname, because krb_realmofhost will - * call gethostbyname as well, and gethostbyname uses - * static storage. - */ - h = camel_service_gethost (service, ex); - hostname = g_strdup (h->h_name); - - fd = CAMEL_STREAM_FS (CAMEL_REMOTE_STORE (service)->ostream)->fd; - - status = krb_sendauth (0, fd, &ticket_st, "pop", hostname, - krb_realmofhost (hostname), 0, - &msg_data, &cred, schedule, - NULL, NULL, "KPOPV0.1"); - g_free (hostname); - if (status != KSUCCESS) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Could not authenticate to " - "KPOP server: %s"), - krb_err_txt[status]); - return FALSE; - } - - if (!service->url->passwd) - service->url->passwd = g_strdup (service->url->user); - } -#endif /* HAVE_KRB4 */ - - /* Read the greeting, check status */ - status = pop3_get_response (store, &buf, ex); - if (status != CAMEL_POP3_OK) - return FALSE; - - apoptime = strchr (buf, '<'); - apopend = apoptime ? strchr (apoptime, '>') : NULL; - if (apopend) { - store->apop_timestamp = g_strndup (apoptime, - apopend - apoptime + 1); - memmove (apoptime, apopend + 1, strlen (apopend + 1)); - } - store->implementation = buf; - - /* Check extensions */ - store->login_delay = -1; - store->supports_top = -1; - store->supports_uidl = -1; - store->expires = -1; - - status = camel_pop3_command (store, NULL, ex, "CAPA"); - if (status == CAMEL_POP3_OK) { - char *p; - int len; - - buf = camel_pop3_command_get_additional_data (store, ex); - if (camel_exception_is_set (ex)) - return FALSE; - - p = buf; - while (*p) { - len = strcspn (p, "\n"); - if (!strncmp (p, "IMPLEMENTATION ", 15)) { - g_free (store->implementation); - store->implementation = - g_strndup (p + 15, len - 15); - } else if (len == 3 && !strncmp (p, "TOP", 3)) - store->supports_top = TRUE; - else if (len == 4 && !strncmp (p, "UIDL", 4)) - store->supports_uidl = TRUE; - else if (!strncmp (p, "LOGIN-DELAY ", 12)) - store->login_delay = atoi (p + 12); - else if (!strncmp (p, "EXPIRE NEVER", 12)) - store->expires = FALSE; - else if (!strncmp (p, "EXPIRE ", 7)) - store->expires = TRUE; - - p += len; - if (*p) - p++; - } - - g_free (buf); - } - - return TRUE; -} - -static GList * -query_auth_types_connected (CamelService *service, CamelException *ex) -{ - CamelPop3Store *store = CAMEL_POP3_STORE (service); - GList *ret = NULL; - gboolean passwd = TRUE, apop = TRUE; -#ifdef HAVE_KRB4 - gboolean kpop = TRUE; - int saved_port; -#endif - - ret = CAMEL_SERVICE_CLASS (parent_class)->query_auth_types_connected (service, ex); - - passwd = camel_service_connect (service, ex); - /*ignore the exception here; the server may just not support passwd */ - /*if (camel_exception_is_set (ex) != CAMEL_EXCEPTION_NONE)*/ - /*return NULL;*/ - - /* should we check apop too? */ - apop = store->apop_timestamp != NULL; - if (passwd) - camel_service_disconnect (service, TRUE, ex); - camel_exception_clear (ex); - -#ifdef HAVE_KRB4 - saved_port = service->url->port; - service->url->port = KPOP_PORT; - kpop = camel_service_connect (service, ex); - service->url->port = saved_port; - /*ignore the exception here; the server may just not support kpop */ - /*if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE)*/ - /*return NULL;*/ - - if (kpop) - camel_service_disconnect (service, TRUE, ex); - camel_exception_clear (ex); -#endif - - if (passwd) - ret = g_list_append (ret, &password_authtype); - if (apop) - ret = g_list_append (ret, &apop_authtype); -#ifdef HAVE_KRB4 - if (kpop) - ret = g_list_append (ret, &kpop_authtype); -#endif - - if (!ret) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Could not connect to POP server on " - "%s."), service->url->host); - } - - return ret; -} - -static GList * -query_auth_types_generic (CamelService *service, CamelException *ex) -{ - GList *ret; - - ret = g_list_append (NULL, &password_authtype); - ret = g_list_append (ret, &apop_authtype); -#ifdef HAVE_KRB4 - ret = g_list_append (ret, &kpop_authtype); -#endif - - return ret; -} - -/** - * camel_pop3_store_expunge: - * @store: the store - * @ex: a CamelException - * - * Expunge messages from the store. This will result in the connection - * being closed, which may cause later commands to fail if they can't - * reconnect. - **/ -void -camel_pop3_store_expunge (CamelPop3Store *store, CamelException *ex) -{ - camel_pop3_command (store, NULL, ex, "QUIT"); - camel_service_disconnect (CAMEL_SERVICE (store), FALSE, ex); -} - - -static gboolean -pop3_try_authenticate (CamelService *service, gboolean kpop, - const char *errmsg, CamelException *ex) -{ - CamelPop3Store *store = (CamelPop3Store *)service; - int status; - char *msg; - - /* The KPOP code will have set the password to be the username - * in connect_to_server. Password and APOP are the only other - * cases, and they both need a password. So if there's no - * password stored, query for it. - */ - if (!service->url->passwd) { - char *prompt; - - prompt = g_strdup_printf (_("%sPlease enter the POP3 password " - "for %s@%s"), errmsg ? errmsg : "", - service->url->user, - service->url->host); - service->url->passwd = camel_session_query_authenticator ( - camel_service_get_session (service), - CAMEL_AUTHENTICATOR_ASK, prompt, TRUE, - service, "password", ex); - g_free (prompt); - if (!service->url->passwd) - return FALSE; - } - - if (!service->url->authmech || kpop) { - status = camel_pop3_command (store, &msg, ex, "USER %s", - service->url->user); - switch (status) { - case CAMEL_POP3_ERR: - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Unable to connect to POP " - "server.\nError sending " - "username: %s"), - msg ? msg : _("(Unknown)")); - g_free (msg); - /*fallll*/ - case CAMEL_POP3_FAIL: - return FALSE; - } - g_free (msg); - - status = camel_pop3_command (store, &msg, ex, "PASS %s", - service->url->passwd); - } else if (!strcmp (service->url->authmech, "+APOP") - && store->apop_timestamp) { - char *secret, md5asc[33], *d; - unsigned char md5sum[16], *s; - - secret = g_strdup_printf ("%s%s", store->apop_timestamp, - service->url->passwd); - md5_get_digest (secret, strlen (secret), md5sum); - g_free (secret); - - for (s = md5sum, d = md5asc; d < md5asc + 32; s++, d += 2) - sprintf (d, "%.2x", *s); - - status = camel_pop3_command (store, &msg, ex, "APOP %s %s", - service->url->user, md5asc); - } else { - camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Unable to connect to POP server.\n" - "No support for requested " - "authentication mechanism.")); - return FALSE; - } - - if (status == CAMEL_POP3_ERR) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Unable to connect to POP server.\n" - "Error sending password: %s"), - msg ? msg : _("(Unknown)")); - } - - g_free (msg); - return camel_exception_is_set (ex); -} - -static gboolean -pop3_connect (CamelService *service, CamelException *ex) -{ - char *errbuf = NULL; - gboolean tryagain, kpop = FALSE; - gboolean res; - -#ifdef HAVE_KRB4 - gboolean set_port = FALSE; - - kpop = (service->url->authmech && - !strcmp (service->url->authmech, "+KPOP")); - - if (kpop && service->url->port == 0) { - set_port = TRUE; - service->url->port = KPOP_PORT; - } -#endif - - res = CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex); - -#ifdef HAVE_KRB4 - /* This is veeery nasty. When we set the port, we're changing the - * hash value of our URL. service_cache_remove() gets called when - * we're done checking the mail, but the hash table lookup fails - * because the url port has changed. Then, a finalized instance of - * the CamelService is stuck in the hash table, and the next time - * we try to look up the service, with a URL of port 0, we look - * up the freed service and a segfault results. - */ - - if (kpop && set_port) - service->url->port = 0; -#endif - - if (res == FALSE) - return FALSE; - - /*FIXME integrate these functions */ - if (!connect_to_server (service, ex)) - return FALSE; - - camel_exception_clear (ex); - do { - if (camel_exception_is_set (ex)) { - errbuf = g_strdup_printf ( - "%s\n\n", - camel_exception_get_description (ex)); - camel_exception_clear (ex); - - /* Uncache the password before prompting again. */ - camel_session_query_authenticator ( - camel_service_get_session (service), - CAMEL_AUTHENTICATOR_TELL, NULL, TRUE, service, - "password", ex); - g_free (service->url->passwd); - service->url->passwd = NULL; - } - - tryagain = pop3_try_authenticate (service, kpop, errbuf, ex); - g_free (errbuf); - } while (tryagain); - - if (camel_exception_is_set (ex)) - return FALSE; - - return TRUE; -} - -static gboolean -pop3_disconnect (CamelService *service, gboolean clean, CamelException *ex) -{ - CamelPop3Store *store = CAMEL_POP3_STORE (service); - - if (clean) - camel_pop3_command (store, NULL, ex, "QUIT"); - - if (!CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, clean, ex)) - return FALSE; - - return TRUE; -} - -static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, - guint32 flags, CamelException *ex) -{ - return camel_pop3_folder_new (store, ex); -} - -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - if (!g_strcasecmp (folder_name, "inbox")) - return g_strdup ("inbox"); - else { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID, - _("No such folder `%s'."), folder_name); - return NULL; - } -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup ("inbox"); -} - - -/** - * camel_pop3_command: Send a command to a POP3 server. - * @store: the POP3 store - * @ret: a pointer to return the full server response in - * @fmt: a printf-style format string, followed by arguments - * - * This command sends the command specified by @fmt and the following - * arguments to the connected POP3 store specified by @store. It then - * reads the server's response and parses out the status code. If - * the caller passed a non-NULL pointer for @ret, camel_pop3_command - * will set it to point to an buffer containing the rest of the - * response from the POP3 server. (If @ret was passed but there was - * no extended response, @ret will be set to NULL.) The caller must - * free this buffer when it is done with it. - * - * Return value: one of CAMEL_POP3_OK (command executed successfully), - * CAMEL_POP3_ERR (command encounted an error), or CAMEL_POP3_FAIL - * (a protocol-level error occurred, and Camel is uncertain of the - * result of the command.) - **/ -int -camel_pop3_command (CamelPop3Store *store, char **ret, CamelException *ex, char *fmt, ...) -{ - char *cmdbuf; - va_list ap; - - va_start (ap, fmt); - cmdbuf = g_strdup_vprintf (fmt, ap); - va_end (ap); - - /* Send the command */ - if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex, "%s\r\n", cmdbuf) < 0) { - g_free (cmdbuf); - if (ret) - *ret = NULL; - return CAMEL_POP3_FAIL; - } - g_free (cmdbuf); - - return pop3_get_response (store, ret, ex); -} - -static int -pop3_get_response (CamelPop3Store *store, char **ret, CamelException *ex) -{ - char *respbuf; - int status; - - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0) { - if (ret) - *ret = NULL; - return CAMEL_POP3_FAIL; - } - - if (!strncmp (respbuf, "+OK", 3)) - status = CAMEL_POP3_OK; - else if (!strncmp (respbuf, "-ERR", 4)) - status = CAMEL_POP3_ERR; - else - status = CAMEL_POP3_FAIL; - - if (ret) { - if (status != CAMEL_POP3_FAIL) { - *ret = strchr (respbuf, ' '); - if (*ret) - *ret = g_strdup (*ret + 1); - } else - *ret = NULL; - } - g_free (respbuf); - - return status; -} - -/** - * camel_pop3_command_get_additional_data: get "additional data" from - * a POP3 command. - * @store: the POP3 store - * - * This command gets the additional data returned by "multi-line" POP - * commands, such as LIST, RETR, TOP, and UIDL. This command _must_ - * be called after a successful (CAMEL_POP3_OK) call to - * camel_pop3_command for a command that has a multi-line response. - * The returned data is un-byte-stuffed, and has lines termined by - * newlines rather than CR/LF pairs. - * - * Return value: the data, which the caller must free. - **/ -char * -camel_pop3_command_get_additional_data (CamelPop3Store *store, CamelException *ex) -{ - GPtrArray *data; - char *buf, *p; - int i, len = 0, status = CAMEL_POP3_OK; - - data = g_ptr_array_new (); - while (1) { - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &buf, ex) < 0) { - status = CAMEL_POP3_FAIL; - break; - } - - if (!strcmp (buf, ".")) - break; - - g_ptr_array_add (data, buf); - len += strlen (buf) + 1; - } - - if (buf) - g_free (buf); - - if (status == CAMEL_POP3_OK) { - buf = g_malloc0 (len + 1); - - for (i = 0, p = buf; i < data->len; i++) { - char *ptr, *datap; - - datap = (char *) data->pdata[i]; - ptr = (*datap == '.') ? datap + 1 : datap; - len = strlen (ptr); - memcpy (p, ptr, len); - p += len; - *p++ = '\n'; - } - *p = '\0'; - } else - buf = NULL; - - for (i = 0; i < data->len; i++) - g_free (data->pdata[i]); - g_ptr_array_free (data, TRUE); - - return buf; -} - diff --git a/camel/providers/pop3/camel-pop3-store.h b/camel/providers/pop3/camel-pop3-store.h deleted file mode 100644 index cfa28f313f..0000000000 --- a/camel/providers/pop3/camel-pop3-store.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-pop3-store.h : class for an pop3 store */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_POP3_STORE_H -#define CAMEL_POP3_STORE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-types.h" -#include "camel-remote-store.h" - -#define CAMEL_POP3_STORE_TYPE (camel_pop3_store_get_type ()) -#define CAMEL_POP3_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_POP3_STORE_TYPE, CamelPop3Store)) -#define CAMEL_POP3_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_POP3_STORE_TYPE, CamelPop3StoreClass)) -#define IS_CAMEL_POP3_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_POP3_STORE_TYPE)) - - -typedef struct { - CamelRemoteStore parent_object; - - char *apop_timestamp, *implementation; - gboolean supports_top, supports_uidl, expires; - int login_delay; - -} CamelPop3Store; - - - -typedef struct { - CamelRemoteStoreClass parent_class; - -} CamelPop3StoreClass; - - -/* public methods */ -void camel_pop3_store_expunge (CamelPop3Store *store, CamelException *ex); - -/* support functions */ -enum { CAMEL_POP3_OK, CAMEL_POP3_ERR, CAMEL_POP3_FAIL }; -int camel_pop3_command (CamelPop3Store *store, char **ret, CamelException *ex, char *fmt, ...); -char *camel_pop3_command_get_additional_data (CamelPop3Store *store, - CamelException *ex); - -/* Standard Camel function */ -CamelType camel_pop3_store_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_POP3_STORE_H */ - - diff --git a/camel/providers/pop3/libcamelpop3.urls b/camel/providers/pop3/libcamelpop3.urls deleted file mode 100644 index 7fffa4d861..0000000000 --- a/camel/providers/pop3/libcamelpop3.urls +++ /dev/null @@ -1 +0,0 @@ -pop diff --git a/camel/providers/sendmail/.cvsignore b/camel/providers/sendmail/.cvsignore deleted file mode 100644 index cacc3c5d5f..0000000000 --- a/camel/providers/sendmail/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -Makefile -Makefile.in -.deps -.libs -*.lo -*.la -*.o diff --git a/camel/providers/sendmail/Makefile.am b/camel/providers/sendmail/Makefile.am deleted file mode 100644 index 965f56afb8..0000000000 --- a/camel/providers/sendmail/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelsendmailincludedir = $(includedir)/camel - - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelsendmail.la -provider_DATA = libcamelsendmail.urls - -INCLUDES = \ - -I.. \ - -I$(srcdir)/.. \ - -I$(srcdir)/../../.. \ - -I$(includedir) \ - -I$(top_srcdir)/intl \ - $(GTK_INCLUDEDIR) -I$(top_srcdir)/camel \ - -DG_LOG_DOMAIN=\"camel-sendmail-provider\" - -libcamelsendmail_la_SOURCES = \ - camel-sendmail-provider.c \ - camel-sendmail-transport.c - -libcamelsendmailinclude_HEADERS = \ - camel-sendmail-transport.h - -libcamelsendmail_la_LDFLAGS = -version-info 0:0:0 - -EXTRA_DIST = libcamelsendmail.urls diff --git a/camel/providers/sendmail/camel-sendmail-provider.c b/camel/providers/sendmail/camel-sendmail-provider.c deleted file mode 100644 index d0e40b4cf8..0000000000 --- a/camel/providers/sendmail/camel-sendmail-provider.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-sendmail-provider.c: sendmail provider registration code */ - -/* - * Authors : - * Dan Winship <danw@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-provider.h" -#include "camel-sendmail-transport.h" -#include "camel-session.h" -#include "camel-url.h" - -static CamelProvider sendmail_provider = { - "sendmail", - N_("Sendmail"), - - N_("For delivering mail by passing it to the \"sendmail\" program " - "on the local system."), - - "mail", - - 0, - - 0, - - { 0, 0 }, - - NULL -}; - -void -camel_provider_module_init (CamelSession *session) -{ - sendmail_provider.object_types[CAMEL_PROVIDER_TRANSPORT] = - camel_sendmail_transport_get_type(); - - sendmail_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal); - - camel_session_register_provider (session, &sendmail_provider); -} - - - diff --git a/camel/providers/sendmail/camel-sendmail-transport.c b/camel/providers/sendmail/camel-sendmail-transport.c deleted file mode 100644 index 137c1d32a9..0000000000 --- a/camel/providers/sendmail/camel-sendmail-transport.c +++ /dev/null @@ -1,223 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-sendmail-transport.c: Sendmail-based transport class. */ - -/* - * - * Author : - * Dan Winship <danw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> - -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> -#include <unistd.h> -#include <string.h> - -#include "camel-sendmail-transport.h" -#include "camel-mime-message.h" -#include "camel-data-wrapper.h" -#include "camel-stream-fs.h" -#include "camel-exception.h" - -static char *get_name (CamelService *service, gboolean brief); - -static gboolean _can_send (CamelTransport *transport, CamelMedium *message); -static gboolean _send (CamelTransport *transport, CamelMedium *message, - CamelException *ex); -static gboolean _send_to (CamelTransport *transport, CamelMedium *message, - GList *recipients, CamelException *ex); - - -static void -camel_sendmail_transport_class_init (CamelSendmailTransportClass *camel_sendmail_transport_class) -{ - CamelTransportClass *camel_transport_class = - CAMEL_TRANSPORT_CLASS (camel_sendmail_transport_class); - CamelServiceClass *camel_service_class = - CAMEL_SERVICE_CLASS (camel_sendmail_transport_class); - - /* virtual method overload */ - camel_service_class->get_name = get_name; - - camel_transport_class->can_send = _can_send; - camel_transport_class->send = _send; - camel_transport_class->send_to = _send_to; -} - -CamelType -camel_sendmail_transport_get_type (void) -{ - static CamelType camel_sendmail_transport_type = CAMEL_INVALID_TYPE; - - if (camel_sendmail_transport_type == CAMEL_INVALID_TYPE) { - camel_sendmail_transport_type = camel_type_register (CAMEL_TRANSPORT_TYPE, "CamelSendmailTransport", - sizeof (CamelSendmailTransport), - sizeof (CamelSendmailTransportClass), - (CamelObjectClassInitFunc) camel_sendmail_transport_class_init, - NULL, - (CamelObjectInitFunc) NULL, - NULL); - } - - return camel_sendmail_transport_type; -} - - -static gboolean -_can_send (CamelTransport *transport, CamelMedium *message) -{ - return CAMEL_IS_MIME_MESSAGE (message); -} - - -static gboolean -_send_internal (CamelMedium *message, char **argv, CamelException *ex) -{ - int fd[2], nullfd, wstat; - sigset_t mask, omask; - CamelStream *out; - pid_t pid; - - g_assert (CAMEL_IS_MIME_MESSAGE (message)); - - if (pipe (fd) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not create pipe to sendmail: " - "%s: mail not sent"), - g_strerror (errno)); - return FALSE; - } - - /* Block SIGCHLD so the calling application doesn't notice - * sendmail exiting before we do. - */ - sigemptyset (&mask); - sigaddset (&mask, SIGCHLD); - sigprocmask (SIG_BLOCK, &mask, &omask); - - pid = fork (); - switch (pid) { - case -1: - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not fork sendmail: " - "%s: mail not sent"), - g_strerror (errno)); - sigprocmask (SIG_SETMASK, &omask, NULL); - return FALSE; - - case 0: - /* Child process */ - nullfd = open ("/dev/null", O_RDWR); - dup2 (fd[0], STDIN_FILENO); - dup2 (nullfd, STDOUT_FILENO); - dup2 (nullfd, STDERR_FILENO); - close (nullfd); - close (fd[1]); - - execv (SENDMAIL_PATH, argv); - _exit (255); - } - - /* Parent process. Write the message out. */ - close (fd[0]); - out = camel_stream_fs_new_with_fd (fd[1]); - if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), out) == -1 - || camel_stream_close(out) == -1) { - camel_object_unref (CAMEL_OBJECT (out)); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not send message: %s"), - strerror(errno)); - return FALSE; - } - camel_object_unref (CAMEL_OBJECT (out)); - - /* Wait for sendmail to exit. */ - while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR) - ; - sigprocmask (SIG_SETMASK, &omask, NULL); - - if (!WIFEXITED (wstat)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("sendmail exited with signal %s: " - "mail not sent."), - g_strsignal (WTERMSIG (wstat))); - return FALSE; - } else if (WEXITSTATUS (wstat) != 0) { - if (WEXITSTATUS (wstat) == 255) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not execute %s: " - "mail not sent."), - SENDMAIL_PATH); - } else { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("sendmail exited with status " - "%d: mail not sent."), - WEXITSTATUS (wstat)); - } - return FALSE; - } - - return TRUE; -} - -static gboolean -_send_to (CamelTransport *transport, CamelMedium *message, - GList *recipients, CamelException *ex) -{ - GList *r; - char **argv; - int i, len; - gboolean status; - - len = g_list_length (recipients); - argv = g_malloc ((len + 4) * sizeof (char *)); - argv[0] = "sendmail"; - argv[1] = "-i"; - argv[2] = "--"; - - for (i = 1, r = recipients; i <= len; i++, r = r->next) - argv[i + 2] = r->data; - argv[i + 2] = NULL; - - status = _send_internal (message, argv, ex); - g_free (argv); - return status; -} - -static gboolean -_send (CamelTransport *transport, CamelMedium *message, - CamelException *ex) -{ - char *argv[4] = { "sendmail", "-t", "-i", NULL }; - - return _send_internal (message, argv, ex); -} - -static char * -get_name (CamelService *service, gboolean brief) -{ - if (brief) - return g_strdup (_("sendmail")); - else - return g_strdup (_("Mail delivery via the sendmail program")); -} diff --git a/camel/providers/sendmail/camel-sendmail-transport.h b/camel/providers/sendmail/camel-sendmail-transport.h deleted file mode 100644 index bb5dca071b..0000000000 --- a/camel/providers/sendmail/camel-sendmail-transport.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-sendmail-transport.h: Sendmail-based transport class */ - -/* - * - * Author : - * Dan Winship <danw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_SENDMAIL_TRANSPORT_H -#define CAMEL_SENDMAIL_TRANSPORT_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include "camel-transport.h" - -#define CAMEL_SENDMAIL_TRANSPORT_TYPE (camel_sendmail_transport_get_type ()) -#define CAMEL_SENDMAIL_TRANSPORT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SENDMAIL_TRANSPORT_TYPE, CamelSendmailTransport)) -#define CAMEL_SENDMAIL_TRANSPORT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SENDMAIL_TRANSPORT_TYPE, CamelSendmailTransportClass)) -#define CAMEL_IS_SENDMAIL_TRANSPORT(o) (CAMEL_CHECK_TYPE((o), CAMEL_SENDMAIL_TRANSPORT_TYPE)) - - -typedef struct { - CamelTransport parent_object; - -} CamelSendmailTransport; - - -typedef struct { - CamelTransportClass parent_class; - -} CamelSendmailTransportClass; - - -/* Standard Camel function */ -CamelType camel_sendmail_transport_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_SENDMAIL_TRANSPORT_H */ diff --git a/camel/providers/sendmail/libcamelsendmail.urls b/camel/providers/sendmail/libcamelsendmail.urls deleted file mode 100644 index ccad52828e..0000000000 --- a/camel/providers/sendmail/libcamelsendmail.urls +++ /dev/null @@ -1 +0,0 @@ -sendmail diff --git a/camel/providers/smtp/.cvsignore b/camel/providers/smtp/.cvsignore deleted file mode 100644 index 09980ae6ba..0000000000 --- a/camel/providers/smtp/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.lo -*.la diff --git a/camel/providers/smtp/Makefile.am b/camel/providers/smtp/Makefile.am deleted file mode 100644 index 734a4e5128..0000000000 --- a/camel/providers/smtp/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelsmtpincludedir = $(includedir)/camel - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelsmtp.la -provider_DATA = libcamelsmtp.urls - -INCLUDES = \ - -I.. \ - -I$(srcdir)/.. \ - -I$(srcdir)/../../.. \ - -I$(includedir) \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/e-util \ - $(GTK_INCLUDEDIR) \ - -DG_LOG_DOMAIN=\"camel-smtp-provider\" - -libcamelsmtp_la_SOURCES = \ - camel-smtp-provider.c \ - camel-smtp-transport.c - -libcamelsmtpinclude_HEADERS = \ - camel-smtp-transport.h - - -libcamelsmtp_la_LDFLAGS = -version-info 0:0:0 - -libcamelsmtp_la_LIBADD = $(top_builddir)/e-util/libeutil.la $(UNICODE_LIBS) - -EXTRA_DIST = libcamelsmtp.urls diff --git a/camel/providers/smtp/camel-smtp-provider.c b/camel/providers/smtp/camel-smtp-provider.c deleted file mode 100644 index 6d94536937..0000000000 --- a/camel/providers/smtp/camel-smtp-provider.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-smtp-provider.c: smtp provider registration code */ - -/* - * Authors : - * Jeffrey Stedfast <fejj@stampede.org> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-smtp-transport.h" -#include "camel-provider.h" -#include "camel-session.h" -#include "camel-url.h" - -static CamelProvider smtp_provider = { - "smtp", - "SMTP", - - N_("For delivering mail by connecting to a remote mailhub " - "using SMTP."), - - "mail", - - CAMEL_PROVIDER_IS_REMOTE, - - CAMEL_URL_NEED_HOST, - - { 0, 0 }, - - NULL -}; - -void -camel_provider_module_init (CamelSession *session) -{ - smtp_provider.object_types[CAMEL_PROVIDER_TRANSPORT] = - camel_smtp_transport_get_type(); - - smtp_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal); - - camel_session_register_provider (session, &smtp_provider); -} - - - diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c deleted file mode 100644 index 6fa39bb930..0000000000 --- a/camel/providers/smtp/camel-smtp-transport.c +++ /dev/null @@ -1,788 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-smtp-transport.c : class for a smtp transport */ - -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#undef MIN -#undef MAX -#include "camel-mime-filter-crlf.h" -#include "camel-mime-filter-linewrap.h" -#include "camel-stream-filter.h" -#include "camel-smtp-transport.h" -#include "camel-mime-message.h" -#include "camel-multipart.h" -#include "camel-mime-part.h" -#include "camel-stream-buffer.h" -#include "camel-stream-fs.h" -#include "camel-session.h" -#include "camel-exception.h" - -#define d(x) x - -/* Specified in RFC 821 */ -#define SMTP_PORT 25 - -/* camel smtp transport class prototypes */ -static gboolean _can_send (CamelTransport *transport, CamelMedium *message); -static gboolean _send (CamelTransport *transport, CamelMedium *message, CamelException *ex); -static gboolean _send_to (CamelTransport *transport, CamelMedium *message, GList *recipients, CamelException *ex); - -/* support prototypes */ -static gboolean smtp_connect (CamelService *service, CamelException *ex); -static gboolean smtp_disconnect (CamelService *service, gboolean clean, CamelException *ex); -static GList *esmtp_get_authtypes(gchar *buffer); -static GList *query_auth_types_connected (CamelService *service, CamelException *ex); -static GList *query_auth_types_generic (CamelService *service, CamelException *ex); -static void free_auth_types (CamelService *service, GList *authtypes); -static char *get_name (CamelService *service, gboolean brief); - -static gboolean smtp_helo (CamelSmtpTransport *transport, CamelException *ex); -static gboolean smtp_mail (CamelSmtpTransport *transport, const char *sender, - gboolean has_8bit_parts, CamelException *ex); -static gboolean smtp_rcpt (CamelSmtpTransport *transport, const char *recipient, CamelException *ex); -static gboolean smtp_data (CamelSmtpTransport *transport, CamelMedium *message, - gboolean has_8bit_parts, CamelException *ex); -static gboolean smtp_rset (CamelSmtpTransport *transport, CamelException *ex); -static gboolean smtp_quit (CamelSmtpTransport *transport, CamelException *ex); - -/* private data members */ -static CamelServiceClass *service_class = NULL; - -static void -camel_smtp_transport_class_init (CamelSmtpTransportClass *camel_smtp_transport_class) -{ - CamelTransportClass *camel_transport_class = - CAMEL_TRANSPORT_CLASS (camel_smtp_transport_class); - CamelServiceClass *camel_service_class = - CAMEL_SERVICE_CLASS (camel_smtp_transport_class); - - service_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ())); - - /* virtual method overload */ - camel_service_class->connect = smtp_connect; - camel_service_class->disconnect = smtp_disconnect; - camel_service_class->query_auth_types_generic = query_auth_types_generic; - camel_service_class->query_auth_types_connected = query_auth_types_connected; - camel_service_class->free_auth_types = free_auth_types; - camel_service_class->get_name = get_name; - - camel_transport_class->can_send = _can_send; - camel_transport_class->send = _send; - camel_transport_class->send_to = _send_to; -} - -static void -camel_smtp_transport_init (gpointer object) -{ - CamelTransport *transport = CAMEL_TRANSPORT (object); - - transport->supports_8bit = FALSE; -} - -CamelType -camel_smtp_transport_get_type (void) -{ - static CamelType camel_smtp_transport_type = CAMEL_INVALID_TYPE; - - if (camel_smtp_transport_type == CAMEL_INVALID_TYPE) { - camel_smtp_transport_type = - camel_type_register (CAMEL_TRANSPORT_TYPE, "CamelSmtpTransport", - sizeof (CamelSmtpTransport), - sizeof (CamelSmtpTransportClass), - (CamelObjectClassInitFunc) camel_smtp_transport_class_init, - NULL, - (CamelObjectInitFunc) camel_smtp_transport_init, - NULL); - } - - return camel_smtp_transport_type; -} - -static gboolean -smtp_connect (CamelService *service, CamelException *ex) -{ - CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service); - struct hostent *h; - struct sockaddr_in sin; - gint fd, num, i; - guint32 addrlen; - gchar *pass = NULL, *respbuf = NULL; - - if (!service_class->connect (service, ex)) - return FALSE; - - h = camel_service_gethost (service, ex); - if (!h) - return FALSE; - - /* set some smtp transport defaults */ - transport->is_esmtp = FALSE; - transport->esmtp_supported_authtypes = NULL; - CAMEL_TRANSPORT (transport)->supports_8bit = FALSE; - - sin.sin_family = h->h_addrtype; - sin.sin_port = htons (service->url->port ? service->url->port : SMTP_PORT); - memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr)); - - fd = socket (h->h_addrtype, SOCK_STREAM, 0); - if (fd == -1 || connect (fd, (struct sockaddr *)&sin, sizeof (sin)) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not connect to %s (port %d): %s", - service->url->host, - service->url->port ? service->url->port : SMTP_PORT, - strerror (errno)); - if (fd > -1) - close (fd); - g_free (pass); - return FALSE; - } - - /* get the localaddr - needed later by smtp_helo */ - addrlen = sizeof (transport->localaddr); - getsockname (fd, (struct sockaddr*)&transport->localaddr, &addrlen); - - transport->ostream = camel_stream_fs_new_with_fd (fd); - transport->istream = camel_stream_buffer_new (transport->ostream, - CAMEL_STREAM_BUFFER_READ); - - /* Read the greeting, note whether the server is ESMTP or not. */ - do { - /* Check for "220" */ - g_free (respbuf); - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream)); - if (!respbuf || strncmp (respbuf, "220", 3)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Welcome response error: " - "%s: possibly non-fatal", - g_strerror (errno)); - return FALSE; - } - if (strstr (respbuf, "ESMTP")) - transport->is_esmtp = TRUE; - } while (*(respbuf+3) == '-'); /* if we got "220-" then loop again */ - g_free (respbuf); - - /* send HELO (or EHLO, depending on the service type) */ - if (!transport->is_esmtp) { - /* If we did not auto-detect ESMTP, we should still send EHLO */ - transport->is_esmtp = TRUE; - if (!smtp_helo (transport, ex)) { - /* Okay, apprently this server doesn't support ESMTP */ - transport->is_esmtp = FALSE; - smtp_helo (transport, ex); - } - } else { - smtp_helo (transport, ex); - } - - /* check to see if AUTH is required, if so...then AUTH ourselves */ - if (transport->is_esmtp && transport->esmtp_supported_authtypes) { - /* not really supported yet, but we can at least show what auth types are supported */ - d(fprintf (stderr, "camel-smtp-transport::connect(): %s requires AUTH\n", service->url->host)); - num = g_list_length (transport->esmtp_supported_authtypes); - - for (i = 0; i < num; i++) - d(fprintf (stderr, "\nSupported AUTH: %s\n\n", - (gchar *) g_list_nth_data (transport->esmtp_supported_authtypes, i))); - - g_list_free (transport->esmtp_supported_authtypes); - transport->esmtp_supported_authtypes = NULL; - } else { - d(fprintf (stderr, "\ncamel-smtp-transport::connect(): provider does not use AUTH\n\n")); - } - - return TRUE; -} - -static gboolean -smtp_disconnect (CamelService *service, gboolean clean, CamelException *ex) -{ - CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service); - - /*if (!service->connected) - * return TRUE; - */ - - if (clean) { - /* send the QUIT command to the SMTP server */ - smtp_quit (transport, ex); - } - - if (!service_class->disconnect (service, clean, ex)) - return FALSE; - - g_free (transport->esmtp_supported_authtypes); - transport->esmtp_supported_authtypes = NULL; - camel_object_unref (CAMEL_OBJECT (transport->ostream)); - camel_object_unref (CAMEL_OBJECT (transport->istream)); - transport->ostream = NULL; - transport->istream = NULL; - - return TRUE; -} - -static GList * -esmtp_get_authtypes (gchar *buffer) -{ - GList *ret = NULL; - gchar *start, *end; - - /* advance to the first token */ - for (start = buffer; *start == ' ' || *start == '='; start++); - - for ( ; *start; ) { - /* advance to the end of the token */ - for (end = start; *end && *end != ' '; end++); - - ret = g_list_append (ret, g_strndup (start, end - start)); - - /* advance to the next token */ - for (start = end; *start == ' '; start++); - } - - return ret; -} - -/* FIXME: use these? */ -#ifdef notyet -static CamelServiceAuthType no_authtype = { - "No authentication required", - - "This option will connect to the SMTP server without using any " - "kind of authentication. This should be fine for connecting to " - "most SMTP servers." - - "", - FALSE -}; - -static CamelServiceAuthType cram_md5_authtype = { - "CRAM-MD5", - - "This option will connect to the SMTP server using CRAM-MD5 " - "authentication.", - - "CRAM-MD5", - TRUE -}; -#endif - -static GList * -query_auth_types_connected (CamelService *service, CamelException *ex) -{ - /* FIXME: Re-enable this when auth types are actually - * implemented. - */ - - return NULL; -} - -static GList * -query_auth_types_generic (CamelService *service, CamelException *ex) -{ - /* FIXME: Re-enable this when auth types are actually - * implemented. - */ - - return NULL; -} - -static void -free_auth_types (CamelService *service, GList *authtypes) -{ - g_list_free (authtypes); -} - -static char * -get_name (CamelService *service, gboolean brief) -{ - if (brief) - return g_strdup_printf ("SMTP server %s", service->url->host); - else { - return g_strdup_printf ("SMTP mail delivery via %s", - service->url->host); - } -} - -static gboolean -_can_send (CamelTransport *transport, CamelMedium *message) -{ - return CAMEL_IS_MIME_MESSAGE (message); -} - -static gboolean -_send_to (CamelTransport *transport, CamelMedium *message, - GList *recipients, CamelException *ex) -{ - CamelSmtpTransport *smtp_transport = CAMEL_SMTP_TRANSPORT (transport); - CamelInternetAddress *cia; - char *recipient, *sender; - const char *addr; - gboolean has_8bit_parts; - GList *r; - - sender = g_strdup (camel_mime_message_get_from (CAMEL_MIME_MESSAGE (message))); - if (!sender) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Cannot send message: " - "sender address not defined."); - return FALSE; - } - - cia = camel_internet_address_new (); - camel_address_decode (CAMEL_ADDRESS (cia), sender); - g_free (sender); - - if (!camel_internet_address_get (cia, 0, NULL, &addr)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Cannot send message: " - "sender address not valid."); - return FALSE; - } - - /* find out if the message has 8bit mime parts */ - has_8bit_parts = camel_mime_message_has_8bit_parts (CAMEL_MIME_MESSAGE (message)); - - /* rfc1652 (8BITMIME) requires that you notify the ESMTP daemon that - you'll be sending an 8bit mime message at "MAIL FROM:" time. */ - smtp_mail (smtp_transport, addr, has_8bit_parts, ex); - - if (!recipients) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Cannot send message: " - "no recipients defined."); - return FALSE; - } - - for (r = recipients; r; r = r->next) { - recipient = (char *) r->data; - if (!smtp_rcpt (smtp_transport, recipient, ex)) { - g_free (recipient); - return FALSE; - } - g_free (recipient); - } - - /* passing in has_8bit_parts saves time as we don't have to - recurse through the message all over again if the user is - not sending 8bit mime parts */ - if (!smtp_data (smtp_transport, message, has_8bit_parts, ex)) - return FALSE; - - /* reset the service for our next transfer session */ - smtp_rset (smtp_transport, ex); - - return TRUE; -} - -static gboolean -_send (CamelTransport *transport, CamelMedium *message, CamelException *ex) -{ - const CamelInternetAddress *to, *cc, *bcc; - GList *recipients = NULL; - guint index, len; - - to = camel_mime_message_get_recipients (CAMEL_MIME_MESSAGE (message), CAMEL_RECIPIENT_TYPE_TO); - cc = camel_mime_message_get_recipients (CAMEL_MIME_MESSAGE (message), CAMEL_RECIPIENT_TYPE_CC); - bcc = camel_mime_message_get_recipients (CAMEL_MIME_MESSAGE (message), CAMEL_RECIPIENT_TYPE_BCC); - - /* get all of the To addresses into our recipient list */ - len = CAMEL_ADDRESS (to)->addresses->len; - for (index = 0; index < len; index++) { - const char *addr; - - if (camel_internet_address_get (to, index, NULL, &addr)) - recipients = g_list_append (recipients, g_strdup (addr)); - } - - /* get all of the Cc addresses into our recipient list */ - len = CAMEL_ADDRESS (cc)->addresses->len; - for (index = 0; index < len; index++) { - const char *addr; - - if (camel_internet_address_get (cc, index, NULL, &addr)) - recipients = g_list_append (recipients, g_strdup (addr)); - } - - /* get all of the Bcc addresses into our recipient list */ - len = CAMEL_ADDRESS (bcc)->addresses->len; - for (index = 0; index < len; index++) { - const char *addr; - - if (camel_internet_address_get (bcc, index, NULL, &addr)) - recipients = g_list_append (recipients, g_strdup (addr)); - } - - return _send_to (transport, message, recipients, ex); -} - -static gboolean -smtp_helo (CamelSmtpTransport *transport, CamelException *ex) -{ - /* say hello to the server */ - gchar *cmdbuf, *respbuf = NULL; - struct hostent *host; - - /* get the local host name */ - host = gethostbyaddr ((gchar *)&transport->localaddr.sin_addr, sizeof (transport->localaddr.sin_addr), AF_INET); - - /* hiya server! how are you today? */ - if (transport->is_esmtp) { - if (host && host->h_name) - cmdbuf = g_strdup_printf ("EHLO %s\r\n", host->h_name); - else - cmdbuf = g_strdup_printf ("EHLO [%s]\r\n", inet_ntoa (transport->localaddr.sin_addr)); - } else { - if (host && host->h_name) - cmdbuf = g_strdup_printf ("HELO %s\r\n", host->h_name); - else - cmdbuf = g_strdup_printf ("HELO [%s]\r\n", inet_ntoa (transport->localaddr.sin_addr)); - } - - d(fprintf (stderr, "sending : %s", cmdbuf)); - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) { - g_free (cmdbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "HELO request timed out: " - "%s: non-fatal", - g_strerror (errno)); - return FALSE; - } - g_free (cmdbuf); - - do { - /* Check for "250" */ - g_free (respbuf); - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream)); - - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - if (!respbuf || strncmp (respbuf, "250", 3)) { - g_free (respbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "HELO response error: " - "%s: non-fatal", - g_strerror (errno)); - return FALSE; - } - - if (strstr (respbuf, "8BITMIME")) { - d(fprintf (stderr, "This server supports 8bit\n")); - CAMEL_TRANSPORT (transport)->supports_8bit = TRUE; - } - - if (transport->is_esmtp && strstr (respbuf, "AUTH")) { - /* parse for supported AUTH types */ - char *auths = strstr (respbuf, "AUTH") + 4; - - transport->esmtp_supported_authtypes = esmtp_get_authtypes (auths); - } - } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */ - g_free (respbuf); - - return TRUE; -} - -static gboolean -smtp_mail (CamelSmtpTransport *transport, const char *sender, gboolean has_8bit_parts, CamelException *ex) -{ - /* we gotta tell the smtp server who we are. (our email addy) */ - gchar *cmdbuf, *respbuf = NULL; - - /* enclose address in <>'s since some SMTP daemons *require* that */ - if (CAMEL_TRANSPORT (transport)->supports_8bit && has_8bit_parts) - cmdbuf = g_strdup_printf ("MAIL FROM: <%s> BODY=8BITMIME\r\n", sender); - else - cmdbuf = g_strdup_printf ("MAIL FROM: <%s>\r\n", sender); - - d(fprintf (stderr, "sending : %s", cmdbuf)); - - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) { - g_free (cmdbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "MAIL FROM request timed out: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - g_free (cmdbuf); - - do { - /* Check for "250 Sender OK..." */ - g_free (respbuf); - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream)); - - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - if (!respbuf || strncmp (respbuf, "250", 3)) { - g_free (respbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "MAIL FROM response error: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */ - g_free (respbuf); - - return TRUE; -} - -static gboolean -smtp_rcpt (CamelSmtpTransport *transport, const char *recipient, CamelException *ex) -{ - /* we gotta tell the smtp server who we are going to be sending - * our email to */ - gchar *cmdbuf, *respbuf = NULL; - - /* enclose address in <>'s since some SMTP daemons *require* that */ - cmdbuf = g_strdup_printf ("RCPT TO: <%s>\r\n", recipient); - - d(fprintf (stderr, "sending : %s", cmdbuf)); - - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) { - g_free (cmdbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "RCPT TO request timed out: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - g_free (cmdbuf); - - do { - /* Check for "250 Sender OK..." */ - g_free (respbuf); - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream)); - - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - if (!respbuf || strncmp (respbuf, "250", 3)) { - g_free (respbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "RCPT TO response error: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */ - g_free (respbuf); - - return TRUE; -} - -static gboolean -smtp_data (CamelSmtpTransport *transport, CamelMedium *message, gboolean has_8bit_parts, CamelException *ex) -{ - /* now we can actually send what's important :p */ - gchar *cmdbuf, *respbuf = NULL; - CamelStreamFilter *filtered_stream; - CamelMimeFilter *crlffilter, *lwfilter; - gint crlfid, lwid; - - - /* if the message contains 8bit mime parts and the server - doesn't support it, encode 8bit parts to the best - encoding. */ - if (has_8bit_parts && !CAMEL_TRANSPORT (transport)->supports_8bit) - camel_mime_message_encode_8bit_parts (CAMEL_MIME_MESSAGE (message)); - - cmdbuf = g_strdup ("DATA\r\n"); - - d(fprintf (stderr, "sending : %s", cmdbuf)); - - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) { - g_free (cmdbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "DATA request timed out: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - g_free (cmdbuf); - - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream)); - - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - if (!respbuf || strncmp (respbuf, "354", 3)) { - /* we should have gotten instructions on how to use the DATA command: - * 354 Enter mail, end with "." on a line by itself - */ - g_free (respbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "DATA response error: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - - g_free (respbuf); - respbuf = NULL; - - /* setup stream filtering */ - lwfilter = camel_mime_filter_linewrap_new (998, 998, '\t'); - crlffilter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_DOTS); - - filtered_stream = camel_stream_filter_new_with_stream (transport->ostream); - lwid = camel_stream_filter_add (filtered_stream, CAMEL_MIME_FILTER (lwfilter)); - crlfid = camel_stream_filter_add (filtered_stream, CAMEL_MIME_FILTER (crlffilter)); - - if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), CAMEL_STREAM (filtered_stream)) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "DATA send timed out: message termination: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - - camel_stream_filter_remove (filtered_stream, lwid); - camel_stream_filter_remove (filtered_stream, crlfid); - camel_stream_flush (CAMEL_STREAM (filtered_stream)); - camel_object_unref (CAMEL_OBJECT (filtered_stream)); - - /* terminate the message body */ - - d(fprintf (stderr, "sending : \\r\\n.\\r\\n\n")); - - if (camel_stream_write (transport->ostream, "\r\n.\r\n", 5) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "DATA send timed out: message termination: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - - do { - /* Check for "250 Sender OK..." */ - g_free (respbuf); - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream)); - - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - if (!respbuf || strncmp (respbuf, "250", 3)) { - g_free (respbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "DATA response error: message termination: " - "%s: mail not sent", - g_strerror (errno)); - return FALSE; - } - } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */ - g_free (respbuf); - - return TRUE; -} - -static gboolean -smtp_rset (CamelSmtpTransport *transport, CamelException *ex) -{ - /* we are going to reset the smtp server (just to be nice) */ - gchar *cmdbuf, *respbuf = NULL; - - cmdbuf = g_strdup ("RSET\r\n"); - - d(fprintf (stderr, "sending : %s", cmdbuf)); - - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) { - g_free (cmdbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "RSET request timed out: " - "%s", - g_strerror (errno)); - return FALSE; - } - g_free (cmdbuf); - - do { - /* Check for "250" */ - g_free (respbuf); - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream)); - - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - if (!respbuf || strncmp (respbuf, "250", 3)) { - g_free (respbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "RSET response error: %s", - g_strerror (errno)); - return FALSE; - } - } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */ - g_free (respbuf); - - return TRUE; -} - -static gboolean -smtp_quit (CamelSmtpTransport *transport, CamelException *ex) -{ - /* we are going to reset the smtp server (just to be nice) */ - gchar *cmdbuf, *respbuf = NULL; - - cmdbuf = g_strdup ("QUIT\r\n"); - - d(fprintf (stderr, "sending : %s", cmdbuf)); - - if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) { - g_free (cmdbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "QUIT request timed out: " - "%s: non-fatal", - g_strerror (errno)); - return FALSE; - } - g_free (cmdbuf); - - do { - /* Check for "221" */ - g_free (respbuf); - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream)); - - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - if (!respbuf || strncmp (respbuf, "221", 3)) { - g_free (respbuf); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "QUIT response error: " - "%s: non-fatal", - g_strerror (errno)); - return FALSE; - } - } while (*(respbuf+3) == '-'); /* if we got "221-" then loop again */ - g_free (respbuf); - - return TRUE; -} diff --git a/camel/providers/smtp/camel-smtp-transport.h b/camel/providers/smtp/camel-smtp-transport.h deleted file mode 100644 index b880230add..0000000000 --- a/camel/providers/smtp/camel-smtp-transport.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-smtp-transport.h : class for an smtp transfer */ - -/* - * Authors: - * Jeffrey Stedfast <fejj@stampede.org> - * - * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_SMTP_TRANSPORT_H -#define CAMEL_SMTP_TRANSPORT_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include "camel-transport.h" - -#define CAMEL_SMTP_TRANSPORT_TYPE (camel_smtp_transport_get_type ()) -#define CAMEL_SMTP_TRANSPORT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SMTP_TRANSPORT_TYPE, CamelSmtpTransport)) -#define CAMEL_SMTP_TRANSPORT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SMTP_TRANSPORT_TYPE, CamelSmtpTransportClass)) -#define IS_CAMEL_SMTP_TRANSPORT(o) (CAMEL_CHECK_TYPE((o), CAMEL_SMTP_TRANSPORT_TYPE)) - - -typedef struct { - CamelTransport parent_object; - - CamelStream *istream, *ostream; - - gboolean is_esmtp; - - struct sockaddr_in localaddr; - - GList *esmtp_supported_authtypes; - -} CamelSmtpTransport; - - - -typedef struct { - CamelTransportClass parent_class; - -} CamelSmtpTransportClass; - - -/* Standard Camel function */ -CamelType camel_smtp_transport_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_SMTP_TRANSPORT_H */ - - diff --git a/camel/providers/smtp/libcamelsmtp.urls b/camel/providers/smtp/libcamelsmtp.urls deleted file mode 100644 index ec2fc0fc16..0000000000 --- a/camel/providers/smtp/libcamelsmtp.urls +++ /dev/null @@ -1 +0,0 @@ -smtp diff --git a/camel/providers/vee/.cvsignore b/camel/providers/vee/.cvsignore deleted file mode 100644 index fd6b811c68..0000000000 --- a/camel/providers/vee/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la diff --git a/camel/providers/vee/Makefile.am b/camel/providers/vee/Makefile.am deleted file mode 100644 index 6c0693b02d..0000000000 --- a/camel/providers/vee/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelveeincludedir = $(includedir)/camel - - -providerdir = $(pkglibdir)/camel-providers/$(VERSION) - -provider_LTLIBRARIES = libcamelvee.la -provider_DATA = libcamelvee.urls - -INCLUDES = -I.. \ - -I$(srcdir)/.. \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/libibex \ - -I$(top_srcdir)/e-util \ - -I$(top_srcdir) \ - -I$(includedir) \ - $(GTK_INCLUDEDIR) \ - -DG_LOG_DOMAIN=\"camel-vee-provider\" - -libcamelvee_la_SOURCES = \ - camel-vee-folder.c \ - camel-vee-provider.c \ - camel-vee-store.c - -libcamelveeinclude_HEADERS = \ - camel-vee-folder.h \ - camel-vee-store.h - -libcamelvee_la_LDFLAGS = -version-info 0:0:0 - -libcamelvee_la_LIBADD = $(top_builddir)/e-util/libeutil.la $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) -#libcamelvee_la_LIBADD = $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) - -EXTRA_DIST = libcamelvee.urls - diff --git a/camel/providers/vee/camel-vee-folder.c b/camel/providers/vee/camel-vee-folder.c deleted file mode 100644 index da47761754..0000000000 --- a/camel/providers/vee/camel-vee-folder.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "camel-exception.h" -#include "camel-vee-folder.h" -#include "camel-folder-summary.h" -#include "camel-mime-message.h" - -#include <string.h> - -/* our message info includes the parent folder */ -typedef struct _CamelVeeMessageInfo { - CamelMessageInfo info; - CamelFolder *folder; -} CamelVeeMessageInfo; - -struct _CamelVeeFolderPrivate { - GList *folders; -}; - -#define _PRIVATE(o) (((CamelVeeFolder *)(o))->priv) - -static void vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex); - -static GPtrArray *vee_get_uids (CamelFolder *folder); -GPtrArray *vee_get_summary (CamelFolder *folder); - -static gint vee_get_message_count (CamelFolder *folder); -static gint vee_get_unread_message_count (CamelFolder *folder); -static CamelMimeMessage *vee_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex); - -static const CamelMessageInfo *vee_get_message_info (CamelFolder *folder, const char *uid); -static GPtrArray *vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); - -static guint32 vee_get_message_flags (CamelFolder *folder, const char *uid); -static void vee_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set); -static gboolean vee_get_message_user_flag (CamelFolder *folder, const char *uid, const char *name); -static void vee_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, gboolean value); - - -static void camel_vee_folder_class_init (CamelVeeFolderClass *klass); -static void camel_vee_folder_init (CamelVeeFolder *obj); -static void camel_vee_folder_finalise (CamelObject *obj); - -static void vee_folder_build(CamelVeeFolder *vf, CamelException *ex); -static void vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex); - -static CamelFolderClass *camel_vee_folder_parent; - -CamelType -camel_vee_folder_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register (camel_folder_get_type (), "CamelVeeFolder", - sizeof (CamelVeeFolder), - sizeof (CamelVeeFolderClass), - (CamelObjectClassInitFunc) camel_vee_folder_class_init, - NULL, - (CamelObjectInitFunc) camel_vee_folder_init, - (CamelObjectFinalizeFunc) camel_vee_folder_finalise); - } - - return type; -} - -static void -camel_vee_folder_class_init (CamelVeeFolderClass *klass) -{ - CamelFolderClass *folder_class = (CamelFolderClass *) klass; - - camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ())); - - folder_class->sync = vee_sync; - - folder_class->get_uids = vee_get_uids; - folder_class->free_uids = camel_folder_free_deep; - folder_class->get_summary = vee_get_summary; - folder_class->free_summary = camel_folder_free_nop; - folder_class->get_message = vee_get_message; - - folder_class->get_message_info = vee_get_message_info; - - folder_class->get_message_count = vee_get_message_count; - folder_class->get_unread_message_count = vee_get_unread_message_count; - folder_class->search_by_expression = vee_search_by_expression; - - folder_class->get_message_flags = vee_get_message_flags; - folder_class->set_message_flags = vee_set_message_flags; - folder_class->get_message_user_flag = vee_get_message_user_flag; - folder_class->set_message_user_flag = vee_set_message_user_flag; -} - -static void -camel_vee_folder_init (CamelVeeFolder *obj) -{ - struct _CamelVeeFolderPrivate *p; - CamelFolder *folder = (CamelFolder *)obj; - - p = _PRIVATE(obj) = g_malloc0(sizeof(*p)); - - folder->has_summary_capability = TRUE; - folder->has_search_capability = TRUE; - - /* FIXME: what to do about user flags if the subfolder doesn't support them? */ - folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | - CAMEL_MESSAGE_DELETED | - CAMEL_MESSAGE_DRAFT | - CAMEL_MESSAGE_FLAGGED | - CAMEL_MESSAGE_SEEN; -} - -static void -camel_vee_folder_finalise (CamelObject *obj) -{ - CamelVeeFolder *vf = (CamelVeeFolder *)obj; - struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); - GList *node; - - node = p->folders; - while (node) { - CamelFolder *f = node->data; - camel_object_unref((CamelObject *)f); - node = g_list_next(node); - } -} - -/** - * camel_vee_folder_new: - * @parent_store: the parent CamelVeeStore - * @name: the vfolder name - * @ex: a CamelException - * - * Create a new CamelVeeFolder object. - * - * Return value: A new CamelVeeFolder widget. - **/ -CamelFolder * -camel_vee_folder_new (CamelStore *parent_store, const char *name, - CamelException *ex) -{ - CamelFolder *folder; - CamelVeeFolder *vf; - char *namepart, *searchpart; - - folder = CAMEL_FOLDER (camel_object_new (camel_vee_folder_get_type())); - vf = (CamelVeeFolder *)folder; - - camel_folder_construct (folder, parent_store, name, name); - - namepart = g_strdup(name); - searchpart = strchr(namepart, '?'); - if (searchpart == NULL) { - /* no search, no result! */ - searchpart = "(body-contains \"=some-invalid_string-sequence=xx\")"; - } else { - *searchpart++ = 0; - } - - vf->messages = g_ptr_array_new(); - vf->messages_uid = g_hash_table_new(g_str_hash, g_str_equal); - - vf->expression = g_strdup(searchpart); - vf->vname = namepart; - - vee_folder_build(vf, ex); - if (camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (folder)); - return NULL; - } - - return folder; -} - -static void -folder_changed(CamelFolder *sub, gpointer type, CamelVeeFolder *vf) -{ - CamelException *ex; - - ex = camel_exception_new(); - vee_folder_build_folder(vf, sub, ex); - camel_exception_free(ex); - /* FIXME: should only raise follow-on event if the result changed */ - camel_object_trigger_event( CAMEL_OBJECT(vf), "folder_changed", GINT_TO_POINTER(0)); -} - -/* track flag changes in the summary */ -static void -message_changed(CamelFolder *f, const char *uid, CamelVeeFolder *mf) -{ - const CamelMessageInfo *info; - CamelMessageInfo *vinfo; - CamelFlag *flag; - char *vuid; - - info = camel_folder_get_message_info(f, uid); - - vuid = g_strdup_printf("%p:%s", f, uid); - vinfo = (CamelMessageInfo *)vee_get_message_info((CamelFolder *)mf, vuid); - if (info && vinfo) { - vinfo->flags = info->flags; - camel_flag_list_free(&vinfo->user_flags); - flag = info->user_flags; - while (flag) { - camel_flag_set(&vinfo->user_flags, flag->name, TRUE); - flag = flag->next; - } - camel_object_trigger_event( CAMEL_OBJECT(mf), "message_changed", vinfo->uid); - } - g_free(vuid); -} - -void -camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub) -{ - struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); - CamelException *ex; - - camel_object_ref((CamelObject *)sub); - p->folders = g_list_append(p->folders, sub); - - camel_object_hook_event ((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf); - camel_object_hook_event ((CamelObject *)sub, "message_changed", (CamelObjectEventHookFunc) message_changed, vf); - - ex = camel_exception_new(); - vee_folder_build_folder(vf, sub, ex); - camel_exception_free(ex); - /* FIXME: should only raise follow-on event if the result changed */ - camel_object_trigger_event( CAMEL_OBJECT(vf), "folder_changed", GINT_TO_POINTER(0)); -} - - -static void -vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - ; -} - -static gint vee_get_message_count (CamelFolder *folder) -{ - CamelVeeFolder *vf = (CamelVeeFolder *)folder; - - return vf->messages->len; -} - -static gint -vee_get_unread_message_count (CamelFolder *folder) -{ - CamelVeeFolder *vee_folder = CAMEL_VEE_FOLDER (folder); - CamelMessageInfo *info; - GPtrArray *infolist; - gint i, count = 0; - - g_return_val_if_fail (folder != NULL, -1); - - infolist = vee_folder->messages; - - for (i = 0; i < infolist->len; i++) { - info = (CamelMessageInfo *) g_ptr_array_index (infolist, i); - if (!(info->flags & CAMEL_MESSAGE_SEEN)) - count++; - } - - return count; -} - -static gboolean -get_real_message(CamelFolder *folder, const char *uid, CamelFolder **out_folder, const char **out_uid) -{ - CamelVeeMessageInfo *mi; - - mi = (CamelVeeMessageInfo *)vee_get_message_info(folder, uid); - g_return_val_if_fail(mi != NULL, FALSE); - - *out_folder = mi->folder; - *out_uid = strchr(mi->info.uid, ':')+1; - return TRUE; -} - -static CamelMimeMessage *vee_get_message(CamelFolder *folder, const gchar *uid, CamelException *ex) -{ - const char *real_uid; - CamelFolder *real_folder; - - if (!get_real_message(folder, uid, &real_folder, &real_uid)) { - camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - "No such message %s in %s", uid, - folder->name); - return NULL; - } - - return camel_folder_get_message (real_folder, real_uid, ex); -} - -GPtrArray *vee_get_summary(CamelFolder *folder) -{ - CamelVeeFolder *vf = (CamelVeeFolder *)folder; - - return vf->messages; -} - -static const CamelMessageInfo *vee_get_message_info(CamelFolder *f, const char *uid) -{ - CamelVeeFolder *vf = (CamelVeeFolder *)f; - - return g_hash_table_lookup(vf->messages_uid, uid); -} - -static GPtrArray *vee_get_uids (CamelFolder *folder) -{ - GPtrArray *result; - int i; - CamelVeeFolder *vf = (CamelVeeFolder *)folder; - - result = g_ptr_array_new (); - g_ptr_array_set_size (result, vf->messages->len); - for (i=0;i<vf->messages->len;i++) { - CamelMessageInfo *mi = g_ptr_array_index(vf->messages, i); - result->pdata[i] = g_strdup(mi->uid); - } - - return result; -} - -static GPtrArray * -vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex) -{ - GList *node; - GPtrArray *matches, *result = g_ptr_array_new (); - char *expr; - CamelVeeFolder *vf = (CamelVeeFolder *)folder; - struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); - - expr = g_strdup_printf("(and %s %s)", vf->expression, expression); - node = p->folders; - while (node) { - CamelFolder *f = node->data; - int i; - - matches = camel_folder_search_by_expression(f, expression, ex); - for (i = 0; i < matches->len; i++) { - char *uid = matches->pdata[i]; - g_ptr_array_add(result, g_strdup_printf("%p:%s", f, uid)); - } - camel_folder_search_free(f, matches); - node = g_list_next(node); - } - return result; -} - -static guint32 -vee_get_message_flags(CamelFolder *folder, const char *uid) -{ - const char *real_uid; - CamelFolder *real_folder; - - if (!get_real_message (folder, uid, &real_folder, &real_uid)) - return 0; - - return camel_folder_get_message_flags(real_folder, real_uid); -} - -static void -vee_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set) -{ - const char *real_uid; - CamelFolder *real_folder; - - if (!get_real_message(folder, uid, &real_folder, &real_uid)) - return; - - camel_folder_set_message_flags(real_folder, real_uid, flags, set); -} - -static gboolean -vee_get_message_user_flag(CamelFolder *folder, const char *uid, const char *name) -{ - const char *real_uid; - CamelFolder *real_folder; - - if (!get_real_message(folder, uid, &real_folder, &real_uid)) - return FALSE; - - return camel_folder_get_message_user_flag(real_folder, real_uid, name); -} - -static void -vee_set_message_user_flag(CamelFolder *folder, const char *uid, - const char *name, gboolean value) -{ - const char *real_uid; - CamelFolder *real_folder; - - if (!get_real_message(folder, uid, &real_folder, &real_uid)) - return; - - return camel_folder_set_message_user_flag(real_folder, real_uid, name, value); -} - - -/* - need incremental update, based on folder. - Need to watch folders for changes and update accordingly. -*/ - -/* this does most of the vfolder magic */ -static void -vee_folder_build(CamelVeeFolder *vf, CamelException *ex) -{ - struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); - GList *node; - int i; - GPtrArray *messages; - GHashTable *messages_uid; - - for (i=0;i<vf->messages->len;i++) { - CamelMessageInfo *mi = g_ptr_array_index(vf->messages, i); - camel_message_info_free(mi); - } - - messages = g_ptr_array_new(); - messages_uid = g_hash_table_new(g_str_hash, g_str_equal); - - node = p->folders; - while (node) { - GPtrArray *matches; - CamelFolder *f = node->data; - CamelVeeMessageInfo *mi; - const CamelMessageInfo *info; - int i; - - matches = camel_folder_search_by_expression(f, vf->expression, ex); - for (i = 0; i < matches->len; i++) { - info = camel_folder_get_message_info(f, matches->pdata[i]); - if (info) { - mi = g_malloc0(sizeof(*mi)); - camel_message_info_dup_to(info, (CamelMessageInfo *)mi); - g_free (mi->info.uid); - mi->info.uid = g_strdup_printf("%p:%s", f, info->uid); - mi->folder = f; - g_ptr_array_add(messages, mi); - g_hash_table_insert(messages_uid, mi->info.uid, mi); - } - } - camel_folder_search_free(f, matches); - node = g_list_next(node); - } - - g_ptr_array_free(vf->messages, TRUE); - vf->messages = messages; - g_hash_table_destroy(vf->messages_uid); - vf->messages_uid = messages_uid; -} - - -/* build query contents for a single folder */ -static void -vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex) -{ - GPtrArray *matches; - CamelFolder *f = source; - CamelVeeMessageInfo *mi; - const CamelMessageInfo *info; - - GPtrArray *messages; - GHashTable *messages_uid; - int i; - - for (i=0;i<vf->messages->len;i++) { - CamelVeeMessageInfo *mi = g_ptr_array_index(vf->messages, i); - if (mi->folder == source) { - g_hash_table_remove(vf->messages_uid, mi->info.uid); - g_ptr_array_remove_index_fast(vf->messages, i); - - camel_message_info_free((CamelMessageInfo *)mi); - i--; - } - } - - messages = vf->messages; - messages_uid = vf->messages_uid; - - matches = camel_folder_search_by_expression(f, vf->expression, ex); - for (i = 0; i < matches->len; i++) { - info = camel_folder_get_message_info(f, matches->pdata[i]); - if (info) { - mi = g_malloc0(sizeof(*mi)); - camel_message_info_dup_to(info, (CamelMessageInfo*)mi); - g_free (mi->info.uid); - mi->info.uid = g_strdup_printf("%p:%s", f, info->uid); - mi->folder = f; - g_ptr_array_add(messages, mi); - g_hash_table_insert(messages_uid, mi->info.uid, mi); - } - } - camel_folder_search_free(f, matches); -} - - -/* - - (match-folder "folder1" "folder2") - - */ diff --git a/camel/providers/vee/camel-vee-folder.h b/camel/providers/vee/camel-vee-folder.h deleted file mode 100644 index 2263854912..0000000000 --- a/camel/providers/vee/camel-vee-folder.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _CAMEL_VEE_FOLDER_H -#define _CAMEL_VEE_FOLDER_H - -#include <camel/camel-folder.h> - -#define CAMEL_VEE_FOLDER(obj) CAMEL_CHECK_CAST (obj, camel_vee_folder_get_type (), CamelVeeFolder) -#define CAMEL_VEE_FOLDER_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_folder_get_type (), CamelVeeFolderClass) -#define IS_CAMEL_VEE_FOLDER(obj) CAMEL_CHECK_TYPE (obj, camel_vee_folder_get_type ()) - -typedef struct _CamelVeeFolder CamelVeeFolder; -typedef struct _CamelVeeFolderClass CamelVeeFolderClass; - -struct _CamelVeeFolder { - CamelFolder parent; - - struct _CamelVeeFolderPrivate *priv; - - char *expression; /* query expression */ - char *vname; /* local name */ - CamelFolder *local; /* local storage for folder */ - - /* FIXME: Move this to a summary object??? */ - GPtrArray *messages; /* message info's */ - GHashTable *messages_uid; -}; - -struct _CamelVeeFolderClass { - CamelFolderClass parent_class; -}; - -guint camel_vee_folder_get_type (void); -CamelFolder *camel_vee_folder_new (CamelStore *parent_store, - const char *name, - CamelException *ex); - -void camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub); - -#endif /* ! _CAMEL_VEE_FOLDER_H */ diff --git a/camel/providers/vee/camel-vee-provider.c b/camel/providers/vee/camel-vee-provider.c deleted file mode 100644 index 4588fb77d3..0000000000 --- a/camel/providers/vee/camel-vee-provider.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "config.h" -#include "camel-vee-store.h" -#include "camel-provider.h" -#include "camel-session.h" -#include "camel-url.h" - -static CamelProvider vee_provider = { - "vfolder", - N_("Virtual folder email provider"), - - N_("For reading mail as a query of another set of folders"), - - "vfolder", - - 0, - - 0, - - { 0, 0 }, - - NULL -}; - -void -camel_provider_module_init (CamelSession *session) -{ - vee_provider.object_types[CAMEL_PROVIDER_STORE] = - camel_vee_store_get_type(); - - vee_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal); - - camel_session_register_provider (session, &vee_provider); -} diff --git a/camel/providers/vee/camel-vee-store.c b/camel/providers/vee/camel-vee-store.c deleted file mode 100644 index 7acc127542..0000000000 --- a/camel/providers/vee/camel-vee-store.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "camel-vee-store.h" -#include "camel-vee-folder.h" - -static CamelFolder *vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static char *vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); - -struct _CamelVeeStorePrivate { -}; - -#define _PRIVATE(o) (((CamelVeeStore *)(o))->priv) - -static void camel_vee_store_class_init (CamelVeeStoreClass *klass); -static void camel_vee_store_init (CamelVeeStore *obj); - -static CamelStoreClass *camel_vee_store_parent; - -CamelType -camel_vee_store_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register (camel_store_get_type (), "CamelVeeStore", - sizeof (CamelVeeStore), - sizeof (CamelVeeStoreClass), - (CamelObjectClassInitFunc) camel_vee_store_class_init, - NULL, - (CamelObjectInitFunc) camel_vee_store_init, - NULL); - } - - return type; -} - -static void - -camel_vee_store_class_init (CamelVeeStoreClass *klass) -{ - CamelStoreClass *store_class = (CamelStoreClass *) klass; - - camel_vee_store_parent = CAMEL_STORE_CLASS(camel_type_get_global_classfuncs (camel_store_get_type ())); - - /* virtual method overload */ - store_class->get_folder = vee_get_folder; - store_class->get_folder_name = vee_get_folder_name; -} - -static void -camel_vee_store_init (CamelVeeStore *obj) -{ - struct _CamelVeeStorePrivate *p; - - p = _PRIVATE(obj) = g_malloc0(sizeof(*p)); -} - -/** - * camel_vee_store_new: - * - * Create a new CamelVeeStore object. - * - * Return value: A new CamelVeeStore widget. - **/ -CamelVeeStore * -camel_vee_store_new (void) -{ - CamelVeeStore *new = CAMEL_VEE_STORE ( camel_object_new (camel_vee_store_get_type ())); - return new; -} - -static CamelFolder * -vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) -{ - return camel_vee_folder_new (store, folder_name, ex); -} - -static char * -vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - return g_strdup(folder_name); -} - diff --git a/camel/providers/vee/camel-vee-store.h b/camel/providers/vee/camel-vee-store.h deleted file mode 100644 index d4ed7a0610..0000000000 --- a/camel/providers/vee/camel-vee-store.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _CAMEL_VEE_STORE_H -#define _CAMEL_VEE_STORE_H - -#include <camel/camel-store.h> - -#define CAMEL_VEE_STORE(obj) CAMEL_CHECK_CAST (obj, camel_vee_store_get_type (), CamelVeeStore) -#define CAMEL_VEE_STORE_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_store_get_type (), CamelVeeStoreClass) -#define IS_CAMEL_VEE_STORE(obj) CAMEL_CHECK_TYPE (obj, camel_vee_store_get_type ()) - -typedef struct _CamelVeeStore CamelVeeStore; -typedef struct _CamelVeeStoreClass CamelVeeStoreClass; - -struct _CamelVeeStore { - CamelStore parent; - - struct _CamelVeeStorePrivate *priv; -}; - -struct _CamelVeeStoreClass { - CamelStoreClass parent_class; -}; - -guint camel_vee_store_get_type (void); -CamelVeeStore *camel_vee_store_new (void); - -#endif /* ! _CAMEL_VEE_STORE_H */ diff --git a/camel/providers/vee/libcamelvee.urls b/camel/providers/vee/libcamelvee.urls deleted file mode 100644 index 6fa58dadb5..0000000000 --- a/camel/providers/vee/libcamelvee.urls +++ /dev/null @@ -1 +0,0 @@ -vfolder |