diff options
Diffstat (limited to 'camel/providers/imap')
-rw-r--r-- | camel/providers/imap/.cvsignore | 7 | ||||
-rw-r--r-- | camel/providers/imap/Makefile.am | 42 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-folder.c | 1578 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-folder.h | 77 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-provider.c | 109 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 1262 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.h | 103 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-stream.c | 197 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-stream.h | 71 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-utils.c | 486 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-utils.h | 43 | ||||
-rw-r--r-- | camel/providers/imap/libcamelimap.urls | 1 |
12 files changed, 0 insertions, 3976 deletions
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 5ff249739f..0000000000 --- a/camel/providers/imap/Makefile.am +++ /dev/null @@ -1,42 +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) \ - -DG_LOG_DOMAIN=\"camel-imap-provider\" - -libcamelimap_la_SOURCES = \ - camel-imap-folder.c \ - camel-imap-provider.c \ - camel-imap-store.c \ - camel-imap-stream.c \ - camel-imap-utils.c - -libcamelimapinclude_HEADERS = \ - camel-imap-folder.h \ - camel-imap-store.h \ - camel-imap-stream.h \ - camel-imap-utils.h - -libcamelimap_la_LDFLAGS = -version-info 0:0:0 - -EXTRA_DIST = libcamelimap.urls - - - - - diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c deleted file mode 100644 index 2118554607..0000000000 --- a/camel/providers/imap/camel-imap-folder.c +++ /dev/null @@ -1,1578 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ -/* camel-imap-folder.c: Abstract class for an email 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 <e-util/e-util.h> - -#include "camel-imap-folder.h" -#include "camel-imap-store.h" -#include "camel-imap-stream.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_init (CamelFolder *folder, CamelStore *parent_store, - CamelFolder *parent_folder, const gchar *name, - gchar *separator, gboolean path_begns_with_sep, - CamelException *ex); - -static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex); -static void imap_expunge (CamelFolder *folder, CamelException *ex); - -static gint imap_get_message_count_internal (CamelFolder *folder, CamelException *ex); -static gint imap_get_message_count (CamelFolder *folder); -static gint imap_get_unread_message_count (CamelFolder *folder); - -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); - -static GPtrArray *imap_get_subfolder_names_internal (CamelFolder *folder, CamelException *ex); -static GPtrArray *imap_get_subfolder_names (CamelFolder *folder); - -static GPtrArray *imap_get_uids (CamelFolder *folder); -static GPtrArray *imap_get_summary_internal (CamelFolder *folder, CamelException *ex); -static GPtrArray *imap_get_summary (CamelFolder *folder); -static const CamelMessageInfo *imap_get_message_info (CamelFolder *folder, const char *uid); - -static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex); - -static void imap_finalize (CamelObject *object); - -/* flag methods */ -/*static guint32 imap_get_permanent_flags (CamelFolder *folder, CamelException *ex);*/ -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->init = imap_init; - camel_folder_class->sync = imap_sync; - camel_folder_class->expunge = imap_expunge; - - camel_folder_class->get_uids = imap_get_uids; - camel_folder_class->free_uids = camel_folder_free_nop; - camel_folder_class->get_subfolder_names = imap_get_subfolder_names; - camel_folder_class->free_subfolder_names = 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_permanent_flags = imap_get_permanent_flags;*/ - 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->can_hold_messages = TRUE; - folder->can_hold_folders = TRUE; - folder->has_summary_capability = TRUE; - folder->has_search_capability = TRUE; - - imap_folder->summary = NULL; - imap_folder->summary_hash = NULL; - imap_folder->lsub = 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, char *folder_name, CamelException *ex) -{ - CamelFolder *folder = CAMEL_FOLDER (camel_object_new (camel_imap_folder_get_type ())); - CamelURL *url = CAMEL_SERVICE (parent)->url; - char *dir_sep; - - dir_sep = CAMEL_IMAP_STORE (parent)->dir_sep; - - CF_CLASS (folder)->init (folder, parent, NULL, folder_name, dir_sep, FALSE, ex); - - if (!strcmp (folder_name, url->path + 1)) - folder->can_hold_messages = FALSE; - - imap_get_subfolder_names_internal (folder, ex); - - if (folder->can_hold_messages) - imap_get_summary_internal (folder, ex); - - return folder; -} - -static void -imap_summary_free (GPtrArray **summary) -{ - CamelMessageInfo *info; - GPtrArray *array = *summary; - gint i, max; - - if (array) { - max = array->len; - for (i = 0; i < max; i++) { - info = g_ptr_array_index (array, i); - g_free (info->subject); - g_free (info->from); - g_free (info->to); - g_free (info->cc); - g_free (info->uid); - g_free (info->message_id); - header_references_list_clear (&info->references); - g_free (info); - info = NULL; - } - - g_ptr_array_free (array, TRUE); - *summary = NULL; - } -} - -static void -imap_folder_summary_free (CamelImapFolder *imap_folder) -{ - if (imap_folder->summary_hash) { - g_hash_table_destroy (imap_folder->summary_hash); - imap_folder->summary_hash = NULL; - } - - imap_summary_free (&imap_folder->summary); -} - -static void -imap_finalize (CamelObject *object) -{ - /* TODO: do we need to do more cleanup here? */ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object); - gint max, i; - - imap_folder_summary_free (imap_folder); - - if (imap_folder->lsub) { - max = imap_folder->lsub->len; - - for (i = 0; i < max; i++) { - g_free (imap_folder->lsub->pdata[i]); - imap_folder->lsub->pdata[i] = NULL; - } - - g_ptr_array_free (imap_folder->lsub, TRUE); - } -} - -static void -imap_init (CamelFolder *folder, CamelStore *parent_store, CamelFolder *parent_folder, - const gchar *name, gchar *separator, gboolean path_begins_with_sep, CamelException *ex) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - /* call parent method */ - parent_class->init (folder, parent_store, parent_folder, name, separator, path_begins_with_sep, ex); - if (camel_exception_get_id (ex)) - return; - - /* we assume that the parent init - method checks for the existance of @folder */ - folder->can_hold_messages = TRUE; - folder->can_hold_folders = TRUE; - folder->has_summary_capability = TRUE; - folder->has_search_capability = TRUE; - - /* some IMAP daemons support user-flags * - * I would not, however, rely on this feature as * - * most IMAP daemons are not 100% RFC compliant */ - folder->permanent_flags = CAMEL_MESSAGE_SEEN | - CAMEL_MESSAGE_ANSWERED | - CAMEL_MESSAGE_FLAGGED | - CAMEL_MESSAGE_DELETED | - CAMEL_MESSAGE_DRAFT | - CAMEL_MESSAGE_USER; - - imap_folder->search = NULL; - imap_folder->summary = NULL; - imap_folder->summary_hash = NULL; - imap_folder->lsub = NULL; -} - -static void -imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - gint i, max; - - if (expunge) { - imap_expunge (folder, ex); - return; - } - - /* Set the flags on any messages that have changed this session */ - if (imap_folder->summary) { - max = imap_folder->summary->len; - for (i = 0; i < max; i++) { - CamelMessageInfo *info; - - info = (CamelMessageInfo *) g_ptr_array_index (imap_folder->summary, i); - if (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) { - char *flags; - - flags = g_strconcat (info->flags & CAMEL_MESSAGE_SEEN ? "\\Seen " : "", - info->flags & CAMEL_MESSAGE_DRAFT ? "\\Draft " : "", - info->flags & CAMEL_MESSAGE_DELETED ? "\\Deleted " : "", - info->flags & CAMEL_MESSAGE_ANSWERED ? "\\Answered " : "", - NULL); - if (*flags) { - gchar *result; - gint s; - - *(flags + strlen (flags) - 1) = '\0'; - s = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), - folder, &result, - "UID STORE %s FLAGS.SILENT (%s)", - info->uid, flags); - - if (s != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not set flags on message %s on IMAP " - "server %s: %s.", info->uid, - service->url->host, - s != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - return; - } - - g_free (result); - } - g_free (flags); - } - } - } -} - -static void -imap_expunge (CamelFolder *folder, CamelException *ex) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - gchar *node, *result; - gint i, status, recent = -1; - - g_return_if_fail (folder != NULL); - - imap_sync (folder, FALSE, ex); - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, - &result, "EXPUNGE"); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not EXPUNGE from IMAP server %s: %s.", - service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - return; - } - - /* determine which messages were successfully expunged */ - node = result; - for (i = 0; node; i++) { - if (*node == '*') { - char *word; - - word = imap_next_word (node); - - if (!strncmp (word, "NO", 2)) { - /* Something failed, probably a Read-Only mailbox? */ - CamelService *service = CAMEL_SERVICE (folder->parent_store); - char *reason, *ep; - - word = imap_next_word (word); - for (ep = word; *ep && *ep != '\n'; ep++); - reason = g_strndup (word, (gint)(ep - word) + 1); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not EXPUNGE from IMAP server %s: %s.", - service->url->host, reason ? reason : - "Unknown error"); - - g_free (reason); - break; - } - - /* else we have a message id? */ - if (*word >= '0' && *word <= '9' && !strncmp ("EXPUNGE", imap_next_word (word), 7)) { - int id; - - id = atoi (word); - - d(fprintf (stderr, "Expunging message %d from the summary (i = %d)\n", id + i, i)); - - if (id <= imap_folder->summary->len) { - CamelMessageInfo *info; - - info = (CamelMessageInfo *) imap_folder->summary->pdata[id - 1]; - - /* remove from the lookup table and summary */ - g_hash_table_remove (imap_folder->summary_hash, info->uid); - g_ptr_array_remove_index (imap_folder->summary, id - 1); - - /* free the info data */ - g_free (info->subject); - g_free (info->from); - g_free (info->to); - g_free (info->cc); - g_free (info->uid); - g_free (info->message_id); - header_references_list_clear (&info->references); - g_free (info); - info = NULL; - } else { - /* Hopefully this should never happen */ - d(fprintf (stderr, "imap expunge-error: message %d is out of range\n", id)); - } - } else if (*word >= '0' && *word <= '9' && !strncmp ("RECENT", imap_next_word (word), 6)) { - recent = atoi (word); - if (!recent) - recent = -1; - } - } else { - break; - } - - for ( ; *node && *node != '\n'; node++); - if (*node) - node++; - } - - g_free (result); - - camel_imap_folder_changed (folder, recent, ex); -} - -static gint -imap_get_message_count_internal (CamelFolder *folder, CamelException *ex) -{ - CamelStore *store = CAMEL_STORE (folder->parent_store); - CamelURL *url = CAMEL_SERVICE (store)->url; - gchar *result, *msg_count, *folder_path, *dir_sep; - gint status, count = 0; - - g_return_val_if_fail (folder != NULL, 0); - g_return_val_if_fail (folder->can_hold_messages, 0); - - dir_sep = CAMEL_IMAP_STORE (folder->parent_store)->dir_sep; - - if (url && url->path && *(url->path + 1) && strcmp (folder->full_name, "INBOX")) - folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name); - else - folder_path = g_strdup (folder->full_name); - - if (CAMEL_IMAP_STORE (store)->has_status_capability) - status = camel_imap_command_extended (CAMEL_IMAP_STORE (store), folder, - &result, "STATUS %s (MESSAGES)", folder_path); - else - status = camel_imap_command_extended (CAMEL_IMAP_STORE (store), folder, - &result, "EXAMINE %s", folder_path); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not get message count for %s from IMAP " - "server %s: %s.", folder_path, service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - g_free (folder_path); - return 0; - } - g_free (folder_path); - - /* parse out the message count */ - if (result && *result == '*') { - if (CAMEL_IMAP_STORE (store)->has_status_capability) { - /* should come in the form: "* STATUS <folder> (MESSAGES <count>)" */ - if ((msg_count = strstr (result, "MESSAGES")) != NULL) { - msg_count = imap_next_word (msg_count); - - /* we should now be pointing to the message count */ - count = atoi (msg_count); - } - } else { - /* should come in the form: "* <count> EXISTS" */ - if ((msg_count = strstr (result, "EXISTS")) != NULL) { - for ( ; msg_count > result && *msg_count != '*'; msg_count--); - - msg_count = imap_next_word (msg_count); - - /* we should now be pointing to the message count */ - count = atoi (msg_count); - } - } - } - g_free (result); - - return count; -} - -static gint -imap_get_message_count (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - if (imap_folder->summary) - return imap_folder->summary->len; - else - return 0; -} - -static gint -imap_get_unread_message_count (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - CamelMessageInfo *info; - GPtrArray *infolist; - gint i, count = 0; - - g_return_val_if_fail (folder != NULL, 0); - - /* If we don't have a message count, return 0 */ - if (!imap_folder->summary) - return 0; - - infolist = imap_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 -imap_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex) -{ - CamelStore *store = CAMEL_STORE (folder->parent_store); - CamelURL *url = CAMEL_SERVICE (store)->url; - CamelStream *memstream; - GByteArray *ba; - gchar *result, *cmdid, *dir_sep; - gchar *folder_path, *flagstr = NULL; - gint status; - - g_return_if_fail (folder != NULL); - g_return_if_fail (message != NULL); - - dir_sep = CAMEL_IMAP_STORE (folder->parent_store)->dir_sep; - - if (url && url->path && *(url->path + 1) && strcmp (folder->full_name, "INBOX")) - folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name); - else - folder_path = g_strdup (folder->full_name); - - /* create flag string param */ - if (info && info->flags) { - flagstr = g_strconcat (" (", info->flags & CAMEL_MESSAGE_SEEN ? "\\Seen " : "", - info->flags & CAMEL_MESSAGE_DRAFT ? "\\Draft " : "", - info->flags & CAMEL_MESSAGE_DELETED ? "\\Answered " : "", - NULL); - if (flagstr) - *(flagstr + strlen (flagstr) - 1) = ')'; - } - - ba = g_byte_array_new (); - memstream = camel_stream_mem_new_with_byte_array (ba); - /* FIXME: we need to crlf/dot filter */ - camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), memstream); - camel_stream_write_string (memstream, "\r\n"); - camel_stream_reset (memstream); - - status = camel_imap_command_preliminary (CAMEL_IMAP_STORE (folder->parent_store), - &result, &cmdid, "APPEND %s%s {%d}", - folder_path, flagstr ? flagstr : "", ba->len - 2); - - if (status != CAMEL_IMAP_PLUS) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not APPEND message to IMAP server %s: %s.", - service->url->host, result ? result : "Unknown error"); - - g_free (result); - g_free (cmdid); - g_free (folder_path); - return; - } - - g_free (result); - g_free (folder_path); - - /* send the rest of our data - the mime message */ - status = camel_imap_command_continuation_with_stream (CAMEL_IMAP_STORE (folder->parent_store), - &result, cmdid, memstream); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not APPEND message to IMAP server %s: %s.", - service->url->host, result ? result : "Unknown error"); - - camel_object_unref (CAMEL_OBJECT (memstream)); - g_free (result); - g_free (cmdid); - return; - } - - camel_object_unref (CAMEL_OBJECT (memstream)); - g_free (cmdid); - g_free (result); - - camel_imap_folder_changed (folder, 1, ex); -} - -static void -imap_copy_message_to (CamelFolder *source, const char *uid, CamelFolder *destination, CamelException *ex) -{ - CamelStore *store = CAMEL_STORE (source->parent_store); - CamelURL *url = CAMEL_SERVICE (store)->url; - char *result, *folder_path, *dir_sep; - int status; - - dir_sep = CAMEL_IMAP_STORE (source->parent_store)->dir_sep; - - if (url && url->path && *(url->path + 1) && strcmp (destination->full_name, "INBOX")) - folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, destination->full_name); - else - folder_path = g_strdup (destination->full_name); - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (store), source, &result, - "UID COPY %s %s", uid, folder_path); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not COPY message %s to %s on IMAP server %s: %s.", - uid, folder_path, service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - g_free (folder_path); - return; - } - - g_free (result); - g_free (folder_path); - - camel_imap_folder_changed (destination, 1, ex); -} - -/* FIXME: Duplication of code! */ -static void -imap_move_message_to (CamelFolder *source, const char *uid, CamelFolder *destination, CamelException *ex) -{ - CamelStore *store = CAMEL_STORE (source->parent_store); - CamelURL *url = CAMEL_SERVICE (store)->url; - CamelMessageInfo *info; - char *result, *folder_path, *dir_sep; - int status; - - dir_sep = CAMEL_IMAP_STORE (source->parent_store)->dir_sep; - - if (url && url->path && *(url->path + 1) && strcmp (destination->full_name, "INBOX")) - folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, destination->full_name); - else - folder_path = g_strdup (destination->full_name); - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (store), source, &result, - "UID COPY %s %s", uid, folder_path); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not COPY message %s to %s on IMAP server %s: %s.", - uid, folder_path, service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - g_free (folder_path); - return; - } - - g_free (result); - g_free (folder_path); - - if (!(info = (CamelMessageInfo *)imap_get_message_info (source, uid))) { - CamelService *service = CAMEL_SERVICE (store); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not set flags for message %s on IMAP server %s: %s", - uid, service->url->host, "Unknown error"); - return; - } - - imap_set_message_flags (source, uid, CAMEL_MESSAGE_DELETED, ~(info->flags)); - - camel_imap_folder_changed (destination, 1, ex); -} - -static GPtrArray * -imap_get_uids (CamelFolder *folder) -{ - CamelMessageInfo *info; - GPtrArray *array, *infolist; - gint i, count; - - infolist = imap_get_summary (folder); - count = infolist->len; - - array = g_ptr_array_new (); - g_ptr_array_set_size (array, count); - - for (i = 0; i < count; i++) { - info = (CamelMessageInfo *) g_ptr_array_index (infolist, i); - array->pdata[i] = g_strdup (info->uid); - } - - return array; -} - -static GPtrArray * -imap_get_subfolder_names_internal (CamelFolder *folder, CamelException *ex) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - CamelStore *store = CAMEL_STORE (folder->parent_store); - CamelURL *url = CAMEL_SERVICE (store)->url; - GPtrArray *listing; - gboolean found_inbox = FALSE; - gint status; - gchar *result, *namespace, *dir_sep; - - g_return_val_if_fail (folder != NULL, g_ptr_array_new ()); - - dir_sep = CAMEL_IMAP_STORE (folder->parent_store)->dir_sep; - - if (url && url->path) { - if (!strcmp (folder->full_name, url->path + 1)) - namespace = g_strdup (url->path + 1); - else if (!strcmp (folder->full_name, "INBOX")) - namespace = g_strdup (url->path + 1); /* FIXME: erm...not sure */ - else - namespace = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name); - } else { - namespace = g_strdup (folder->full_name); - } - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), NULL, - &result, "LIST \"\" \"%s%s*\"", namespace, - *namespace ? dir_sep : ""); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not get subfolder listing from IMAP " - "server %s: %s.", service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - g_free (namespace); - - imap_folder->lsub = g_ptr_array_new (); - return imap_folder->lsub; - } - - /* parse out the subfolders */ - listing = g_ptr_array_new (); - if (result) { - char *ptr = result; - - while (ptr && *ptr == '*') { - gchar *flags, *sep, *dir, *buf, *end; - - for (end = ptr; *end && *end != '\n'; end++); - buf = g_strndup (ptr, (gint)(end - ptr)); - ptr = end; - - if (!imap_parse_list_response (buf, namespace, &flags, &sep, &dir)) { - g_free (buf); - g_free (flags); - g_free (sep); - g_free (dir); - - if (*ptr == '\n') - ptr++; - - continue; - } - - g_free (buf); - g_free (flags); - - if (*dir) { - d(fprintf (stderr, "adding folder: %s\n", dir)); - if (!g_strcasecmp (dir, "INBOX")) - found_inbox = TRUE; - g_ptr_array_add (listing, dir); - } - - g_free (sep); - - if (*ptr == '\n') - ptr++; - } - } - - if (!strcmp (folder->name, namespace) && !found_inbox) { - g_ptr_array_add (listing, g_strdup ("INBOX")); - } - - g_free (result); - g_free (namespace); - - imap_folder->lsub = listing; - - return listing; -} - -static GPtrArray * -imap_get_subfolder_names (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - return imap_folder->lsub; -} - -static CamelMimeMessage * -imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex) -{ - CamelStream *msgstream = NULL; - /*CamelStreamFilter *f_stream;*/ - /*CamelMimeFilter *filter;*/ - CamelMimeMessage *msg = NULL; - /*CamelMimePart *part;*/ - gchar *result, *header, *body, *mesg, *p, *q, *data_item; - int status, part_len; - - if (CAMEL_IMAP_STORE (folder->parent_store)->server_level >= IMAP_LEVEL_IMAP4REV1) - data_item = "BODY.PEEK[HEADER]"; - else - data_item = "RFC822.HEADER"; - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, - &result, "UID FETCH %s %s", uid, - data_item); - - if (!result || status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not fetch message %s on IMAP server %s: %s", - uid, service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - return NULL; - } - - for (p = result; *p && *p != '{' && *p != '\n'; p++); - if (*p != '{') { - g_free (result); - return NULL; - } - - part_len = atoi (p + 1); - for ( ; *p && *p != '\n'; p++); - if (*p != '\n') { - g_free (result); - return NULL; - } - - /* 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--, part_len--; q > p && *(q-1) != '\n'; q--, part_len--); - - header = g_strndup (p, part_len + 1); - - g_free (result); - d(fprintf (stderr, "*** We got the header ***\n")); - - if (CAMEL_IMAP_STORE (folder->parent_store)->server_level >= IMAP_LEVEL_IMAP4REV1) - data_item = "BODY[TEXT]"; - else - data_item = "RFC822.TEXT"; - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, - &result, "UID FETCH %s %s", uid, - data_item); - - if (!result || status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not fetch message %s on IMAP server %s: %s", - uid, service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - g_free (header); - return NULL; - } - - for (p = result; *p && *p != '{' && *p != '\n'; p++); - if (*p != '{') { - /* this is a hack for when the part length isn't in {}'s */ - part_len = 1; - for ( ; *p && *p != '\n'; p++); - p++; - } else { - part_len = atoi (p + 1); - for ( ; *p && *p != '\n'; p++); - if (*p != '\n') { - g_free (result); - g_free (header); - return NULL; - } - } - - /* 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--); - - body = g_strndup (p, part_len + 1); - - g_free (result); - d(fprintf (stderr, "*** We got the body ***\n")); - - mesg = g_strdup_printf ("%s\n%s", header, body); - g_free (header); - g_free (body); - d(fprintf (stderr, "*** We got the mesg ***\n")); - - d(fprintf (stderr, "Message:\n%s\n", mesg)); - - msgstream = camel_stream_mem_new_with_buffer (mesg, strlen (mesg) + 1); -#if 0 - f_stream = camel_stream_filter_new_with_stream (msgstream); - filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_DOTS); - id = camel_stream_filter_add (f_stream, CAMEL_MIME_FILTER (filter)); -#endif - msg = camel_mime_message_new (); - d(fprintf (stderr, "*** We created the camel_mime_message ***\n")); - - camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), msgstream); -#if 0 - camel_stream_filter_remove (f_stream, id); - camel_stream_close (CAMEL_STREAM (f_stream)); -#endif - camel_object_unref (CAMEL_OBJECT (msgstream)); - /*camel_object_unref (CAMEL_OBJECT (f_stream));*/ - - d(fprintf (stderr, "*** We're returning... ***\n")); - - g_free (mesg); - return msg; - -#if 0 - CamelStream *imap_stream; - CamelStream *msgstream; - CamelStreamFilter *f_stream; /* will be used later w/ crlf filter */ - CamelMimeFilter *filter; /* crlf/dot filter */ - CamelMimeMessage *msg; - CamelMimePart *part; - CamelDataWrapper *cdw; - gchar *cmdbuf; - int id; - - /* TODO: fetch the correct part, get rid of the hard-coded stuff */ - cmdbuf = g_strdup_printf ("UID FETCH %s BODY[TEXT]", uid); - imap_stream = camel_imap_stream_new (CAMEL_IMAP_FOLDER (folder), cmdbuf); - g_free (cmdbuf); - - - /* Temp hack - basically we read in the entire message instead of getting a part as it's needed */ - msgstream = camel_stream_mem_new (); - camel_stream_write_to_stream (CAMEL_STREAM (imap_stream), msgstream); - camel_object_unref (CAMEL_OBJECT (imap_stream)); - - f_stream = camel_stream_filter_new_with_stream (msgstream); - filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_DOTS); - id = camel_stream_filter_add (f_stream, CAMEL_MIME_FILTER (filter)); - - msg = camel_mime_message_new (); - - /*cdw = camel_data_wrapper_new ();*/ - /*camel_data_wrapper_construct_from_stream (cdw, CAMEL_STREAM (f_stream));*/ - camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), CAMEL_STREAM (f_stream)); - - camel_stream_filter_remove (f_stream, id); - camel_stream_close (CAMEL_STREAM (f_stream)); - camel_object_unref (CAMEL_OBJECT (msgstream)); - camel_object_unref (CAMEL_OBJECT (f_stream)); - - /*camel_data_wrapper_set_mime_type (cdw, "text/plain");*/ - - /*camel_medium_set_content_object (CAMEL_MEDIUM (msg), CAMEL_DATA_WRAPPER (cdw));*/ - /*camel_object_unref (CAMEL_OBJECT (cdw));*/ - - return msg; -#endif -} - -/* This probably shouldn't go here...but it will for now */ -static gchar * -get_header_field (gchar *header, gchar *field) -{ - gchar *part, *index, *p, *q; - - index = (char *) e_strstrcase (header, field); - if (index == NULL) - return NULL; - - p = index + strlen (field) + 1; - for (q = p; *q; q++) - if (*q == '\n' && (*(q + 1) != ' ' && *(q + 1) != '\t')) - break; - - part = g_strndup (p, (gint)(q - p)); - - /* it may be wrapped on multiple lines, so lets strip out \n's */ - for (p = part; *p; ) { - if (*p == '\n') - memmove (p, p + 1, strlen (p)); - else - p++; - } - - return part; -} - -static char *header_fields[] = { "subject", "from", "to", "cc", "date", - "received", "message-id", "references", - "in-reply-to", "" }; -/** - * 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[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 (CamelFolder *folder) -{ - char *sect_begin, *sect_end; - char *headers_wanted = "SUBJECT FROM TO CC DATE MESSAGE-ID REFERENCES IN-REPLY-TO"; - - if (CAMEL_IMAP_STORE (folder->parent_store)->server_level >= IMAP_LEVEL_IMAP4REV1) { - sect_begin = "BODY[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 GPtrArray * -imap_get_summary_internal (CamelFolder *folder, CamelException *ex) -{ - /* This ALWAYS updates the summary except on fail */ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - GPtrArray *summary = NULL, *headers = NULL; - GHashTable *hash = NULL; - gint num, i, j, status = 0; - char *result, *q, *node; - const char *received; - char *summary_specifier; - struct _header_raw *h = NULL, *tail = NULL; - - num = imap_get_message_count_internal (folder, ex); - - /* sync any previously set/changed message flags */ - imap_sync (folder, FALSE, ex); - - if (num == 0) { - /* clean up any previous summary data */ - imap_folder_summary_free (imap_folder); - - imap_folder->summary = g_ptr_array_new (); - imap_folder->summary_hash = g_hash_table_new (g_str_hash, g_str_equal); - - return imap_folder->summary; - } - - summary_specifier = imap_protocol_get_summary_specifier (folder); - - if (num == 1) { - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, - &result, "FETCH 1 (%s)", summary_specifier); - } else { - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, - &result, "FETCH 1:%d (%s)", num, summary_specifier); - } - g_free (summary_specifier); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not get summary for %s on IMAP server %s: %s", - folder->full_name, service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - - if (!imap_folder->summary) { - imap_folder->summary = g_ptr_array_new (); - imap_folder->summary_hash = g_hash_table_new (g_str_hash, g_str_equal); - } - - return imap_folder->summary; - } - - /* initialize our new summary-to-be */ - summary = g_ptr_array_new (); - hash = g_hash_table_new (g_str_hash, g_str_equal); - - /* create our array of headers from the server response */ - headers = g_ptr_array_new (); - node = result; - for (i = 1; node; i++) { - char *end; - - if ((end = strstr (node + 2, "\n*"))) { - g_ptr_array_add (headers, g_strndup (node, (gint)(end - node))); - } else { - g_ptr_array_add (headers, g_strdup (node)); - } - node = end; - } - if (i < num) { - d(fprintf (stderr, "IMAP server didn't respond with as many headers as we expected...\n")); - /* should we error?? */ - } - - g_free (result); - result = NULL; - - for (i = 0; i < headers->len; i++) { - CamelMessageInfo *info; - char *uid, *flags, *header; - - info = g_malloc0 (sizeof (CamelMessageInfo)); - - /* lets 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])); - g_free (info); - break; - } - - for (uid += 4; *uid && (*uid < '0' || *uid > '9'); uid++); /* advance to <uid> */ - for (q = uid; *q && *q >= '0' && *q <= '9'; q++); /* find the end of the <uid> */ - info->uid = g_strndup (uid, (gint)(q - uid)); - d(fprintf (stderr, "*** info->uid = %s\n", info->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)); - g_free (info->uid); - g_free (info); - break; - } - - for (flags += 6; *flags && *flags != '('; flags++); /* advance to <flags> */ - for (q = flags; *q && *q != ')'; q++); /* find the end of <flags> */ - flags = g_strndup (flags, (gint)(q - flags + 1)); - d(fprintf (stderr, "*** info->flags = %s\n", flags)); - - /* now we gotta parse for the flags */ - info->flags = 0; - if (strstr (flags, "\\Seen")) - info->flags |= CAMEL_MESSAGE_SEEN; - if (strstr (flags, "\\Answered")) - info->flags |= CAMEL_MESSAGE_ANSWERED; - if (strstr (flags, "\\Flagged")) - info->flags |= CAMEL_MESSAGE_FLAGGED; - if (strstr (flags, "\\Deleted")) - info->flags |= CAMEL_MESSAGE_DELETED; - if (strstr (flags, "\\Draft")) - info->flags |= CAMEL_MESSAGE_DRAFT; - g_free (flags); - flags = NULL; - - /* construct the header list */ - /* fast-forward to beginning of header info... */ - for (header = headers->pdata[i]; *header && *header != '\n'; header++); - h = NULL; - for (j = 0; *header_fields[j]; j++) { - struct _header_raw *raw; - char *field, *value; - - field = g_strdup_printf ("\n%s:", header_fields[j]); - value = get_header_field (header, field); - g_free (field); - if (!value) - continue; - - raw = g_malloc0 (sizeof (struct _header_raw)); - raw->next = NULL; - raw->name = g_strdup (header_fields[j]); - raw->value = value; - raw->offset = -1; - - if (!h) { - h = raw; - tail = h; - } else { - tail->next = raw; - tail = raw; - } - } - - /* construct the CamelMessageInfo */ - info->subject = camel_summary_format_string (h, "subject"); - info->from = camel_summary_format_address (h, "from"); - info->to = camel_summary_format_address (h, "to"); - info->cc = camel_summary_format_address (h, "cc"); - info->user_flags = NULL; - info->date_sent = header_decode_date (header_raw_find (&h, "date", NULL), NULL); - received = header_raw_find (&h, "received", NULL); - if (received) - received = strrchr (received, ';'); - if (received) - info->date_received = header_decode_date (received + 1, NULL); - else - info->date_received = 0; - info->message_id = header_msgid_decode (header_raw_find (&h, "message-id", NULL)); - /* if we have a references, use that, otherwise, see if we have an in-reply-to - header, with parsable content, otherwise *shrug* */ - info->references = header_references_decode (header_raw_find (&h, "references", NULL)); - if (info->references == NULL) - info->references = header_references_decode (header_raw_find (&h, "in-reply-to", NULL)); - - while (h) { - struct _header_raw *next = h->next; - - g_free (h->name); - g_free (h->value); - g_free (h); - h = next; - } - - g_ptr_array_add (summary, info); - g_hash_table_insert (hash, info->uid, info); - } - - for (i = 0; i < headers->len; i++) - g_free (headers->pdata[i]); - g_ptr_array_free (headers, TRUE); - - /* clean up any previous summary data */ - imap_folder_summary_free (imap_folder); - - imap_folder->summary = summary; - imap_folder->summary_hash = hash; - - return imap_folder->summary; -} - -static GPtrArray * -imap_get_summary (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - return imap_folder->summary; -} - -/* get a single message info from the server */ -static CamelMessageInfo * -imap_get_message_info_internal (CamelFolder *folder, guint id) -{ - CamelMessageInfo *info = NULL; - struct _header_raw *h, *tail = NULL; - const char *received; - char *result, *uid, *flags, *header, *q; - char *summary_specifier; - int j, status; - - /* we don't have a cached copy, so fetch it */ - summary_specifier = imap_protocol_get_summary_specifier (folder); - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, - &result, "FETCH %d (%s)", id, summary_specifier); - - g_free (summary_specifier); - - if (status != CAMEL_IMAP_OK) { - g_free (result); - return NULL; - } - - /* lets grab the UID... */ - if (!(uid = (char *) e_strstrcase (result, "UID "))) { - d(fprintf (stderr, "Cannot get a uid for %d\n\n%s\n\n", id, result)); - g_free (result); - return NULL; - } - - for (uid += 4; *uid && (*uid < '0' || *uid > '9'); uid++); /* advance to <uid> */ - for (q = uid; *q && *q >= '0' && *q <= '9'; q++); /* find the end of the <uid> */ - uid = g_strndup (uid, (gint)(q - uid)); - - info = g_malloc0 (sizeof (CamelMessageInfo)); - info->uid = uid; - d(fprintf (stderr, "*** info->uid = %s\n", info->uid)); - - /* now lets grab the FLAGS */ - if (!(flags = strstr (q, "FLAGS "))) { - d(fprintf (stderr, "We didn't seem to get any flags for %s...\n", uid)); - g_free (info->uid); - g_free (info); - g_free (result); - return NULL; - } - - for (flags += 6; *flags && *flags != '('; flags++); /* advance to <flags> */ - for (q = flags; *q && *q != ')'; q++); /* find the end of <flags> */ - flags = g_strndup (flags, (gint)(q - flags + 1)); - d(fprintf (stderr, "*** info->flags = %s\n", flags)); - - /* now we gotta parse for the flags */ - info->flags = 0; - if (strstr (flags, "\\Seen")) - info->flags |= CAMEL_MESSAGE_SEEN; - if (strstr (flags, "\\Answered")) - info->flags |= CAMEL_MESSAGE_ANSWERED; - if (strstr (flags, "\\Flagged")) - info->flags |= CAMEL_MESSAGE_FLAGGED; - if (strstr (flags, "\\Deleted")) - info->flags |= CAMEL_MESSAGE_DELETED; - if (strstr (flags, "\\Draft")) - info->flags |= CAMEL_MESSAGE_DRAFT; - g_free (flags); - flags = NULL; - - /* construct the header list */ - /* fast-forward to beginning of header info... */ - for (header = q; *header && *header != '\n'; header++); - h = NULL; - for (j = 0; *header_fields[j]; j++) { - struct _header_raw *raw; - char *field, *value; - - field = g_strdup_printf ("\n%s:", header_fields[j]); - value = get_header_field (header, field); - g_free (field); - if (!value) - continue; - - raw = g_malloc0 (sizeof (struct _header_raw)); - raw->next = NULL; - raw->name = g_strdup (header_fields[j]); - raw->value = value; - raw->offset = -1; - - if (!h) { - h = raw; - tail = h; - } else { - tail->next = raw; - tail = raw; - } - } - - /* construct the CamelMessageInfo */ - info->subject = camel_summary_format_string (h, "subject"); - info->from = camel_summary_format_address (h, "from"); - info->to = camel_summary_format_address (h, "to"); - info->cc = camel_summary_format_address (h, "cc"); - info->user_flags = NULL; - info->date_sent = header_decode_date (header_raw_find (&h, "date", NULL), NULL); - received = header_raw_find (&h, "received", NULL); - if (received) - received = strrchr (received, ';'); - if (received) - info->date_received = header_decode_date (received + 1, NULL); - else - info->date_received = 0; - info->message_id = header_msgid_decode (header_raw_find (&h, "message-id", NULL)); - /* if we have a references, use that, otherwise, see if we have an in-reply-to - header, with parsable content, otherwise *shrug* */ - info->references = header_references_decode (header_raw_find (&h, "references", NULL)); - if (info->references == NULL) - info->references = header_references_decode (header_raw_find (&h, "in-reply-to", NULL)); - - while (h->next) { - struct _header_raw *next = h->next; - - g_free (h->name); - g_free (h->value); - g_free (h); - h = next; - } - - g_free (result); - - return info; -} - -/* 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); - - g_return_val_if_fail (*uid != '\0', NULL); - - if (imap_folder->summary) - return (CamelMessageInfo *) g_hash_table_lookup (imap_folder->summary_hash, uid); - - return NULL; -} - -static GPtrArray * -imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex) -{ - /* NOTE: This is experimental code... */ - GPtrArray *uids = NULL; - char *result, *sexp, *p; - int status; - - 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; - } - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, - &result, "UID SEARCH %s", sexp); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not get summary for %s on IMAP server %s: %s", - folder->full_name, service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - g_free (sexp); - 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); - g_free (sexp); - - return uids; -} - -#if 0 -static guint32 -imap_get_permanent_flags (CamelFolder *folder, CamelException *ex) -{ - /* return permamnant flags */ - return folder->permanent_flags; -} -#endif - -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) -{ - CamelMessageInfo *info; - - info = (CamelMessageInfo*)imap_get_message_info (folder, uid); - g_return_if_fail (info != NULL); - - info->flags = (info->flags & ~flags) | (set & flags) | CAMEL_MESSAGE_FOLDER_FLAGGED; - - /*gtk_signal_emit_by_name (GTK_OBJECT (folder), "message_changed", uid);*/ - 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) -{ - return FALSE; -} - -static void -imap_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, gboolean value) -{ - /*gtk_signal_emit_by_name (GTK_OBJECT (folder), "message_changed", uid);*/ - camel_object_trigger_event (CAMEL_OBJECT (folder), "message_changed", (gpointer *) uid); -} - -void -camel_imap_folder_changed (CamelFolder *folder, gint recent, CamelException *ex) -{ - d(fprintf (stderr, "camel_imap_folder_changed: recent = %d\n", recent)); - - g_return_if_fail (recent); - - if (recent > 0) { - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - CamelMessageInfo *info; - gint i, j, last; - - if (!imap_folder->summary) { - imap_folder->summary = g_ptr_array_new (); - imap_folder->summary_hash = g_hash_table_new (g_str_hash, g_str_equal); - } - - last = imap_folder->summary->len + 1; - - for (i = last, j = 0; j < recent; i++, j++) { - info = imap_get_message_info_internal (folder, i); - if (info) { - g_ptr_array_add (imap_folder->summary, info); - g_hash_table_insert (imap_folder->summary_hash, info->uid, info); - } else { - /* our hack failed so now we need to do it the old fashioned way */ - /*imap_get_summary_internal (folder, ex);*/ - d(fprintf (stderr, "*** we tried to get message %d but failed\n", i)); - break; - } - } - } - - /*gtk_signal_emit_by_name (GTK_OBJECT (folder), "folder_changed", 0);*/ - camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", GINT_TO_POINTER (0)); -} diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h deleted file mode 100644 index bd1647c300..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; - - CamelFolderSearch *search; /* used to run searches */ - - GPtrArray *summary; - GHashTable *summary_hash; - - GPtrArray *lsub; -} CamelImapFolder; - - -typedef struct { - CamelFolderClass parent_class; - - /* Virtual methods */ - -} CamelImapFolderClass; - - -/* public methods */ -CamelFolder *camel_imap_folder_new (CamelStore *parent, char *folder_name, - CamelException *ex); - -void camel_imap_folder_changed (CamelFolder *folder, gint recent, 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 21452d5cee..0000000000 --- a/camel/providers/imap/camel-imap-provider.c +++ /dev/null @@ -1,109 +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", - "IMAPv4", - - "For reading and storing mail on IMAP servers.", - - "mail", - - CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE, - - { 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 0a2be4f326..0000000000 --- a/camel/providers/imap/camel-imap-store.c +++ /dev/null @@ -1,1262 +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 <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 <e-util/e-util.h> - -#include "camel-imap-store.h" -#include "camel-imap-folder.h" -#include "camel-imap-utils.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 CamelServiceClass *service_class = NULL; - -static void finalize (CamelObject *object); -static gboolean imap_create (CamelFolder *folder, CamelException *ex); -static gboolean imap_connect (CamelService *service, CamelException *ex); -static gboolean imap_disconnect (CamelService *service, CamelException *ex); -static GList *query_auth_types (CamelService *service, CamelException *ex); -static void free_auth_types (CamelService *service, GList *authtypes); -static char *get_name (CamelService *service, gboolean brief); -static CamelFolder *get_folder (CamelStore *store, const char *folder_name, gboolean create, - CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); -static gboolean imap_noop (gpointer data); -/*static gboolean stream_is_alive (CamelStream *istream);*/ -static int camel_imap_status (char *cmdid, char *respbuf); - -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); - - service_class = CAMEL_SERVICE_CLASS(camel_type_get_global_classfuncs (camel_service_get_type ())); - - /* virtual method overload */ - camel_service_class->connect = imap_connect; - camel_service_class->disconnect = imap_disconnect; - camel_service_class->query_auth_types = query_auth_types; - camel_service_class->free_auth_types = free_auth_types; - camel_service_class->get_name = get_name; - - camel_store_class->get_folder = get_folder; - camel_store_class->get_folder_name = get_folder_name; -} - -static void -camel_imap_store_init (gpointer object, gpointer klass) -{ - CamelService *service = CAMEL_SERVICE (object); - CamelStore *store = CAMEL_STORE (object); - - service->url_flags = (CAMEL_SERVICE_URL_NEED_USER | - CAMEL_SERVICE_URL_NEED_HOST | - CAMEL_SERVICE_URL_ALLOW_PATH); - - store->folders = g_hash_table_new (g_str_hash, g_str_equal); - CAMEL_IMAP_STORE (store)->dir_sep = g_strdup ("/"); /*default*/ - CAMEL_IMAP_STORE (store)->current_folder = NULL; - CAMEL_IMAP_STORE (store)->timeout_id = 0; -} - -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_STORE_TYPE, "CamelImapStore", - sizeof (CamelImapStore), - sizeof (CamelImapStoreClass), - (CamelObjectClassInitFunc) camel_imap_store_class_init, - NULL, - (CamelObjectInitFunc) camel_imap_store_init, - (CamelObjectFinalizeFunc) finalize); - } - - return camel_imap_store_type; -} - -static void -finalize (CamelObject *object) -{ - CamelException ex; - - camel_exception_init (&ex); - imap_disconnect (CAMEL_SERVICE (object), &ex); - camel_exception_clear (&ex); -} - -static CamelServiceAuthType password_authtype = { - "Password", - - "This option will connect to the IMAP server using a " - "plaintext password.", - - "", - TRUE -}; - -#if 0 -static gboolean -try_connect (CamelService *service, CamelException *ex) -{ - struct hostent *h; - struct sockaddr_in sin; - gint fd; - - h = camel_service_gethost (service, ex); - if (!h) - return FALSE; - - sin.sin_family = h->h_addrtype; - sin.sin_port = htons (service->url->port ? service->url->port : IMAP_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) { - /* We don't want to set a CamelException here */ - - if (fd > -1) - close (fd); - - return FALSE; - } - - close (fd); - return TRUE; -} -#endif - -static GList * -query_auth_types (CamelService *service, CamelException *ex) -{ - GList *ret = NULL; - gboolean passwd = TRUE; -#if 0 - if (service->url) { - passwd = try_connect (service, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) - return NULL; - } -#endif - if (passwd) - ret = g_list_append (ret, &password_authtype); - - if (!ret) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not connect to IMAP server on %s.", - service->url->host ? service->url->host : - "(unknown host)"); - } - - return ret; -} - -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 ("IMAP server %s", service->url->host); - else { - return g_strdup_printf ("IMAP service for %s on %s", - service->url->user, - service->url->host); - } -} - -static gboolean -imap_connect (CamelService *service, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (service); - struct hostent *h; - struct sockaddr_in sin; - gint fd, status; - gchar *buf, *msg, *result, *errbuf = NULL; - gboolean authenticated = FALSE; - - /* FIXME: do we really need this here? */ - /* - *if (store->timeout_id) { - * gtk_timeout_remove (store->timeout_id); - * store->timeout_id = 0; - *} - */ - - h = camel_service_gethost (service, ex); - if (!h) - return FALSE; - - /* connect to the IMAP server */ - sin.sin_family = h->h_addrtype; - if (service->url->port) - sin.sin_port = htons(service->url->port); - else - sin.sin_port = htons(IMAP_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->host : "(unknown host)", - service->url->port ? service->url->port : IMAP_PORT, - strerror(errno)); - if (fd > -1) - close (fd); - - return FALSE; - } - - /* parent class conect initialization */ - service_class->connect (service, ex); - - store->ostream = camel_stream_fs_new_with_fd (fd); - store->istream = camel_stream_buffer_new (store->ostream, CAMEL_STREAM_BUFFER_READ); - store->command = 0; - g_free (store->dir_sep); - store->dir_sep = g_strdup ("/"); /* default dir sep */ - - /* Read the greeting, if any. */ - buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream)); - if (!buf) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not read greeting from IMAP " - "server: %s", - camel_exception_get_description (ex)); - - imap_disconnect (service, ex); - return FALSE; - } - g_free (buf); - - /* authenticate the user */ - while (!authenticated) { - if (errbuf) { - /* We need to un-cache 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; - } - - if (!service->url->authmech && !service->url->passwd) { - gchar *prompt; - - prompt = g_strdup_printf ("%sPlease enter the IMAP password for %s@%s", - errbuf ? errbuf : "", service->url->user, h->h_name); - service->url->passwd = - camel_session_query_authenticator (camel_service_get_session (service), - CAMEL_AUTHENTICATOR_ASK, prompt, - TRUE, service, "password", ex); - g_free (prompt); - g_free (errbuf); - errbuf = NULL; - - if (!service->url->passwd) { - imap_disconnect (service, ex); - return FALSE; - } - } - - status = camel_imap_command (store, NULL, &msg, "LOGIN \"%s\" \"%s\"", - service->url->user, - service->url->passwd); - - if (status != CAMEL_IMAP_OK) { - errbuf = g_strdup_printf ("Unable to authenticate to IMAP server.\n" - "Error sending password: %s\n\n", - msg ? msg : "(Unknown)"); - } else { - g_message ("IMAP Service sucessfully authenticated user %s", service->url->user); - authenticated = TRUE; - } - } - - /* Now lets find out the IMAP capabilities */ - status = camel_imap_command_extended (store, NULL, &result, "CAPABILITY"); - - if (status != CAMEL_IMAP_OK) { - /* Non-fatal error, but we should still warn the user... */ - CamelService *service = CAMEL_SERVICE (store); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not get capabilities on IMAP server %s: %s.", - service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - } - - /* parse for capabilities here. */ - if (e_strstrcase (result, "IMAP4REV1")) - store->server_level = IMAP_LEVEL_IMAP4REV1; - else if (e_strstrcase (result, "IMAP4")) - store->server_level = IMAP_LEVEL_IMAP4; - else - store->server_level = IMAP_LEVEL_UNKNOWN; - - if ((store->server_level >= IMAP_LEVEL_IMAP4REV1) || (e_strstrcase (result, "STATUS"))) - store->has_status_capability = TRUE; - else - store->has_status_capability = FALSE; - - g_free (result); - - /* We now need to find out which directory separator this daemon uses */ - status = camel_imap_command_extended (store, NULL, &result, "LIST \"\" \"\""); - - if (status != CAMEL_IMAP_OK) { - /* Again, this is non-fatal */ - CamelService *service = CAMEL_SERVICE (store); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not get directory separator on IMAP server %s: %s.", - service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - } else { - char *flags, *sep, *folder; - - if (imap_parse_list_response (result, "", &flags, &sep, &folder)) { - if (*sep) { - g_free (store->dir_sep); - store->dir_sep = g_strdup (sep); - } - } - - g_free (flags); - g_free (sep); - g_free (folder); - } - - /* default directory separator */ - if (!store->dir_sep) - store->dir_sep = g_strdup ("/"); - - g_free (result); - - /* Lets add a timeout so that we can hopefully prevent getting disconnected */ - /* FIXME fast timeout */ - store->timeout_id = camel_session_register_timeout (camel_service_get_session (service), - 10 * 60 * 1000, imap_noop, service); - /*store->timeout_id = gtk_timeout_add (600000, imap_noop, store);*/ - - return TRUE; -} - -static gboolean -imap_disconnect (CamelService *service, CamelException *ex) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (service); - char *result; - int status; - - if (!service->connected) - return TRUE; - - /* send the logout command */ - status = camel_imap_command_extended (CAMEL_IMAP_STORE (service), NULL, &result, "LOGOUT"); - if (status != CAMEL_IMAP_OK) { - /* Oh fuck it, we're disconnecting anyway... */ - } - g_free (result); - - if (!service_class->disconnect (service, ex)) - return FALSE; - - if (store->istream) { - camel_object_unref (CAMEL_OBJECT (store->istream)); - store->istream = NULL; - } - - if (store->ostream) { - camel_object_unref (CAMEL_OBJECT (store->ostream)); - store->ostream = NULL; - } - - g_free (store->dir_sep); - store->dir_sep = NULL; - - store->current_folder = NULL; - - if (store->timeout_id) { - camel_session_remove_timeout (camel_service_get_session (CAMEL_SERVICE (store)), - store->timeout_id); - store->timeout_id = 0; - } - - return TRUE; -} - -const gchar * -camel_imap_store_get_toplevel_dir (CamelImapStore *store) -{ - CamelURL *url = CAMEL_SERVICE (store)->url; - - g_assert (url != NULL); - return url->path; -} - -static gboolean -imap_folder_exists (CamelFolder *folder) -{ - CamelStore *store = CAMEL_STORE (folder->parent_store); - CamelURL *url = CAMEL_SERVICE (store)->url; - gchar *result, *folder_path, *dir_sep; - gint status; - - dir_sep = CAMEL_IMAP_STORE (folder->parent_store)->dir_sep; - - g_return_val_if_fail (dir_sep, FALSE); - - if (url && url->path && *(url->path + 1) && strcmp (folder->full_name, "INBOX")) - folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name); - else - folder_path = g_strdup (folder->full_name); - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), NULL, - &result, "EXAMINE %s", folder_path); - - if (status != CAMEL_IMAP_OK) { - g_free (result); - g_free (folder_path); - return FALSE; - } - g_free (folder_path); - g_free (result); - - return TRUE; -} - -static gboolean -imap_create (CamelFolder *folder, CamelException *ex) -{ - CamelStore *store = CAMEL_STORE (folder->parent_store); - CamelURL *url = CAMEL_SERVICE (store)->url; - gchar *result, *folder_path, *dir_sep; - gint status; - - g_return_val_if_fail (folder != NULL, FALSE); - - if (!(folder->full_name || folder->name)) { - camel_exception_set (ex, CAMEL_EXCEPTION_FOLDER_INVALID, - "invalid folder path. Use set_name ?"); - return FALSE; - } - - if (!strcmp (folder->full_name, "INBOX")) - return TRUE; - - if (imap_folder_exists (folder)) - return TRUE; - - /* create the directory for the subfolder */ - dir_sep = CAMEL_IMAP_STORE (folder->parent_store)->dir_sep; - - g_return_val_if_fail (dir_sep, FALSE); - - if (url && url->path && *(url->path + 1) && strcmp (folder->full_name, "INBOX")) - folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name); - else - folder_path = g_strdup (folder->full_name); - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), NULL, - &result, "CREATE %s", folder_path); - - if (status != CAMEL_IMAP_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not CREATE %s on IMAP server %s: %s.", - folder_path, service->url->host, - status != CAMEL_IMAP_FAIL && result ? result : - "Unknown error"); - g_free (result); - g_free (folder_path); - return FALSE; - } - g_free (folder_path); - g_free (result); - - return TRUE; -} - -static gboolean -folder_is_selectable (CamelStore *store, const char *folder_path) -{ - char *result, *flags, *sep, *folder; - int status; - - if (!strcmp (folder_path, "INBOX")) - return TRUE; - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (store), NULL, - &result, "LIST \"\" %s", folder_path); - if (status != CAMEL_IMAP_OK) { - g_free (result); - return FALSE; - } - - if (imap_parse_list_response (result, "", &flags, &sep, &folder)) { - gboolean retval; - - retval = !e_strstrcase (flags, "NoSelect"); - g_free (flags); - g_free (sep); - g_free (folder); - - return retval; - } - g_free (flags); - g_free (sep); - g_free (folder); - - return FALSE; -} - -static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex) -{ - CamelURL *url = CAMEL_SERVICE (store)->url; - CamelFolder *new_folder; - char *folder_path, *dir_sep; - - g_return_val_if_fail (store != NULL, NULL); - g_return_val_if_fail (folder_name != NULL, NULL); - - dir_sep = CAMEL_IMAP_STORE (store)->dir_sep; - - /* if we're trying to get the top-level dir, we really want the namespace */ - if (!dir_sep || !strcmp (folder_name, dir_sep)) - folder_path = g_strdup (url->path + 1); - else - folder_path = g_strdup (folder_name); - - new_folder = camel_imap_folder_new (store, folder_path, ex); - - /* this is the top-level dir, we already know it exists - it has to! */ - if (!strcmp (folder_name, dir_sep)) - return new_folder; - - if (create && !imap_create (new_folder, ex)) { - if (!folder_is_selectable (store, folder_path)) { - camel_exception_clear (ex); - new_folder->can_hold_messages = FALSE; - return new_folder; - } else { - g_free (folder_path); - camel_object_unref (CAMEL_OBJECT (new_folder)); - return NULL; - } - } - - return new_folder; -} - -static gchar * -get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - return g_strdup (folder_name); -} - -static gboolean -imap_noop (gpointer data) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (data); - char *result; - int status; - - status = camel_imap_command_extended (store, store->current_folder, &result, "NOOP"); - - g_free (result); - - return TRUE; -} - -#if 0 -static gboolean -stream_is_alive (CamelStream *istream) -{ - CamelStreamFs *fs_stream; - char buf; - - g_return_val_if_fail (istream != NULL, FALSE); - - fs_stream = CAMEL_STREAM_FS (CAMEL_STREAM_BUFFER (istream)->stream); - g_return_val_if_fail (fs_stream->fd != -1, FALSE); - - if (read (fs_stream->fd, (void *) &buf, 0) == 0) - return TRUE; - - return FALSE; -} -#endif - -static int -camel_imap_status (char *cmdid, char *respbuf) -{ - char *retcode; - - if (respbuf) { - if (!strncmp (respbuf, cmdid, strlen (cmdid))) { - retcode = imap_next_word (respbuf); - - if (!strncmp (retcode, "OK", 2)) - return CAMEL_IMAP_OK; - else if (!strncmp (retcode, "NO", 2)) - return CAMEL_IMAP_NO; - else if (!strncmp (retcode, "BAD", 3)) - return CAMEL_IMAP_BAD; - } - } - - return CAMEL_IMAP_FAIL; -} - -/** - * camel_imap_command: Send a command to a IMAP server. - * @store: the IMAP store - * @folder: The folder to perform the operation in - * @ret: a pointer to return the full server response in - * @fmt: a printf-style format string, followed by arguments - * - * This camel method sends the command specified by @fmt and the following - * arguments to the connected IMAP 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_imap_command - * will set it to point to a buffer containing the rest of the - * response from the IMAP server. (If @ret was passed but there was - * no extended response, @ret will be set to NULL.) The caller function is - * responsible for freeing @ret. - * - * Return value: one of CAMEL_IMAP_OK (command executed successfully), - * CAMEL_IMAP_NO (operational error message), CAMEL_IMAP_BAD (error - * message from the server), or CAMEL_IMAP_FAIL (a protocol-level error - * occurred, and Camel is uncertain of the result of the command.) - **/ -gint -camel_imap_command (CamelImapStore *store, CamelFolder *folder, char **ret, char *fmt, ...) -{ - CamelURL *url = CAMEL_SERVICE (store)->url; - gchar *cmdbuf, *respbuf; - gchar *cmdid; - va_list ap; - gint status = CAMEL_IMAP_OK; - - if (folder && store->current_folder != folder && strncmp (fmt, "CREATE", 5)) { - /* We need to select the correct mailbox first */ - char *r, *folder_path, *dir_sep; - int s; - - dir_sep = store->dir_sep; - if (url && url->path && *(url->path + 1) && strcmp (folder->full_name, "INBOX")) - folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name); - else - folder_path = g_strdup (folder->full_name); - - s = camel_imap_command_extended (store, NULL, &r, "SELECT %s", folder_path); - g_free (folder_path); - if (!r || s != CAMEL_IMAP_OK) { - *ret = r; - store->current_folder = NULL; - - return s; - } - - g_free (r); - - store->current_folder = folder; - } - - /* create the command */ - cmdid = g_strdup_printf ("A%.5d", store->command++); - va_start (ap, fmt); - cmdbuf = g_strdup_vprintf (fmt, ap); - va_end (ap); - - d(fprintf (stderr, "sending : %s %s\r\n", cmdid, cmdbuf)); - - if (camel_stream_printf (store->ostream, "%s %s\r\n", cmdid, cmdbuf) == -1) { - g_free (cmdbuf); - g_free (cmdid); - if (*ret) - *ret = g_strdup (strerror (errno)); - return CAMEL_IMAP_FAIL; - } - g_free (cmdbuf); - - /* Read the response */ - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream)); - if (respbuf == NULL) { - if (*ret) - *ret = g_strdup (strerror (errno)); - return CAMEL_IMAP_FAIL; - } - - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - status = camel_imap_status (cmdid, respbuf); - g_free (cmdid); - - if (ret) { - if (status != CAMEL_IMAP_FAIL && respbuf) { - char *word; - - word = imap_next_word (respbuf); /* word should now point to NO or BAD */ - - *ret = g_strdup (imap_next_word (word)); - } else { - *ret = NULL; - } - } - - g_free (respbuf); - - return status; -} - -/** - * camel_imap_command_extended: Send a command to a IMAP server and get - * a multi-line response. - * @store: the IMAP store - * @folder: The folder to perform the operation in - * @ret: a pointer to return the full server response in - * @fmt: a printf-style format string, followed by arguments - * - * This camel method sends the IMAP command specified by @fmt and the - * following arguments to the IMAP store specified by @store. If the - * store is in a disconnected state, camel_imap_command_extended will first - * re-connect the store before sending the specified IMAP command. It then - * reads the server's response and parses out the status code. If the caller - * passed a non-NULL pointer for @ret, camel_imap_command_extended will set - * it to point to a buffer containing the rest of the response from the IMAP - * server. (If @ret was passed but there was no extended response, @ret will - * be set to NULL.) The caller function is responsible for freeing @ret. - * - * This camel method gets the additional data returned by "multi-line" IMAP - * commands, such as SELECT, LIST, FETCH, and various other commands. - * The returned data is un-byte-stuffed, and has lines termined by - * newlines rather than CR/LF pairs. - * - * Return value: one of CAMEL_IMAP_OK (command executed successfully), - * CAMEL_IMAP_NO (operational error message), CAMEL_IMAP_BAD (error - * message from the server), or CAMEL_IMAP_FAIL (a protocol-level error - * occurred, and Camel is uncertain of the result of the command.) - **/ -gint -camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **ret, char *fmt, ...) -{ - CamelService *service = CAMEL_SERVICE (store); - CamelURL *url = service->url; - gint len = 0, recent = 0, status = CAMEL_IMAP_OK; - gchar *cmdid, *cmdbuf, *respbuf; - GPtrArray *data; - va_list app; - int i; - -#if 0 - /* First make sure we're connected... */ - if (!service->connected || !stream_is_alive (store->istream)) { - CamelException *ex; - - ex = camel_exception_new (); - - if (!imap_disconnect (service, ex) || !imap_connect (service, ex)) { - camel_exception_free (ex); - - *ret = NULL; - - return CAMEL_IMAP_FAIL; - } - service->connected = TRUE; - - camel_exception_free (ex); - } -#endif - - if (folder && store->current_folder != folder && strncmp (fmt, "CREATE", 6)) { - /* We need to select the correct mailbox first */ - char *r, *folder_path, *dir_sep; - int s; - - dir_sep = store->dir_sep; - - if (url && url->path && *(url->path + 1) && strcmp (folder->full_name, "INBOX")) - folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name); - else - folder_path = g_strdup (folder->full_name); - - s = camel_imap_command_extended (store, NULL, &r, "SELECT %s", folder_path); - g_free (folder_path); - if (!r || s != CAMEL_IMAP_OK) { - *ret = r; - store->current_folder = NULL; - - return s; - } - - g_free (r); - - store->current_folder = folder; - } - - /* Create the command */ - cmdid = g_strdup_printf ("A%.5d", store->command++); - va_start (app, fmt); - cmdbuf = g_strdup_vprintf (fmt, app); - va_end (app); - - d(fprintf (stderr, "sending : %s %s\r\n", cmdid, cmdbuf)); - - if (camel_stream_printf (store->ostream, "%s %s\r\n", cmdid, cmdbuf) == -1) { - g_free (cmdbuf); - g_free (cmdid); - - *ret = g_strdup (strerror (errno)); - - return CAMEL_IMAP_FAIL; - } - g_free (cmdbuf); - - data = g_ptr_array_new (); - - while (1) { - CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream); - char *ptr; - - respbuf = camel_stream_buffer_read_line (stream); - if (!respbuf || !strncmp (respbuf, cmdid, strlen (cmdid))) { - /* IMAP's last response starts with our command id */ - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); -#if 0 - if (!respbuf && strcmp (fmt, "LOGOUT")) { - /* we need to force a disconnect here? */ - CamelException *ex; - - ex = camel_exception_new (); - imap_disconnect (service, ex); - camel_exception_free (ex); - } -#endif - break; - } - - d(fprintf (stderr, "received: %s\n", respbuf)); - - g_ptr_array_add (data, respbuf); - len += strlen (respbuf) + 1; - - /* If recent was somehow set and this response doesn't begin with a '*' - then recent must have been misdetected */ - if (recent && *respbuf != '*') - recent = 0; - - if (*respbuf == '*' && (ptr = strstr (respbuf, "RECENT"))) { - char *rcnt; - - d(fprintf (stderr, "*** We may have found a 'RECENT' flag: %s\n", respbuf)); - /* Make sure it's in the form: "* %d RECENT" */ - rcnt = imap_next_word (respbuf); - if (*rcnt >= '0' && *rcnt <= '9' && !strncmp ("RECENT", imap_next_word (rcnt), 6)) - recent = atoi (rcnt); - } - } - - if (respbuf) { - g_ptr_array_add (data, respbuf); - len += strlen (respbuf) + 1; - - status = camel_imap_status (cmdid, respbuf); - } else { - status = CAMEL_IMAP_FAIL; - } - g_free (cmdid); - - if (status == CAMEL_IMAP_OK) { - char *p; - - *ret = g_malloc0 (len + 1); - - for (i = 0, p = *ret; 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 { - if (status != CAMEL_IMAP_FAIL && respbuf) { - char *word; - - word = imap_next_word (respbuf); /* word should now point to NO or BAD */ - - *ret = g_strdup (imap_next_word (word)); - } else { - *ret = NULL; - } - } - - for (i = 0; i < data->len; i++) - g_free (data->pdata[i]); - g_ptr_array_free (data, TRUE); - - if (folder && recent > 0) { - CamelException *ex; - - ex = camel_exception_new (); - camel_imap_folder_changed (folder, recent, ex); - camel_exception_free (ex); - } - - return status; -} - -/** - * camel_imap_command_preliminary: Send a preliminary command to the - * IMAP server. - * @store: the IMAP store - * @ret: a pointer to return the full server response in - * @cmdid: a pointer to return the command identifier (for use in - * camel_imap_command_continuation) - * @fmt: a printf-style format string, followed by arguments - * - * This camel method sends a preliminary IMAP command specified by - * @fmt and the following arguments to the IMAP store specified by - * @store. This function is meant for use with multi-transactional - * IMAP communications like Kerberos authentication and APPEND. - * - * If the caller passed a non-NULL pointer for @ret, - * camel_imap_command_preliminary will set it to point to a buffer - * containing the rest of the response from the IMAP server. The - * caller function is responsible for freeing @ret. - * - * Return value: one of CAMEL_IMAP_PLUS or CAMEL_IMAP_FAIL - * - * Note: on success (CAMEL_IMAP_PLUS), you will need to follow up with - * a camel_imap_command_continuation call. - **/ -gint -camel_imap_command_preliminary (CamelImapStore *store, char **ret, char **cmdid, char *fmt, ...) -{ - gchar *cmdbuf, *respbuf; - gint status = CAMEL_IMAP_OK; - va_list app; - - /* Create the command */ - *cmdid = g_strdup_printf ("A%.5d", store->command++); - va_start (app, fmt); - cmdbuf = g_strdup_vprintf (fmt, app); - va_end (app); - - d(fprintf (stderr, "sending : %s %s\r\n", *cmdid, cmdbuf)); - - if (camel_stream_printf (store->ostream, "%s %s\r\n", *cmdid, cmdbuf) == -1) { - g_free (cmdbuf); - - if (ret) - *ret = g_strdup (strerror (errno)); - - return CAMEL_IMAP_FAIL; - } - g_free (cmdbuf); - - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream)); - - if (respbuf) { - switch (*respbuf) { - case '+': - /* continuation request */ - status = CAMEL_IMAP_PLUS; - break; - default: - status = camel_imap_status (*cmdid, respbuf); - } - - if (ret) - *ret = g_strdup (imap_next_word (respbuf)); - } else { - status = CAMEL_IMAP_FAIL; - if (ret) - *ret = NULL; - } - - return status; -} - -/** - * camel_imap_command_continuation: Handle another transaction with the IMAP - * server and possibly get a multi-line response. - * @store: the IMAP store - * @cmdid: The command identifier returned from camel_imap_command_preliminary - * @ret: a pointer to return the full server response in - * @cmdbuf: buffer containing the response/request data - * - * This method is for sending continuing responses to the IMAP server. Meant - * to be used as a followup to camel_imap_command_preliminary. - * camel_imap_command_continuation will set @ret to point to a buffer - * containing the rest of the response from the IMAP server. The - * caller function is responsible for freeing @ret. - * - * Return value: one of CAMEL_IMAP_PLUS (command requires additional data), - * CAMEL_IMAP_OK (command executed successfully), - * CAMEL_IMAP_NO (operational error message), - * CAMEL_IMAP_BAD (error message from the server), or - * CAMEL_IMAP_FAIL (a protocol-level error occurred, and Camel is uncertain - * of the result of the command.) - **/ -gint -camel_imap_command_continuation (CamelImapStore *store, char **ret, char *cmdid, char *cmdbuf) -{ - gint len = 0, status = CAMEL_IMAP_OK; - gchar *respbuf; - GPtrArray *data; - int i; - - d(fprintf (stderr, "sending : %s\r\n", cmdbuf)); - - if (camel_stream_printf (store->ostream, "%s\r\n", cmdbuf) == -1) { - *ret = g_strdup (strerror (errno)); - - return CAMEL_IMAP_FAIL; - } - - data = g_ptr_array_new (); - - while (1) { - CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream); - - respbuf = camel_stream_buffer_read_line (stream); - if (!respbuf || *respbuf == '+' || !strncmp (respbuf, cmdid, strlen (cmdid))) { - /* IMAP's last response starts with our command id or a continuation request */ - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - break; - } - - d(fprintf (stderr, "received: %s\n", respbuf)); - - g_ptr_array_add (data, respbuf); - len += strlen (respbuf) + 1; - } - - if (respbuf) { - g_ptr_array_add (data, respbuf); - len += strlen (respbuf) + 1; - - switch (*respbuf) { - case '+': - status = CAMEL_IMAP_PLUS; - break; - default: - status = camel_imap_status (cmdid, respbuf); - } - } else { - status = CAMEL_IMAP_FAIL; - } - - if (status == CAMEL_IMAP_OK || status == CAMEL_IMAP_PLUS) { - char *p; - - *ret = g_malloc0 (len + 1); - - for (i = 0, p = *ret; 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 { - if (status != CAMEL_IMAP_FAIL && respbuf) { - char *word; - - word = imap_next_word (respbuf); - - if (*respbuf == '-') - *ret = g_strdup (word); - else - *ret = g_strdup (imap_next_word (word)); - } else { - *ret = NULL; - } - } - - for (i = 0; i < data->len; i++) - g_free (data->pdata[i]); - g_ptr_array_free (data, TRUE); - - return status; -} - -/** - * camel_imap_command_continuation_with_stream: Handle another transaction with the IMAP - * server and possibly get a multi-line response. - * @store: the IMAP store - * @cmdid: The command identifier returned from camel_imap_command_preliminary - * @ret: a pointer to return the full server response in - * @cstream: a CamelStream containing a continuation response. - * - * This method is for sending continuing responses to the IMAP server. Meant - * to be used as a followup to camel_imap_command_preliminary. - * camel_imap_command_continuation will set @ret to point to a buffer - * containing the rest of the response from the IMAP server. The - * caller function is responsible for freeing @ret. - * - * Return value: one of CAMEL_IMAP_PLUS (command requires additional data), - * CAMEL_IMAP_OK (command executed successfully), - * CAMEL_IMAP_NO (operational error message), - * CAMEL_IMAP_BAD (error message from the server), or - * CAMEL_IMAP_FAIL (a protocol-level error occurred, and Camel is uncertain - * of the result of the command.) - **/ -gint -camel_imap_command_continuation_with_stream (CamelImapStore *store, char **ret, char *cmdid, CamelStream *cstream) -{ - gint len = 0, status = CAMEL_IMAP_OK; - gchar *respbuf; - GPtrArray *data; - int i; - - d(fprintf (stderr, "sending continuation stream\r\n")); - - if (camel_stream_write_to_stream (cstream, store->ostream) == -1) { - *ret = g_strdup (strerror (errno)); - - return CAMEL_IMAP_FAIL; - } - - data = g_ptr_array_new (); - - while (1) { - CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream); - - respbuf = camel_stream_buffer_read_line (stream); - if (!respbuf || *respbuf == '+' || !strncmp (respbuf, cmdid, strlen (cmdid))) { - /* IMAP's last response starts with our command id or a continuation request */ - d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); - - break; - } - - d(fprintf (stderr, "received: %s\n", respbuf)); - - g_ptr_array_add (data, respbuf); - len += strlen (respbuf) + 1; - } - - if (respbuf) { - g_ptr_array_add (data, respbuf); - len += strlen (respbuf) + 1; - - switch (*respbuf) { - case '+': - status = CAMEL_IMAP_PLUS; - break; - default: - status = camel_imap_status (cmdid, respbuf); - } - } else { - status = CAMEL_IMAP_FAIL; - } - - if (status == CAMEL_IMAP_OK || status == CAMEL_IMAP_PLUS) { - char *p; - - *ret = g_malloc0 (len + 1); - - for (i = 0, p = *ret; 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 { - if (status != CAMEL_IMAP_FAIL && respbuf) { - char *word; - - word = imap_next_word (respbuf); - - if (*respbuf == '-') - *ret = g_strdup (word); - else - *ret = g_strdup (imap_next_word (word)); - } else { - *ret = NULL; - } - } - - for (i = 0; i < data->len; i++) - g_free (data->pdata[i]); - g_ptr_array_free (data, TRUE); - - return status; -} diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h deleted file mode 100644 index fcf0bcaf39..0000000000 --- a/camel/providers/imap/camel-imap-store.h +++ /dev/null @@ -1,103 +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-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; - - -typedef struct { - CamelStore parent_object; - - CamelFolder *current_folder; - CamelStream *istream, *ostream; - - guint32 command; - - CamelImapServerLevel server_level; - gboolean has_status_capability; - - gchar *dir_sep; - - guint timeout_id; -} CamelImapStore; - - -typedef struct { - CamelStoreClass parent_class; - -} CamelImapStoreClass; - - -/* public methods */ -void camel_imap_store_open (CamelImapStore *store, CamelException *ex); -void camel_imap_store_close (CamelImapStore *store, gboolean expunge, CamelException *ex); - -/* support functions */ - -enum { - CAMEL_IMAP_OK = 0, - CAMEL_IMAP_NO, - CAMEL_IMAP_BAD, - CAMEL_IMAP_PLUS, - CAMEL_IMAP_FAIL -}; - -gint camel_imap_command (CamelImapStore *store, CamelFolder *folder, char **ret, char *fmt, ...); -gint camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **ret, char *fmt, ...); - -/* multi-transactional commands... */ -gint camel_imap_command_preliminary (CamelImapStore *store, char **ret, char **cmdid, char *fmt, ...); -gint camel_imap_command_continuation (CamelImapStore *store, char **ret, char *cmdid, char *cmdbuf); -gint camel_imap_command_continuation_with_stream (CamelImapStore *store, char **ret, char *cmdid, CamelStream *cstream); - -/* Standard Camel function */ -CamelType camel_imap_store_get_type (void); - -const gchar *camel_imap_store_get_toplevel_dir (CamelImapStore *store); - -#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 7b885437a2..0000000000 --- a/camel/providers/imap/camel-imap-stream.c +++ /dev/null @@ -1,197 +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 <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); - gchar *result, *p, *q; - gint status, part_len; - - status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), - CAMEL_FOLDER (imap_stream->folder), - &result, "%s\r\n", - imap_stream->command); - - 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 != '\n'; p++); - if (*p != '{') { - g_free (result); - return -1; - } - - part_len = atoi (p + 1); - for ( ; *p && *p != '\n'; p++); - if (*p != '\n') { - g_free (result); - return -1; - } - - /* 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--, part_len--; q > p && *(q-1) != '\n'; q--, part_len--); - - imap_stream->cache = g_strndup (p, part_len + 1); - 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-utils.c b/camel/providers/imap/camel-imap-utils.c deleted file mode 100644 index 3378758a69..0000000000 --- a/camel/providers/imap/camel-imap-utils.c +++ /dev/null @@ -1,486 +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 <stdio.h> -#include <string.h> - -#include <gtk/gtk.h> -#include "camel-imap-utils.h" -#include "string-utils.h" -#include <e-sexp.h> - -#define d(x) x - -static char *esexp_keys[] = { "and", "or", "body-contains", "header-contains", "match-all", NULL }; -static char *imap_keys[] = { "", "OR", "BODY", "HEADER", NULL }; - -struct sexp_node { - struct sexp_node *l_node, *r_node; - char *function; - char *data; -}; - -static char *get_quoted_token (char *string, int *len); -static char *get_token (char *string, int *len); -struct sexp_node *get_sexp_node (const char *exp); -static void print_node (struct sexp_node *node, int depth); -static const char *get_func (struct sexp_node *node); -static char *get_data (struct sexp_node *node); -static char *str_sexp_node (struct sexp_node *node); -static void free_sexp_node (struct sexp_node *node); - - -char * -imap_next_word (char *buf) -{ - char *word; - - /* skip over current word */ - for (word = buf; *word && *word != ' '; word++); - - /* skip over white space */ - for ( ; *word && *word == ' '; word++); - - return word; -} - -gboolean -imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, char **folder) -{ - char *word, *ep, *f; - - *flags = NULL; - *sep = NULL; - *folder = NULL; - - 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; - - word++; - for (ep = word; *ep && *ep != ')'; ep++); - if (*ep != ')') - return FALSE; - - *flags = g_strndup (word, (gint)(ep - word)); - - /* get the directory separator */ - word = imap_next_word (ep); - if (*word) { - if (!strncmp (word, "NIL", 3)) { - *sep = NULL; - } else { - for (ep = word; *ep && *ep != ' '; ep++); - *sep = g_strndup (word, (gint)(ep - word)); - string_unquote (*sep); - } - } else { - return FALSE; - } - - /* get the folder name */ - word = imap_next_word (word); - *folder = g_strdup (word); - g_strstrip (*folder); - - /* chop out the folder prefix */ - if (*namespace && !strncmp (*folder, namespace, strlen (namespace))) { - f = *folder + strlen (namespace) + strlen (*sep); - memmove (*folder, f, strlen (f) + 1); - } - - string_unquote (*folder); /* unquote the mailbox if it's quoted */ - - return TRUE; -} - -static char * -get_quoted_token (char *string, int *len) -{ - char *ep; - - for (ep = string + 1; *ep; ep++) - if (*ep == '"' && *(ep - 1) != '\\') - break; - if (*ep) - ep++; - - *len = ep - string; - - return g_strndup (string, *len); -} - -static char * -get_token (char *string, int *len) -{ - char *p, *ep; - - for (p = string; *p && *p == ' '; p++); - - if (*p == '"') { - char *token; - int i; - - token = get_quoted_token (p, &i); - - *len = i + (p - string); - - return token; - } - - for (ep = p; *ep && *ep != ' ' && *ep != ')'; ep++); - - *len = ep - string; - - return g_strndup (p, *len); -} - -struct sexp_node * -get_sexp_node (const char *exp) -{ - struct sexp_node *node = NULL; - char *left_exp, *right_exp, *this_exp; - char *p, *ep; - int len, pbal; - - if (exp && *exp) { - node = g_malloc0 (sizeof (struct sexp_node)); - node->l_node = NULL; - node->r_node = NULL; - node->function = NULL; - node->data = NULL; - - p = (char *) exp + 1; - for (ep = p, pbal = 1; *ep && pbal; ep++) { - if (*ep == '(') - pbal++; - if (*ep == ')') - pbal--; - } - - this_exp = g_strndup (p, (gint)(ep - p)); - - for (left_exp = ep; *left_exp && *left_exp != '('; left_exp++); - left_exp = g_strdup (left_exp); - - for (right_exp = this_exp; *right_exp && *right_exp != '('; right_exp++); - pbal = 1; - for (ep = right_exp; *ep && pbal; ep++) { - if (*ep == '(') - pbal++; - if (*ep == ')') - pbal--; - } - right_exp = g_strndup (right_exp, (gint)(ep - right_exp)); - - /* fill in the node */ - node->function = get_token (this_exp, &len); - p = this_exp + len; - for (ep = p; *ep && *ep != '(' && *ep != ')'; ep++); - node->data = g_strndup (p, (gint)(ep - p)); - - g_strstrip (node->data); - - node->l_node = get_sexp_node (left_exp); - node->r_node = get_sexp_node (right_exp); - - g_free (this_exp); - g_free (left_exp); - g_free (right_exp); - } - - return node; -} - -static void -print_node (struct sexp_node *node, int depth) -{ - int i; - - for (i = 0; i < depth; i++) - d(fprintf (stderr, " ")); - - d(fprintf (stderr, "%s\n", node->function)); - - if (*node->data) { - for (i = 0; i < depth + 1; i++) - d(fprintf (stderr, " ")); - - d(fprintf (stderr, "%s\n", node->data)); - } - - if (node->r_node) - print_node (node->r_node, depth + 1); - - if (node->l_node) - print_node (node->l_node, depth); -} - -static const char * -get_func (struct sexp_node *node) -{ - int i; - - for (i = 0; esexp_keys[i]; i++) - if (!strncmp (esexp_keys[i], node->function, strlen (node->function))) - break; - - if (esexp_keys[i]) - return imap_keys[i]; - else - return node->function; -} - -static char * -get_data (struct sexp_node *node) -{ - GPtrArray *args; - const char *func; - char *data, *token, *p; - int i, len; - - func = get_func (node); - - args = g_ptr_array_new (); - - p = node->data; - while (p && *p) { - token = get_token (p, &len); - g_ptr_array_add (args, token); - p += len; - } - - if (func && !strcmp ("HEADER", func) && args->len > 0) - string_unquote (args->pdata[0]); - - if (args->len > 0) { - data = g_strjoinv (" ", (char **) args->pdata); - } else { - data = g_strdup (""); - } - - for (i = 0; i < args->len; i++) - g_free (args->pdata[i]); - - g_ptr_array_free (args, TRUE); - - return data; -} - -static char * -str_sexp_node (struct sexp_node *node) -{ - char *node_str, *data, *str, *l_str, *r_str; - const char *func; - - func = get_func (node); - data = get_data (node); - - if (func) { - if (*data) - str = g_strdup_printf ("%s %s", func, data); - else - str = g_strdup (func); - } else { - str = NULL; - } - - g_free (data); - - r_str = NULL; - if (node->r_node) - r_str = str_sexp_node (node->r_node); - - l_str = NULL; - if (node->l_node) - l_str = str_sexp_node (node->l_node); - - if (str) { - if (r_str) { - if (l_str) - node_str = g_strdup_printf ("%s %s %s", str, r_str, l_str); - else - node_str = g_strdup_printf ("%s %s", str, r_str); - } else { - if (l_str) - node_str = g_strdup_printf ("%s %s", str, l_str); - else - node_str = g_strdup_printf ("%s", str); - } - } else { - if (r_str) { - if (l_str) - node_str = g_strdup_printf ("%s %s", r_str, l_str); - else - node_str = g_strdup_printf ("%s", r_str); - } else { - if (l_str) - node_str = g_strdup_printf ("%s", l_str); - else - node_str = g_strdup (""); - } - } - - g_free (str); - g_free (l_str); - g_free (r_str); - - return node_str; -} - -static void -free_sexp_node (struct sexp_node *node) -{ - if (node->r_node) - free_sexp_node (node->r_node); - - if (node->l_node) - free_sexp_node (node->l_node); - - g_free (node->function); - g_free (node->data); - g_free (node); -} - -char * -imap_translate_sexp (const char *expression) -{ - struct sexp_node *root; - char *sexp, *exp; - - exp = g_strdup (expression); - strip (exp, '\n'); - root = get_sexp_node (exp); - g_free (exp); - - d(print_node (root, 0)); - d(fprintf (stderr, "\n")); - - sexp = str_sexp_node (root); - - free_sexp_node (root); - - return sexp; -} - - - - - - - - - - -#ifdef _ALL_HELL_BROKE_LOOSE_ -static char * -stresexptree (ESExpTerm *node) -{ - char *node_str, *func, *str, *l_str, *r_str; - int i; - - for (i = 0; esexp_keys[i]; i++) - if (!strncmp (esexp_keys[i], node->func->sym->name, strlen (node->func->sym->name))) - break; - - if (esexp_keys[i]) - func = imap_keys[i]; - else - func = node->func->sym->name; - - if (func) { - if (*node->var->name) - str = g_strdup_printf ("%s %s", func, node->var->name); - else - str = g_strdup (func); - } else { - str = NULL; - } - - r_str = NULL; - if (node->r_node) - r_str = str_sexp_node (node->r_node); - - l_str = NULL; - if (node->l_node) - l_str = str_sexp_node (node->l_node); - - if (str) { - if (r_str) { - if (l_str) - node_str = g_strdup_printf ("%s %s %s", str, r_str, l_str); - else - node_str = g_strdup_printf ("%s %s", str, r_str); - } else { - if (l_str) - node_str = g_strdup_printf ("%s %s", str, l_str); - else - node_str = g_strdup_printf ("%s", str); - } - } else { - - if (r_str) { - if (l_str) - node_str = g_strdup_printf ("%s %s", r_str, l_str); - else - node_str = g_strdup_printf ("%s", r_str); - } else { - if (l_str) - node_str = g_strdup_printf ("%s", l_str); - else - node_str = g_strdup (""); - } - } - - g_free (str); - g_free (l_str); - g_free (r_str); - - return node_str; -} - -char * -imap_translate_sexp (const char *expression) -{ - ESExp *esexp; - char *sexp; - - esexp = e_sexp_new (); - - e_sexp_input_text (esexp, exp, strlen (exp)); - e_sexp_parse (esexp); - - sexp = stresexptree (esexp->tree); - - gtk_object_unref (GTK_OBJECT (esexp)); - - return sexp; -} -#endif /* _ALL_HELL_BROKE_LOOSE_ */ diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h deleted file mode 100644 index 11c6c48956..0000000000 --- a/camel/providers/imap/camel-imap-utils.h +++ /dev/null @@ -1,43 +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 (char *buf); - -gboolean imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, char **folder); - -char *imap_translate_sexp (const char *expression); - -#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 |