aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/.cvsignore2
-rw-r--r--camel/providers/Makefile.am12
-rw-r--r--camel/providers/imap/.cvsignore11
-rw-r--r--camel/providers/imap/Makefile.am48
-rw-r--r--camel/providers/imap/camel-imap-command.c822
-rw-r--r--camel/providers/imap/camel-imap-command.h80
-rw-r--r--camel/providers/imap/camel-imap-folder.c2729
-rw-r--r--camel/providers/imap/camel-imap-folder.h90
-rw-r--r--camel/providers/imap/camel-imap-message-cache.c527
-rw-r--r--camel/providers/imap/camel-imap-message-cache.h111
-rw-r--r--camel/providers/imap/camel-imap-private.h76
-rw-r--r--camel/providers/imap/camel-imap-provider.c158
-rw-r--r--camel/providers/imap/camel-imap-search.c499
-rw-r--r--camel/providers/imap/camel-imap-search.h62
-rw-r--r--camel/providers/imap/camel-imap-store-summary.c619
-rw-r--r--camel/providers/imap/camel-imap-store-summary.h102
-rw-r--r--camel/providers/imap/camel-imap-store.c2845
-rw-r--r--camel/providers/imap/camel-imap-store.h148
-rw-r--r--camel/providers/imap/camel-imap-summary.c255
-rw-r--r--camel/providers/imap/camel-imap-summary.h79
-rw-r--r--camel/providers/imap/camel-imap-types.h39
-rw-r--r--camel/providers/imap/camel-imap-utils.c1261
-rw-r--r--camel/providers/imap/camel-imap-utils.h95
-rw-r--r--camel/providers/imap/camel-imap-wrapper.c185
-rw-r--r--camel/providers/imap/camel-imap-wrapper.h70
-rw-r--r--camel/providers/imap/libcamelimap.urls1
-rw-r--r--camel/providers/imapp/.cvsignore11
-rw-r--r--camel/providers/imapp/Makefile.am45
-rw-r--r--camel/providers/imapp/camel-imapp-driver.c771
-rw-r--r--camel/providers/imapp/camel-imapp-driver.h81
-rw-r--r--camel/providers/imapp/camel-imapp-engine.c1180
-rw-r--r--camel/providers/imapp/camel-imapp-engine.h155
-rw-r--r--camel/providers/imapp/camel-imapp-exception.h35
-rw-r--r--camel/providers/imapp/camel-imapp-fetch-stream.c183
-rw-r--r--camel/providers/imapp/camel-imapp-fetch-stream.h47
-rw-r--r--camel/providers/imapp/camel-imapp-folder.c269
-rw-r--r--camel/providers/imapp/camel-imapp-folder.h66
-rw-r--r--camel/providers/imapp/camel-imapp-provider.c97
-rw-r--r--camel/providers/imapp/camel-imapp-store-summary.c616
-rw-r--r--camel/providers/imapp/camel-imapp-store-summary.h102
-rw-r--r--camel/providers/imapp/camel-imapp-store.c1006
-rw-r--r--camel/providers/imapp/camel-imapp-store.h77
-rw-r--r--camel/providers/imapp/camel-imapp-stream.c761
-rw-r--r--camel/providers/imapp/camel-imapp-stream.h90
-rw-r--r--camel/providers/imapp/camel-imapp-summary.c166
-rw-r--r--camel/providers/imapp/camel-imapp-summary.h65
-rw-r--r--camel/providers/imapp/camel-imapp-utils.c1339
-rw-r--r--camel/providers/imapp/camel-imapp-utils.h145
-rw-r--r--camel/providers/imapp/libcamelimapp.urls1
-rw-r--r--camel/providers/local/.cvsignore11
-rw-r--r--camel/providers/local/Makefile.am61
-rw-r--r--camel/providers/local/camel-local-folder.c646
-rw-r--r--camel/providers/local/camel-local-folder.h109
-rw-r--r--camel/providers/local/camel-local-private.h53
-rw-r--r--camel/providers/local/camel-local-provider.c222
-rw-r--r--camel/providers/local/camel-local-store.c442
-rw-r--r--camel/providers/local/camel-local-store.h68
-rw-r--r--camel/providers/local/camel-local-summary.c614
-rw-r--r--camel/providers/local/camel-local-summary.h88
-rw-r--r--camel/providers/local/camel-maildir-folder.c245
-rw-r--r--camel/providers/local/camel-maildir-folder.h58
-rw-r--r--camel/providers/local/camel-maildir-store.c416
-rw-r--r--camel/providers/local/camel-maildir-store.h55
-rw-r--r--camel/providers/local/camel-maildir-summary.c807
-rw-r--r--camel/providers/local/camel-maildir-summary.h84
-rw-r--r--camel/providers/local/camel-mbox-folder.c549
-rw-r--r--camel/providers/local/camel-mbox-folder.h62
-rw-r--r--camel/providers/local/camel-mbox-store.c753
-rw-r--r--camel/providers/local/camel-mbox-store.h58
-rw-r--r--camel/providers/local/camel-mbox-summary.c1029
-rw-r--r--camel/providers/local/camel-mbox-summary.h75
-rw-r--r--camel/providers/local/camel-mh-folder.c231
-rw-r--r--camel/providers/local/camel-mh-folder.h58
-rw-r--r--camel/providers/local/camel-mh-store.c533
-rw-r--r--camel/providers/local/camel-mh-store.h60
-rw-r--r--camel/providers/local/camel-mh-summary.c420
-rw-r--r--camel/providers/local/camel-mh-summary.h53
-rw-r--r--camel/providers/local/camel-spool-folder.c186
-rw-r--r--camel/providers/local/camel-spool-folder.h64
-rw-r--r--camel/providers/local/camel-spool-store.c483
-rw-r--r--camel/providers/local/camel-spool-store.h69
-rw-r--r--camel/providers/local/camel-spool-summary.c344
-rw-r--r--camel/providers/local/camel-spool-summary.h69
-rw-r--r--camel/providers/local/libcamellocal.urls5
-rw-r--r--camel/providers/nntp/.cvsignore12
-rw-r--r--camel/providers/nntp/Makefile.am36
-rw-r--r--camel/providers/nntp/camel-nntp-auth.c92
-rw-r--r--camel/providers/nntp/camel-nntp-auth.h42
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c405
-rw-r--r--camel/providers/nntp/camel-nntp-folder.h72
-rw-r--r--camel/providers/nntp/camel-nntp-grouplist.c219
-rw-r--r--camel/providers/nntp/camel-nntp-grouplist.h48
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.c651
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.h34
-rw-r--r--camel/providers/nntp/camel-nntp-private.h64
-rw-r--r--camel/providers/nntp/camel-nntp-provider.c113
-rw-r--r--camel/providers/nntp/camel-nntp-resp-codes.h55
-rw-r--r--camel/providers/nntp/camel-nntp-store.c576
-rw-r--r--camel/providers/nntp/camel-nntp-store.h92
-rw-r--r--camel/providers/nntp/camel-nntp-stream.c462
-rw-r--r--camel/providers/nntp/camel-nntp-stream.h66
-rw-r--r--camel/providers/nntp/camel-nntp-summary.c584
-rw-r--r--camel/providers/nntp/camel-nntp-summary.h67
-rw-r--r--camel/providers/nntp/camel-nntp-types.h33
-rw-r--r--camel/providers/nntp/camel-nntp-utils.c299
-rw-r--r--camel/providers/nntp/camel-nntp-utils.h41
-rw-r--r--camel/providers/nntp/libcamelnntp.urls2
-rw-r--r--camel/providers/nntp/test-newsrc.c10
-rw-r--r--camel/providers/pop3/.cvsignore10
-rw-r--r--camel/providers/pop3/Makefile.am38
-rw-r--r--camel/providers/pop3/camel-pop3-engine.c382
-rw-r--r--camel/providers/pop3/camel-pop3-engine.h134
-rw-r--r--camel/providers/pop3/camel-pop3-folder.c558
-rw-r--r--camel/providers/pop3/camel-pop3-folder.h77
-rw-r--r--camel/providers/pop3/camel-pop3-provider.c108
-rw-r--r--camel/providers/pop3/camel-pop3-store.c657
-rw-r--r--camel/providers/pop3/camel-pop3-store.h79
-rw-r--r--camel/providers/pop3/camel-pop3-stream.c471
-rw-r--r--camel/providers/pop3/camel-pop3-stream.h69
-rw-r--r--camel/providers/pop3/libcamelpop3.urls1
-rw-r--r--camel/providers/sendmail/.cvsignore11
-rw-r--r--camel/providers/sendmail/Makefile.am28
-rw-r--r--camel/providers/sendmail/camel-sendmail-provider.c63
-rw-r--r--camel/providers/sendmail/camel-sendmail-transport.c262
-rw-r--r--camel/providers/sendmail/camel-sendmail-transport.h63
-rw-r--r--camel/providers/sendmail/libcamelsendmail.urls1
-rw-r--r--camel/providers/smtp/.cvsignore10
-rw-r--r--camel/providers/smtp/Makefile.am35
-rw-r--r--camel/providers/smtp/camel-smtp-provider.c65
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c1455
-rw-r--r--camel/providers/smtp/camel-smtp-transport.h89
-rw-r--r--camel/providers/smtp/libcamelsmtp.urls1
132 files changed, 0 insertions, 36056 deletions
diff --git a/camel/providers/.cvsignore b/camel/providers/.cvsignore
deleted file mode 100644
index 3dda72986f..0000000000
--- a/camel/providers/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile.in
-Makefile
diff --git a/camel/providers/Makefile.am b/camel/providers/Makefile.am
deleted file mode 100644
index 119966aacb..0000000000
--- a/camel/providers/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-if ENABLE_NNTP
-NNTP_DIR=nntp
-endif
-
-if ENABLE_IMAPP
-IMAPP_DIR=imapp
-endif
-
-SUBDIRS = pop3 sendmail smtp imap $(NNTP_DIR) local $(IMAPP_DIR)
-
diff --git a/camel/providers/imap/.cvsignore b/camel/providers/imap/.cvsignore
deleted file mode 100644
index 3fa8afaa38..0000000000
--- a/camel/providers/imap/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.deps
-Makefile
-Makefile.in
-.libs
-.deps
-*.lo
-*.la
-*.bb
-*.bbg
-*.da
-*.gcov
diff --git a/camel/providers/imap/Makefile.am b/camel/providers/imap/Makefile.am
deleted file mode 100644
index 1a2f46faf9..0000000000
--- a/camel/providers/imap/Makefile.am
+++ /dev/null
@@ -1,48 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelimapincludedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamelimap.la
-camel_provider_DATA = libcamelimap.urls
-
-INCLUDES = -I.. \
- -I$(srcdir)/.. \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/e-util \
- -I$(top_srcdir) \
- $(CAMEL_CFLAGS) \
- $(GNOME_INCLUDEDIR) \
- $(GTK_INCLUDEDIR) \
- -DG_LOG_DOMAIN=\"camel-imap-provider\"
-
-libcamelimap_la_SOURCES = \
- camel-imap-command.c \
- camel-imap-folder.c \
- camel-imap-message-cache.c \
- camel-imap-provider.c \
- camel-imap-search.c \
- camel-imap-store.c \
- camel-imap-store-summary.c \
- camel-imap-summary.c \
- camel-imap-utils.c \
- camel-imap-wrapper.c
-
-libcamelimapinclude_HEADERS = \
- camel-imap-command.h \
- camel-imap-folder.h \
- camel-imap-message-cache.h \
- camel-imap-search.h \
- camel-imap-store.h \
- camel-imap-store-summary.h \
- camel-imap-summary.h \
- camel-imap-types.h \
- camel-imap-utils.h \
- camel-imap-wrapper.h
-
-libcamelimap_la_LDFLAGS = -avoid-version -module
-
-noinst_HEADERS = \
- camel-imap-private.h
-
-EXTRA_DIST = libcamelimap.urls
diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c
deleted file mode 100644
index 45e5751b87..0000000000
--- a/camel/providers/imap/camel-imap-command.c
+++ /dev/null
@@ -1,822 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-command.c: IMAP command sending/parsing routines */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2000, 2001 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "camel-imap-command.h"
-#include "camel-imap-utils.h"
-#include "camel-imap-folder.h"
-#include "camel-imap-store.h"
-#include "camel-imap-store-summary.h"
-#include "camel-imap-private.h"
-#include <camel/camel-exception.h>
-#include <camel/camel-private.h>
-#include <camel/camel-utf8.h>
-#include <camel/camel-session.h>
-
-
-extern int camel_verbose_debug;
-
-static gboolean imap_command_start (CamelImapStore *store, CamelFolder *folder,
- const char *cmd, CamelException *ex);
-CamelImapResponse *imap_read_response (CamelImapStore *store,
- CamelException *ex);
-static char *imap_read_untagged (CamelImapStore *store, char *line,
- CamelException *ex);
-static char *imap_command_strdup_vprintf (CamelImapStore *store,
- const char *fmt, va_list ap);
-static char *imap_command_strdup_printf (CamelImapStore *store,
- const char *fmt, ...);
-
-/**
- * camel_imap_command:
- * @store: the IMAP store
- * @folder: The folder to perform the operation in (or %NULL if not
- * relevant).
- * @ex: a CamelException
- * @fmt: a sort of printf-style format string, followed by arguments
- *
- * This function calls camel_imap_command_start() to send the
- * command, then reads the complete response to it using
- * camel_imap_command_response() and returns a CamelImapResponse
- * structure.
- *
- * As a special case, if @fmt is %NULL, it will just select @folder
- * and return the response from doing so.
- *
- * See camel_imap_command_start() for details on @fmt.
- *
- * On success, the store's connect_lock will be locked. It will be freed
- * when you call camel_imap_response_free. (The lock is recursive, so
- * callers can grab and release it themselves if they need to run
- * multiple commands atomically.)
- *
- * Return value: %NULL if an error occurred (in which case @ex will
- * be set). Otherwise, a CamelImapResponse describing the server's
- * response, which the caller must free with camel_imap_response_free().
- **/
-CamelImapResponse *
-camel_imap_command (CamelImapStore *store, CamelFolder *folder,
- CamelException *ex, const char *fmt, ...)
-{
- va_list ap;
- char *cmd;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- if (fmt) {
- va_start (ap, fmt);
- cmd = imap_command_strdup_vprintf (store, fmt, ap);
- va_end (ap);
- } else {
- if (store->current_folder) {
- camel_object_unref (CAMEL_OBJECT (store->current_folder));
- store->current_folder = NULL;
- }
- store->current_folder = folder;
- camel_object_ref (CAMEL_OBJECT (folder));
- cmd = imap_command_strdup_printf (store, "SELECT %F",
- folder->full_name);
- }
-
- if (!imap_command_start (store, folder, cmd, ex)) {
- g_free (cmd);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return NULL;
- }
- g_free (cmd);
-
- return imap_read_response (store, ex);
-}
-
-/**
- * camel_imap_command_start:
- * @store: the IMAP store
- * @folder: The folder to perform the operation in (or %NULL if not
- * relevant).
- * @ex: a CamelException
- * @fmt: a sort of printf-style format string, followed by arguments
- *
- * This function makes sure that @folder (if non-%NULL) is the
- * currently-selected folder on @store and then sends the IMAP command
- * specified by @fmt and the following arguments.
- *
- * @fmt can include the following %-escapes ONLY:
- * %s, %d, %%: as with printf
- * %S: an IMAP "string" (quoted string or literal)
- * %F: an IMAP folder name
- *
- * %S strings will be passed as literals if the server supports LITERAL+
- * and quoted strings otherwise. (%S does not support strings that
- * contain newlines.)
- *
- * %F will have the imap store's namespace prepended and then be processed
- * like %S.
- *
- * On success, the store's connect_lock will be locked. It will be
- * freed when %CAMEL_IMAP_RESPONSE_TAGGED or %CAMEL_IMAP_RESPONSE_ERROR
- * is returned from camel_imap_command_response(). (The lock is
- * recursive, so callers can grab and release it themselves if they
- * need to run multiple commands atomically.)
- *
- * Return value: %TRUE if the command was sent successfully, %FALSE if
- * an error occurred (in which case @ex will be set).
- **/
-gboolean
-camel_imap_command_start (CamelImapStore *store, CamelFolder *folder,
- CamelException *ex, const char *fmt, ...)
-{
- va_list ap;
- char *cmd;
- gboolean ok;
-
- va_start (ap, fmt);
- cmd = imap_command_strdup_vprintf (store, fmt, ap);
- va_end (ap);
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- ok = imap_command_start (store, folder, cmd, ex);
- g_free (cmd);
-
- if (!ok)
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return ok;
-}
-
-static gboolean
-imap_command_start (CamelImapStore *store, CamelFolder *folder,
- const char *cmd, CamelException *ex)
-{
- ssize_t nwritten;
-
- /* Check for current folder */
- if (folder && folder != store->current_folder) {
- CamelImapResponse *response;
- CamelException internal_ex;
-
- response = camel_imap_command (store, folder, ex, NULL);
- if (!response)
- return FALSE;
- camel_exception_init (&internal_ex);
- camel_imap_folder_selected (folder, response, &internal_ex);
- camel_imap_response_free (store, response);
- if (camel_exception_is_set (&internal_ex)) {
- camel_exception_xfer (ex, &internal_ex);
- return FALSE;
- }
- }
-
- /* Send the command */
- if (camel_verbose_debug) {
- const char *mask;
-
- if (!strncmp ("LOGIN \"", cmd, 7))
- mask = "LOGIN \"xxx\" xxx";
- else if (!strncmp ("LOGIN {", cmd, 7))
- mask = "LOGIN {N+}\r\nxxx {N+}\r\nxxx";
- else if (!strncmp ("LOGIN ", cmd, 6))
- mask = "LOGIN xxx xxx";
- else
- mask = cmd;
-
- fprintf (stderr, "sending : %c%.5d %s\r\n", store->tag_prefix, store->command, mask);
- }
-
- nwritten = camel_stream_printf (store->ostream, "%c%.5d %s\r\n",
- store->tag_prefix, store->command++, cmd);
-
- if (nwritten == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Operation cancelled"));
- else
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- g_strerror (errno));
-
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * camel_imap_command_continuation:
- * @store: the IMAP store
- * @cmd: buffer containing the response/request data
- * @cmdlen: command length
- * @ex: a CamelException
- *
- * This method is for sending continuing responses to the IMAP server
- * after camel_imap_command() or camel_imap_command_response() returns
- * a continuation response.
- *
- * This function assumes you have an exclusive lock on the imap stream.
- *
- * Return value: as for camel_imap_command(). On failure, the store's
- * connect_lock will be released.
- **/
-CamelImapResponse *
-camel_imap_command_continuation (CamelImapStore *store, const char *cmd,
- size_t cmdlen, CamelException *ex)
-{
- if (!camel_imap_store_connected (store, ex))
- return NULL;
-
- if (camel_stream_write (store->ostream, cmd, cmdlen) == -1 ||
- camel_stream_write (store->ostream, "\r\n", 2) == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Operation cancelled"));
- else
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- g_strerror (errno));
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return NULL;
- }
-
- return imap_read_response (store, ex);
-}
-
-/**
- * camel_imap_command_response:
- * @store: the IMAP store
- * @response: a pointer to pass back the response data in
- * @ex: a CamelException
- *
- * This reads a single tagged, untagged, or continuation response from
- * @store into *@response. The caller must free the string when it is
- * done with it.
- *
- * Return value: One of %CAMEL_IMAP_RESPONSE_CONTINUATION,
- * %CAMEL_IMAP_RESPONSE_UNTAGGED, %CAMEL_IMAP_RESPONSE_TAGGED, or
- * %CAMEL_IMAP_RESPONSE_ERROR. If either of the last two, @store's
- * command lock will be unlocked.
- **/
-CamelImapResponseType
-camel_imap_command_response (CamelImapStore *store, char **response,
- CamelException *ex)
-{
- CamelImapResponseType type;
- char *respbuf;
-
- if (camel_imap_store_readline (store, &respbuf, ex) < 0) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return CAMEL_IMAP_RESPONSE_ERROR;
- }
-
- switch (*respbuf) {
- case '*':
- if (!strncasecmp (respbuf, "* BYE", 5)) {
- /* Connection was lost, no more data to fetch */
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Server unexpectedly disconnected: %s"),
- _("Unknown error")); /* g_strerror (104)); FIXME after 1.0 is released */
- store->connected = FALSE;
- g_free (respbuf);
- respbuf = NULL;
- type = CAMEL_IMAP_RESPONSE_ERROR;
- break;
- }
-
- /* Read the rest of the response. */
- type = CAMEL_IMAP_RESPONSE_UNTAGGED;
- respbuf = imap_read_untagged (store, respbuf, ex);
- if (!respbuf)
- type = CAMEL_IMAP_RESPONSE_ERROR;
- else if (!strncasecmp (respbuf, "* OK [ALERT]", 12)) {
- char *msg;
-
- /* for imap ALERT codes, account user@host */
- msg = g_strdup_printf(_("Alert from IMAP server %s@%s:\n%s"),
- ((CamelService *)store)->url->user, ((CamelService *)store)->url->host, respbuf+12);
- camel_session_alert_user(((CamelService *)store)->session, CAMEL_SESSION_ALERT_WARNING, msg, FALSE);
- g_free(msg);
- }
-
- break;
- case '+':
- type = CAMEL_IMAP_RESPONSE_CONTINUATION;
- break;
- default:
- type = CAMEL_IMAP_RESPONSE_TAGGED;
- break;
- }
- *response = respbuf;
-
- if (type == CAMEL_IMAP_RESPONSE_ERROR ||
- type == CAMEL_IMAP_RESPONSE_TAGGED)
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return type;
-}
-
-CamelImapResponse *
-imap_read_response (CamelImapStore *store, CamelException *ex)
-{
- CamelImapResponse *response;
- CamelImapResponseType type;
- char *respbuf, *p;
-
- /* Get another lock so that when we reach the tagged
- * response and camel_imap_command_response unlocks,
- * we're still locked. This lock is owned by response
- * and gets unlocked when response is freed.
- */
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- response = g_new0 (CamelImapResponse, 1);
- if (store->current_folder && camel_disco_store_status (CAMEL_DISCO_STORE (store)) != CAMEL_DISCO_STORE_RESYNCING) {
- response->folder = store->current_folder;
- camel_object_ref (CAMEL_OBJECT (response->folder));
- }
-
- response->untagged = g_ptr_array_new ();
- while ((type = camel_imap_command_response (store, &respbuf, ex))
- == CAMEL_IMAP_RESPONSE_UNTAGGED)
- g_ptr_array_add (response->untagged, respbuf);
-
- if (type == CAMEL_IMAP_RESPONSE_ERROR) {
- camel_imap_response_free_without_processing (store, response);
- return NULL;
- }
-
- response->status = respbuf;
-
- /* Check for OK or continuation response. */
- if (*respbuf == '+')
- return response;
- p = strchr (respbuf, ' ');
- if (p && !strncasecmp (p, " OK", 3))
- return response;
-
- /* We should never get BAD, or anything else but +, OK, or NO
- * for that matter.
- */
- if (!p || strncasecmp (p, " NO", 3) != 0) {
- g_warning ("Unexpected response from IMAP server: %s",
- respbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Unexpected response from IMAP "
- "server: %s"), respbuf);
- camel_imap_response_free_without_processing (store, response);
- return NULL;
- }
-
- p += 3;
- if (!*p++)
- p = NULL;
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP command failed: %s"),
- p ? p : _("Unknown error"));
- camel_imap_response_free_without_processing (store, response);
- return NULL;
-}
-
-/* Given a line that is the start of an untagged response, read and
- * return the complete response, which may include an arbitrary number
- * of literals.
- */
-static char *
-imap_read_untagged (CamelImapStore *store, char *line, CamelException *ex)
-{
- int fulllen, ldigits, nread, i;
- unsigned int length;
- GPtrArray *data;
- GString *str;
- char *end, *p, *s, *d;
-
- p = strrchr (line, '{');
- if (!p)
- return line;
-
- data = g_ptr_array_new ();
- fulllen = 0;
-
- while (1) {
- str = g_string_new (line);
- g_free (line);
- fulllen += str->len;
- g_ptr_array_add (data, str);
-
- p = strrchr (str->str, '{');
- if (!p)
- break;
-
- length = strtoul (p + 1, &end, 10);
- if (*end != '}' || *(end + 1) || end == p + 1 || length >= UINT_MAX - 2)
- break;
- ldigits = end - (p + 1);
-
- /* Read the literal */
- str = g_string_sized_new (length + 2);
- str->str[0] = '\n';
- nread = camel_stream_read (store->istream, str->str + 1, length);
- if (nread == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Operation cancelled"));
- else
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- g_strerror (errno));
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- g_string_free (str, TRUE);
- goto lose;
- }
- if (nread < length) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Server response ended too soon."));
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- g_string_free (str, TRUE);
- goto lose;
- }
- str->str[length + 1] = '\0';
-
- /* Fix up the literal, turning CRLFs into LF. Also, if
- * we find any embedded NULs, strip them. This is
- * dubious, but:
- * - The IMAP grammar says you can't have NULs here
- * anyway, so this will not affect our behavior
- * against any completely correct server.
- * - WU-imapd 12.264 (at least) will cheerily pass
- * NULs along if they are embedded in the message
- */
-
- s = d = str->str + 1;
- end = str->str + 1 + length;
- while (s < end) {
- while (s < end && *s == '\0') {
- s++;
- length--;
- }
- if (*s == '\r' && *(s + 1) == '\n') {
- s++;
- length--;
- }
- *d++ = *s++;
- }
- *d = '\0';
- str->len = length + 1;
-
- /* p points to the "{" in the line that starts the
- * literal. The length of the CR-less response must be
- * less than or equal to the length of the response
- * with CRs, therefore overwriting the old value with
- * the new value cannot cause an overrun. However, we
- * don't want it to be shorter either, because then the
- * GString's length would be off...
- */
- sprintf (p, "{%0*d}", ldigits, length);
-
- fulllen += str->len;
- g_ptr_array_add (data, str);
-
- /* Read the next line. */
- if (camel_imap_store_readline (store, &line, ex) < 0)
- goto lose;
- }
-
- /* Now reassemble the data. */
- p = line = g_malloc (fulllen + 1);
- for (i = 0; i < data->len; i++) {
- str = data->pdata[i];
- memcpy (p, str->str, str->len);
- p += str->len;
- g_string_free (str, TRUE);
- }
- *p = '\0';
- g_ptr_array_free (data, TRUE);
- return line;
-
- lose:
- for (i = 0; i < data->len; i++)
- g_string_free (data->pdata[i], TRUE);
- g_ptr_array_free (data, TRUE);
- return NULL;
-}
-
-
-/**
- * camel_imap_response_free:
- * @store: the CamelImapStore the response is from
- * @response: a CamelImapResponse
- *
- * Frees all of the data in @response and processes any untagged
- * EXPUNGE and EXISTS responses in it. Releases @store's connect_lock.
- **/
-void
-camel_imap_response_free (CamelImapStore *store, CamelImapResponse *response)
-{
- int i, number, exists = 0;
- GArray *expunged = NULL;
- char *resp, *p;
-
- if (!response)
- return;
-
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i];
-
- if (response->folder) {
- /* Check if it's something we need to handle. */
- number = strtoul (resp + 2, &p, 10);
- if (!strcasecmp (p, " EXISTS")) {
- exists = number;
- } else if (!strcasecmp (p, " EXPUNGE")) {
- if (!expunged) {
- expunged = g_array_new (FALSE, FALSE,
- sizeof (int));
- }
- g_array_append_val (expunged, number);
- }
- }
- g_free (resp);
- }
-
- g_ptr_array_free (response->untagged, TRUE);
- g_free (response->status);
-
- if (response->folder) {
- if (exists > 0 || expunged) {
- /* Update the summary */
- camel_imap_folder_changed (response->folder,
- exists, expunged, NULL);
- if (expunged)
- g_array_free (expunged, TRUE);
- }
-
- camel_object_unref (CAMEL_OBJECT (response->folder));
- }
-
- g_free (response);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-/**
- * camel_imap_response_free_without_processing:
- * @store: the CamelImapStore the response is from.
- * @response: a CamelImapResponse:
- *
- * Frees all of the data in @response without processing any untagged
- * responses. Releases @store's command lock.
- **/
-void
-camel_imap_response_free_without_processing (CamelImapStore *store,
- CamelImapResponse *response)
-{
- if (!response)
- return;
-
- if (response->folder) {
- camel_object_unref (CAMEL_OBJECT (response->folder));
- response->folder = NULL;
- }
- camel_imap_response_free (store, response);
-}
-
-/**
- * camel_imap_response_extract:
- * @store: the store the response came from
- * @response: the response data returned from camel_imap_command
- * @type: the response type to extract
- * @ex: a CamelException
- *
- * This checks that @response contains a single untagged response of
- * type @type and returns just that response data. If @response
- * doesn't contain the right information, the function will set @ex
- * and return %NULL. Either way, @response will be freed and the
- * store's connect_lock released.
- *
- * Return value: the desired response string, which the caller must free.
- **/
-char *
-camel_imap_response_extract (CamelImapStore *store,
- CamelImapResponse *response,
- const char *type,
- CamelException *ex)
-{
- int len = strlen (type), i;
- char *resp;
-
- len = strlen (type);
-
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i];
- /* Skip "* ", and initial sequence number, if present */
- strtoul (resp + 2, &resp, 10);
- if (*resp == ' ')
- resp = (char *) imap_next_word (resp);
-
- if (!strncasecmp (resp, type, len))
- break;
- }
-
- if (i < response->untagged->len) {
- resp = response->untagged->pdata[i];
- g_ptr_array_remove_index (response->untagged, i);
- } else {
- resp = NULL;
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("IMAP server response did not contain "
- "%s information"), type);
- }
-
- camel_imap_response_free (store, response);
- return resp;
-}
-
-/**
- * camel_imap_response_extract_continuation:
- * @store: the store the response came from
- * @response: the response data returned from camel_imap_command
- * @ex: a CamelException
- *
- * This checks that @response contains a continuation response, and
- * returns just that data. If @response doesn't contain a continuation
- * response, the function will set @ex, release @store's connect_lock,
- * and return %NULL. Either way, @response will be freed.
- *
- * Return value: the desired response string, which the caller must free.
- **/
-char *
-camel_imap_response_extract_continuation (CamelImapStore *store,
- CamelImapResponse *response,
- CamelException *ex)
-{
- char *status;
-
- if (response->status && *response->status == '+') {
- status = response->status;
- response->status = NULL;
- camel_imap_response_free (store, response);
- return status;
- }
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Unexpected OK response from IMAP server: %s"),
- response->status);
- camel_imap_response_free (store, response);
- return NULL;
-}
-
-static char *
-imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt,
- va_list ap)
-{
- GPtrArray *args;
- const char *p, *start;
- char *out, *outptr, *string;
- int num, len, i, arglen;
-
- args = g_ptr_array_new ();
-
- /* Determine the length of the data */
- len = strlen (fmt);
- p = start = fmt;
- while (*p) {
- p = strchr (start, '%');
- if (!p)
- break;
-
- switch (*++p) {
- case 'd':
- num = va_arg (ap, int);
- g_ptr_array_add (args, GINT_TO_POINTER (num));
- start = p + 1;
- len += 10;
- break;
- case 's':
- string = va_arg (ap, char *);
- g_ptr_array_add (args, string);
- start = p + 1;
- len += strlen (string);
- break;
- case 'S':
- case 'F':
- string = va_arg (ap, char *);
- if (*p == 'F') {
- /* NB: this is freed during output */
- char *s = camel_imap_store_summary_full_from_path(store->summary, string);
- string = s?s:camel_utf8_utf7(string);
- }
- arglen = strlen (string);
- g_ptr_array_add (args, string);
- if (imap_is_atom (string)) {
- len += arglen;
- } else {
- if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS)
- len += arglen + 15;
- else
- len += arglen * 2;
- }
- start = p + 1;
- break;
- case '%':
- start = p;
- break;
- default:
- g_warning ("camel-imap-command is not printf. I don't "
- "know what '%%%c' means.", *p);
- start = *p ? p + 1 : p;
- break;
- }
- }
-
- /* Now write out the string */
- outptr = out = g_malloc (len + 1);
- p = start = fmt;
- i = 0;
- while (*p) {
- p = strchr (start, '%');
- if (!p) {
- strcpy (outptr, start);
- break;
- } else {
- strncpy (outptr, start, p - start);
- outptr += p - start;
- }
-
- switch (*++p) {
- case 'd':
- num = GPOINTER_TO_INT (args->pdata[i++]);
- outptr += sprintf (outptr, "%d", num);
- break;
-
- case 's':
- string = args->pdata[i++];
- outptr += sprintf (outptr, "%s", string);
- break;
- case 'S':
- case 'F':
- string = args->pdata[i++];
- if (imap_is_atom (string)) {
- outptr += sprintf (outptr, "%s", string);
- } else {
- if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) {
- outptr += sprintf (outptr, "{%d+}\r\n%s", strlen (string), string);
- } else {
- char *quoted = imap_quote_string (string);
-
- outptr += sprintf (outptr, "%s", quoted);
- g_free (quoted);
- }
- }
-
- if (*p == 'F')
- g_free (string);
- break;
- default:
- *outptr++ = '%';
- *outptr++ = *p;
- }
-
- start = *p ? p + 1 : p;
- }
-
- return out;
-}
-
-static char *
-imap_command_strdup_printf (CamelImapStore *store, const char *fmt, ...)
-{
- va_list ap;
- char *result;
-
- va_start (ap, fmt);
- result = imap_command_strdup_vprintf (store, fmt, ap);
- va_end (ap);
-
- return result;
-}
diff --git a/camel/providers/imap/camel-imap-command.h b/camel/providers/imap/camel-imap-command.h
deleted file mode 100644
index 3539ac63d2..0000000000
--- a/camel/providers/imap/camel-imap-command.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-command.h: IMAP command sending/parsing routines */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_COMMAND_H
-#define CAMEL_IMAP_COMMAND_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <glib.h>
-#include "camel-imap-types.h"
-
-typedef enum {
- CAMEL_IMAP_RESPONSE_ERROR,
- CAMEL_IMAP_RESPONSE_CONTINUATION,
- CAMEL_IMAP_RESPONSE_UNTAGGED,
- CAMEL_IMAP_RESPONSE_TAGGED
-} CamelImapResponseType;
-
-struct _CamelImapResponse {
- CamelFolder *folder;
- GPtrArray *untagged;
- char *status;
-};
-
-CamelImapResponse *camel_imap_command (CamelImapStore *store,
- CamelFolder *folder,
- CamelException *ex,
- const char *fmt, ...);
-CamelImapResponse *camel_imap_command_continuation (CamelImapStore *store,
- const char *cmd,
- size_t cmdlen,
- CamelException *ex);
-
-void camel_imap_response_free (CamelImapStore *store,
- CamelImapResponse *response);
-void camel_imap_response_free_without_processing (CamelImapStore *store,
- CamelImapResponse *response);
-char *camel_imap_response_extract (CamelImapStore *store,
- CamelImapResponse *response,
- const char *type,
- CamelException *ex);
-char *camel_imap_response_extract_continuation (CamelImapStore *store,
- CamelImapResponse *response,
- CamelException *ex);
-
-gboolean camel_imap_command_start (CamelImapStore *store,
- CamelFolder *folder,
- CamelException *ex,
- const char *fmt, ...);
-CamelImapResponseType camel_imap_command_response (CamelImapStore *store,
- char **respbuf,
- CamelException *ex);
-
-#endif /* CAMEL_IMAP_COMMAND_H */
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
deleted file mode 100644
index 4db0c7a43f..0000000000
--- a/camel/providers/imap/camel-imap-folder.c
+++ /dev/null
@@ -1,2729 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-folder.c: class for an imap folder */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-#include "e-util/e-path.h"
-#include "e-util/e-time-utils.h"
-
-#include "camel-imap-folder.h"
-#include "camel-imap-command.h"
-#include "camel-imap-message-cache.h"
-#include "camel-imap-private.h"
-#include "camel-imap-search.h"
-#include "camel-imap-store.h"
-#include "camel-imap-summary.h"
-#include "camel-imap-utils.h"
-#include "camel-imap-wrapper.h"
-#include "camel-data-wrapper.h"
-#include "camel-disco-diary.h"
-#include "camel-exception.h"
-#include "camel-mime-filter-crlf.h"
-#include "camel-mime-filter-from.h"
-#include "camel-mime-message.h"
-#include "camel-mime-utils.h"
-#include "camel-multipart.h"
-#include "camel-multipart-signed.h"
-#include "camel-multipart-encrypted.h"
-#include "camel-operation.h"
-#include "camel-session.h"
-#include "camel-stream-buffer.h"
-#include "camel-stream-filter.h"
-#include "camel-stream-mem.h"
-#include "camel-stream.h"
-#include "camel-private.h"
-#include "camel-string-utils.h"
-#include "camel-file-utils.h"
-
-
-#define d(x)
-
-/* set to -1 for infinite size */
-#define UID_SET_LIMIT (4096)
-
-
-#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(o)))
-static CamelDiscoFolderClass *disco_folder_class = NULL;
-
-static void imap_finalize (CamelObject *object);
-static int imap_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args);
-
-static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex);
-static void imap_refresh_info (CamelFolder *folder, CamelException *ex);
-static void imap_sync_online (CamelFolder *folder, CamelException *ex);
-static void imap_sync_offline (CamelFolder *folder, CamelException *ex);
-static void imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
-static void imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
-static void imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
-static void imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex);
-static void imap_rename (CamelFolder *folder, const char *new);
-
-/* message manipulation */
-static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid,
- CamelException *ex);
-static void imap_append_online (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex);
-static void imap_append_offline (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex);
-static void imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex);
-
-static void imap_transfer_online (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals,
- CamelException *ex);
-static void imap_transfer_offline (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals,
- CamelException *ex);
-static void imap_transfer_resyncing (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals,
- CamelException *ex);
-
-/* searching */
-static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex);
-static GPtrArray *imap_search_by_uids (CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex);
-static void imap_search_free (CamelFolder *folder, GPtrArray *uids);
-
-static void imap_thaw (CamelFolder *folder);
-
-static CamelObjectClass *parent_class;
-
-static GData *parse_fetch_response (CamelImapFolder *imap_folder, char *msg_att);
-
-static void
-camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_imap_folder_class);
- CamelDiscoFolderClass *camel_disco_folder_class = CAMEL_DISCO_FOLDER_CLASS (camel_imap_folder_class);
-
- disco_folder_class = CAMEL_DISCO_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_disco_folder_get_type ()));
-
- /* virtual method overload */
- ((CamelObjectClass *)camel_imap_folder_class)->getv = imap_getv;
-
- camel_folder_class->get_message = imap_get_message;
- camel_folder_class->rename = imap_rename;
- camel_folder_class->search_by_expression = imap_search_by_expression;
- camel_folder_class->search_by_uids = imap_search_by_uids;
- camel_folder_class->search_free = imap_search_free;
- camel_folder_class->thaw = imap_thaw;
-
- camel_disco_folder_class->refresh_info_online = imap_refresh_info;
- camel_disco_folder_class->sync_online = imap_sync_online;
- camel_disco_folder_class->sync_offline = imap_sync_offline;
- /* We don't sync flags at resync time: the online code will
- * deal with it eventually.
- */
- camel_disco_folder_class->sync_resyncing = imap_sync_offline;
- camel_disco_folder_class->expunge_uids_online = imap_expunge_uids_online;
- camel_disco_folder_class->expunge_uids_offline = imap_expunge_uids_offline;
- camel_disco_folder_class->expunge_uids_resyncing = imap_expunge_uids_resyncing;
- camel_disco_folder_class->append_online = imap_append_online;
- camel_disco_folder_class->append_offline = imap_append_offline;
- camel_disco_folder_class->append_resyncing = imap_append_resyncing;
- camel_disco_folder_class->transfer_online = imap_transfer_online;
- camel_disco_folder_class->transfer_offline = imap_transfer_offline;
- camel_disco_folder_class->transfer_resyncing = imap_transfer_resyncing;
- camel_disco_folder_class->cache_message = imap_cache_message;
-}
-
-static void
-camel_imap_folder_init (gpointer object, gpointer klass)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
- CamelFolder *folder = CAMEL_FOLDER (object);
-
- folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED |
- CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN;
-
- folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY |
- CAMEL_FOLDER_HAS_SEARCH_CAPABILITY);
-
- imap_folder->priv = g_malloc0(sizeof(*imap_folder->priv));
-#ifdef ENABLE_THREADS
- imap_folder->priv->search_lock = e_mutex_new(E_MUTEX_SIMPLE);
- imap_folder->priv->cache_lock = e_mutex_new(E_MUTEX_REC);
-#endif
-
- imap_folder->need_rescan = TRUE;
-}
-
-CamelType
-camel_imap_folder_get_type (void)
-{
- static CamelType camel_imap_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_imap_folder_type == CAMEL_INVALID_TYPE) {
- parent_class = camel_disco_folder_get_type();
- camel_imap_folder_type =
- camel_type_register (parent_class, "CamelImapFolder",
- sizeof (CamelImapFolder),
- sizeof (CamelImapFolderClass),
- (CamelObjectClassInitFunc) camel_imap_folder_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_folder_init,
- (CamelObjectFinalizeFunc) imap_finalize);
- }
-
- return camel_imap_folder_type;
-}
-
-CamelFolder *
-camel_imap_folder_new (CamelStore *parent, const char *folder_name,
- const char *folder_dir, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (parent);
- CamelFolder *folder;
- CamelImapFolder *imap_folder;
- const char *short_name;
- char *summary_file;
-
- if (camel_mkdir (folder_dir, S_IRWXU) != 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create directory %s: %s"),
- folder_dir, g_strerror (errno));
- return NULL;
- }
-
- folder = CAMEL_FOLDER (camel_object_new (camel_imap_folder_get_type ()));
- short_name = strrchr (folder_name, imap_store->dir_sep);
- if (short_name)
- short_name++;
- else
- short_name = folder_name;
- camel_folder_construct (folder, parent, folder_name, short_name);
-
- summary_file = g_strdup_printf ("%s/summary", folder_dir);
- folder->summary = camel_imap_summary_new (summary_file);
- g_free (summary_file);
- if (!folder->summary) {
- camel_object_unref (CAMEL_OBJECT (folder));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not load summary for %s"),
- folder_name);
- return NULL;
- }
-
- imap_folder = CAMEL_IMAP_FOLDER (folder);
- imap_folder->cache = camel_imap_message_cache_new (folder_dir, folder->summary, ex);
- if (!imap_folder->cache) {
- camel_object_unref (CAMEL_OBJECT (folder));
- return NULL;
- }
-
- if ((imap_store->parameters & IMAP_PARAM_FILTER_INBOX) &&
- !strcasecmp (folder_name, "INBOX"))
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
-
- imap_folder->search = camel_imap_search_new(folder_dir);
-
- return folder;
-}
-
-/* Called with the store's connect_lock locked */
-void
-camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response,
- CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelImapSummary *imap_summary = CAMEL_IMAP_SUMMARY (folder->summary);
- unsigned long exists = 0, validity = 0, val, uid;
- CamelMessageInfo *info;
- GData *fetch_data;
- int i, count;
- char *resp;
-
- CAMEL_SERVICE_ASSERT_LOCKED (folder->parent_store, connect_lock);
-
- count = camel_folder_summary_count (folder->summary);
-
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i] + 2;
- if (!strncasecmp (resp, "FLAGS ", 6) &&
- !folder->permanent_flags) {
- resp += 6;
- folder->permanent_flags = imap_parse_flag_list (&resp);
- } else if (!strncasecmp (resp, "OK [PERMANENTFLAGS ", 19)) {
- resp += 19;
- folder->permanent_flags = imap_parse_flag_list (&resp);
- } else if (!strncasecmp (resp, "OK [UIDVALIDITY ", 16)) {
- validity = strtoul (resp + 16, NULL, 10);
- } else if (isdigit ((unsigned char)*resp)) {
- unsigned long num = strtoul (resp, &resp, 10);
-
- if (!strncasecmp (resp, " EXISTS", 7)) {
- exists = num;
- /* Remove from the response so nothing
- * else tries to interpret it.
- */
- g_free (response->untagged->pdata[i]);
- g_ptr_array_remove_index (response->untagged, i--);
- }
- }
- }
-
- if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) == CAMEL_DISCO_STORE_RESYNCING) {
- if (validity != imap_summary->validity) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID,
- _("Folder was destroyed and recreated on server."));
- return;
- }
-
- /* FIXME: find missing UIDs ? */
- return;
- }
-
- if (!imap_summary->validity)
- imap_summary->validity = validity;
- else if (validity != imap_summary->validity) {
- imap_summary->validity = validity;
- camel_folder_summary_clear (folder->summary);
- CAMEL_IMAP_FOLDER_LOCK (imap_folder, cache_lock);
- camel_imap_message_cache_clear (imap_folder->cache);
- CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
- imap_folder->need_rescan = FALSE;
- camel_imap_folder_changed (folder, exists, NULL, ex);
- return;
- }
-
- /* If we've lost messages, we have to rescan everything */
- if (exists < count)
- imap_folder->need_rescan = TRUE;
- else if (count != 0 && !imap_folder->need_rescan) {
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
-
- /* Similarly, if the UID of the highest message we
- * know about has changed, then that indicates that
- * messages have been both added and removed, so we
- * have to rescan to find the removed ones. (We pass
- * NULL for the folder since we know that this folder
- * is selected, and we don't want camel_imap_command
- * to worry about it.)
- */
- response = camel_imap_command (store, NULL, ex, "FETCH %d UID", count);
- if (!response)
- return;
- uid = 0;
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i];
- val = strtoul (resp + 2, &resp, 10);
- if (val == 0)
- continue;
- if (!strcasecmp (resp, " EXISTS")) {
- /* Another one?? */
- exists = val;
- continue;
- }
- if (uid != 0 || val != count || strncasecmp (resp, " FETCH (", 8) != 0)
- continue;
-
- fetch_data = parse_fetch_response (imap_folder, resp + 7);
- uid = strtoul (g_datalist_get_data (&fetch_data, "UID"), NULL, 10);
- g_datalist_clear (&fetch_data);
- }
- camel_imap_response_free_without_processing (store, response);
-
- info = camel_folder_summary_index (folder->summary, count - 1);
- val = strtoul (camel_message_info_uid (info), NULL, 10);
- camel_folder_summary_info_free (folder->summary, info);
- if (uid == 0 || uid != val)
- imap_folder->need_rescan = TRUE;
- }
-
- /* Now rescan if we need to */
- if (imap_folder->need_rescan) {
- imap_rescan (folder, exists, ex);
- return;
- }
-
- /* If we don't need to rescan completely, but new messages
- * have been added, find out about them.
- */
- if (exists > count)
- camel_imap_folder_changed (folder, exists, NULL, ex);
-
- /* And we're done. */
-}
-
-static void
-imap_finalize (CamelObject *object)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
-
- if (imap_folder->search)
- camel_object_unref (CAMEL_OBJECT (imap_folder->search));
- if (imap_folder->cache)
- camel_object_unref (CAMEL_OBJECT (imap_folder->cache));
-
-#ifdef ENABLE_THREADS
- e_mutex_destroy(imap_folder->priv->search_lock);
- e_mutex_destroy(imap_folder->priv->cache_lock);
-#endif
- g_free(imap_folder->priv);
-}
-
-static int
-imap_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
-{
- CamelFolder *folder = (CamelFolder *)object;
- int i, count=args->argc;
- guint32 tag;
-
- for (i=0;i<args->argc;i++) {
- CamelArgGet *arg = &args->argv[i];
-
- tag = arg->tag;
-
- switch (tag & CAMEL_ARG_TAG) {
- /* CamelObject args */
- case CAMEL_OBJECT_ARG_DESCRIPTION:
- if (folder->description == NULL) {
- CamelURL *uri = ((CamelService *)folder->parent_store)->url;
-
- /* what if the full name doesn't incclude /'s? does it matter? */
- folder->description = g_strdup_printf("%s@%s:%s", uri->user, uri->host, folder->full_name);
- }
- *arg->ca_str = folder->description;
- break;
- default:
- count--;
- continue;
- }
-
- arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
- }
-
- if (count)
- return ((CamelObjectClass *)parent_class)->getv(object, ex, args);
-
- return 0;
-}
-
-static void
-imap_rename (CamelFolder *folder, const char *new)
-{
- CamelImapFolder *imap_folder = (CamelImapFolder *)folder;
- CamelImapStore *imap_store = (CamelImapStore *)folder->parent_store;
- char *folder_dir, *summary_path;
- char *folders;
-
- folders = g_strconcat (imap_store->storage_path, "/folders", NULL);
- folder_dir = e_path_to_physical (folders, new);
- g_free (folders);
- summary_path = g_strdup_printf("%s/summary", folder_dir);
-
- CAMEL_IMAP_FOLDER_LOCK (folder, cache_lock);
- camel_imap_message_cache_set_path(imap_folder->cache, folder_dir);
- CAMEL_IMAP_FOLDER_UNLOCK (folder, cache_lock);
-
- camel_folder_summary_set_filename(folder->summary, summary_path);
-
- g_free(summary_path);
- g_free(folder_dir);
-
- ((CamelFolderClass *)disco_folder_class)->rename(folder, new);
-}
-
-static void
-imap_refresh_info (CamelFolder *folder, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelImapResponse *response;
-
- if (camel_disco_store_status (CAMEL_DISCO_STORE (imap_store)) == CAMEL_DISCO_STORE_OFFLINE)
- return;
-
- if (camel_folder_is_frozen (folder)) {
- imap_folder->need_refresh = TRUE;
- return;
- }
-
- /* If the folder isn't selected, select it (which will force
- * a rescan if one is needed).
- * Also, if this is the INBOX, some servers (cryus) wont tell
- * us with a NOOP of new messages, so force a reselect which
- * should do it. */
- CAMEL_SERVICE_LOCK (imap_store, connect_lock);
- if (imap_store->current_folder != folder
- || strcasecmp(folder->full_name, "INBOX") == 0) {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- response = camel_imap_command (imap_store, folder, ex, NULL);
- if (response) {
- camel_imap_folder_selected (folder, response, ex);
- camel_imap_response_free (imap_store, response);
- }
- return;
- }
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
-
- /* Otherwise, if we need a rescan, do it, and if not, just do
- * a NOOP to give the server a chance to tell us about new
- * messages.
- */
- if (imap_folder->need_rescan)
- imap_rescan (folder, camel_folder_summary_count (folder->summary), ex);
- else {
-#if 0
- /* on some servers need to CHECKpoint INBOX to recieve new messages?? */
- /* rfc2060 suggests this, but havent seen a server that requires it */
- if (strcasecmp(folder->full_name, "INBOX") == 0) {
- response = camel_imap_command (imap_store, folder, ex, "CHECK");
- camel_imap_response_free (imap_store, response);
- }
-#endif
- response = camel_imap_command (imap_store, folder, ex, "NOOP");
- camel_imap_response_free (imap_store, response);
- }
-}
-
-/* Called with the store's connect_lock locked */
-static void
-imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- struct {
- char *uid;
- guint32 flags;
- } *new;
- char *resp;
- CamelImapResponseType type;
- int i, seq, summary_len, summary_got;
- CamelMessageInfo *info;
- CamelImapMessageInfo *iinfo;
- GArray *removed;
- gboolean ok;
- CamelFolderChangeInfo *changes = NULL;
-
- CAMEL_SERVICE_ASSERT_LOCKED (store, connect_lock);
- imap_folder->need_rescan = FALSE;
-
- summary_len = camel_folder_summary_count (folder->summary);
- if (summary_len == 0) {
- if (exists)
- camel_imap_folder_changed (folder, exists, NULL, ex);
- return;
- }
-
- /* Check UIDs and flags of all messages we already know of. */
- camel_operation_start (NULL, _("Scanning for changed messages"));
- info = camel_folder_summary_index (folder->summary, summary_len - 1);
- ok = camel_imap_command_start (store, folder, ex,
- "UID FETCH 1:%s (FLAGS)",
- camel_message_info_uid (info));
- camel_folder_summary_info_free (folder->summary, info);
- if (!ok) {
- camel_operation_end (NULL);
- return;
- }
-
- new = g_malloc0 (summary_len * sizeof (*new));
- summary_got = 0;
- while ((type = camel_imap_command_response (store, &resp, ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) {
- GData *data;
- char *uid;
- guint32 flags;
-
- data = parse_fetch_response (imap_folder, resp);
- g_free (resp);
- if (!data)
- continue;
-
- seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
- uid = g_datalist_get_data (&data, "UID");
- flags = GPOINTER_TO_UINT (g_datalist_get_data (&data, "FLAGS"));
-
- if (!uid || !seq || seq > summary_len) {
- g_datalist_clear (&data);
- continue;
- }
-
- camel_operation_progress (NULL, ++summary_got * 100 / summary_len);
- new[seq - 1].uid = g_strdup (uid);
- new[seq - 1].flags = flags;
- g_datalist_clear (&data);
- }
-
- camel_operation_end (NULL);
- if (type == CAMEL_IMAP_RESPONSE_ERROR) {
- for (i = 0; i < summary_len && new[i].uid; i++)
- g_free (new[i].uid);
- g_free (new);
- return;
- }
-
- /* Free the final tagged response */
- g_free (resp);
-
- /* If we find a UID in the summary that doesn't correspond to
- * the UID in the folder, then either: (a) it's a real UID,
- * but the message was deleted on the server, or (b) it's a
- * fake UID, and needs to be removed from the summary in order
- * to sync up with the server. So either way, we remove it
- * from the summary.
- */
- removed = g_array_new (FALSE, FALSE, sizeof (int));
- for (i = 0; i < summary_len && new[i].uid; i++) {
- info = camel_folder_summary_index (folder->summary, i);
- iinfo = (CamelImapMessageInfo *)info;
-
- if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
- camel_folder_summary_info_free(folder->summary, info);
- seq = i + 1;
- g_array_append_val (removed, seq);
- i--;
- summary_len--;
- continue;
- }
-
- /* Update summary flags */
- if (new[i].flags != iinfo->server_flags) {
- guint32 server_set, server_cleared;
-
- server_set = new[i].flags & ~iinfo->server_flags;
- server_cleared = iinfo->server_flags & ~new[i].flags;
-
- info->flags = (info->flags | server_set) & ~server_cleared;
- iinfo->server_flags = new[i].flags;
-
- if (changes == NULL)
- changes = camel_folder_change_info_new();
- camel_folder_change_info_change_uid(changes, new[i].uid);
- }
-
- camel_folder_summary_info_free (folder->summary, info);
- g_free (new[i].uid);
- }
-
- if (changes) {
- camel_object_trigger_event(CAMEL_OBJECT (folder), "folder_changed", changes);
- camel_folder_change_info_free(changes);
- }
-
- seq = i + 1;
-
- /* Free remaining memory. */
- while (i < summary_len && new[i].uid)
- g_free (new[i++].uid);
- g_free (new);
-
- /* Remove any leftover cached summary messages. (Yes, we
- * repeatedly add the same number to the removed array.
- * See RFC2060 7.4.1)
- */
-
- for (i = seq; i <= summary_len; i++)
- g_array_append_val (removed, seq);
-
- /* And finally update the summary. */
- camel_imap_folder_changed (folder, exists, removed, ex);
- g_array_free (removed, TRUE);
-}
-
-/* the max number of chars that an unsigned 32-bit int can be is 10 chars plus 1 for a possible : */
-#define UID_SET_FULL(setlen, maxlen) (maxlen > 0 ? setlen + 11 >= maxlen : FALSE)
-
-/* Find all messages in @folder with flags matching @flags and @mask.
- * If no messages match, returns %NULL. Otherwise, returns an array of
- * CamelMessageInfo and sets *@set to a message set corresponding the
- * UIDs of the matched messages (up to @UID_SET_LIMIT bytes). The
- * caller must free the infos, the array, and the set string.
- */
-static GPtrArray *
-get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
-{
- GPtrArray *matches;
- CamelMessageInfo *info;
- int i, max, range;
- GString *gset;
-
- matches = g_ptr_array_new ();
- gset = g_string_new ("");
- max = camel_folder_summary_count (folder->summary);
- range = -1;
- for (i = 0; i < max && !UID_SET_FULL (gset->len, UID_SET_LIMIT); i++) {
- info = camel_folder_summary_index (folder->summary, i);
- if (!info)
- continue;
- if ((info->flags & mask) != flags) {
- camel_folder_summary_info_free (folder->summary, info);
- if (range != -1) {
- if (range != i - 1) {
- info = matches->pdata[matches->len - 1];
- g_string_append_printf (gset, ":%s", camel_message_info_uid (info));
- }
- range = -1;
- }
- continue;
- }
-
- g_ptr_array_add (matches, info);
- if (range != -1)
- continue;
- range = i;
- if (gset->len)
- g_string_append_c (gset, ',');
- g_string_append_printf (gset, "%s", camel_message_info_uid (info));
- }
-
- if (range != -1 && range != max - 1) {
- info = matches->pdata[matches->len - 1];
- g_string_append_printf (gset, ":%s", camel_message_info_uid (info));
- }
-
- if (matches->len) {
- *set = gset->str;
- g_string_free (gset, FALSE);
- return matches;
- } else {
- *set = NULL;
- g_string_free (gset, TRUE);
- g_ptr_array_free (matches, TRUE);
- return NULL;
- }
-}
-
-static void
-imap_sync_offline (CamelFolder *folder, CamelException *ex)
-{
- camel_folder_summary_save (folder->summary);
-}
-
-static void
-imap_sync_online (CamelFolder *folder, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response = NULL;
- CamelMessageInfo *info;
- CamelException local_ex;
- GPtrArray *matches;
- char *set, *flaglist;
- gboolean unset;
- int i, j, max;
-
- camel_exception_init (&local_ex);
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- /* Find a message with changed flags, find all of the other
- * messages like it, sync them as a group, mark them as
- * updated, and continue.
- */
- max = camel_folder_summary_count (folder->summary);
- for (i = 0; i < max; i++) {
- info = camel_folder_summary_index (folder->summary, i);
- if (!info)
- continue;
- if (!(info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- camel_folder_summary_info_free (folder->summary, info);
- continue;
- }
-
- /* Note: Cyrus is broken and will not accept an
- empty-set of flags so... if this is true then we
- want to unset the previously set flags.*/
- unset = !(info->flags & CAMEL_IMAP_SERVER_FLAGS);
-
- /* Note: get_matching() uses UID_SET_LIMIT to limit
- the size of the uid-set string. We don't have to
- loop here to flush all the matching uids because
- they will be scooped up later by our parent loop (I
- think?). -- Jeff */
- matches = get_matching (folder, info->flags & (CAMEL_IMAP_SERVER_FLAGS | CAMEL_MESSAGE_FOLDER_FLAGGED),
- CAMEL_IMAP_SERVER_FLAGS | CAMEL_MESSAGE_FOLDER_FLAGGED, &set);
- camel_folder_summary_info_free (folder->summary, info);
- if (matches == NULL)
- continue;
-
- /* FIXME: since we don't know the previously set flags,
- if unset is TRUE then just unset all the flags? */
- flaglist = imap_create_flag_list (unset ? CAMEL_IMAP_SERVER_FLAGS : info->flags);
-
- /* Note: to `unset' flags, use -FLAGS.SILENT (<flag list>) */
- response = camel_imap_command (store, folder, &local_ex,
- "UID STORE %s %sFLAGS.SILENT %s",
- set, unset ? "-" : "", flaglist);
- g_free (set);
- g_free (flaglist);
-
- if (response)
- camel_imap_response_free (store, response);
-
- if (!camel_exception_is_set (&local_ex)) {
- for (j = 0; j < matches->len; j++) {
- info = matches->pdata[j];
- info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- ((CamelImapMessageInfo*)info)->server_flags =
- info->flags & CAMEL_IMAP_SERVER_FLAGS;
- }
- camel_folder_summary_touch (folder->summary);
- }
-
- for (j = 0; j < matches->len; j++) {
- info = matches->pdata[j];
- camel_folder_summary_info_free (folder->summary, info);
- }
- g_ptr_array_free (matches, TRUE);
-
- /* We unlock here so that other threads can have a chance to grab the connect_lock */
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- /* check for an exception */
- if (camel_exception_is_set (&local_ex)) {
- camel_exception_xfer (ex, &local_ex);
- return;
- }
-
- /* Re-lock the connect_lock */
- CAMEL_SERVICE_LOCK (store, connect_lock);
- }
-
- /* Save the summary */
- imap_sync_offline (folder, ex);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static int
-uid_compar (const void *va, const void *vb)
-{
- const char **sa = (const char **)va, **sb = (const char **)vb;
- unsigned long a, b;
-
- a = strtoul (*sa, NULL, 10);
- b = strtoul (*sb, NULL, 10);
- if (a < b)
- return -1;
- else if (a == b)
- return 0;
- else
- return 1;
-}
-
-static void
-imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, CamelException *ex)
-{
- CamelFolderChangeInfo *changes;
- int i;
-
- qsort (uids->pdata, uids->len, sizeof (void *), uid_compar);
-
- changes = camel_folder_change_info_new ();
-
- for (i = 0; i < uids->len; i++) {
- camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
- camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
- /* We intentionally don't remove it from the cache because
- * the cached data may be useful in replaying a COPY later.
- */
- }
- camel_folder_summary_save (folder->summary);
-
- camel_disco_diary_log (CAMEL_DISCO_STORE (folder->parent_store)->diary,
- CAMEL_DISCO_DIARY_FOLDER_EXPUNGE, folder, uids);
-
- camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes);
- camel_folder_change_info_free (changes);
-}
-
-static void
-imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- int uid = 0;
- char *set;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- if ((store->capabilities & IMAP_CAPABILITY_UIDPLUS) == 0) {
- ((CamelFolderClass *)CAMEL_OBJECT_GET_CLASS(folder))->sync(folder, 0, ex);
- if (camel_exception_is_set(ex)) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
- }
-
- qsort (uids->pdata, uids->len, sizeof (void *), uid_compar);
-
- while (uid < uids->len) {
- set = imap_uid_array_to_set (folder->summary, uids, uid, UID_SET_LIMIT, &uid);
- response = camel_imap_command (store, folder, ex,
- "UID STORE %s +FLAGS.SILENT \\Deleted",
- set);
- if (response)
- camel_imap_response_free (store, response);
- if (camel_exception_is_set (ex)) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- g_free (set);
- return;
- }
-
- if (store->capabilities & IMAP_CAPABILITY_UIDPLUS) {
- response = camel_imap_command (store, folder, ex,
- "UID EXPUNGE %s", set);
- } else
- response = camel_imap_command (store, folder, ex, "EXPUNGE");
-
- if (response)
- camel_imap_response_free (store, response);
- }
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static void
-imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- GPtrArray *keep_uids, *mark_uids;
- CamelImapResponse *response;
- char *result;
-
- if (store->capabilities & IMAP_CAPABILITY_UIDPLUS) {
- imap_expunge_uids_online (folder, uids, ex);
- return;
- }
-
- /* If we don't have UID EXPUNGE we need to avoid expunging any
- * of the wrong messages. So we search for deleted messages,
- * and any that aren't in our to-expunge list get temporarily
- * marked un-deleted.
- */
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- ((CamelFolderClass *)CAMEL_OBJECT_GET_CLASS(folder))->sync(folder, 0, ex);
- if (camel_exception_is_set(ex)) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- response = camel_imap_command (store, folder, ex, "UID SEARCH DELETED");
- if (!response) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
- result = camel_imap_response_extract (store, response, "SEARCH", ex);
- if (!result) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- if (result[8] == ' ') {
- char *uid, *lasts = NULL;
- unsigned long euid, kuid;
- int ei, ki;
-
- keep_uids = g_ptr_array_new ();
- mark_uids = g_ptr_array_new ();
-
- /* Parse SEARCH response */
- for (uid = strtok_r (result + 9, " ", &lasts); uid; uid = strtok_r (NULL, " ", &lasts))
- g_ptr_array_add (keep_uids, uid);
- qsort (keep_uids->pdata, keep_uids->len,
- sizeof (void *), uid_compar);
-
- /* Fill in "mark_uids", empty out "keep_uids" as needed */
- for (ei = ki = 0; ei < uids->len; ei++) {
- euid = strtoul (uids->pdata[ei], NULL, 10);
-
- for (kuid = 0; ki < keep_uids->len; ki++) {
- kuid = strtoul (keep_uids->pdata[ki], NULL, 10);
-
- if (kuid >= euid)
- break;
- }
-
- if (euid == kuid)
- g_ptr_array_remove_index (keep_uids, ki);
- else
- g_ptr_array_add (mark_uids, uids->pdata[ei]);
- }
- } else {
- /* Empty SEARCH result, meaning nothing is marked deleted
- * on server.
- */
-
- keep_uids = NULL;
- mark_uids = uids;
- }
-
- /* Unmark messages to be kept */
-
- if (keep_uids) {
- char *uidset;
- int uid = 0;
-
- while (uid < keep_uids->len) {
- uidset = imap_uid_array_to_set (folder->summary, keep_uids, uid, UID_SET_LIMIT, &uid);
-
- response = camel_imap_command (store, folder, ex,
- "UID STORE %s -FLAGS.SILENT \\Deleted",
- uidset);
-
- g_free (uidset);
-
- if (!response) {
- g_ptr_array_free (keep_uids, TRUE);
- g_ptr_array_free (mark_uids, TRUE);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
- camel_imap_response_free (store, response);
- }
- }
-
- /* Mark any messages that still need to be marked */
- if (mark_uids) {
- char *uidset;
- int uid = 0;
-
- while (uid < mark_uids->len) {
- uidset = imap_uid_array_to_set (folder->summary, mark_uids, uid, UID_SET_LIMIT, &uid);
-
- response = camel_imap_command (store, folder, ex,
- "UID STORE %s +FLAGS.SILENT \\Deleted",
- uidset);
-
- g_free (uidset);
-
- if (!response) {
- g_ptr_array_free (keep_uids, TRUE);
- g_ptr_array_free (mark_uids, TRUE);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
- camel_imap_response_free (store, response);
- }
-
- if (mark_uids != uids)
- g_ptr_array_free (mark_uids, TRUE);
- }
-
- /* Do the actual expunging */
- response = camel_imap_command (store, folder, ex, "EXPUNGE");
- if (response)
- camel_imap_response_free (store, response);
-
- /* And fix the remaining messages if we mangled them */
- if (keep_uids) {
- char *uidset;
- int uid = 0;
-
- while (uid < keep_uids->len) {
- uidset = imap_uid_array_to_set (folder->summary, keep_uids, uid, UID_SET_LIMIT, &uid);
-
- /* Don't pass ex if it's already been set */
- response = camel_imap_command (store, folder,
- camel_exception_is_set (ex) ? NULL : ex,
- "UID STORE %s +FLAGS.SILENT \\Deleted",
- uidset);
-
- g_free (uidset);
- if (response)
- camel_imap_response_free (store, response);
- }
-
- g_ptr_array_free (keep_uids, TRUE);
- }
-
- /* now we can free this, now that we're done with keep_uids */
- g_free (result);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static gchar *
-get_temp_uid (void)
-{
- gchar *res;
-
- static int counter = 0;
- G_LOCK_DEFINE_STATIC (lock);
-
- G_LOCK (lock);
- res = g_strdup_printf ("tempuid-%lx-%d",
- (unsigned long) time (NULL),
- counter++);
- G_UNLOCK (lock);
-
- return res;
-}
-
-static void
-imap_append_offline (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapMessageCache *cache = CAMEL_IMAP_FOLDER (folder)->cache;
- CamelFolderChangeInfo *changes;
- char *uid;
-
- uid = get_temp_uid ();
-
- camel_imap_summary_add_offline (folder->summary, uid, message, info);
- CAMEL_IMAP_FOLDER_LOCK (folder, cache_lock);
- camel_imap_message_cache_insert_wrapper (cache, uid, "",
- CAMEL_DATA_WRAPPER (message), ex);
- CAMEL_IMAP_FOLDER_UNLOCK (folder, cache_lock);
-
- changes = camel_folder_change_info_new ();
- camel_folder_change_info_add_uid (changes, uid);
- camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed",
- changes);
- camel_folder_change_info_free (changes);
-
- camel_disco_diary_log (CAMEL_DISCO_STORE (imap_store)->diary,
- CAMEL_DISCO_DIARY_FOLDER_APPEND, folder, uid);
- if (appended_uid)
- *appended_uid = uid;
- else
- g_free (uid);
-}
-
-static CamelImapResponse *
-do_append (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **uid,
- CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response, *response2;
- CamelStream *memstream;
- CamelMimeFilter *crlf_filter;
- CamelStreamFilter *streamfilter;
- GByteArray *ba;
- char *flagstr, *end;
-
- /* create flag string param */
- if (info && info->flags)
- flagstr = imap_create_flag_list (info->flags);
- else
- flagstr = NULL;
-
- /* encode any 8bit parts so we avoid sending embedded nul-chars and such */
- camel_mime_message_encode_8bit_parts (message);
-
- /* FIXME: We could avoid this if we knew how big the message was. */
- memstream = camel_stream_mem_new ();
- ba = g_byte_array_new ();
- camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (memstream), ba);
-
- streamfilter = camel_stream_filter_new_with_stream (memstream);
- crlf_filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE,
- CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- camel_stream_filter_add (streamfilter, crlf_filter);
- camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message),
- CAMEL_STREAM (streamfilter));
- camel_object_unref (CAMEL_OBJECT (streamfilter));
- camel_object_unref (CAMEL_OBJECT (crlf_filter));
- camel_object_unref (CAMEL_OBJECT (memstream));
-
- response = camel_imap_command (store, NULL, ex, "APPEND %F%s%s {%d}",
- folder->full_name, flagstr ? " " : "",
- flagstr ? flagstr : "", ba->len);
- g_free (flagstr);
-
- if (!response) {
- g_byte_array_free (ba, TRUE);
- return NULL;
- }
-
- if (*response->status != '+') {
- camel_imap_response_free (store, response);
- g_byte_array_free (ba, TRUE);
- return NULL;
- }
-
- /* send the rest of our data - the mime message */
- response2 = camel_imap_command_continuation (store, ba->data, ba->len, ex);
- g_byte_array_free (ba, TRUE);
-
- /* free it only after message is sent. This may cause more FETCHes. */
- camel_imap_response_free (store, response);
- if (!response2)
- return response2;
-
- if (store->capabilities & IMAP_CAPABILITY_UIDPLUS) {
- *uid = camel_strstrcase (response2->status, "[APPENDUID ");
- if (*uid)
- *uid = strchr (*uid + 11, ' ');
- if (*uid) {
- *uid = g_strndup (*uid + 1, strcspn (*uid + 1, "]"));
- /* Make sure it's a number */
- if (strtoul (*uid, &end, 10) == 0 || *end) {
- g_free (*uid);
- *uid = NULL;
- }
- }
- } else
- *uid = NULL;
-
- return response2;
-}
-
-static void
-imap_append_online (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- char *uid;
- int count;
-
- count = camel_folder_summary_count (folder->summary);
- response = do_append (folder, message, info, &uid, ex);
- if (!response)
- return;
-
- if (uid) {
- /* Cache first, since freeing response may trigger a
- * summary update that will want this information.
- */
- CAMEL_IMAP_FOLDER_LOCK (folder, cache_lock);
- camel_imap_message_cache_insert_wrapper (
- CAMEL_IMAP_FOLDER (folder)->cache, uid,
- "", CAMEL_DATA_WRAPPER (message), ex);
- CAMEL_IMAP_FOLDER_UNLOCK (folder, cache_lock);
- if (appended_uid)
- *appended_uid = uid;
- else
- g_free (uid);
- } else if (appended_uid)
- *appended_uid = NULL;
-
- camel_imap_response_free (store, response);
-
- /* Make sure a "folder_changed" is emitted. */
- CAMEL_SERVICE_LOCK (store, connect_lock);
- if (store->current_folder != folder ||
- camel_folder_summary_count (folder->summary) == count)
- imap_refresh_info (folder, ex);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static void
-imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- char *uid;
-
- response = do_append (folder, message, info, &uid, ex);
- if (!response)
- return;
-
- if (uid) {
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- const char *olduid = camel_message_info_uid (info);
-
- CAMEL_IMAP_FOLDER_LOCK (imap_folder, cache_lock);
- camel_imap_message_cache_copy (imap_folder->cache, olduid,
- imap_folder->cache, uid, ex);
- CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
-
- if (appended_uid)
- *appended_uid = uid;
- else
- g_free (uid);
- } else if (appended_uid)
- *appended_uid = NULL;
-
- camel_imap_response_free (store, response);
-}
-
-
-static void
-imap_transfer_offline (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store);
- CamelImapMessageCache *sc = CAMEL_IMAP_FOLDER (source)->cache;
- CamelImapMessageCache *dc = CAMEL_IMAP_FOLDER (dest)->cache;
- CamelFolderChangeInfo *changes;
- CamelMimeMessage *message;
- CamelMessageInfo *mi;
- char *uid, *destuid;
- int i;
-
- /* We grab the store's command lock first, and then grab the
- * source and destination cache_locks. This way we can't
- * deadlock in the case where we're simultaneously also trying
- * to copy messages in the other direction from another thread.
- */
- CAMEL_SERVICE_LOCK (store, connect_lock);
- CAMEL_IMAP_FOLDER_LOCK (source, cache_lock);
- CAMEL_IMAP_FOLDER_LOCK (dest, cache_lock);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- if (transferred_uids) {
- *transferred_uids = g_ptr_array_new ();
- g_ptr_array_set_size (*transferred_uids, uids->len);
- }
-
- changes = camel_folder_change_info_new ();
-
- for (i = 0; i < uids->len; i++) {
- uid = uids->pdata[i];
-
- destuid = get_temp_uid ();
-
- mi = camel_folder_summary_uid (source->summary, uid);
- g_return_if_fail (mi != NULL);
-
- message = camel_folder_get_message (source, uid, NULL);
-
- if (message) {
- camel_imap_summary_add_offline (dest->summary, destuid, message, mi);
- camel_object_unref (CAMEL_OBJECT (message));
- } else
- camel_imap_summary_add_offline_uncached (dest->summary, destuid, mi);
-
- camel_imap_message_cache_copy (sc, uid, dc, destuid, ex);
- camel_folder_summary_info_free (source->summary, mi);
-
- camel_folder_change_info_add_uid (changes, destuid);
- if (transferred_uids)
- (*transferred_uids)->pdata[i] = destuid;
- else
- g_free (destuid);
-
- if (delete_originals)
- camel_folder_delete_message (source, uid);
- }
-
- CAMEL_IMAP_FOLDER_UNLOCK (dest, cache_lock);
- CAMEL_IMAP_FOLDER_UNLOCK (source, cache_lock);
-
- camel_object_trigger_event (CAMEL_OBJECT (dest), "folder_changed", changes);
- camel_folder_change_info_free (changes);
-
- camel_disco_diary_log (CAMEL_DISCO_STORE (store)->diary,
- CAMEL_DISCO_DIARY_FOLDER_TRANSFER,
- source, dest, uids, delete_originals);
-}
-
-static void
-handle_copyuid (CamelImapResponse *response, CamelFolder *source,
- CamelFolder *destination)
-{
- CamelImapMessageCache *scache = CAMEL_IMAP_FOLDER (source)->cache;
- CamelImapMessageCache *dcache = CAMEL_IMAP_FOLDER (destination)->cache;
- char *validity, *srcset, *destset;
- GPtrArray *src, *dest;
- int i;
-
- validity = camel_strstrcase (response->status, "[COPYUID ");
- if (!validity)
- return;
- validity += 9;
- if (strtoul (validity, NULL, 10) !=
- CAMEL_IMAP_SUMMARY (destination->summary)->validity)
- return;
-
- srcset = strchr (validity, ' ');
- if (!srcset++)
- goto lose;
- destset = strchr (srcset, ' ');
- if (!destset++)
- goto lose;
-
- src = imap_uid_set_to_array (source->summary, srcset);
- dest = imap_uid_set_to_array (destination->summary, destset);
-
- if (src && dest && src->len == dest->len) {
- /* We don't have to worry about deadlocking on the
- * cache locks here, because we've got the store's
- * command lock too, so no one else could be here.
- */
- CAMEL_IMAP_FOLDER_LOCK (source, cache_lock);
- CAMEL_IMAP_FOLDER_LOCK (destination, cache_lock);
- for (i = 0; i < src->len; i++) {
- camel_imap_message_cache_copy (scache, src->pdata[i],
- dcache, dest->pdata[i],
- NULL);
- }
- CAMEL_IMAP_FOLDER_UNLOCK (source, cache_lock);
- CAMEL_IMAP_FOLDER_UNLOCK (destination, cache_lock);
-
- imap_uid_array_free (src);
- imap_uid_array_free (dest);
- return;
- }
-
- imap_uid_array_free (src);
- imap_uid_array_free (dest);
- lose:
- g_warning ("Bad COPYUID response from server");
-}
-
-static void
-do_copy (CamelFolder *source, GPtrArray *uids,
- CamelFolder *destination, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store);
- CamelImapResponse *response;
- char *uidset;
- int uid = 0;
-
- while (uid < uids->len && !camel_exception_is_set (ex)) {
- uidset = imap_uid_array_to_set (source->summary, uids, uid, UID_SET_LIMIT, &uid);
-
- response = camel_imap_command (store, source, ex, "UID COPY %s %F",
- uidset, destination->full_name);
-
- g_free (uidset);
-
- if (response && (store->capabilities & IMAP_CAPABILITY_UIDPLUS))
- handle_copyuid (response, source, destination);
-
- camel_imap_response_free (store, response);
- }
-}
-
-static void
-imap_transfer_online (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store);
- int count, i;
-
- /* Sync message flags if needed. */
- imap_sync_online (source, ex);
- if (camel_exception_is_set (ex))
- return;
-
- count = camel_folder_summary_count (dest->summary);
-
- qsort (uids->pdata, uids->len, sizeof (void *), uid_compar);
-
- /* Now copy the messages */
- do_copy (source, uids, dest, ex);
- if (camel_exception_is_set (ex))
- return;
-
- /* Make the destination notice its new messages */
- CAMEL_SERVICE_LOCK (store, connect_lock);
- if (store->current_folder != dest ||
- camel_folder_summary_count (dest->summary) == count)
- camel_folder_refresh_info (dest, ex);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- if (delete_originals) {
- for (i = 0; i < uids->len; i++)
- camel_folder_delete_message (source, uids->pdata[i]);
- }
-
- /* FIXME */
- if (transferred_uids)
- *transferred_uids = NULL;
-}
-
-static void
-imap_transfer_resyncing (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals, CamelException *ex)
-{
- CamelDiscoDiary *diary = CAMEL_DISCO_STORE (source->parent_store)->diary;
- GPtrArray *realuids;
- int first, i;
- const char *uid;
- CamelMimeMessage *message;
- CamelMessageInfo *info;
-
- qsort (uids->pdata, uids->len, sizeof (void *), uid_compar);
-
- /* This is trickier than append_resyncing, because some of
- * the messages we are copying may have been copied or
- * appended into @source while we were offline, in which case
- * if we don't have UIDPLUS, we won't know their real UIDs,
- * so we'll have to append them rather than copying.
- */
-
- realuids = g_ptr_array_new ();
-
- i = 0;
- while (i < uids->len) {
- /* Skip past real UIDs */
- for (first = i; i < uids->len; i++) {
- uid = uids->pdata[i];
-
- if (!isdigit ((unsigned char)*uid)) {
- uid = camel_disco_diary_uidmap_lookup (diary, uid);
- if (!uid)
- break;
- }
- g_ptr_array_add (realuids, (char *)uid);
-
- if (delete_originals)
- camel_folder_delete_message (source, uid);
- }
-
- /* If we saw any real UIDs, do a COPY */
- if (i != first) {
- do_copy (source, realuids, dest, ex);
- g_ptr_array_set_size (realuids, 0);
- if (i == uids->len || camel_exception_is_set (ex))
- break;
- }
-
- /* Deal with fake UIDs */
- while (i < uids->len &&
- !isdigit (*(unsigned char *)(uids->pdata[i])) &&
- !camel_exception_is_set (ex)) {
- uid = uids->pdata[i];
- message = camel_folder_get_message (source, uid, NULL);
- if (!message) {
- /* Message must have been expunged */
- continue;
- }
- info = camel_folder_get_message_info (source, uid);
- g_return_if_fail (info != NULL);
-
- imap_append_online (dest, message, info, NULL, ex);
- camel_folder_free_message_info (source, info);
- camel_object_unref (CAMEL_OBJECT (message));
- if (delete_originals)
- camel_folder_delete_message (source, uid);
- i++;
- }
- }
-
- g_ptr_array_free (realuids, FALSE);
-
- /* FIXME */
- if (transferred_uids)
- *transferred_uids = NULL;
-}
-
-static GPtrArray *
-imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- GPtrArray *matches, *summary;
-
- /* we could get around this by creating a new search object each time,
- but i doubt its worth it since any long operation would lock the
- command channel too */
- CAMEL_IMAP_FOLDER_LOCK(folder, search_lock);
-
- camel_folder_search_set_folder (imap_folder->search, folder);
- summary = camel_folder_get_summary(folder);
- camel_folder_search_set_summary(imap_folder->search, summary);
- matches = camel_folder_search_execute_expression (imap_folder->search, expression, ex);
-
- CAMEL_IMAP_FOLDER_UNLOCK(folder, search_lock);
-
- camel_folder_free_summary(folder, summary);
-
- return matches;
-}
-
-static GPtrArray *
-imap_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER(folder);
- GPtrArray *summary, *matches;
- int i;
-
- /* NOTE: could get away without the search lock by creating a new
- search object each time */
-
- qsort (uids->pdata, uids->len, sizeof (void *), uid_compar);
-
- summary = g_ptr_array_new();
- for (i=0;i<uids->len;i++) {
- CamelMessageInfo *info;
-
- info = camel_folder_get_message_info(folder, uids->pdata[i]);
- if (info)
- g_ptr_array_add(summary, info);
- }
-
- if (summary->len == 0)
- return summary;
-
- CAMEL_IMAP_FOLDER_LOCK(folder, search_lock);
-
- camel_folder_search_set_folder(imap_folder->search, folder);
- camel_folder_search_set_summary(imap_folder->search, summary);
-
- matches = camel_folder_search_execute_expression(imap_folder->search, expression, ex);
-
- CAMEL_IMAP_FOLDER_UNLOCK(folder, search_lock);
-
- for (i=0;i<summary->len;i++)
- camel_folder_free_message_info(folder, summary->pdata[i]);
- g_ptr_array_free(summary, TRUE);
-
- return matches;
-}
-
-static void
-imap_search_free (CamelFolder *folder, GPtrArray *uids)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
-
- g_return_if_fail (imap_folder->search);
-
- CAMEL_IMAP_FOLDER_LOCK(folder, search_lock);
-
- camel_folder_search_free_result (imap_folder->search, uids);
-
- CAMEL_IMAP_FOLDER_UNLOCK(folder, search_lock);
-}
-
-static CamelMimeMessage *get_message (CamelImapFolder *imap_folder,
- const char *uid,
- const char *part_specifier,
- CamelMessageContentInfo *ci,
- CamelException *ex);
-
-struct _part_spec_stack {
- struct _part_spec_stack *parent;
- int part;
-};
-
-static void
-part_spec_push (struct _part_spec_stack **stack, int part)
-{
- struct _part_spec_stack *node;
-
- node = g_new (struct _part_spec_stack, 1);
- node->parent = *stack;
- node->part = part;
-
- *stack = node;
-}
-
-static int
-part_spec_pop (struct _part_spec_stack **stack)
-{
- struct _part_spec_stack *node;
- int part;
-
- g_return_val_if_fail (*stack != NULL, 0);
-
- node = *stack;
- *stack = node->parent;
-
- part = node->part;
- g_free (node);
-
- return part;
-}
-
-static char *
-content_info_get_part_spec (CamelMessageContentInfo *ci)
-{
- struct _part_spec_stack *stack = NULL;
- CamelMessageContentInfo *node;
- char *part_spec, *buf;
- size_t len = 1;
- int part;
-
- node = ci;
- while (node->parent) {
- CamelMessageContentInfo *child;
-
- /* FIXME: is this only supposed to apply if 'node' is a multipart? */
- if (node->parent->parent && camel_content_type_is (node->parent->type, "message", "*")) {
- node = node->parent;
- continue;
- }
-
- child = node->parent->childs;
- for (part = 1; child; part++) {
- if (child == node)
- break;
-
- child = child->next;
- }
-
- part_spec_push (&stack, part);
-
- len += 2;
- while ((part = part / 10))
- len++;
-
- node = node->parent;
- }
-
- buf = part_spec = g_malloc (len);
- part_spec[0] = '\0';
-
- while (stack) {
- part = part_spec_pop (&stack);
- buf += sprintf (buf, "%d%s", part, stack ? "." : "");
- }
-
- return part_spec;
-}
-
-/* Fetch the contents of the MIME part indicated by @ci, which is part
- * of message @uid in @folder.
- */
-static CamelDataWrapper *
-get_content (CamelImapFolder *imap_folder, const char *uid,
- CamelMimePart *part, CamelMessageContentInfo *ci,
- CamelException *ex)
-{
- CamelDataWrapper *content = NULL;
- CamelStream *stream;
- char *part_spec;
-
- part_spec = content_info_get_part_spec (ci);
-
- /* There are three cases: multipart/signed, multipart, message/rfc822, and "other" */
- if (camel_content_type_is (ci->type, "multipart", "signed")) {
- CamelMultipartSigned *body_mp;
- char *spec;
- int ret;
-
- /* Note: because we get the content parts uninterpreted anyway, we could potentially
- just use the normalmultipart code, except that multipart/signed wont let you yet! */
-
- body_mp = camel_multipart_signed_new ();
- /* need to set this so it grabs the boundary and other info about the signed type */
- /* we assume that part->content_type is more accurate/full than ci->type */
- camel_data_wrapper_set_mime_type_field (CAMEL_DATA_WRAPPER (body_mp), CAMEL_DATA_WRAPPER (part)->mime_type);
-
- spec = g_alloca (strlen (part_spec) + 6);
- sprintf (spec, part_spec[0] ? "%s.TEXT" : "TEXT", part_spec);
- g_free (part_spec);
-
- stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, ex);
- if (stream) {
- ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (body_mp), stream);
- camel_object_unref (CAMEL_OBJECT (stream));
- if (ret == -1) {
- camel_object_unref ((CamelObject *) body_mp);
- return NULL;
- }
- }
-
- return (CamelDataWrapper *) body_mp;
- } else if (camel_content_type_is (ci->type, "multipart", "*")) {
- CamelMultipart *body_mp;
- char *child_spec;
- int speclen, num;
-
- if (camel_content_type_is (ci->type, "multipart", "encrypted"))
- body_mp = (CamelMultipart *) camel_multipart_encrypted_new ();
- else
- body_mp = camel_multipart_new ();
-
- /* need to set this so it grabs the boundary and other info about the multipart */
- /* we assume that part->content_type is more accurate/full than ci->type */
- camel_data_wrapper_set_mime_type_field (CAMEL_DATA_WRAPPER (body_mp), CAMEL_DATA_WRAPPER (part)->mime_type);
-
- speclen = strlen (part_spec);
- child_spec = g_malloc (speclen + 17); /* dot + 10 + dot + MIME + nul */
- memcpy (child_spec, part_spec, speclen);
- if (speclen > 0)
- child_spec[speclen++] = '.';
- g_free (part_spec);
-
- ci = ci->childs;
- num = 1;
- while (ci) {
- sprintf (child_spec + speclen, "%d.MIME", num++);
- stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, ex);
- if (stream) {
- int ret;
-
- part = camel_mime_part_new ();
- ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (part), stream);
- camel_object_unref (CAMEL_OBJECT (stream));
- if (ret == -1) {
- camel_object_unref (CAMEL_OBJECT (part));
- camel_object_unref (CAMEL_OBJECT (body_mp));
- g_free (child_spec);
- return NULL;
- }
-
- content = get_content (imap_folder, uid, part, ci, ex);
- }
-
- if (!stream || !content) {
- camel_object_unref (CAMEL_OBJECT (body_mp));
- g_free (child_spec);
- return NULL;
- }
-
- camel_medium_set_content_object (CAMEL_MEDIUM (part), content);
- camel_object_unref (CAMEL_OBJECT (content));
- camel_multipart_add_part (body_mp, part);
- camel_object_unref (CAMEL_OBJECT (part));
-
- ci = ci->next;
- }
-
- g_free (child_spec);
-
- return (CamelDataWrapper *) body_mp;
- } else if (camel_content_type_is (ci->type, "message", "rfc822")) {
- content = (CamelDataWrapper *) get_message (imap_folder, uid, part_spec, ci->childs, ex);
- g_free (part_spec);
- return content;
- } else {
- content = camel_imap_wrapper_new (imap_folder, ci->type, uid, *part_spec ? part_spec : "1", part);
- g_free (part_spec);
- return content;
- }
-}
-
-static CamelMimeMessage *
-get_message (CamelImapFolder *imap_folder, const char *uid,
- const char *part_spec, CamelMessageContentInfo *ci,
- CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (CAMEL_FOLDER (imap_folder)->parent_store);
- CamelDataWrapper *content;
- CamelMimeMessage *msg;
- CamelStream *stream;
- char *section_text;
- int ret;
-
- section_text = g_strdup_printf ("%s%s%s", part_spec, *part_spec ? "." : "",
- store->server_level >= IMAP_LEVEL_IMAP4REV1 ? "HEADER" : "0");
- stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, ex);
- g_free (section_text);
- if (!stream)
- return NULL;
-
- msg = camel_mime_message_new ();
- ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream);
- camel_object_unref (CAMEL_OBJECT (stream));
- if (ret == -1) {
- camel_object_unref (CAMEL_OBJECT (msg));
- return NULL;
- }
-
- content = get_content (imap_folder, uid, CAMEL_MIME_PART (msg), ci, ex);
- if (!content) {
- camel_object_unref (CAMEL_OBJECT (msg));
- return NULL;
- }
-
- camel_medium_set_content_object (CAMEL_MEDIUM (msg), content);
- camel_object_unref (CAMEL_OBJECT (content));
-
- return msg;
-}
-
-/* FIXME: I pulled this number out of my butt. */
-#define IMAP_SMALL_BODY_SIZE 5120
-
-static CamelMimeMessage *
-get_message_simple (CamelImapFolder *imap_folder, const char *uid,
- CamelStream *stream, CamelException *ex)
-{
- CamelMimeMessage *msg;
- CamelImapStore *imap_store =
- CAMEL_IMAP_STORE (CAMEL_FOLDER (imap_folder)->parent_store);
- int ret;
-
- if (!stream) {
- stream = camel_imap_folder_fetch_data (imap_folder, uid, "",
- FALSE, ex);
- if (!stream)
- return NULL;
- }
-
- msg = camel_mime_message_new ();
- ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg),
- stream);
- camel_object_unref (CAMEL_OBJECT (stream));
- if (ret == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Unable to retrieve message: %s"),
- g_strerror (errno));
- camel_object_unref (CAMEL_OBJECT (msg));
- return NULL;
- }
-
- /* FIXME, this shouldn't be done this way. */
- camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source",
- imap_store->base_url);
- return msg;
-}
-
-static CamelMimeMessage *
-imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelMessageInfo *mi;
- CamelMimeMessage *msg;
- CamelStream *stream = NULL;
-
- /* If the server doesn't support IMAP4rev1, or we already have
- * the whole thing cached, fetch it in one piece.
- */
- if (store->server_level < IMAP_LEVEL_IMAP4REV1 ||
- (stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, NULL)))
- return get_message_simple (imap_folder, uid, stream, ex);
-
- /* If we're not actually connected and it's not in the cache,
- * that's as far as we can go.
- */
- if (camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex) == FALSE)
- return NULL;
-
- mi = camel_folder_summary_uid (folder->summary, uid);
- if (mi == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s\n %s"), uid, _("No such message"));
- return NULL;
- }
-
- /* If the message is small, fetch it in one piece. */
- if (mi->size < IMAP_SMALL_BODY_SIZE) {
- camel_folder_summary_info_free (folder->summary, mi);
- return get_message_simple (imap_folder, uid, NULL, ex);
- }
-
- /* For larger messages, fetch the structure and build a message
- * with offline parts. (We check mi->content->type rather than
- * mi->content because camel_folder_summary_info_new always creates
- * an empty content struct.)
- */
- if (!mi->content->type) {
- CamelImapResponse *response;
- GData *fetch_data = NULL;
- char *body, *found_uid;
- int i;
-
- if (camel_disco_store_status (CAMEL_DISCO_STORE (store)) == CAMEL_DISCO_STORE_OFFLINE) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("This message is not currently available"));
- return NULL;
- }
-
- response = camel_imap_command (store, folder, ex,
- "UID FETCH %s BODY", uid);
- if (!response) {
- camel_folder_summary_info_free (folder->summary, mi);
- return NULL;
- }
-
- for (i = 0, body = NULL; i < response->untagged->len; i++) {
- fetch_data = parse_fetch_response (imap_folder, response->untagged->pdata[i]);
- if (fetch_data) {
- found_uid = g_datalist_get_data (&fetch_data, "UID");
- body = g_datalist_get_data (&fetch_data, "BODY");
- if (found_uid && body && !strcmp (found_uid, uid))
- break;
- g_datalist_clear (&fetch_data);
- fetch_data = NULL;
- body = NULL;
- }
- }
-
- if (body)
- imap_parse_body ((const char **) &body, folder, mi->content);
-
- if (fetch_data)
- g_datalist_clear (&fetch_data);
-
- camel_imap_response_free (store, response);
-
- if (!mi->content->type) {
- /* FETCH returned OK, but we didn't parse a BODY
- * response. Courier will return invalid BODY
- * responses for invalidly MIMEd messages, so
- * fall back to fetching the entire thing and
- * let the mailer's "bad MIME" code handle it.
- */
- camel_folder_summary_info_free (folder->summary, mi);
- return get_message_simple (imap_folder, uid, NULL, ex);
- }
- }
-
- msg = get_message (imap_folder, uid, "", mi->content, ex);
- /* FIXME, this shouldn't be done this way. */
- camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source",
- store->base_url);
- camel_folder_summary_info_free (folder->summary, mi);
-
- return msg;
-}
-
-static void
-imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid,
- CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (disco_folder);
- CamelStream *stream;
-
- stream = camel_imap_folder_fetch_data (imap_folder, uid, "", FALSE, ex);
- if (stream)
- camel_object_unref (CAMEL_OBJECT (stream));
-}
-
-/* We pretend that a FLAGS or RFC822.SIZE response is always exactly
- * 20 bytes long, and a BODY[HEADERS] response is always 2000 bytes
- * long. Since we know how many of each kind of response we're
- * expecting, we can find the total (pretend) amount of server traffic
- * to expect and then count off the responses as we read them to update
- * the progress bar.
- */
-#define IMAP_PRETEND_SIZEOF_FLAGS 20
-#define IMAP_PRETEND_SIZEOF_SIZE 20
-#define IMAP_PRETEND_SIZEOF_HEADERS 2000
-
-static char *tm_months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static gboolean
-decode_time (const unsigned char **in, int *hour, int *min, int *sec)
-{
- register const unsigned char *inptr;
- int *val, colons = 0;
-
- *hour = *min = *sec = 0;
-
- val = hour;
- for (inptr = *in; *inptr && !isspace ((int) *inptr); inptr++) {
- if (*inptr == ':') {
- colons++;
- switch (colons) {
- case 1:
- val = min;
- break;
- case 2:
- val = sec;
- break;
- default:
- return FALSE;
- }
- } else if (!isdigit ((int) *inptr))
- return FALSE;
- else
- *val = (*val * 10) + (*inptr - '0');
- }
-
- *in = inptr;
-
- return TRUE;
-}
-
-static time_t
-decode_internaldate (const unsigned char *in)
-{
- const unsigned char *inptr = in;
- int hour, min, sec, n;
- unsigned char *buf;
- struct tm tm;
- time_t date;
-
- memset ((void *) &tm, 0, sizeof (struct tm));
-
- tm.tm_mday = strtoul (inptr, (char **) &buf, 10);
- if (buf == inptr || *buf != '-')
- return (time_t) -1;
-
- inptr = buf + 1;
- if (inptr[3] != '-')
- return (time_t) -1;
-
- for (n = 0; n < 12; n++) {
- if (!strncasecmp (inptr, tm_months[n], 3))
- break;
- }
-
- if (n >= 12)
- return (time_t) -1;
-
- tm.tm_mon = n;
-
- inptr += 4;
-
- n = strtoul (inptr, (char **) &buf, 10);
- if (buf == inptr || *buf != ' ')
- return (time_t) -1;
-
- tm.tm_year = n - 1900;
-
- inptr = buf + 1;
- if (!decode_time (&inptr, &hour, &min, &sec))
- return (time_t) -1;
-
- tm.tm_hour = hour;
- tm.tm_min = min;
- tm.tm_sec = sec;
-
- n = strtol (inptr, NULL, 10);
-
- date = e_mktime_utc (&tm);
-
- /* date is now GMT of the time we want, but not offset by the timezone ... */
-
- /* this should convert the time to the GMT equiv time */
- date -= ((n / 100) * 60 * 60) + (n % 100) * 60;
-
- return date;
-}
-
-static void
-add_message_from_data (CamelFolder *folder, GPtrArray *messages,
- int first, GData *data)
-{
- CamelMimeMessage *msg;
- CamelStream *stream;
- CamelMessageInfo *mi;
- const char *idate;
- int seq;
-
- seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
- if (seq < first)
- return;
- stream = g_datalist_get_data (&data, "BODY_PART_STREAM");
- if (!stream)
- return;
-
- if (seq - first >= messages->len)
- g_ptr_array_set_size (messages, seq - first + 1);
-
- msg = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream) == -1) {
- camel_object_unref (CAMEL_OBJECT (msg));
- return;
- }
-
- mi = camel_folder_summary_info_new_from_message (folder->summary, msg);
- camel_object_unref (CAMEL_OBJECT (msg));
-
- if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
- mi->date_received = decode_internaldate (idate);
-
- if (mi->date_received == -1)
- mi->date_received = mi->date_sent;
-
- messages->pdata[seq - first] = mi;
-}
-
-
-#define CAMEL_MESSAGE_INFO_HEADERS "DATE FROM TO CC SUBJECT REFERENCES IN-REPLY-TO MESSAGE-ID MIME-VERSION CONTENT-TYPE"
-
-/* FIXME: this needs to be kept in sync with camel-mime-utils.c's list
- of mailing-list headers and so might be best if this were
- auto-generated? */
-#define MAILING_LIST_HEADERS "X-MAILING-LIST X-LOOP LIST-ID LIST-POST MAILING-LIST ORIGINATOR X-LIST SENDER RETURN-PATH X-BEENTHERE"
-
-static void
-imap_update_summary (CamelFolder *folder, int exists,
- CamelFolderChangeInfo *changes,
- CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- GPtrArray *fetch_data = NULL, *messages = NULL, *needheaders;
- guint32 flags, uidval;
- int i, seq, first, size, got;
- CamelImapResponseType type;
- const char *header_spec;
- CamelMessageInfo *mi, *info;
- CamelStream *stream;
- char *uid, *resp;
- GData *data;
-
- CAMEL_SERVICE_ASSERT_LOCKED (store, connect_lock);
- if (store->server_level >= IMAP_LEVEL_IMAP4REV1)
- header_spec = "HEADER.FIELDS.NOT (RECEIVED)";
- else
- header_spec = "0";
-
- /* Figure out if any of the new messages are already cached (which
- * may be the case if we're re-syncing after disconnected operation).
- * If so, get their UIDs, FLAGS, and SIZEs. If not, get all that
- * and ask for the headers too at the same time.
- */
- seq = camel_folder_summary_count (folder->summary);
- first = seq + 1;
- if (seq > 0) {
- mi = camel_folder_summary_index (folder->summary, seq - 1);
- uidval = strtoul(camel_message_info_uid (mi), NULL, 10);
- camel_folder_summary_info_free (folder->summary, mi);
- } else
- uidval = 0;
-
- size = (exists - seq) * (IMAP_PRETEND_SIZEOF_FLAGS + IMAP_PRETEND_SIZEOF_SIZE + IMAP_PRETEND_SIZEOF_HEADERS);
- got = 0;
- if (!camel_imap_command_start (store, folder, ex,
- "UID FETCH %d:* (FLAGS RFC822.SIZE INTERNALDATE BODY.PEEK[%s])",
- uidval + 1, header_spec))
- return;
- camel_operation_start (NULL, _("Fetching summary information for new messages"));
-
- /* Parse the responses. We can't add a message to the summary
- * until we've gotten its headers, and there's no guarantee
- * the server will send the responses in a useful order...
- */
- fetch_data = g_ptr_array_new ();
- messages = g_ptr_array_new ();
- while ((type = camel_imap_command_response (store, &resp, ex)) ==
- CAMEL_IMAP_RESPONSE_UNTAGGED) {
- data = parse_fetch_response (imap_folder, resp);
- g_free (resp);
- if (!data)
- continue;
-
- seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
- if (seq < first) {
- g_datalist_clear (&data);
- continue;
- }
-
- if (g_datalist_get_data (&data, "FLAGS"))
- got += IMAP_PRETEND_SIZEOF_FLAGS;
- if (g_datalist_get_data (&data, "RFC822.SIZE"))
- got += IMAP_PRETEND_SIZEOF_SIZE;
- stream = g_datalist_get_data (&data, "BODY_PART_STREAM");
- if (stream) {
- got += IMAP_PRETEND_SIZEOF_HEADERS;
-
- /* Use the stream now so we don't tie up many
- * many fds if we're fetching many many messages.
- */
- add_message_from_data (folder, messages, first, data);
- g_datalist_set_data (&data, "BODY_PART_STREAM", NULL);
- }
-
- camel_operation_progress (NULL, got * 100 / size);
- g_ptr_array_add (fetch_data, data);
- }
- camel_operation_end (NULL);
-
- if (type == CAMEL_IMAP_RESPONSE_ERROR)
- goto lose;
-
- /* Free the final tagged response */
- g_free (resp);
-
- /* Figure out which headers we still need to fetch. */
- needheaders = g_ptr_array_new ();
- size = got = 0;
- for (i = 0; i < fetch_data->len; i++) {
- data = fetch_data->pdata[i];
- if (g_datalist_get_data (&data, "BODY_PART_LEN"))
- continue;
-
- uid = g_datalist_get_data (&data, "UID");
- if (uid) {
- g_ptr_array_add (needheaders, uid);
- size += IMAP_PRETEND_SIZEOF_HEADERS;
- }
- }
-
- /* And fetch them */
- if (needheaders->len) {
- char *uidset;
- int uid = 0;
-
- qsort (needheaders->pdata, needheaders->len,
- sizeof (void *), uid_compar);
-
- camel_operation_start (NULL, _("Fetching summary information for new messages"));
-
- while (uid < needheaders->len) {
- uidset = imap_uid_array_to_set (folder->summary, needheaders, uid, UID_SET_LIMIT, &uid);
- if (!camel_imap_command_start (store, folder, ex,
- "UID FETCH %s BODY.PEEK[%s]",
- uidset, header_spec)) {
- g_ptr_array_free (needheaders, TRUE);
- camel_operation_end (NULL);
- g_free (uidset);
- goto lose;
- }
- g_free (uidset);
-
- while ((type = camel_imap_command_response (store, &resp, ex))
- == CAMEL_IMAP_RESPONSE_UNTAGGED) {
- data = parse_fetch_response (imap_folder, resp);
- g_free (resp);
- if (!data)
- continue;
-
- stream = g_datalist_get_data (&data, "BODY_PART_STREAM");
- if (stream) {
- add_message_from_data (folder, messages, first, data);
- got += IMAP_PRETEND_SIZEOF_HEADERS;
- camel_operation_progress (NULL, got * 100 / size);
- }
- g_datalist_clear (&data);
- }
-
- if (type == CAMEL_IMAP_RESPONSE_ERROR) {
- g_ptr_array_free (needheaders, TRUE);
- camel_operation_end (NULL);
- goto lose;
- }
- }
-
- g_ptr_array_free (needheaders, TRUE);
- camel_operation_end (NULL);
- }
-
- /* Now finish up summary entries (fix UIDs, set flags and size) */
- for (i = 0; i < fetch_data->len; i++) {
- data = fetch_data->pdata[i];
-
- seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
- if (seq >= first + messages->len) {
- g_datalist_clear (&data);
- continue;
- }
-
- mi = messages->pdata[seq - first];
- if (mi == NULL) {
- CamelMessageInfo *pmi = NULL;
- int j;
-
- /* This is a kludge around a bug in Exchange
- * 5.5 that sometimes claims multiple messages
- * have the same UID. See bug #17694 for
- * details. The "solution" is to create a fake
- * message-info with the same details as the
- * previously valid message. Yes, the user
- * will have a clone in his/her message-list,
- * but at least we don't crash.
- */
-
- /* find the previous valid message info */
- for (j = seq - first - 1; j >= 0; j--) {
- pmi = messages->pdata[j];
- if (pmi != NULL)
- break;
- }
-
- if (pmi == NULL) {
- /* Server response is *really* fucked up,
- I guess we just pretend it never happened? */
- continue;
- }
-
- mi = camel_message_info_new ();
- camel_message_info_dup_to (pmi, mi);
- }
-
- uid = g_datalist_get_data (&data, "UID");
- if (uid)
- camel_message_info_set_uid (mi, g_strdup (uid));
- flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS"));
- if (flags) {
- ((CamelImapMessageInfo *)mi)->server_flags = flags;
- /* "or" them in with the existing flags that may
- * have been set by summary_info_new_from_message.
- */
- mi->flags |= flags;
- }
- size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE"));
- if (size)
- mi->size = size;
-
- g_datalist_clear (&data);
- }
- g_ptr_array_free (fetch_data, TRUE);
-
- /* And add the entries to the summary, etc. */
- for (i = 0; i < messages->len; i++) {
- mi = messages->pdata[i];
- if (!mi) {
- g_warning ("No information for message %d", i + first);
- continue;
- }
- uid = (char *)camel_message_info_uid(mi);
- if (uid[0] == 0) {
- g_warning("Server provided no uid: message %d", i + first);
- continue;
- }
- info = camel_folder_summary_uid(folder->summary, uid);
- if (info) {
- g_warning("Message already present? %s", camel_message_info_uid(mi));
- camel_folder_summary_info_free(folder->summary, info);
- camel_folder_summary_info_free(folder->summary, mi);
- continue;
- }
-
- camel_folder_summary_add (folder->summary, mi);
- camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
-
- if ((mi->flags & CAMEL_IMAP_MESSAGE_RECENT))
- camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi));
- }
- g_ptr_array_free (messages, TRUE);
-
- /* Kludge around Microsoft Exchange 5.5 IMAP - See bug #5348 for details */
- if (camel_folder_summary_count (folder->summary) != exists) {
- CamelImapStore *imap_store = (CamelImapStore *) folder->parent_store;
- CamelImapResponse *response;
-
- /* forget the currently selected folder */
- if (imap_store->current_folder) {
- camel_object_unref (CAMEL_OBJECT (imap_store->current_folder));
- imap_store->current_folder = NULL;
- }
-
- /* now re-select it and process the EXISTS response */
- response = camel_imap_command (imap_store, folder, ex, NULL);
- if (response) {
- camel_imap_folder_selected (folder, response, NULL);
- camel_imap_response_free (imap_store, response);
- }
- }
-
- return;
-
- lose:
- if (fetch_data) {
- for (i = 0; i < fetch_data->len; i++) {
- data = fetch_data->pdata[i];
- g_datalist_clear (&data);
- }
- g_ptr_array_free (fetch_data, TRUE);
- }
- if (messages) {
- for (i = 0; i < messages->len; i++) {
- if (messages->pdata[i])
- camel_folder_summary_info_free (folder->summary, messages->pdata[i]);
- }
- g_ptr_array_free (messages, TRUE);
- }
-}
-
-/* Called with the store's connect_lock locked */
-void
-camel_imap_folder_changed (CamelFolder *folder, int exists,
- GArray *expunged, CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelFolderChangeInfo *changes;
- CamelMessageInfo *info;
- int len;
-
- CAMEL_SERVICE_ASSERT_LOCKED (folder->parent_store, connect_lock);
-
- changes = camel_folder_change_info_new ();
- if (expunged) {
- int i, id;
-
- for (i = 0; i < expunged->len; i++) {
- id = g_array_index (expunged, int, i);
- info = camel_folder_summary_index (folder->summary, id - 1);
- if (info == NULL) {
- /* FIXME: danw: does this mean that the summary is corrupt? */
- /* I guess a message that we never retrieved got expunged? */
- continue;
- }
-
- camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
- CAMEL_IMAP_FOLDER_LOCK (imap_folder, cache_lock);
- camel_imap_message_cache_remove (imap_folder->cache, camel_message_info_uid (info));
- CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
- camel_folder_summary_remove (folder->summary, info);
- camel_folder_summary_info_free(folder->summary, info);
- }
- }
-
- len = camel_folder_summary_count (folder->summary);
- if (exists > len)
- imap_update_summary (folder, exists, changes, ex);
-
- if (camel_folder_change_info_changed (changes))
- camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes);
-
- camel_folder_change_info_free (changes);
- camel_folder_summary_save (folder->summary);
-}
-
-static void
-imap_thaw (CamelFolder *folder)
-{
- CamelImapFolder *imap_folder;
-
- CAMEL_FOLDER_CLASS (disco_folder_class)->thaw (folder);
- if (camel_folder_is_frozen (folder))
- return;
-
- imap_folder = CAMEL_IMAP_FOLDER (folder);
- if (imap_folder->need_refresh) {
- imap_folder->need_refresh = FALSE;
- imap_refresh_info (folder, NULL);
- }
-}
-
-
-CamelStream *
-camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const char *uid,
- const char *section_text, gboolean cache_only,
- CamelException *ex)
-{
- CamelFolder *folder = CAMEL_FOLDER (imap_folder);
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- CamelStream *stream;
- GData *fetch_data;
- char *found_uid;
- int i;
-
- /* EXPUNGE responses have to modify the cache, which means
- * they have to grab the cache_lock while holding the
- * connect_lock. So we grab the connect_lock now, in case
- * we're going to need it below, since we can't grab it
- * after the cache_lock.
- */
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- CAMEL_IMAP_FOLDER_LOCK (imap_folder, cache_lock);
- stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text, ex);
- if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0"))) {
- camel_exception_clear (ex);
- stream = camel_imap_message_cache_get (imap_folder->cache, uid, "", ex);
- }
-
- if (stream || cache_only) {
- CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return stream;
- }
-
- if (camel_disco_store_status (CAMEL_DISCO_STORE (store)) == CAMEL_DISCO_STORE_OFFLINE) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("This message is not currently available"));
- CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return NULL;
- }
-
- camel_exception_clear (ex);
- if (store->server_level < IMAP_LEVEL_IMAP4REV1 && !*section_text) {
- response = camel_imap_command (store, folder, ex,
- "UID FETCH %s RFC822.PEEK",
- uid);
- } else {
- response = camel_imap_command (store, folder, ex,
- "UID FETCH %s BODY.PEEK[%s]",
- uid, section_text);
- }
- /* We won't need the connect_lock again after this. */
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- if (!response) {
- CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
- return NULL;
- }
-
- for (i = 0; i < response->untagged->len; i++) {
- fetch_data = parse_fetch_response (imap_folder, response->untagged->pdata[i]);
- found_uid = g_datalist_get_data (&fetch_data, "UID");
- stream = g_datalist_get_data (&fetch_data, "BODY_PART_STREAM");
- if (found_uid && stream && !strcmp (uid, found_uid))
- break;
-
- g_datalist_clear (&fetch_data);
- stream = NULL;
- }
- camel_imap_response_free (store, response);
- CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
- if (!stream) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not find message body in FETCH response."));
- } else {
- camel_object_ref (CAMEL_OBJECT (stream));
- g_datalist_clear (&fetch_data);
- }
-
- return stream;
-}
-
-static GData *
-parse_fetch_response (CamelImapFolder *imap_folder, char *response)
-{
- GData *data = NULL;
- char *start, *part_spec = NULL, *body = NULL, *uid = NULL, *idate = NULL;
- gboolean cache_header = TRUE, header = FALSE;
- size_t body_len = 0;
-
- if (*response != '(') {
- long seq;
-
- if (*response != '*' || *(response + 1) != ' ')
- return NULL;
- seq = strtol (response + 2, &response, 10);
- if (seq == 0)
- return NULL;
- if (strncasecmp (response, " FETCH (", 8) != 0)
- return NULL;
- response += 7;
-
- g_datalist_set_data (&data, "SEQUENCE", GINT_TO_POINTER (seq));
- }
-
- do {
- /* Skip the initial '(' or the ' ' between elements */
- response++;
-
- if (!strncasecmp (response, "FLAGS ", 6)) {
- guint32 flags;
-
- response += 6;
- /* FIXME user flags */
- flags = imap_parse_flag_list (&response);
-
- g_datalist_set_data (&data, "FLAGS", GUINT_TO_POINTER (flags));
- } else if (!strncasecmp (response, "RFC822.SIZE ", 12)) {
- unsigned long size;
-
- response += 12;
- size = strtoul (response, &response, 10);
- g_datalist_set_data (&data, "RFC822.SIZE", GUINT_TO_POINTER (size));
- } else if (!strncasecmp (response, "BODY[", 5) ||
- !strncasecmp (response, "RFC822 ", 7)) {
- char *p;
-
- if (*response == 'B') {
- response += 5;
-
- /* HEADER], HEADER.FIELDS (...)], or 0] */
- if (!strncasecmp (response, "HEADER", 6)) {
- header = TRUE;
- if (!strncasecmp (response + 6, ".FIELDS", 7))
- cache_header = FALSE;
- } else if (!strncasecmp (response, "0]", 2))
- header = TRUE;
-
- p = strchr (response, ']');
- if (!p || *(p + 1) != ' ')
- break;
-
- if (cache_header)
- part_spec = g_strndup (response, p - response);
- else
- part_spec = g_strdup ("HEADER.FIELDS");
-
- response = p + 2;
- } else {
- part_spec = g_strdup ("");
- response += 7;
-
- if (!strncasecmp (response, "HEADER", 6))
- header = TRUE;
- }
-
- body = imap_parse_nstring ((const char **) &response, &body_len);
- if (!response) {
- g_free (part_spec);
- break;
- }
-
- if (!body)
- body = g_strdup ("");
- g_datalist_set_data_full (&data, "BODY_PART_SPEC", part_spec, g_free);
- g_datalist_set_data_full (&data, "BODY_PART_DATA", body, g_free);
- g_datalist_set_data (&data, "BODY_PART_LEN", GINT_TO_POINTER (body_len));
- } else if (!strncasecmp (response, "BODY ", 5) ||
- !strncasecmp (response, "BODYSTRUCTURE ", 14)) {
- response = strchr (response, ' ') + 1;
- start = response;
- imap_skip_list ((const char **) &response);
- g_datalist_set_data_full (&data, "BODY", g_strndup (start, response - start), g_free);
- } else if (!strncasecmp (response, "UID ", 4)) {
- int len;
-
- len = strcspn (response + 4, " )");
- uid = g_strndup (response + 4, len);
- g_datalist_set_data_full (&data, "UID", uid, g_free);
- response += 4 + len;
- } else if (!strncasecmp (response, "INTERNALDATE ", 13)) {
- int len;
-
- response += 13;
- if (*response == '"') {
- response++;
- len = strcspn (response, "\"");
- idate = g_strndup (response, len);
- g_datalist_set_data_full (&data, "INTERNALDATE", idate, g_free);
- response += len + 1;
- }
- } else {
- g_warning ("Unexpected FETCH response from server: (%s", response);
- break;
- }
- } while (response && *response != ')');
-
- if (!response || *response != ')') {
- g_datalist_clear (&data);
- return NULL;
- }
-
- if (uid && body) {
- CamelStream *stream;
-
- if (header && !cache_header) {
- stream = camel_stream_mem_new_with_buffer (body, body_len);
- } else {
- CAMEL_IMAP_FOLDER_LOCK (imap_folder, cache_lock);
- stream = camel_imap_message_cache_insert (imap_folder->cache,
- uid, part_spec,
- body, body_len, NULL);
- CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
- }
-
- if (stream)
- g_datalist_set_data_full (&data, "BODY_PART_STREAM", stream,
- (GDestroyNotify) camel_object_unref);
- }
-
- return data;
-}
-
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
deleted file mode 100644
index a49f7bd497..0000000000
--- a/camel/providers/imap/camel-imap-folder.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-folder.h: class for an imap folder */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_FOLDER_H
-#define CAMEL_IMAP_FOLDER_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#include "camel-imap-types.h"
-#include <camel/camel-disco-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 CAMEL_IS_IMAP_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_FOLDER_TYPE))
-
-struct _CamelImapFolder {
- CamelDiscoFolder parent_object;
-
- struct _CamelImapFolderPrivate *priv;
-
- gboolean need_rescan, need_refresh;
- CamelFolderSearch *search;
- CamelImapMessageCache *cache;
-};
-
-
-typedef struct {
- CamelDiscoFolderClass parent_class;
-
- /* Virtual methods */
-
-} CamelImapFolderClass;
-
-
-/* public methods */
-CamelFolder *camel_imap_folder_new (CamelStore *parent,
- const char *folder_name,
- const char *folder_dir,
- CamelException *ex);
-
-void camel_imap_folder_selected (CamelFolder *folder,
- CamelImapResponse *response,
- CamelException *ex);
-
-void camel_imap_folder_changed (CamelFolder *folder, int exists,
- GArray *expunged, CamelException *ex);
-
-CamelStream *camel_imap_folder_fetch_data (CamelImapFolder *imap_folder,
- const char *uid,
- const char *section_text,
- gboolean cache_only,
- 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-message-cache.c b/camel/providers/imap/camel-imap-message-cache.c
deleted file mode 100644
index 559c6d2f88..0000000000
--- a/camel/providers/imap/camel-imap-message-cache.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-message-cache.c: Class for an IMAP message cache */
-
-/*
- * Author:
- * Dan Winship <danw@ximian.com>
- *
- * Copyright (C) 2001 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <dirent.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "camel-imap-message-cache.h"
-#include "camel-data-wrapper.h"
-#include "camel-exception.h"
-#include "camel-stream-fs.h"
-
-static void finalize (CamelImapMessageCache *cache);
-static void stream_finalize (CamelObject *stream, gpointer event_data, gpointer user_data);
-
-
-CamelType
-camel_imap_message_cache_get_type (void)
-{
- static CamelType camel_imap_message_cache_type = CAMEL_INVALID_TYPE;
-
- if (camel_imap_message_cache_type == CAMEL_INVALID_TYPE) {
- camel_imap_message_cache_type = camel_type_register (
- CAMEL_OBJECT_TYPE, "CamelImapMessageCache",
- sizeof (CamelImapMessageCache),
- sizeof (CamelImapMessageCacheClass),
- NULL,
- NULL,
- NULL,
- (CamelObjectFinalizeFunc) finalize);
- }
-
- return camel_imap_message_cache_type;
-}
-
-static void
-free_part (gpointer key, gpointer value, gpointer data)
-{
- if (value) {
- if (strchr (key, '.')) {
- camel_object_unhook_event (value, "finalize",
- stream_finalize, data);
- camel_object_unref (value);
- } else
- g_ptr_array_free (value, TRUE);
- }
- g_free (key);
-}
-
-static void
-finalize (CamelImapMessageCache *cache)
-{
- if (cache->path)
- g_free (cache->path);
- if (cache->parts) {
- g_hash_table_foreach (cache->parts, free_part, cache);
- g_hash_table_destroy (cache->parts);
- }
- if (cache->cached)
- g_hash_table_destroy (cache->cached);
-}
-
-static void
-cache_put (CamelImapMessageCache *cache, const char *uid, const char *key,
- CamelStream *stream)
-{
- char *hash_key;
- GPtrArray *subparts;
- gpointer okey, ostream;
- guint32 uidval;
-
- uidval = strtoul (uid, NULL, 10);
- if (uidval > cache->max_uid)
- cache->max_uid = uidval;
-
- subparts = g_hash_table_lookup (cache->parts, uid);
- if (!subparts) {
- subparts = g_ptr_array_new ();
- g_hash_table_insert (cache->parts, g_strdup (uid), subparts);
- }
-
- if (g_hash_table_lookup_extended (cache->parts, key, &okey, &ostream)) {
- if (ostream) {
- camel_object_unhook_event (ostream, "finalize",
- stream_finalize, cache);
- g_hash_table_remove (cache->cached, ostream);
- camel_object_unref (ostream);
- }
- hash_key = okey;
- } else {
- hash_key = g_strdup (key);
- g_ptr_array_add (subparts, hash_key);
- }
-
- g_hash_table_insert (cache->parts, hash_key, stream);
- g_hash_table_insert (cache->cached, stream, hash_key);
-
- if (stream) {
- camel_object_hook_event (CAMEL_OBJECT (stream), "finalize",
- stream_finalize, cache);
- }
-}
-
-/**
- * camel_imap_message_cache_new:
- * @path: directory to use for storage
- * @summary: CamelFolderSummary for the folder we are caching
- * @ex: a CamelException
- *
- * Return value: a new CamelImapMessageCache object using @path for
- * storage. If cache files already exist in @path, then any that do not
- * correspond to messages in @summary will be deleted.
- **/
-CamelImapMessageCache *
-camel_imap_message_cache_new (const char *path, CamelFolderSummary *summary,
- CamelException *ex)
-{
- CamelImapMessageCache *cache;
- DIR *dir;
- struct dirent *d;
- char *uid, *p;
- GPtrArray *deletes;
- CamelMessageInfo *info;
-
- dir = opendir (path);
- if (!dir) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open cache directory: %s"),
- g_strerror (errno));
- return NULL;
- }
-
- cache = (CamelImapMessageCache *)camel_object_new (CAMEL_IMAP_MESSAGE_CACHE_TYPE);
- cache->path = g_strdup (path);
-
- cache->parts = g_hash_table_new (g_str_hash, g_str_equal);
- cache->cached = g_hash_table_new (NULL, NULL);
- deletes = g_ptr_array_new ();
- while ((d = readdir (dir))) {
- if (!isdigit (d->d_name[0]))
- continue;
-
- p = strchr (d->d_name, '.');
- if (p)
- uid = g_strndup (d->d_name, p - d->d_name);
- else
- uid = g_strdup (d->d_name);
-
- info = camel_folder_summary_uid (summary, uid);
- if (info) {
- camel_folder_summary_info_free (summary, info);
- cache_put (cache, uid, d->d_name, NULL);
- } else
- g_ptr_array_add (deletes, g_strdup_printf ("%s/%s", cache->path, d->d_name));
- g_free (uid);
- }
- closedir (dir);
-
- while (deletes->len) {
- unlink (deletes->pdata[0]);
- g_free (deletes->pdata[0]);
- g_ptr_array_remove_index_fast (deletes, 0);
- }
- g_ptr_array_free (deletes, TRUE);
-
- return cache;
-}
-
-/**
- * camel_imap_message_cache_max_uid:
- * @cache: the cache
- *
- * Return value: the largest (real) UID in the cache.
- **/
-guint32
-camel_imap_message_cache_max_uid (CamelImapMessageCache *cache)
-{
- return cache->max_uid;
-}
-
-/**
- * camel_imap_message_cache_set_path:
- * @cache:
- * @path:
- *
- * Set the path used for the message cache.
- **/
-void
-camel_imap_message_cache_set_path (CamelImapMessageCache *cache, const char *path)
-{
- g_free(cache->path);
- cache->path = g_strdup(path);
-}
-
-static void
-stream_finalize (CamelObject *stream, gpointer event_data, gpointer user_data)
-{
- CamelImapMessageCache *cache = user_data;
- char *key;
-
- key = g_hash_table_lookup (cache->cached, stream);
- if (!key)
- return;
- g_hash_table_remove (cache->cached, stream);
- g_hash_table_insert (cache->parts, key, NULL);
-}
-
-
-static CamelStream *
-insert_setup (CamelImapMessageCache *cache, const char *uid, const char *part_spec,
- char **path, char **key, CamelException *ex)
-{
- CamelStream *stream;
- int fd;
-
- *path = g_strdup_printf ("%s/%s.%s", cache->path, uid, part_spec);
- *key = strrchr (*path, '/') + 1;
- stream = g_hash_table_lookup (cache->parts, *key);
- if (stream)
- camel_object_unref (CAMEL_OBJECT (stream));
-
- fd = open (*path, O_RDWR | O_CREAT | O_TRUNC, 0600);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to cache message %s: %s"),
- uid, g_strerror (errno));
- g_free (*path);
- return NULL;
- }
-
- return camel_stream_fs_new_with_fd (fd);
-}
-
-static CamelStream *
-insert_abort (char *path, CamelStream *stream)
-{
- unlink (path);
- g_free (path);
- camel_object_unref (CAMEL_OBJECT (stream));
- return NULL;
-}
-
-static CamelStream *
-insert_finish (CamelImapMessageCache *cache, const char *uid, char *path,
- char *key, CamelStream *stream)
-{
- camel_stream_flush (stream);
- camel_stream_reset (stream);
- cache_put (cache, uid, key, stream);
- g_free (path);
-
- return stream;
-}
-
-/**
- * camel_imap_message_cache_insert:
- * @cache: the cache
- * @uid: UID of the message data to cache
- * @part_spec: the IMAP part_spec of the data
- * @data: the data
- * @len: length of @data
- *
- * Caches the provided data into @cache.
- *
- * Return value: a CamelStream containing the cached data, which the
- * caller must unref.
- **/
-CamelStream *
-camel_imap_message_cache_insert (CamelImapMessageCache *cache, const char *uid,
- const char *part_spec, const char *data,
- int len, CamelException *ex)
-{
- char *path, *key;
- CamelStream *stream;
-
- stream = insert_setup (cache, uid, part_spec, &path, &key, ex);
- if (!stream)
- return NULL;
-
- if (camel_stream_write (stream, data, len) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to cache message %s: %s"),
- uid, g_strerror (errno));
- return insert_abort (path, stream);
- }
-
- return insert_finish (cache, uid, path, key, stream);
-}
-
-/**
- * camel_imap_message_cache_insert_stream:
- * @cache: the cache
- * @uid: UID of the message data to cache
- * @part_spec: the IMAP part_spec of the data
- * @data_stream: the stream to cache
- *
- * Caches the provided data into @cache.
- **/
-void
-camel_imap_message_cache_insert_stream (CamelImapMessageCache *cache,
- const char *uid, const char *part_spec,
- CamelStream *data_stream, CamelException *ex)
-{
- char *path, *key;
- CamelStream *stream;
-
- stream = insert_setup (cache, uid, part_spec, &path, &key, ex);
- if (!stream)
- return;
-
- if (camel_stream_write_to_stream (data_stream, stream) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to cache message %s: %s"),
- uid, g_strerror (errno));
- insert_abort (path, stream);
- } else {
- insert_finish (cache, uid, path, key, stream);
- camel_object_unref (CAMEL_OBJECT (stream));
- }
-}
-
-/**
- * camel_imap_message_cache_insert_wrapper:
- * @cache: the cache
- * @uid: UID of the message data to cache
- * @part_spec: the IMAP part_spec of the data
- * @wrapper: the wrapper to cache
- *
- * Caches the provided data into @cache.
- **/
-void
-camel_imap_message_cache_insert_wrapper (CamelImapMessageCache *cache,
- const char *uid, const char *part_spec,
- CamelDataWrapper *wrapper, CamelException *ex)
-{
- char *path, *key;
- CamelStream *stream;
-
- stream = insert_setup (cache, uid, part_spec, &path, &key, ex);
- if (!stream)
- return;
-
- if (camel_data_wrapper_write_to_stream (wrapper, stream) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to cache message %s: %s"),
- uid, g_strerror (errno));
- insert_abort (path, stream);
- } else {
- insert_finish (cache, uid, path, key, stream);
- camel_object_unref (CAMEL_OBJECT (stream));
- }
-}
-
-
-/**
- * camel_imap_message_cache_get:
- * @cache: the cache
- * @uid: the UID of the data to get
- * @part_spec: the part_spec of the data to get
- * @ex: exception
- *
- * Return value: a CamelStream containing the cached data (which the
- * caller must unref), or %NULL if that data is not cached.
- **/
-CamelStream *
-camel_imap_message_cache_get (CamelImapMessageCache *cache, const char *uid,
- const char *part_spec, CamelException *ex)
-{
- CamelStream *stream;
- char *path, *key;
-
- if (uid[0] == 0)
- return NULL;
-
- path = g_strdup_printf ("%s/%s.%s", cache->path, uid, part_spec);
- key = strrchr (path, '/') + 1;
- stream = g_hash_table_lookup (cache->parts, key);
- if (stream) {
- camel_stream_reset (CAMEL_STREAM (stream));
- camel_object_ref (CAMEL_OBJECT (stream));
- g_free (path);
- return stream;
- }
-
- stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0);
- if (stream) {
- cache_put (cache, uid, key, stream);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to cache %s: %s"),
- part_spec, g_strerror (errno));
- }
-
- g_free (path);
-
- return stream;
-}
-
-/**
- * camel_imap_message_cache_remove:
- * @cache: the cache
- * @uid: UID of the data to remove
- *
- * Removes all data associated with @uid from @cache.
- **/
-void
-camel_imap_message_cache_remove (CamelImapMessageCache *cache, const char *uid)
-{
- GPtrArray *subparts;
- char *key, *path;
- CamelObject *stream;
- int i;
-
- subparts = g_hash_table_lookup (cache->parts, uid);
- if (!subparts)
- return;
- for (i = 0; i < subparts->len; i++) {
- key = subparts->pdata[i];
- path = g_strdup_printf ("%s/%s", cache->path, key);
- unlink (path);
- g_free (path);
- stream = g_hash_table_lookup (cache->parts, key);
- if (stream) {
- camel_object_unhook_event (stream, "finalize",
- stream_finalize, cache);
- camel_object_unref (stream);
- g_hash_table_remove (cache->cached, stream);
- }
- g_hash_table_remove (cache->parts, key);
- g_free (key);
- }
- g_hash_table_remove (cache->parts, uid);
- g_ptr_array_free (subparts, TRUE);
-}
-
-static void
-add_uids (gpointer key, gpointer value, gpointer data)
-{
- if (!strchr (key, '.'))
- g_ptr_array_add (data, key);
-}
-
-/**
- * camel_imap_message_cache_clear:
- * @cache: the cache
- *
- * Removes all cached data from @cache.
- **/
-void
-camel_imap_message_cache_clear (CamelImapMessageCache *cache)
-{
- GPtrArray *uids;
- int i;
-
- uids = g_ptr_array_new ();
- g_hash_table_foreach (cache->parts, add_uids, uids);
-
- for (i = 0; i < uids->len; i++)
- camel_imap_message_cache_remove (cache, uids->pdata[i]);
- g_ptr_array_free (uids, TRUE);
-}
-
-
-/**
- * camel_imap_message_cache_copy:
- * @source: the source message cache
- * @source_uid: UID of a message in @source
- * @dest: the destination message cache
- * @dest_uid: UID of the message in @dest
- *
- * Copies all cached parts from @source_uid in @source to @dest_uid in
- * @destination.
- **/
-void
-camel_imap_message_cache_copy (CamelImapMessageCache *source,
- const char *source_uid,
- CamelImapMessageCache *dest,
- const char *dest_uid,
- CamelException *ex)
-{
- GPtrArray *subparts;
- CamelStream *stream;
- char *part;
- int i;
-
- subparts = g_hash_table_lookup (source->parts, source_uid);
- if (!subparts || !subparts->len)
- return;
-
- for (i = 0; i < subparts->len; i++) {
- part = strchr (subparts->pdata[i], '.');
- if (!part++)
- continue;
-
- if ((stream = camel_imap_message_cache_get (source, source_uid, part, ex))) {
- camel_imap_message_cache_insert_stream (dest, dest_uid, part, stream, ex);
- camel_object_unref (CAMEL_OBJECT (stream));
- }
- }
-}
diff --git a/camel/providers/imap/camel-imap-message-cache.h b/camel/providers/imap/camel-imap-message-cache.h
deleted file mode 100644
index c79195cfa4..0000000000
--- a/camel/providers/imap/camel-imap-message-cache.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-message-cache.h: Class for an IMAP message cache */
-
-/*
- * Author:
- * Dan Winship <danw@ximian.com>
- *
- * Copyright (C) 2001 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_MESSAGE_CACHE_H
-#define CAMEL_IMAP_MESSAGE_CACHE_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-imap-types.h"
-#include "camel-folder.h"
-#include <camel/camel-folder-search.h>
-
-#define CAMEL_IMAP_MESSAGE_CACHE_TYPE (camel_imap_message_cache_get_type ())
-#define CAMEL_IMAP_MESSAGE_CACHE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_MESSAGE_CACHE_TYPE, CamelImapFolder))
-#define CAMEL_IMAP_MESSAGE_CACHE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAP_MESSAGE_CACHE_TYPE, CamelImapFolderClass))
-#define CAMEL_IS_IMAP_MESSAGE_CACHE(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_MESSAGE_CACHE_TYPE))
-
-struct _CamelImapMessageCache {
- CamelObject parent_object;
-
- char *path;
- GHashTable *parts, *cached;
- guint32 max_uid;
-};
-
-
-typedef struct {
- CamelFolderClass parent_class;
-
- /* Virtual methods */
-
-} CamelImapMessageCacheClass;
-
-
-/* public methods */
-CamelImapMessageCache *camel_imap_message_cache_new (const char *path,
- CamelFolderSummary *summ,
- CamelException *ex);
-
-void camel_imap_message_cache_set_path (CamelImapMessageCache *cache,
- const char *path);
-
-guint32 camel_imap_message_cache_max_uid (CamelImapMessageCache *cache);
-
-CamelStream *camel_imap_message_cache_insert (CamelImapMessageCache *cache,
- const char *uid,
- const char *part_spec,
- const char *data,
- int len,
- CamelException *ex);
-void camel_imap_message_cache_insert_stream (CamelImapMessageCache *cache,
- const char *uid,
- const char *part_spec,
- CamelStream *data_stream,
- CamelException *ex);
-void camel_imap_message_cache_insert_wrapper (CamelImapMessageCache *cache,
- const char *uid,
- const char *part_spec,
- CamelDataWrapper *wrapper,
- CamelException *ex);
-
-CamelStream *camel_imap_message_cache_get (CamelImapMessageCache *cache,
- const char *uid,
- const char *part_spec,
- CamelException *ex);
-
-void camel_imap_message_cache_remove (CamelImapMessageCache *cache,
- const char *uid);
-
-void camel_imap_message_cache_clear (CamelImapMessageCache *cache);
-
-void camel_imap_message_cache_copy (CamelImapMessageCache *source,
- const char *source_uid,
- CamelImapMessageCache *dest,
- const char *dest_uid,
- CamelException *ex);
-
-/* Standard Camel function */
-CamelType camel_imap_message_cache_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAP_MESSAGE_CACHE_H */
diff --git a/camel/providers/imap/camel-imap-private.h b/camel/providers/imap/camel-imap-private.h
deleted file mode 100644
index 0f80dbfd1c..0000000000
--- a/camel/providers/imap/camel-imap-private.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- * camel-imap-private.h: Private info for imap.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_IMAP_PRIVATE_H
-#define CAMEL_IMAP_PRIVATE_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* need a way to configure and save this data, if this header is to
- be installed. For now, dont install it */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef ENABLE_THREADS
-#include "e-util/e-msgport.h"
-#endif
-
-struct _CamelImapFolderPrivate {
-#ifdef ENABLE_THREADS
- EMutex *search_lock; /* for locking the search object */
- EMutex *cache_lock; /* for locking the cache object */
-#endif
-};
-
-#ifdef ENABLE_THREADS
-#define CAMEL_IMAP_FOLDER_LOCK(f, l) (e_mutex_lock(((CamelImapFolder *)f)->priv->l))
-#define CAMEL_IMAP_FOLDER_UNLOCK(f, l) (e_mutex_unlock(((CamelImapFolder *)f)->priv->l))
-#else
-#define CAMEL_IMAP_FOLDER_LOCK(f, l)
-#define CAMEL_IMAP_FOLDER_UNLOCK(f, l)
-#endif
-
-struct _CamelImapWrapperPrivate {
-#ifdef ENABLE_THREADS
- GMutex *lock;
-#endif
-};
-
-#ifdef ENABLE_THREADS
-#define CAMEL_IMAP_WRAPPER_LOCK(f, l) (g_mutex_lock(((CamelImapWrapper *)f)->priv->l))
-#define CAMEL_IMAP_WRAPPER_UNLOCK(f, l) (g_mutex_unlock(((CamelImapWrapper *)f)->priv->l))
-#else
-#define CAMEL_IMAP_WRAPPER_LOCK(f, l)
-#define CAMEL_IMAP_WRAPPER_UNLOCK(f, l)
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAP_PRIVATE_H */
-
diff --git a/camel/providers/imap/camel-imap-provider.c b/camel/providers/imap/camel-imap-provider.c
deleted file mode 100644
index abda8f89a0..0000000000
--- a/camel/providers/imap/camel-imap-provider.c
+++ /dev/null
@@ -1,158 +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@ximian.com>
- *
- * Copyright 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include "camel-imap-store.h"
-#include "camel-provider.h"
-#include "camel-session.h"
-#include "camel-url.h"
-#include "camel-sasl.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);
-
-CamelProviderConfEntry imap_conf_entries[] = {
- { CAMEL_PROVIDER_CONF_SECTION_START, "cmdsection", NULL,
- N_("Connection to Server") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "use_command", NULL,
- N_("Use custom command to connect to server"), "0" },
- { CAMEL_PROVIDER_CONF_ENTRY, "command", "use_command",
- N_("Command:"), "ssh -C -l %u %h exec /usr/sbin/imapd" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_SECTION_START, "mailcheck", NULL,
- N_("Checking for new mail") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "check_all", NULL,
- N_("Check for new messages in all folders"), "1" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_SECTION_START, "folders", NULL,
- N_("Folders") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "use_lsub", NULL,
- N_("Show only subscribed folders"), "1" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "override_namespace", NULL,
- N_("Override server-supplied folder namespace"), "0" },
- { CAMEL_PROVIDER_CONF_ENTRY, "namespace", "override_namespace",
- N_("Namespace") },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL,
- N_("Apply filters to new messages in INBOX on this server"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "offline_sync", NULL,
- N_("Automatically synchronize remote mail locally"), "0" },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider imap_provider = {
- "imap",
- N_("IMAP"),
-
- N_("For reading and storing mail on IMAP servers."),
-
- "mail",
-
- CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
- CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL,
-
- CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH,
-
- imap_conf_entries,
-
- /* ... */
-};
-
-CamelServiceAuthType camel_imap_password_authtype = {
- N_("Password"),
-
- N_("This option will connect to the IMAP server using a "
- "plaintext password."),
-
- "",
- TRUE
-};
-
-void
-camel_provider_module_init (CamelSession *session)
-{
- imap_provider.object_types[CAMEL_PROVIDER_STORE] =
- camel_imap_store_get_type ();
- imap_provider.url_hash = imap_url_hash;
- imap_provider.url_equal = imap_url_equal;
- imap_provider.authtypes = camel_sasl_authtype_list (FALSE);
- imap_provider.authtypes = g_list_prepend (imap_provider.authtypes,
- &camel_imap_password_authtype);
-
- 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-search.c b/camel/providers/imap/camel-imap-search.c
deleted file mode 100644
index eacb839cb2..0000000000
--- a/camel/providers/imap/camel-imap-search.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-search.c: IMAP folder search */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 2000, 2001, 2002 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "camel-imap-command.h"
-#include "camel-imap-folder.h"
-#include "camel-imap-store.h"
-#include "camel-imap-search.h"
-#include "camel-imap-private.h"
-#include "camel-imap-utils.h"
-#include "camel-imap-summary.h"
-
-#include "e-util/md5-utils.h" /* md5 hash building */
-#include "camel-mime-utils.h" /* base64 encoding */
-
-#include "camel-seekable-stream.h"
-#include "camel-search-private.h"
-
-#define d(x)
-
-/*
- File is:
- BODY (as in body search)
- Last uid when search performed
- termcount: number of search terms
- matchcount: number of matches
- term0, term1 ...
- match0, match1, match2, ...
-*/
-
-/* size of in-memory cache */
-#define MATCH_CACHE_SIZE (32)
-
-/* Also takes care of 'endianness' file magic */
-#define MATCH_MARK (('B' << 24) | ('O' << 16) | ('D' << 8) | 'Y')
-
-/* on-disk header, in native endianness format, matches follow */
-struct _match_header {
- guint32 mark;
- guint32 validity; /* uidvalidity for this folder */
- guint32 lastuid;
- guint32 termcount;
- guint32 matchcount;
-};
-
-/* in-memory record */
-struct _match_record {
- struct _match_record *next;
- struct _match_record *prev;
-
- char hash[17];
-
- guint32 lastuid;
- guint32 validity;
-
- unsigned int termcount;
- char **terms;
- GArray *matches;
-};
-
-
-static void free_match(CamelImapSearch *is, struct _match_record *mr);
-static ESExpResult *imap_body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
-
-static CamelFolderSearchClass *imap_search_parent_class;
-
-static void
-camel_imap_search_class_init (CamelImapSearchClass *camel_imap_search_class)
-{
- /* virtual method overload */
- CamelFolderSearchClass *camel_folder_search_class =
- CAMEL_FOLDER_SEARCH_CLASS (camel_imap_search_class);
-
- imap_search_parent_class = (CamelFolderSearchClass *)camel_type_get_global_classfuncs (camel_folder_search_get_type ());
-
- /* virtual method overload */
- camel_folder_search_class->body_contains = imap_body_contains;
-}
-
-static void
-camel_imap_search_init(CamelImapSearch *is)
-{
- e_dlist_init(&is->matches);
- is->matches_hash = g_hash_table_new(g_str_hash, g_str_equal);
- is->matches_count = 0;
- is->lastuid = 0;
-}
-
-static void
-camel_imap_search_finalise(CamelImapSearch *is)
-{
- struct _match_record *mr;
-
- while ( (mr = (struct _match_record *)e_dlist_remtail(&is->matches)) )
- free_match(is, mr);
- g_hash_table_destroy(is->matches_hash);
- if (is->cache)
- camel_object_unref((CamelObject *)is->cache);
-}
-
-CamelType
-camel_imap_search_get_type (void)
-{
- static CamelType camel_imap_search_type = CAMEL_INVALID_TYPE;
-
- if (camel_imap_search_type == CAMEL_INVALID_TYPE) {
- camel_imap_search_type = camel_type_register (
- CAMEL_FOLDER_SEARCH_TYPE, "CamelImapSearch",
- sizeof (CamelImapSearch),
- sizeof (CamelImapSearchClass),
- (CamelObjectClassInitFunc) camel_imap_search_class_init, NULL,
- (CamelObjectInitFunc) camel_imap_search_init,
- (CamelObjectFinalizeFunc) camel_imap_search_finalise);
- }
-
- return camel_imap_search_type;
-}
-
-/**
- * camel_imap_search_new:
- *
- * Return value: A new CamelImapSearch widget.
- **/
-CamelFolderSearch *
-camel_imap_search_new (const char *cachedir)
-{
- CamelFolderSearch *new = CAMEL_FOLDER_SEARCH (camel_object_new (camel_imap_search_get_type ()));
- CamelImapSearch *is = (CamelImapSearch *)new;
-
- camel_folder_search_construct (new);
-
- is->cache = camel_data_cache_new(cachedir, 0, NULL);
- if (is->cache) {
- /* Expire entries after 14 days of inactivity */
- camel_data_cache_set_expire_access(is->cache, 60*60*24*14);
- }
-
- return new;
-}
-
-
-static void
-hash_match(char hash[17], int argc, struct _ESExpResult **argv)
-{
- MD5Context ctx;
- unsigned char digest[16];
- unsigned int state = 0, save = 0;
- int i;
-
- md5_init(&ctx);
- for (i=0;i<argc;i++) {
- if (argv[i]->type == ESEXP_RES_STRING)
- md5_update(&ctx, argv[i]->value.string, strlen(argv[i]->value.string));
- }
- md5_final(&ctx, digest);
-
- camel_base64_encode_close(digest, 12, FALSE, hash, &state, &save);
-
- for (i=0;i<16;i++) {
- if (hash[i] == '+')
- hash[i] = ',';
- if (hash[i] == '/')
- hash[i] = '_';
- }
-
- hash[16] = 0;
-}
-
-static int
-save_match(CamelImapSearch *is, struct _match_record *mr)
-{
- guint32 mark = MATCH_MARK;
- int ret = 0;
- struct _match_header header;
- CamelStream *stream;
-
- /* since its a cache, doesn't matter if it doesn't save, at least we have the in-memory cache
- for this session */
- if (is->cache == NULL)
- return -1;
-
- stream = camel_data_cache_add(is->cache, "search/body-contains", mr->hash, NULL);
- if (stream == NULL)
- return -1;
-
- d(printf("Saving search cache entry to '%s': %s\n", mr->hash, mr->terms[0]));
-
- /* we write the whole thing, then re-write the header magic, saves fancy sync code */
- memcpy(&header.mark, " ", 4);
- header.termcount = 0;
- header.matchcount = mr->matches->len;
- header.lastuid = mr->lastuid;
- header.validity = mr->validity;
-
- if (camel_stream_write(stream, (char *)&header, sizeof(header)) != sizeof(header)
- || camel_stream_write(stream, mr->matches->data, mr->matches->len*sizeof(guint32)) != mr->matches->len*sizeof(guint32)
- || camel_seekable_stream_seek((CamelSeekableStream *)stream, 0, CAMEL_STREAM_SET) == -1
- || camel_stream_write(stream, (char *)&mark, sizeof(mark)) != sizeof(mark)) {
- d(printf(" saving failed, removing cache entry\n"));
- camel_data_cache_remove(is->cache, "search/body-contains", mr->hash, NULL);
- ret = -1;
- }
-
- camel_object_unref((CamelObject *)stream);
- return ret;
-}
-
-static void
-free_match(CamelImapSearch *is, struct _match_record *mr)
-{
- int i;
-
- for (i=0;i<mr->termcount;i++)
- g_free(mr->terms[i]);
- g_free(mr->terms);
- g_array_free(mr->matches, TRUE);
- g_free(mr);
-}
-
-static struct _match_record *
-load_match(CamelImapSearch *is, char hash[17], int argc, struct _ESExpResult **argv)
-{
- struct _match_record *mr;
- CamelStream *stream = NULL;
- struct _match_header header;
- int i;
-
- mr = g_malloc0(sizeof(*mr));
- mr->matches = g_array_new(0, 0, sizeof(guint32));
- g_assert(strlen(hash) == 16);
- strcpy(mr->hash, hash);
- mr->terms = g_malloc0(sizeof(mr->terms[0]) * argc);
- for (i=0;i<argc;i++) {
- if (argv[i]->type == ESEXP_RES_STRING) {
- mr->termcount++;
- mr->terms[i] = g_strdup(argv[i]->value.string);
- }
- }
-
- d(printf("Loading search cache entry to '%s': %s\n", mr->hash, mr->terms[0]));
-
- memset(&header, 0, sizeof(header));
- if (is->cache)
- stream = camel_data_cache_get(is->cache, "search/body-contains", mr->hash, NULL);
- if (stream != NULL) {
- /* 'cause i'm gonna be lazy, i'm going to have the termcount == 0 for now,
- and not load or save them since i can't think of a nice way to do it, the hash
- should be sufficient to key it */
- /* This check should also handle endianness changes, we just throw away
- the data (its only a cache) */
- if (camel_stream_read(stream, (char *)&header, sizeof(header)) == sizeof(header)
- && header.validity == is->validity
- && header.mark == MATCH_MARK
- && header.termcount == 0) {
- d(printf(" found %d matches\n", header.matchcount));
- g_array_set_size(mr->matches, header.matchcount);
- camel_stream_read(stream, mr->matches->data, sizeof(guint32)*header.matchcount);
- } else {
- d(printf(" file format invalid/validity changed\n"));
- memset(&header, 0, sizeof(header));
- }
- camel_object_unref((CamelObject *)stream);
- } else {
- d(printf(" no cache entry found\n"));
- }
-
- mr->validity = header.validity;
- if (mr->validity != is->validity)
- mr->lastuid = 0;
- else
- mr->lastuid = header.lastuid;
-
- return mr;
-}
-
-static int
-sync_match(CamelImapSearch *is, struct _match_record *mr)
-{
- char *p, *result, *lasts = NULL;
- CamelImapResponse *response = NULL;
- guint32 uid;
- CamelFolder *folder = ((CamelFolderSearch *)is)->folder;
- CamelImapStore *store = (CamelImapStore *)folder->parent_store;
- struct _camel_search_words *words;
- GString *search;
- int i;
-
- if (mr->lastuid >= is->lastuid && mr->validity == is->validity)
- return 0;
-
- d(printf ("updating match record for uid's %d:%d\n", mr->lastuid+1, is->lastuid));
-
- /* TODO: Handle multiple search terms */
-
- /* This handles multiple search words within a single term */
- words = camel_search_words_split (mr->terms[0]);
- search = g_string_new ("");
- g_string_append_printf (search, "UID %d:%d", mr->lastuid + 1, is->lastuid);
- for (i = 0; i < words->len; i++) {
- char *w = words->words[i]->word, c;
-
- g_string_append_printf (search, " BODY \"");
- while ((c = *w++)) {
- if (c == '\\' || c == '"')
- g_string_append_c (search, '\\');
- g_string_append_c (search, c);
- }
- g_string_append_c (search, '"');
- }
- camel_search_words_free (words);
-
- /* We only try search using utf8 if its non us-ascii text? */
- if ((words->type & CAMEL_SEARCH_WORD_8BIT) && (store->capabilities & IMAP_CAPABILITY_utf8_search)) {
- response = camel_imap_command (store, folder, NULL,
- "UID SEARCH CHARSET UTF-8 %s", search->str);
- /* We can't actually tell if we got a NO response, so assume always */
- if (response == NULL)
- store->capabilities &= ~IMAP_CAPABILITY_utf8_search;
- }
- if (response == NULL)
- response = camel_imap_command (store, folder, NULL,
- "UID SEARCH %s", search->str);
- g_string_free(search, TRUE);
-
- if (!response)
- return -1;
- result = camel_imap_response_extract (store, response, "SEARCH", NULL);
- if (!result)
- return -1;
-
- p = result + sizeof ("* SEARCH");
- for (p = strtok_r (p, " ", &lasts); p; p = strtok_r (NULL, " ", &lasts)) {
- uid = strtoul(p, NULL, 10);
- g_array_append_vals(mr->matches, &uid, 1);
- }
- g_free(result);
-
- mr->validity = is->validity;
- mr->lastuid = is->lastuid;
- save_match(is, mr);
-
- return 0;
-}
-
-static struct _match_record *
-get_match(CamelImapSearch *is, int argc, struct _ESExpResult **argv)
-{
- char hash[17];
- struct _match_record *mr;
-
- hash_match(hash, argc, argv);
-
- mr = g_hash_table_lookup(is->matches_hash, hash);
- if (mr == NULL) {
- while (is->matches_count >= MATCH_CACHE_SIZE) {
- mr = (struct _match_record *)e_dlist_remtail(&is->matches);
- if (mr) {
- printf("expiring match '%s' (%s)\n", mr->hash, mr->terms[0]);
- g_hash_table_remove(is->matches_hash, mr->hash);
- free_match(is, mr);
- is->matches_count--;
- } else {
- is->matches_count = 0;
- }
- }
- mr = load_match(is, hash, argc, argv);
- g_hash_table_insert(is->matches_hash, mr->hash, mr);
- is->matches_count++;
- } else {
- e_dlist_remove((EDListNode *)mr);
- }
-
- e_dlist_addhead(&is->matches, (EDListNode *)mr);
-
- /* what about offline mode? */
- /* We could cache those results too, or should we cache them elsewhere? */
- sync_match(is, mr);
-
- return mr;
-}
-
-static ESExpResult *
-imap_body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (s->folder->parent_store);
- CamelImapSearch *is = (CamelImapSearch *)s;
- char *uid;
- ESExpResult *r;
- CamelMessageInfo *info;
- GHashTable *uid_hash = NULL;
- GPtrArray *array;
- int i, j;
- struct _match_record *mr;
- guint32 uidn, *uidp;
-
- d(printf("Performing body search '%s'\n", argv[0]->value.string));
-
- /* TODO: Cache offline searches too? */
-
- /* If offline, search using the parent class, which can handle this manually */
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), NULL))
- return imap_search_parent_class->body_contains(f, argc, argv, s);
-
- /* optimise the match "" case - match everything */
- if (argc == 1 && argv[0]->value.string[0] == '\0') {
- if (s->current) {
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = TRUE;
- } else {
- r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
- r->value.ptrarray = g_ptr_array_new ();
- for (i = 0; i < s->summary->len; i++) {
- info = g_ptr_array_index(s->summary, i);
- g_ptr_array_add(r->value.ptrarray, (char *)camel_message_info_uid(info));
- }
- }
- } else if (argc == 0 || s->summary->len == 0) {
- /* nothing to match case, do nothing (should be handled higher up?) */
- if (s->current) {
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
- } else {
- r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
- r->value.ptrarray = g_ptr_array_new ();
- }
- } else {
- int truth = FALSE;
-
- /* setup lastuid/validity for synchronising */
- info = g_ptr_array_index(s->summary, s->summary->len-1);
- is->lastuid = strtoul(camel_message_info_uid(info), NULL, 10);
- is->validity = ((CamelImapSummary *)(s->folder->summary))->validity;
-
- mr = get_match(is, argc, argv);
-
- if (s->current) {
- uidn = strtoul(camel_message_info_uid(s->current), NULL, 10);
- uidp = (guint32 *)mr->matches->data;
- j = mr->matches->len;
- for (i=0;i<j && !truth;i++)
- truth = *uidp++ == uidn;
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = truth;
- } else {
- r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
- array = r->value.ptrarray = g_ptr_array_new();
-
- /* We use a hash to map the uid numbers to uid strings as required by the search api */
- /* We use the summary's strings so we dont need to alloc more */
- uid_hash = g_hash_table_new(NULL, NULL);
- for (i = 0; i < s->summary->len; i++) {
- info = s->summary->pdata[i];
- uid = (char *)camel_message_info_uid(info);
- uidn = strtoul(uid, NULL, 10);
- g_hash_table_insert(uid_hash, GUINT_TO_POINTER(uidn), uid);
- }
-
- uidp = (guint32 *)mr->matches->data;
- j = mr->matches->len;
- for (i=0;i<j && !truth;i++) {
- uid = g_hash_table_lookup(uid_hash, GUINT_TO_POINTER(*uidp++));
- if (uid)
- g_ptr_array_add(array, uid);
- }
-
- g_hash_table_destroy(uid_hash);
- }
- }
-
- return r;
-}
diff --git a/camel/providers/imap/camel-imap-search.h b/camel/providers/imap/camel-imap-search.h
deleted file mode 100644
index 7664c4c2ed..0000000000
--- a/camel/providers/imap/camel-imap-search.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-search.h: IMAP folder search */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- *
- * Copyright 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef _CAMEL_IMAP_SEARCH_H
-#define _CAMEL_IMAP_SEARCH_H
-
-#include <camel/camel-folder-search.h>
-#include <e-util/e-msgport.h>
-#include <camel/camel-data-cache.h>
-
-#define CAMEL_IMAP_SEARCH_TYPE (camel_imap_search_get_type ())
-#define CAMEL_IMAP_SEARCH(obj) CAMEL_CHECK_CAST (obj, camel_imap_search_get_type (), CamelImapSearch)
-#define CAMEL_IMAP_SEARCH_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imap_search_get_type (), CamelImapSearchClass)
-#define CAMEL_IS_IMAP_SEARCH(obj) CAMEL_CHECK_TYPE (obj, camel_imap_search_get_type ())
-
-typedef struct _CamelImapSearchClass CamelImapSearchClass;
-
-struct _CamelImapSearch {
- CamelFolderSearch parent;
-
- guint32 lastuid; /* current 'last uid' for the folder */
- guint32 validity; /* validity of the current folder */
-
- CamelDataCache *cache; /* disk-cache for searches */
-
- /* cache of body search matches */
- unsigned int matches_count;
- EDList matches;
- GHashTable *matches_hash;
-};
-
-struct _CamelImapSearchClass {
- CamelFolderSearchClass parent_class;
-
-};
-
-CamelType camel_imap_search_get_type (void);
-CamelFolderSearch *camel_imap_search_new (const char *cachedir);
-
-#endif /* ! _CAMEL_IMAP_SEARCH_H */
diff --git a/camel/providers/imap/camel-imap-store-summary.c b/camel/providers/imap/camel-imap-store-summary.c
deleted file mode 100644
index 32530d3c3f..0000000000
--- a/camel/providers/imap/camel-imap-store-summary.c
+++ /dev/null
@@ -1,619 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2002 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include "camel-imap-store-summary.h"
-
-#include "camel-file-utils.h"
-
-#include "e-util/md5-utils.h"
-#include "e-util/e-memory.h"
-
-#include "camel-private.h"
-#include "camel-utf8.h"
-
-#define d(x)
-#define io(x) /* io debug */
-
-#define CAMEL_IMAP_STORE_SUMMARY_VERSION_0 (0)
-
-#define CAMEL_IMAP_STORE_SUMMARY_VERSION (0)
-
-#define _PRIVATE(o) (((CamelImapStoreSummary *)(o))->priv)
-
-static int summary_header_load(CamelStoreSummary *, FILE *);
-static int summary_header_save(CamelStoreSummary *, FILE *);
-
-/*static CamelStoreInfo * store_info_new(CamelStoreSummary *, const char *);*/
-static CamelStoreInfo * store_info_load(CamelStoreSummary *, FILE *);
-static int store_info_save(CamelStoreSummary *, FILE *, CamelStoreInfo *);
-static void store_info_free(CamelStoreSummary *, CamelStoreInfo *);
-
-static const char *store_info_string(CamelStoreSummary *, const CamelStoreInfo *, int);
-static void store_info_set_string(CamelStoreSummary *, CamelStoreInfo *, int, const char *);
-
-static void camel_imap_store_summary_class_init (CamelImapStoreSummaryClass *klass);
-static void camel_imap_store_summary_init (CamelImapStoreSummary *obj);
-static void camel_imap_store_summary_finalise (CamelObject *obj);
-
-static CamelStoreSummaryClass *camel_imap_store_summary_parent;
-
-static void
-camel_imap_store_summary_class_init (CamelImapStoreSummaryClass *klass)
-{
- CamelStoreSummaryClass *ssklass = (CamelStoreSummaryClass *)klass;
-
- ssklass->summary_header_load = summary_header_load;
- ssklass->summary_header_save = summary_header_save;
-
- /*ssklass->store_info_new = store_info_new;*/
- ssklass->store_info_load = store_info_load;
- ssklass->store_info_save = store_info_save;
- ssklass->store_info_free = store_info_free;
-
- ssklass->store_info_string = store_info_string;
- ssklass->store_info_set_string = store_info_set_string;
-}
-
-static void
-camel_imap_store_summary_init (CamelImapStoreSummary *s)
-{
- /*struct _CamelImapStoreSummaryPrivate *p;
-
- p = _PRIVATE(s) = g_malloc0(sizeof(*p));*/
-
- ((CamelStoreSummary *)s)->store_info_size = sizeof(CamelImapStoreInfo);
- s->version = CAMEL_IMAP_STORE_SUMMARY_VERSION;
-}
-
-static void
-camel_imap_store_summary_finalise (CamelObject *obj)
-{
- /*struct _CamelImapStoreSummaryPrivate *p;*/
- /*CamelImapStoreSummary *s = (CamelImapStoreSummary *)obj;*/
-
- /*p = _PRIVATE(obj);
- g_free(p);*/
-}
-
-CamelType
-camel_imap_store_summary_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- camel_imap_store_summary_parent = (CamelStoreSummaryClass *)camel_store_summary_get_type();
- type = camel_type_register((CamelType)camel_imap_store_summary_parent, "CamelImapStoreSummary",
- sizeof (CamelImapStoreSummary),
- sizeof (CamelImapStoreSummaryClass),
- (CamelObjectClassInitFunc) camel_imap_store_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_store_summary_init,
- (CamelObjectFinalizeFunc) camel_imap_store_summary_finalise);
- }
-
- return type;
-}
-
-/**
- * camel_imap_store_summary_new:
- *
- * Create a new CamelImapStoreSummary object.
- *
- * Return value: A new CamelImapStoreSummary widget.
- **/
-CamelImapStoreSummary *
-camel_imap_store_summary_new (void)
-{
- CamelImapStoreSummary *new = CAMEL_IMAP_STORE_SUMMARY ( camel_object_new (camel_imap_store_summary_get_type ()));
-
- return new;
-}
-
-/**
- * camel_imap_store_summary_full_name:
- * @s:
- * @path:
- *
- * Retrieve a summary item by full name.
- *
- * A referenced to the summary item is returned, which may be
- * ref'd or free'd as appropriate.
- *
- * Return value: The summary item, or NULL if the @full_name name
- * is not available.
- * It must be freed using camel_store_summary_info_free().
- **/
-CamelImapStoreInfo *
-camel_imap_store_summary_full_name(CamelImapStoreSummary *s, const char *full_name)
-{
- int count, i;
- CamelImapStoreInfo *info;
-
- count = camel_store_summary_count((CamelStoreSummary *)s);
- for (i=0;i<count;i++) {
- info = (CamelImapStoreInfo *)camel_store_summary_index((CamelStoreSummary *)s, i);
- if (info) {
- if (strcmp(info->full_name, full_name) == 0)
- return info;
- camel_store_summary_info_free((CamelStoreSummary *)s, (CamelStoreInfo *)info);
- }
- }
-
- return NULL;
-}
-
-char *
-camel_imap_store_summary_full_to_path(CamelImapStoreSummary *s, const char *full_name, char dir_sep)
-{
- char *path, *p;
- int c;
- const char *f;
-
- if (dir_sep != '/') {
- p = path = alloca(strlen(full_name)*3+1);
- f = full_name;
- while ( (c = *f++ & 0xff) ) {
- if (c == dir_sep)
- *p++ = '/';
- else if (c == '/' || c == '%')
- p += sprintf(p, "%%%02X", c);
- else
- *p++ = c;
- }
- *p = 0;
- } else
- path = (char *)full_name;
-
- return camel_utf7_utf8(path);
-}
-
-static guint32 hexnib(guint32 c)
-{
- if (c >= '0' && c <= '9')
- return c-'0';
- else if (c>='A' && c <= 'Z')
- return c-'A'+10;
- else
- return 0;
-}
-
-char *
-camel_imap_store_summary_path_to_full(CamelImapStoreSummary *s, const char *path, char dir_sep)
-{
- unsigned char *full, *f;
- guint32 c, v = 0;
- const char *p;
- int state=0;
- char *subpath, *last = NULL;
- CamelStoreInfo *si;
- CamelImapStoreNamespace *ns;
-
- /* check to see if we have a subpath of path already defined */
- subpath = alloca(strlen(path)+1);
- strcpy(subpath, path);
- do {
- si = camel_store_summary_path((CamelStoreSummary *)s, subpath);
- if (si == NULL) {
- last = strrchr(subpath, '/');
- if (last)
- *last = 0;
- }
- } while (si == NULL && last);
-
- /* path is already present, use the raw version we have */
- if (si && strlen(subpath) == strlen(path)) {
- f = g_strdup(camel_imap_store_info_full_name(s, si));
- camel_store_summary_info_free((CamelStoreSummary *)s, si);
- return f;
- }
-
- ns = camel_imap_store_summary_namespace_find_path(s, path);
-
- f = full = alloca(strlen(path)*2+1);
- if (si)
- p = path + strlen(subpath);
- else if (ns)
- p = path + strlen(ns->path);
- else
- p = path;
-
- while ( (c = camel_utf8_getc((const unsigned char **)&p)) ) {
- switch(state) {
- case 0:
- if (c == '%')
- state = 1;
- else {
- if (c == '/')
- c = dir_sep;
- camel_utf8_putc(&f, c);
- }
- break;
- case 1:
- state = 2;
- v = hexnib(c)<<4;
- break;
- case 2:
- state = 0;
- v |= hexnib(c);
- camel_utf8_putc(&f, v);
- break;
- }
- }
- camel_utf8_putc(&f, c);
-
- /* merge old path part if required */
- f = camel_utf8_utf7(full);
- if (si) {
- full = g_strdup_printf("%s%s", camel_imap_store_info_full_name(s, si), f);
- g_free(f);
- camel_store_summary_info_free((CamelStoreSummary *)s, si);
- f = full;
- } else if (ns) {
- full = g_strdup_printf("%s%s", ns->full_name, f);
- g_free(f);
- f = full;
- }
-
- return f;
-}
-
-CamelImapStoreInfo *
-camel_imap_store_summary_add_from_full(CamelImapStoreSummary *s, const char *full, char dir_sep)
-{
- CamelImapStoreInfo *info;
- char *pathu8, *prefix;
- int len;
- char *full_name;
- CamelImapStoreNamespace *ns;
-
- d(printf("adding full name '%s' '%c'\n", full, dir_sep));
-
- len = strlen(full);
- full_name = alloca(len+1);
- strcpy(full_name, full);
- if (full_name[len-1] == dir_sep)
- full_name[len-1] = 0;
-
- info = camel_imap_store_summary_full_name(s, full_name);
- if (info) {
- camel_store_summary_info_free((CamelStoreSummary *)s, (CamelStoreInfo *)info);
- d(printf(" already there\n"));
- return info;
- }
-
- ns = camel_imap_store_summary_namespace_find_full(s, full_name);
- if (ns) {
- d(printf("(found namespace for '%s' ns '%s') ", full_name, ns->path));
- len = strlen(ns->full_name);
- if (len >= strlen(full_name)) {
- pathu8 = g_strdup(ns->path);
- } else {
- if (full_name[len] == ns->sep)
- len++;
-
- prefix = camel_imap_store_summary_full_to_path(s, full_name+len, ns->sep);
- if (*ns->path) {
- pathu8 = g_strdup_printf ("%s/%s", ns->path, prefix);
- g_free (prefix);
- } else {
- pathu8 = prefix;
- }
- }
- d(printf(" (pathu8 = '%s')", pathu8));
- } else {
- d(printf("(Cannot find namespace for '%s')\n", full_name));
- pathu8 = camel_imap_store_summary_full_to_path(s, full_name, dir_sep);
- }
-
- info = (CamelImapStoreInfo *)camel_store_summary_add_from_path((CamelStoreSummary *)s, pathu8);
- if (info) {
- d(printf(" '%s' -> '%s'\n", pathu8, full_name));
- camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_IMAP_STORE_INFO_FULL_NAME, full_name);
- } else
- d(printf(" failed\n"));
-
- return info;
-}
-
-/* should this be const? */
-/* TODO: deprecate/merge this function with path_to_full */
-char *
-camel_imap_store_summary_full_from_path(CamelImapStoreSummary *s, const char *path)
-{
- CamelImapStoreNamespace *ns;
- char *name = NULL;
-
- ns = camel_imap_store_summary_namespace_find_path(s, path);
- if (ns)
- name = camel_imap_store_summary_path_to_full(s, path, ns->sep);
-
- d(printf("looking up path %s -> %s\n", path, name?name:"not found"));
-
- return name;
-}
-
-/* TODO: this api needs some more work */
-CamelImapStoreNamespace *camel_imap_store_summary_namespace_new(CamelImapStoreSummary *s, const char *full_name, char dir_sep)
-{
- CamelImapStoreNamespace *ns;
- char *p, *o, c;
- int len;
-
- ns = g_malloc0(sizeof(*ns));
- ns->full_name = g_strdup(full_name);
- len = strlen(ns->full_name)-1;
- if (len >= 0 && ns->full_name[len] == dir_sep)
- ns->full_name[len] = 0;
- ns->sep = dir_sep;
-
- o = p = ns->path = camel_imap_store_summary_full_to_path(s, ns->full_name, dir_sep);
- while ((c = *p++)) {
- if (c != '#') {
- if (c == '/')
- c = '.';
- *o++ = c;
- }
- }
- *o = 0;
-
- return ns;
-}
-
-void camel_imap_store_summary_namespace_set(CamelImapStoreSummary *s, CamelImapStoreNamespace *ns)
-{
- static void namespace_clear(CamelStoreSummary *s);
-
- d(printf("Setting namesapce to '%s' '%c' -> '%s'\n", ns->full_name, ns->sep, ns->path));
- namespace_clear((CamelStoreSummary *)s);
- s->namespace = ns;
- camel_store_summary_touch((CamelStoreSummary *)s);
-}
-
-CamelImapStoreNamespace *
-camel_imap_store_summary_namespace_find_path(CamelImapStoreSummary *s, const char *path)
-{
- int len;
- CamelImapStoreNamespace *ns;
-
- /* NB: this currently only compares against 1 namespace, in future compare against others */
- ns = s->namespace;
- while (ns) {
- len = strlen(ns->path);
- if (len == 0
- || (strncmp(ns->path, path, len) == 0
- && (path[len] == '/' || path[len] == 0)))
- break;
- ns = NULL;
- }
-
- /* have a default? */
- return ns;
-}
-
-CamelImapStoreNamespace *
-camel_imap_store_summary_namespace_find_full(CamelImapStoreSummary *s, const char *full)
-{
- int len;
- CamelImapStoreNamespace *ns;
-
- /* NB: this currently only compares against 1 namespace, in future compare against others */
- ns = s->namespace;
- while (ns) {
- len = strlen(ns->full_name);
- d(printf("find_full: comparing namespace '%s' to name '%s'\n", ns->full_name, full));
- if (len == 0
- || (strncmp(ns->full_name, full, len) == 0
- && (full[len] == ns->sep || full[len] == 0)))
- break;
- ns = NULL;
- }
-
- /* have a default? */
- return ns;
-}
-
-static void
-namespace_free(CamelStoreSummary *s, CamelImapStoreNamespace *ns)
-{
- g_free(ns->path);
- g_free(ns->full_name);
- g_free(ns);
-}
-
-static void
-namespace_clear(CamelStoreSummary *s)
-{
- CamelImapStoreSummary *is = (CamelImapStoreSummary *)s;
-
- if (is->namespace)
- namespace_free(s, is->namespace);
- is->namespace = NULL;
-}
-
-static CamelImapStoreNamespace *
-namespace_load(CamelStoreSummary *s, FILE *in)
-{
- CamelImapStoreNamespace *ns;
- guint32 sep = '/';
-
- ns = g_malloc0(sizeof(*ns));
- if (camel_file_util_decode_string(in, &ns->path) == -1
- || camel_file_util_decode_string(in, &ns->full_name) == -1
- || camel_file_util_decode_uint32(in, &sep) == -1) {
- namespace_free(s, ns);
- ns = NULL;
- } else {
- ns->sep = sep;
- }
-
- return ns;
-}
-
-static int
-namespace_save(CamelStoreSummary *s, FILE *in, CamelImapStoreNamespace *ns)
-{
- if (camel_file_util_encode_string(in, ns->path) == -1
- || camel_file_util_encode_string(in, ns->full_name) == -1
- || camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-summary_header_load(CamelStoreSummary *s, FILE *in)
-{
- CamelImapStoreSummary *is = (CamelImapStoreSummary *)s;
- gint32 version, capabilities, count;
-
- namespace_clear(s);
-
- if (camel_imap_store_summary_parent->summary_header_load((CamelStoreSummary *)s, in) == -1
- || camel_file_util_decode_fixed_int32(in, &version) == -1)
- return -1;
-
- is->version = version;
-
- if (version < CAMEL_IMAP_STORE_SUMMARY_VERSION_0) {
- g_warning("Store summary header version too low");
- return -1;
- }
-
- /* note file format can be expanded to contain more namespaces, but only 1 at the moment */
- if (camel_file_util_decode_fixed_int32(in, &capabilities) == -1
- || camel_file_util_decode_fixed_int32(in, &count) == -1
- || count > 1)
- return -1;
-
- is->capabilities = capabilities;
- if (count == 1) {
- if ((is->namespace = namespace_load(s, in)) == NULL)
- return -1;
- }
-
- return 0;
-}
-
-static int
-summary_header_save(CamelStoreSummary *s, FILE *out)
-{
- CamelImapStoreSummary *is = (CamelImapStoreSummary *)s;
- guint32 count;
-
- count = is->namespace?1:0;
-
- /* always write as latest version */
- if (camel_imap_store_summary_parent->summary_header_save((CamelStoreSummary *)s, out) == -1
- || camel_file_util_encode_fixed_int32(out, CAMEL_IMAP_STORE_SUMMARY_VERSION) == -1
- || camel_file_util_encode_fixed_int32(out, is->capabilities) == -1
- || camel_file_util_encode_fixed_int32(out, count) == -1)
- return -1;
-
- if (is->namespace && namespace_save(s, out, is->namespace) == -1)
- return -1;
-
- return 0;
-}
-
-static CamelStoreInfo *
-store_info_load(CamelStoreSummary *s, FILE *in)
-{
- CamelImapStoreInfo *mi;
-
- mi = (CamelImapStoreInfo *)camel_imap_store_summary_parent->store_info_load(s, in);
- if (mi) {
- if (camel_file_util_decode_string(in, &mi->full_name) == -1) {
- camel_store_summary_info_free(s, (CamelStoreInfo *)mi);
- mi = NULL;
- }
- }
-
- return (CamelStoreInfo *)mi;
-}
-
-static int
-store_info_save(CamelStoreSummary *s, FILE *out, CamelStoreInfo *mi)
-{
- CamelImapStoreInfo *isi = (CamelImapStoreInfo *)mi;
-
- if (camel_imap_store_summary_parent->store_info_save(s, out, mi) == -1
- || camel_file_util_encode_string(out, isi->full_name) == -1)
- return -1;
-
- return 0;
-}
-
-static void
-store_info_free(CamelStoreSummary *s, CamelStoreInfo *mi)
-{
- CamelImapStoreInfo *isi = (CamelImapStoreInfo *)mi;
-
- g_free(isi->full_name);
- camel_imap_store_summary_parent->store_info_free(s, mi);
-}
-
-static const char *
-store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, int type)
-{
- CamelImapStoreInfo *isi = (CamelImapStoreInfo *)mi;
-
- /* FIXME: Locks? */
-
- g_assert (mi != NULL);
-
- switch (type) {
- case CAMEL_IMAP_STORE_INFO_FULL_NAME:
- return isi->full_name;
- default:
- return camel_imap_store_summary_parent->store_info_string(s, mi, type);
- }
-}
-
-static void
-store_info_set_string(CamelStoreSummary *s, CamelStoreInfo *mi, int type, const char *str)
-{
- CamelImapStoreInfo *isi = (CamelImapStoreInfo *)mi;
-
- g_assert(mi != NULL);
-
- switch(type) {
- case CAMEL_IMAP_STORE_INFO_FULL_NAME:
- d(printf("Set full name %s -> %s\n", isi->full_name, str));
- CAMEL_STORE_SUMMARY_LOCK(s, summary_lock);
- g_free(isi->full_name);
- isi->full_name = g_strdup(str);
- CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock);
- break;
- default:
- camel_imap_store_summary_parent->store_info_set_string(s, mi, type, str);
- break;
- }
-}
diff --git a/camel/providers/imap/camel-imap-store-summary.h b/camel/providers/imap/camel-imap-store-summary.h
deleted file mode 100644
index 0fa6be0df3..0000000000
--- a/camel/providers/imap/camel-imap-store-summary.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2002 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef _CAMEL_IMAP_STORE_SUMMARY_H
-#define _CAMEL_IMAP_STORE_SUMMARY_H
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#include <camel/camel-object.h>
-#include <camel/camel-store-summary.h>
-
-#define CAMEL_IMAP_STORE_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_imap_store_summary_get_type (), CamelImapStoreSummary)
-#define CAMEL_IMAP_STORE_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imap_store_summary_get_type (), CamelImapStoreSummaryClass)
-#define CAMEL_IS_IMAP_STORE_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_imap_store_summary_get_type ())
-
-typedef struct _CamelImapStoreSummary CamelImapStoreSummary;
-typedef struct _CamelImapStoreSummaryClass CamelImapStoreSummaryClass;
-
-typedef struct _CamelImapStoreInfo CamelImapStoreInfo;
-
-enum {
- CAMEL_IMAP_STORE_INFO_FULL_NAME = CAMEL_STORE_INFO_LAST,
- CAMEL_IMAP_STORE_INFO_LAST,
-};
-
-struct _CamelImapStoreInfo {
- CamelStoreInfo info;
- char *full_name;
-};
-
-typedef struct _CamelImapStoreNamespace CamelImapStoreNamespace;
-
-struct _CamelImapStoreNamespace {
- char *path; /* display path */
- char *full_name; /* real name */
- char sep; /* directory separator */
-};
-
-struct _CamelImapStoreSummary {
- CamelStoreSummary summary;
-
- struct _CamelImapStoreSummaryPrivate *priv;
-
- /* header info */
- guint32 version; /* version of base part of file */
- guint32 capabilities;
- CamelImapStoreNamespace *namespace; /* eventually to be a list */
-};
-
-struct _CamelImapStoreSummaryClass {
- CamelStoreSummaryClass summary_class;
-};
-
-CamelType camel_imap_store_summary_get_type (void);
-CamelImapStoreSummary *camel_imap_store_summary_new (void);
-
-/* TODO: this api needs some more work, needs to support lists */
-CamelImapStoreNamespace *camel_imap_store_summary_namespace_new(CamelImapStoreSummary *s, const char *full_name, char dir_sep);
-void camel_imap_store_summary_namespace_set(CamelImapStoreSummary *s, CamelImapStoreNamespace *ns);
-CamelImapStoreNamespace *camel_imap_store_summary_namespace_find_path(CamelImapStoreSummary *s, const char *path);
-CamelImapStoreNamespace *camel_imap_store_summary_namespace_find_full(CamelImapStoreSummary *s, const char *full_name);
-
-/* converts to/from utf8 canonical nasmes */
-char *camel_imap_store_summary_full_to_path(CamelImapStoreSummary *s, const char *full_name, char dir_sep);
-char *camel_imap_store_summary_path_to_full(CamelImapStoreSummary *s, const char *path, char dir_sep);
-
-CamelImapStoreInfo *camel_imap_store_summary_full_name(CamelImapStoreSummary *s, const char *full_name);
-CamelImapStoreInfo *camel_imap_store_summary_add_from_full(CamelImapStoreSummary *s, const char *full_name, char dir_sep);
-
-/* a convenience lookup function. always use this if path known */
-char *camel_imap_store_summary_full_from_path(CamelImapStoreSummary *s, const char *path);
-
-/* helper macro's */
-#define camel_imap_store_info_full_name(s, i) (camel_store_info_string((CamelStoreSummary *)s, (const CamelStoreInfo *)i, CAMEL_IMAP_STORE_INFO_FULL_NAME))
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* ! _CAMEL_IMAP_STORE_SUMMARY_H */
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
deleted file mode 100644
index 07152eef87..0000000000
--- a/camel/providers/imap/camel-imap-store.c
+++ /dev/null
@@ -1,2845 +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:
- * Dan Winship <danw@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2000, 2003 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "e-util/e-path.h"
-
-#include "camel-imap-store.h"
-#include "camel-imap-store-summary.h"
-#include "camel-imap-folder.h"
-#include "camel-imap-utils.h"
-#include "camel-imap-command.h"
-#include "camel-imap-summary.h"
-#include "camel-imap-message-cache.h"
-#include "camel-disco-diary.h"
-#include "camel-file-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-stream-process.h"
-#include "camel-tcp-stream-raw.h"
-#include "camel-tcp-stream-ssl.h"
-#include "camel-url.h"
-#include "camel-sasl.h"
-#include "camel-utf8.h"
-#include "camel-string-utils.h"
-
-#include "camel-imap-private.h"
-#include "camel-private.h"
-
-#define d(x)
-
-/* Specified in RFC 2060 */
-#define IMAP_PORT 143
-#define SIMAP_PORT 993
-
-
-extern int camel_verbose_debug;
-
-static CamelDiscoStoreClass *parent_class = NULL;
-
-static char imap_tag_prefix = 'A';
-
-static void construct (CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- CamelException *ex);
-
-static int imap_setv (CamelObject *object, CamelException *ex, CamelArgV *args);
-static int imap_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args);
-
-static char *imap_get_name (CamelService *service, gboolean brief);
-
-static gboolean can_work_offline (CamelDiscoStore *disco_store);
-static gboolean imap_connect_online (CamelService *service, CamelException *ex);
-static gboolean imap_connect_offline (CamelService *service, CamelException *ex);
-static gboolean imap_disconnect_online (CamelService *service, gboolean clean, CamelException *ex);
-static gboolean imap_disconnect_offline (CamelService *service, gboolean clean, CamelException *ex);
-static void imap_noop (CamelStore *store, CamelException *ex);
-static GList *query_auth_types (CamelService *service, CamelException *ex);
-static guint hash_folder_name (gconstpointer key);
-static gint compare_folder_name (gconstpointer a, gconstpointer b);
-static CamelFolder *get_folder_online (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
-static CamelFolder *get_folder_offline (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
-static CamelFolderInfo *create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex);
-static void delete_folder (CamelStore *store, const char *folder_name, CamelException *ex);
-static void rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
-static CamelFolderInfo *get_folder_info_online (CamelStore *store,
- const char *top,
- guint32 flags,
- CamelException *ex);
-static CamelFolderInfo *get_folder_info_offline (CamelStore *store,
- const char *top,
- guint32 flags,
- CamelException *ex);
-static gboolean folder_subscribed (CamelStore *store, const char *folder_name);
-static void subscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex);
-static void unsubscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex);
-
-static void get_folders_online (CamelImapStore *imap_store, const char *pattern,
- GPtrArray *folders, gboolean lsub, CamelException *ex);
-
-
-static void imap_folder_effectively_unsubscribed(CamelImapStore *imap_store, const char *folder_name, CamelException *ex);
-static gboolean imap_check_folder_still_extant (CamelImapStore *imap_store, const char *full_name, CamelException *ex);
-static void imap_forget_folder(CamelImapStore *imap_store, const char *folder_name, CamelException *ex);
-static void imap_set_server_level (CamelImapStore *store);
-
-static void
-camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class)
-{
- CamelObjectClass *camel_object_class =
- CAMEL_OBJECT_CLASS (camel_imap_store_class);
- CamelServiceClass *camel_service_class =
- CAMEL_SERVICE_CLASS (camel_imap_store_class);
- CamelStoreClass *camel_store_class =
- CAMEL_STORE_CLASS (camel_imap_store_class);
- CamelDiscoStoreClass *camel_disco_store_class =
- CAMEL_DISCO_STORE_CLASS (camel_imap_store_class);
-
- parent_class = CAMEL_DISCO_STORE_CLASS (camel_type_get_global_classfuncs (camel_disco_store_get_type ()));
-
- /* virtual method overload */
- camel_object_class->setv = imap_setv;
- camel_object_class->getv = imap_getv;
-
- camel_service_class->construct = construct;
- camel_service_class->query_auth_types = query_auth_types;
- camel_service_class->get_name = imap_get_name;
-
- camel_store_class->hash_folder_name = hash_folder_name;
- camel_store_class->compare_folder_name = compare_folder_name;
- camel_store_class->create_folder = create_folder;
- camel_store_class->delete_folder = delete_folder;
- camel_store_class->rename_folder = rename_folder;
- camel_store_class->free_folder_info = camel_store_free_folder_info_full;
- camel_store_class->folder_subscribed = folder_subscribed;
- camel_store_class->subscribe_folder = subscribe_folder;
- camel_store_class->unsubscribe_folder = unsubscribe_folder;
- camel_store_class->noop = imap_noop;
-
- camel_disco_store_class->can_work_offline = can_work_offline;
- camel_disco_store_class->connect_online = imap_connect_online;
- camel_disco_store_class->connect_offline = imap_connect_offline;
- camel_disco_store_class->disconnect_online = imap_disconnect_online;
- camel_disco_store_class->disconnect_offline = imap_disconnect_offline;
- camel_disco_store_class->get_folder_online = get_folder_online;
- camel_disco_store_class->get_folder_offline = get_folder_offline;
- camel_disco_store_class->get_folder_resyncing = get_folder_online;
- camel_disco_store_class->get_folder_info_online = get_folder_info_online;
- camel_disco_store_class->get_folder_info_offline = get_folder_info_offline;
- camel_disco_store_class->get_folder_info_resyncing = get_folder_info_online;
-}
-
-static gboolean
-free_key (gpointer key, gpointer value, gpointer user_data)
-{
- g_free (key);
- return TRUE;
-}
-
-static void
-camel_imap_store_finalize (CamelObject *object)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
-
- /* This frees current_folder, folders, authtypes, streams, and namespace. */
- camel_service_disconnect((CamelService *)imap_store, TRUE, NULL);
-
- if (imap_store->summary) {
- camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
- camel_object_unref(imap_store->summary);
- }
-
- if (imap_store->base_url)
- g_free (imap_store->base_url);
- if (imap_store->storage_path)
- g_free (imap_store->storage_path);
-
-#ifdef ENABLE_THREADS
- e_thread_destroy (imap_store->async_thread);
-#endif
-}
-
-#ifdef ENABLE_THREADS
-static void async_destroy(EThread *et, EMsg *em, void *data)
-{
- CamelImapStore *imap_store = data;
- CamelImapMsg *msg = (CamelImapMsg *)em;
-
- if (msg->free)
- msg->free (imap_store, msg);
-
- g_free (msg);
-}
-
-static void async_received(EThread *et, EMsg *em, void *data)
-{
- CamelImapStore *imap_store = data;
- CamelImapMsg *msg = (CamelImapMsg *)em;
-
- if (msg->receive)
- msg->receive(imap_store, msg);
-}
-
-CamelImapMsg *camel_imap_msg_new(void (*receive)(CamelImapStore *store, struct _CamelImapMsg *m),
- void (*free)(CamelImapStore *store, struct _CamelImapMsg *m),
- size_t size)
-{
- CamelImapMsg *msg;
-
- g_assert(size >= sizeof(*msg));
-
- msg = g_malloc0(size);
- msg->receive = receive;
- msg->free = free;
-
- return msg;
-}
-
-void camel_imap_msg_queue(CamelImapStore *store, CamelImapMsg *msg)
-{
- e_thread_put(store->async_thread, (EMsg *)msg);
-}
-
-#endif
-
-static void
-camel_imap_store_init (gpointer object, gpointer klass)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
-
- imap_store->istream = NULL;
- imap_store->ostream = NULL;
-
- imap_store->dir_sep = '\0';
- imap_store->current_folder = NULL;
- imap_store->connected = FALSE;
- imap_store->preauthed = FALSE;
-
- imap_store->tag_prefix = imap_tag_prefix++;
- if (imap_tag_prefix > 'Z')
- imap_tag_prefix = 'A';
-
-#ifdef ENABLE_THREADS
- imap_store->async_thread = e_thread_new(E_THREAD_QUEUE);
- e_thread_set_msg_destroy(imap_store->async_thread, async_destroy, imap_store);
- e_thread_set_msg_received(imap_store->async_thread, async_received, imap_store);
-#endif /* ENABLE_THREADS */
-}
-
-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_DISCO_STORE_TYPE,
- "CamelImapStore",
- sizeof (CamelImapStore),
- sizeof (CamelImapStoreClass),
- (CamelObjectClassInitFunc) camel_imap_store_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_store_init,
- (CamelObjectFinalizeFunc) camel_imap_store_finalize);
- }
-
- return camel_imap_store_type;
-}
-
-static void
-construct (CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (service);
- CamelStore *store = CAMEL_STORE (service);
- char *tmp;
- CamelURL *summary_url;
-
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
- if (camel_exception_is_set (ex))
- return;
-
- imap_store->storage_path = camel_session_get_storage_path (session, service, ex);
- if (!imap_store->storage_path)
- return;
-
- /* FIXME */
- imap_store->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
- CAMEL_URL_HIDE_PARAMS |
- CAMEL_URL_HIDE_AUTH));
-
- imap_store->parameters = 0;
- if (camel_url_get_param (url, "use_lsub"))
- store->flags |= CAMEL_STORE_SUBSCRIPTIONS;
- if (camel_url_get_param (url, "namespace")) {
- imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE;
- g_free(imap_store->namespace);
- imap_store->namespace = g_strdup (camel_url_get_param (url, "namespace"));
- }
- if (camel_url_get_param (url, "check_all"))
- imap_store->parameters |= IMAP_PARAM_CHECK_ALL;
- if (camel_url_get_param (url, "filter")) {
- imap_store->parameters |= IMAP_PARAM_FILTER_INBOX;
- store->flags |= CAMEL_STORE_FILTER_INBOX;
- }
-
- /* setup/load the store summary */
- tmp = alloca(strlen(imap_store->storage_path)+32);
- sprintf(tmp, "%s/.ev-store-summary", imap_store->storage_path);
- imap_store->summary = camel_imap_store_summary_new();
- camel_store_summary_set_filename((CamelStoreSummary *)imap_store->summary, tmp);
- summary_url = camel_url_new(imap_store->base_url, NULL);
- camel_store_summary_set_uri_base((CamelStoreSummary *)imap_store->summary, summary_url);
- camel_url_free(summary_url);
- if (camel_store_summary_load((CamelStoreSummary *)imap_store->summary) == 0) {
- CamelImapStoreSummary *is = imap_store->summary;
-
- if (is->namespace) {
- /* if namespace has changed, clear folder list */
- if (imap_store->namespace && strcmp(imap_store->namespace, is->namespace->full_name) != 0) {
- camel_store_summary_clear((CamelStoreSummary *)is);
- } else {
- imap_store->namespace = g_strdup(is->namespace->full_name);
- imap_store->dir_sep = is->namespace->sep;
- store->dir_sep = is->namespace->sep;
- }
- }
-
- imap_store->capabilities = is->capabilities;
- imap_set_server_level(imap_store);
- }
-}
-
-static int
-imap_setv (CamelObject *object, CamelException *ex, CamelArgV *args)
-{
- CamelImapStore *store = (CamelImapStore *) object;
- guint32 tag, flags;
- int i;
-
- for (i = 0; i < args->argc; i++) {
- tag = args->argv[i].tag;
-
- /* make sure this arg wasn't already handled */
- if (tag & CAMEL_ARG_IGNORE)
- continue;
-
- /* make sure this is an arg we're supposed to handle */
- if ((tag & CAMEL_ARG_TAG) <= CAMEL_IMAP_STORE_ARG_FIRST ||
- (tag & CAMEL_ARG_TAG) >= CAMEL_IMAP_STORE_ARG_FIRST + 100)
- continue;
-
- if (tag == CAMEL_IMAP_STORE_NAMESPACE) {
- if (strcmp (store->namespace, args->argv[i].ca_str) != 0) {
- g_free (store->namespace);
- store->namespace = g_strdup (args->argv[i].ca_str);
- /* the current imap code will need to do a reconnect for this to take effect */
- /*reconnect = TRUE;*/
- }
- } else if (tag == CAMEL_IMAP_STORE_OVERRIDE_NAMESPACE) {
- flags = args->argv[i].ca_int ? IMAP_PARAM_OVERRIDE_NAMESPACE : 0;
- flags |= (store->parameters & ~IMAP_PARAM_OVERRIDE_NAMESPACE);
-
- if (store->parameters != flags) {
- store->parameters = flags;
- /* the current imap code will need to do a reconnect for this to take effect */
- /*reconnect = TRUE;*/
- }
- } else if (tag == CAMEL_IMAP_STORE_CHECK_ALL) {
- flags = args->argv[i].ca_int ? IMAP_PARAM_CHECK_ALL : 0;
- flags |= (store->parameters & ~IMAP_PARAM_CHECK_ALL);
- store->parameters = flags;
- /* no need to reconnect for this option to take effect... */
- } else if (tag == CAMEL_IMAP_STORE_FILTER_INBOX) {
- flags = args->argv[i].ca_int ? IMAP_PARAM_FILTER_INBOX : 0;
- flags |= (store->parameters & ~IMAP_PARAM_FILTER_INBOX);
- store->parameters = flags;
- /* no need to reconnect for this option to take effect... */
- } else {
- /* error?? */
- continue;
- }
-
- /* let our parent know that we've handled this arg */
- camel_argv_ignore (args, i);
- }
-
- /* FIXME: if we need to reconnect for a change to take affect,
- we need to do it here... or, better yet, somehow chain it
- up to CamelService's setv implementation. */
-
- return CAMEL_OBJECT_CLASS (parent_class)->setv (object, ex, args);
-}
-
-static int
-imap_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
-{
- CamelImapStore *store = (CamelImapStore *) object;
- guint32 tag;
- int i;
-
- for (i = 0; i < args->argc; i++) {
- tag = args->argv[i].tag;
-
- /* make sure this is an arg we're supposed to handle */
- if ((tag & CAMEL_ARG_TAG) <= CAMEL_IMAP_STORE_ARG_FIRST ||
- (tag & CAMEL_ARG_TAG) >= CAMEL_IMAP_STORE_ARG_FIRST + 100)
- continue;
-
- switch (tag) {
- case CAMEL_IMAP_STORE_NAMESPACE:
- /* get the username */
- *args->argv[i].ca_str = store->namespace;
- break;
- case CAMEL_IMAP_STORE_OVERRIDE_NAMESPACE:
- /* get the auth mechanism */
- *args->argv[i].ca_int = store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE ? TRUE : FALSE;
- break;
- case CAMEL_IMAP_STORE_CHECK_ALL:
- /* get the hostname */
- *args->argv[i].ca_int = store->parameters & IMAP_PARAM_CHECK_ALL ? TRUE : FALSE;
- break;
- case CAMEL_IMAP_STORE_FILTER_INBOX:
- /* get the port */
- *args->argv[i].ca_int = store->parameters & IMAP_PARAM_FILTER_INBOX ? TRUE : FALSE;
- break;
- default:
- /* error? */
- break;
- }
- }
-
- return CAMEL_OBJECT_CLASS (parent_class)->getv (object, ex, args);
-}
-
-static char *
-imap_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 void
-imap_set_server_level (CamelImapStore *store)
-{
- if (store->capabilities & IMAP_CAPABILITY_IMAP4REV1) {
- store->server_level = IMAP_LEVEL_IMAP4REV1;
- store->capabilities |= IMAP_CAPABILITY_STATUS;
- } else if (store->capabilities & IMAP_CAPABILITY_IMAP4)
- store->server_level = IMAP_LEVEL_IMAP4;
- else
- store->server_level = IMAP_LEVEL_UNKNOWN;
-}
-
-static struct {
- const char *name;
- guint32 flag;
-} capabilities[] = {
- { "IMAP4", IMAP_CAPABILITY_IMAP4 },
- { "IMAP4REV1", IMAP_CAPABILITY_IMAP4REV1 },
- { "STATUS", IMAP_CAPABILITY_STATUS },
- { "NAMESPACE", IMAP_CAPABILITY_NAMESPACE },
- { "UIDPLUS", IMAP_CAPABILITY_UIDPLUS },
- { "LITERAL+", IMAP_CAPABILITY_LITERALPLUS },
- { "STARTTLS", IMAP_CAPABILITY_STARTTLS },
- { NULL, 0 }
-};
-
-
-static gboolean
-imap_get_capability (CamelService *service, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelImapResponse *response;
- char *result, *capa, *lasts;
- int i;
-
- CAMEL_SERVICE_ASSERT_LOCKED (store, connect_lock);
-
- /* Find out the IMAP capabilities */
- /* We assume we have utf8 capable search until a failed search tells us otherwise */
- store->capabilities = IMAP_CAPABILITY_utf8_search;
- store->authtypes = g_hash_table_new (g_str_hash, g_str_equal);
- response = camel_imap_command (store, NULL, ex, "CAPABILITY");
- if (!response)
- return FALSE;
- result = camel_imap_response_extract (store, response, "CAPABILITY ", ex);
- if (!result)
- return FALSE;
-
- /* Skip over "* CAPABILITY ". */
- capa = result + 13;
- for (capa = strtok_r (capa, " ", &lasts); capa;
- capa = strtok_r (NULL, " ", &lasts)) {
- if (!strncmp (capa, "AUTH=", 5)) {
- g_hash_table_insert (store->authtypes,
- g_strdup (capa + 5),
- GINT_TO_POINTER (1));
- continue;
- }
- for (i = 0; capabilities[i].name; i++) {
- if (strcasecmp (capa, capabilities[i].name) == 0) {
- store->capabilities |= capabilities[i].flag;
- break;
- }
- }
- }
- g_free (result);
-
- imap_set_server_level (store);
-
- if (store->summary->capabilities != store->capabilities) {
- store->summary->capabilities = store->capabilities;
- camel_store_summary_touch((CamelStoreSummary *)store->summary);
- camel_store_summary_save((CamelStoreSummary *)store->summary);
- }
-
- return TRUE;
-}
-
-enum {
- USE_SSL_NEVER,
- USE_SSL_ALWAYS,
- USE_SSL_WHEN_POSSIBLE
-};
-
-#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
-
-static gboolean
-connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelException *ex)
-{
- CamelImapStore *store = (CamelImapStore *) service;
- CamelImapResponse *response;
- CamelStream *tcp_stream;
- struct hostent *h;
- int clean_quit;
- int port, ret;
- char *buf;
-
- h = camel_service_gethost (service, ex);
- if (!h)
- return FALSE;
-
- port = service->url->port ? service->url->port : 143;
-
- if (ssl_mode != USE_SSL_NEVER) {
-#ifdef HAVE_SSL
- if (try_starttls) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- port = service->url->port ? service->url->port : 993;
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- if (!try_starttls)
- port = service->url->port ? service->url->port : 993;
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port,
- _("SSL unavailable"));
-
- camel_free_host (h);
-
- return FALSE;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- ret = camel_tcp_stream_connect (CAMEL_TCP_STREAM (tcp_stream), h, port);
- camel_free_host (h);
- if (ret == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Connection cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port, g_strerror (errno));
-
- camel_object_unref (CAMEL_OBJECT (tcp_stream));
-
- return FALSE;
- }
-
- store->ostream = tcp_stream;
- store->istream = camel_stream_buffer_new (tcp_stream, CAMEL_STREAM_BUFFER_READ);
-
- store->connected = TRUE;
- store->preauthed = FALSE;
- store->command = 0;
-
- /* Read the greeting, if any, and deal with PREAUTH */
- if (camel_imap_store_readline (store, &buf, ex) < 0) {
- 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;
- }
-
- store->connected = FALSE;
-
- return FALSE;
- }
- if (!strncmp(buf, "* PREAUTH", 9))
- store->preauthed = TRUE;
- g_free (buf);
-
- /* get the imap server capabilities */
- if (!imap_get_capability (service, ex)) {
- 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;
- }
-
- store->connected = FALSE;
- return FALSE;
- }
-
-#ifdef HAVE_SSL
- if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
- if (store->capabilities & IMAP_CAPABILITY_STARTTLS)
- goto starttls;
- } else if (ssl_mode == USE_SSL_ALWAYS) {
- if (try_starttls) {
- if (store->capabilities & IMAP_CAPABILITY_STARTTLS) {
- /* attempt to toggle STARTTLS mode */
- goto starttls;
- } else {
- /* server doesn't support STARTTLS, abort */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to IMAP server %s in secure mode: %s"),
- service->url->host, _("SSL/TLS extension not supported."));
- /* we have the possibility of quitting cleanly here */
- clean_quit = TRUE;
- goto exception;
- }
- }
- }
-#endif /* HAVE_SSL */
-
- return TRUE;
-
-#ifdef HAVE_SSL
- starttls:
-
- /* as soon as we send a STARTTLS command, all hope is lost of a clean QUIT if problems arise */
- clean_quit = FALSE;
-
- response = camel_imap_command (store, NULL, ex, "STARTTLS");
- if (!response) {
- camel_object_unref (CAMEL_OBJECT (store->istream));
- camel_object_unref (CAMEL_OBJECT (store->ostream));
- store->istream = store->ostream = NULL;
- return FALSE;
- }
-
- camel_imap_response_free_without_processing (store, response);
-
- /* Okay, now toggle SSL/TLS mode */
- if (camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream)) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to IMAP server %s in secure mode: %s"),
- service->url->host, _("SSL negotiations failed"));
- goto exception;
- }
-
- /* rfc2595, section 4 states that after a successful STLS
- command, the client MUST discard prior CAPA responses */
- if (!imap_get_capability (service, ex)) {
- 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;
- }
-
- store->connected = FALSE;
-
- return FALSE;
- }
-
- return TRUE;
-
- exception:
-
- if (clean_quit && store->connected) {
- /* try to disconnect cleanly */
- response = camel_imap_command (store, NULL, ex, "LOGOUT");
- if (response)
- camel_imap_response_free_without_processing (store, response);
- }
-
- 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;
- }
-
- store->connected = FALSE;
-
- return FALSE;
-#endif /* HAVE_SSL */
-}
-
-static gboolean
-connect_to_server_process (CamelService *service, const char *cmd, CamelException *ex)
-{
- CamelImapStore *store = (CamelImapStore *) service;
- CamelStream *cmd_stream;
- int ret, i = 0;
- char *buf;
- char *cmd_copy;
- char *full_cmd;
- char *child_env[7];
-
- /* Put full details in the environment, in case the connection
- program needs them */
- buf = camel_url_to_string(service->url, 0);
- child_env[i++] = g_strdup_printf("URL=%s", buf);
- g_free(buf);
-
- child_env[i++] = g_strdup_printf("URLHOST=%s", service->url->host);
- if (service->url->port)
- child_env[i++] = g_strdup_printf("URLPORT=%d", service->url->port);
- if (service->url->user)
- child_env[i++] = g_strdup_printf("URLUSER=%s", service->url->user);
- if (service->url->passwd)
- child_env[i++] = g_strdup_printf("URLPASSWD=%s", service->url->passwd);
- if (service->url->path)
- child_env[i++] = g_strdup_printf("URLPATH=%s", service->url->path);
- child_env[i] = NULL;
-
- /* Now do %h, %u, etc. substitution in cmd */
- buf = cmd_copy = g_strdup(cmd);
-
- full_cmd = g_strdup("");
-
- for(;;) {
- char *pc;
- char *tmp;
- char *var;
- int len;
-
- pc = strchr(buf, '%');
- ignore:
- if (!pc) {
- tmp = g_strdup_printf("%s%s", full_cmd, buf);
- g_free(full_cmd);
- full_cmd = tmp;
- break;
- }
-
- len = pc - buf;
-
- var = NULL;
-
- switch(pc[1]) {
- case 'h':
- var = service->url->host;
- break;
- case 'u':
- var = service->url->user;
- break;
- }
- if (!var) {
- /* If there wasn't a valid %-code, with an actual
- variable to insert, pretend we didn't see the % */
- pc = strchr(pc + 1, '%');
- goto ignore;
- }
- tmp = g_strdup_printf("%s%.*s%s", full_cmd, len, buf, var);
- g_free(full_cmd);
- full_cmd = tmp;
- buf = pc + 2;
- }
-
- g_free(cmd_copy);
-
- cmd_stream = camel_stream_process_new ();
-
- ret = camel_stream_process_connect (CAMEL_STREAM_PROCESS(cmd_stream),
- full_cmd, (const char **)child_env);
-
- while (i)
- g_free(child_env[--i]);
-
- if (ret == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Connection cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect with command \"%s\": %s"),
- full_cmd, g_strerror (errno));
-
- camel_object_unref (CAMEL_OBJECT (cmd_stream));
- g_free(full_cmd);
- return FALSE;
- }
- g_free(full_cmd);
-
- store->ostream = cmd_stream;
- store->istream = camel_stream_buffer_new (cmd_stream, CAMEL_STREAM_BUFFER_READ);
-
- store->connected = TRUE;
- store->preauthed = FALSE;
- store->command = 0;
-
- /* Read the greeting, if any, and deal with PREAUTH */
- if (camel_imap_store_readline (store, &buf, ex) < 0) {
- 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;
- }
-
- store->connected = FALSE;
- return FALSE;
- }
- if (!strncmp(buf, "* PREAUTH", 9))
- store->preauthed = TRUE;
- g_free (buf);
-
- /* get the imap server capabilities */
- if (!imap_get_capability (service, ex)) {
- 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;
- }
-
- store->connected = FALSE;
- return FALSE;
- }
-
- return TRUE;
-
-}
-
-static struct {
- char *value;
- int mode;
-} ssl_options[] = {
- { "", USE_SSL_ALWAYS },
- { "always", USE_SSL_ALWAYS },
- { "when-possible", USE_SSL_WHEN_POSSIBLE },
- { "never", USE_SSL_NEVER },
- { NULL, USE_SSL_NEVER },
-};
-
-static gboolean
-connect_to_server_wrapper (CamelService *service, CamelException *ex)
-{
- const char *command;
-#ifdef HAVE_SSL
- const char *use_ssl;
- int i, ssl_mode;
-#endif
- command = camel_url_get_param (service->url, "command");
- if (command)
- return connect_to_server_process (service, command, ex);
-
-#ifdef HAVE_SSL
- use_ssl = camel_url_get_param (service->url, "use_ssl");
- if (use_ssl) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, use_ssl))
- break;
- ssl_mode = ssl_options[i].mode;
- } else
- ssl_mode = USE_SSL_NEVER;
-
- if (ssl_mode == USE_SSL_ALWAYS) {
- /* First try the ssl port */
- if (!connect_to_server (service, ssl_mode, FALSE, ex)) {
- if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
- /* The ssl port seems to be unavailable, lets try STARTTLS */
- camel_exception_clear (ex);
- return connect_to_server (service, ssl_mode, TRUE, ex);
- } else {
- return FALSE;
- }
- }
-
- return TRUE;
- } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
- /* If the server supports STARTTLS, use it */
- return connect_to_server (service, ssl_mode, TRUE, ex);
- } else {
- /* User doesn't care about SSL */
- return connect_to_server (service, ssl_mode, FALSE, ex);
- }
-#else
- return connect_to_server (service, USE_SSL_NEVER, FALSE, ex);
-#endif
-}
-
-extern CamelServiceAuthType camel_imap_password_authtype;
-
-static GList *
-query_auth_types (CamelService *service, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelServiceAuthType *authtype;
- GList *sasl_types, *t, *next;
- gboolean connected;
-
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
- return NULL;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- connected = connect_to_server_wrapper (service, ex);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- if (!connected)
- return NULL;
-
- sasl_types = camel_sasl_authtype_list (FALSE);
- for (t = sasl_types; t; t = next) {
- authtype = t->data;
- next = t->next;
-
- if (!g_hash_table_lookup (store->authtypes, authtype->authproto)) {
- sasl_types = g_list_remove_link (sasl_types, t);
- g_list_free_1 (t);
- }
- }
-
- return g_list_prepend (sasl_types, &camel_imap_password_authtype);
-}
-
-/* folder_name is path name */
-static CamelFolderInfo *
-imap_build_folder_info(CamelImapStore *imap_store, const char *folder_name)
-{
- CamelURL *url;
- const char *name;
- CamelFolderInfo *fi;
-
- fi = g_malloc0(sizeof(*fi));
-
- fi->full_name = g_strdup(folder_name);
- fi->unread_message_count = 0;
-
- url = camel_url_new (imap_store->base_url, NULL);
- g_free (url->path);
- url->path = g_strdup_printf ("/%s", folder_name);
- fi->url = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free(url);
- fi->path = g_strdup_printf("/%s", folder_name);
- name = strrchr (fi->path, '/');
- if (name)
- name++;
- else
- name = fi->path;
-
- fi->name = g_strdup (name);
-
- return fi;
-}
-
-static void
-imap_folder_effectively_unsubscribed(CamelImapStore *imap_store,
- const char *folder_name, CamelException *ex)
-{
- CamelFolderInfo *fi;
- CamelStoreInfo *si;
-
- si = camel_store_summary_path((CamelStoreSummary *)imap_store->summary, folder_name);
- if (si) {
- if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
- si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
- camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
- }
- camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
- }
-
- if (imap_store->renaming) {
- /* we don't need to emit a "folder_unsubscribed" signal
- if we are in the process of renaming folders, so we
- are done here... */
- return;
-
- }
-
- fi = imap_build_folder_info(imap_store, folder_name);
- camel_object_trigger_event (CAMEL_OBJECT (imap_store), "folder_unsubscribed", fi);
- camel_folder_info_free (fi);
-}
-
-static void
-imap_forget_folder (CamelImapStore *imap_store, const char *folder_name, CamelException *ex)
-{
- CamelFolderSummary *summary;
- CamelImapMessageCache *cache;
- char *summary_file;
- char *journal_file;
- char *folder_dir, *storage_path;
- CamelFolderInfo *fi;
- const char *name;
-
- name = strrchr (folder_name, imap_store->dir_sep);
- if (name)
- name++;
- else
- name = folder_name;
-
- storage_path = g_strdup_printf ("%s/folders", imap_store->storage_path);
- folder_dir = e_path_to_physical (storage_path, folder_name);
- g_free (storage_path);
- if (access (folder_dir, F_OK) != 0) {
- g_free (folder_dir);
- goto event;
- }
-
- summary_file = g_strdup_printf ("%s/summary", folder_dir);
- summary = camel_imap_summary_new (summary_file);
- if (!summary) {
- g_free (summary_file);
- g_free (folder_dir);
- goto event;
- }
-
- cache = camel_imap_message_cache_new (folder_dir, summary, ex);
- if (cache)
- camel_imap_message_cache_clear (cache);
-
- camel_object_unref (cache);
- camel_object_unref (summary);
-
- unlink (summary_file);
- g_free (summary_file);
-
- journal_file = g_strdup_printf ("%s/summary", folder_dir);
- unlink (journal_file);
- g_free (journal_file);
-
- rmdir (folder_dir);
- g_free (folder_dir);
-
- event:
-
- camel_store_summary_remove_path((CamelStoreSummary *)imap_store->summary, folder_name);
- camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
-
- fi = imap_build_folder_info(imap_store, folder_name);
- camel_object_trigger_event (CAMEL_OBJECT (imap_store), "folder_deleted", fi);
- camel_folder_info_free (fi);
-}
-
-static gboolean
-imap_check_folder_still_extant (CamelImapStore *imap_store, const char *full_name,
- CamelException *ex)
-{
- CamelImapResponse *response;
-
- response = camel_imap_command (imap_store, NULL, ex, "LIST \"\" %S",
- full_name);
-
- if (response) {
- gboolean stillthere = response->untagged->len != 0;
-
- camel_imap_response_free_without_processing (imap_store, response);
-
- return stillthere;
- }
-
- /* if the command was rejected, there must be some other error,
- assume it worked so we dont blow away the folder unecessarily */
- return TRUE;
-}
-
-/* This is a little 'hack' to avoid the deadlock conditions that would otherwise
- ensue when calling camel_folder_refresh_info from inside a lock */
-/* NB: on second thougts this is probably not entirely safe, but it'll do for now */
-/* No, its definetly not safe. So its been changed to copy the folders first */
-/* the alternative is to:
- make the camel folder->lock recursive (which should probably be done)
- or remove it from camel_folder_refresh_info, and use another locking mechanism */
-/* also see get_folder_info_online() for the same hack repeated */
-static void
-imap_store_refresh_folders (CamelImapStore *store, CamelException *ex)
-{
- GPtrArray *folders;
- int i;
-
- folders = camel_object_bag_list(CAMEL_STORE (store)->folders);
-
- for (i = 0; i <folders->len; i++) {
- CamelFolder *folder = folders->pdata[i];
-
- CAMEL_IMAP_FOLDER (folder)->need_rescan = TRUE;
- if (!camel_exception_is_set(ex))
- CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->refresh_info(folder, ex);
-
- if (camel_exception_is_set (ex) &&
- imap_check_folder_still_extant (store, folder->full_name, ex) == FALSE) {
- gchar *namedup;
-
- /* the folder was deleted (may happen when we come back online
- * after being offline */
-
- namedup = g_strdup (folder->full_name);
- camel_object_unref(folder);
- imap_folder_effectively_unsubscribed (store, namedup, ex);
- imap_forget_folder (store, namedup, ex);
- g_free (namedup);
- } else
- camel_object_unref(folder);
- }
-
- g_ptr_array_free (folders, TRUE);
-}
-
-static gboolean
-try_auth (CamelImapStore *store, const char *mech, CamelException *ex)
-{
- CamelSasl *sasl;
- CamelImapResponse *response;
- char *resp;
- char *sasl_resp;
-
- CAMEL_SERVICE_ASSERT_LOCKED (store, connect_lock);
-
- response = camel_imap_command (store, NULL, ex, "AUTHENTICATE %s", mech);
- if (!response)
- return FALSE;
-
- sasl = camel_sasl_new ("imap", mech, CAMEL_SERVICE (store));
- while (!camel_sasl_authenticated (sasl)) {
- resp = camel_imap_response_extract_continuation (store, response, ex);
- if (!resp)
- goto lose;
-
- sasl_resp = camel_sasl_challenge_base64 (sasl, imap_next_word (resp), ex);
- g_free (resp);
- if (camel_exception_is_set (ex))
- goto break_and_lose;
-
- response = camel_imap_command_continuation (store, sasl_resp, strlen (sasl_resp), ex);
- g_free (sasl_resp);
- if (!response)
- goto lose;
- }
-
- resp = camel_imap_response_extract_continuation (store, response, NULL);
- if (resp) {
- /* Oops. SASL claims we're done, but the IMAP server
- * doesn't think so...
- */
- g_free (resp);
- goto lose;
- }
-
- camel_object_unref (CAMEL_OBJECT (sasl));
-
- return TRUE;
-
- break_and_lose:
- /* Get the server out of "waiting for continuation data" mode. */
- response = camel_imap_command_continuation (store, "*", 1, NULL);
- if (response)
- camel_imap_response_free (store, response);
-
- lose:
- if (!camel_exception_is_set (ex)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Bad authentication response from server."));
- }
-
- camel_object_unref (CAMEL_OBJECT (sasl));
-
- return FALSE;
-}
-
-static gboolean
-imap_auth_loop (CamelService *service, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelSession *session = camel_service_get_session (service);
- CamelServiceAuthType *authtype = NULL;
- CamelImapResponse *response;
- char *errbuf = NULL;
- gboolean authenticated = FALSE;
-
- CAMEL_SERVICE_ASSERT_LOCKED (store, connect_lock);
-
- if (store->preauthed) {
- if (camel_verbose_debug)
- fprintf(stderr, "Server %s has preauthenticated us.\n",
- service->url->host);
- return TRUE;
- }
-
- if (service->url->authmech) {
- if (!g_hash_table_lookup (store->authtypes, service->url->authmech)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("IMAP server %s does not support requested "
- "authentication type %s"),
- service->url->host,
- service->url->authmech);
- return FALSE;
- }
-
- authtype = camel_sasl_authtype (service->url->authmech);
- if (!authtype) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("No support for authentication type %s"),
- service->url->authmech);
- return FALSE;
- }
-
- if (!authtype->need_password) {
- authenticated = try_auth (store, authtype->authproto, ex);
- if (!authenticated)
- return FALSE;
- }
- }
-
- while (!authenticated) {
- if (errbuf) {
- /* We need to un-cache the password before prompting again */
- camel_session_forget_password (session, service, "password", ex);
- g_free (service->url->passwd);
- service->url->passwd = NULL;
- }
-
- if (!service->url->passwd) {
- char *prompt;
-
- prompt = g_strdup_printf (_("%sPlease enter the IMAP "
- "password for %s@%s"),
- errbuf ? errbuf : "",
- service->url->user,
- service->url->host);
- service->url->passwd =
- camel_session_get_password (session, prompt, FALSE, TRUE,
- service, "password", ex);
- g_free (prompt);
- g_free (errbuf);
- errbuf = NULL;
-
- if (!service->url->passwd) {
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("You didn't enter a password."));
- return FALSE;
- }
- }
-
- if (!store->connected) {
- /* Some servers (eg, courier) will disconnect on
- * a bad password. So reconnect here.
- */
- if (!connect_to_server_wrapper (service, ex))
- return FALSE;
- }
-
- if (authtype)
- authenticated = try_auth (store, authtype->authproto, ex);
- else {
- response = camel_imap_command (store, NULL, ex,
- "LOGIN %S %S",
- service->url->user,
- service->url->passwd);
- if (response) {
- camel_imap_response_free (store, response);
- authenticated = TRUE;
- }
- }
- if (!authenticated) {
- if (camel_exception_get_id(ex) == CAMEL_EXCEPTION_USER_CANCEL)
- return FALSE;
-
- errbuf = g_strdup_printf (_("Unable to authenticate "
- "to IMAP server.\n%s\n\n"),
- camel_exception_get_description (ex));
- camel_exception_clear (ex);
- }
- }
-
- return TRUE;
-}
-
-static gboolean
-can_work_offline (CamelDiscoStore *disco_store)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (disco_store);
-
- return camel_store_summary_count((CamelStoreSummary *)store->summary) != 0;
-}
-
-static gboolean
-imap_connect_online (CamelService *service, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (service);
- CamelImapResponse *response;
- /*struct _namespaces *namespaces;*/
- char *result, *name, *path;
- int i;
- size_t len;
- CamelImapStoreNamespace *ns;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- if (!connect_to_server_wrapper (service, ex) ||
- !imap_auth_loop (service, ex)) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- camel_service_disconnect (service, TRUE, NULL);
- return FALSE;
- }
-
- /* Get namespace and hierarchy separator */
- if ((store->capabilities & IMAP_CAPABILITY_NAMESPACE) &&
- !(store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE)) {
- response = camel_imap_command (store, NULL, ex, "NAMESPACE");
- if (!response)
- goto done;
-
- result = camel_imap_response_extract (store, response, "NAMESPACE", ex);
- if (!result)
- goto done;
-
-#if 0
- /* new code... */
- namespaces = imap_parse_namespace_response (result);
- imap_namespaces_destroy (namespaces);
- /* end new code */
-#endif
-
- name = camel_strstrcase (result, "NAMESPACE ((");
- if (name) {
- char *sep;
-
- name += 12;
- store->namespace = imap_parse_string ((const char **) &name, &len);
- if (name && *name++ == ' ') {
- sep = imap_parse_string ((const char **) &name, &len);
- if (sep) {
- store->dir_sep = *sep;
- ((CamelStore *)store)->dir_sep = store->dir_sep;
- g_free (sep);
- }
- }
- }
- g_free (result);
- }
-
- if (!store->namespace)
- store->namespace = g_strdup ("");
-
- if (!store->dir_sep) {
- if (store->server_level >= IMAP_LEVEL_IMAP4REV1) {
- /* This idiom means "tell me the hierarchy separator
- * for the given path, even if that path doesn't exist.
- */
- response = camel_imap_command (store, NULL, ex,
- "LIST %S \"\"",
- store->namespace);
- } else {
- /* Plain IMAP4 doesn't have that idiom, so we fall back
- * to "tell me about this folder", which will fail if
- * the folder doesn't exist (eg, if namespace is "").
- */
- response = camel_imap_command (store, NULL, ex,
- "LIST \"\" %S",
- store->namespace);
- }
- if (!response)
- goto done;
-
- result = camel_imap_response_extract (store, response, "LIST", NULL);
- if (result) {
- imap_parse_list_response (store, result, NULL, &store->dir_sep, NULL);
- g_free (result);
- }
- if (!store->dir_sep) {
- store->dir_sep = '/'; /* Guess */
- ((CamelStore *)store)->dir_sep = store->dir_sep;
- }
- }
-
- /* canonicalize the namespace to end with dir_sep */
- len = strlen (store->namespace);
- if (len && store->namespace[len - 1] != store->dir_sep) {
- gchar *tmp;
-
- tmp = g_strdup_printf ("%s%c", store->namespace, store->dir_sep);
- g_free (store->namespace);
- store->namespace = tmp;
- }
-
- ns = camel_imap_store_summary_namespace_new(store->summary, store->namespace, store->dir_sep);
- camel_imap_store_summary_namespace_set(store->summary, ns);
-
- if (CAMEL_STORE (store)->flags & CAMEL_STORE_SUBSCRIPTIONS) {
- gboolean haveinbox = FALSE;
- GPtrArray *folders;
- char *pattern;
-
- /* this pre-fills the summary, and checks that lsub is useful */
- folders = g_ptr_array_new ();
- pattern = g_strdup_printf ("%s*", store->namespace);
- get_folders_online (store, pattern, folders, TRUE, ex);
- g_free (pattern);
-
- for (i = 0; i < folders->len; i++) {
- CamelFolderInfo *fi = folders->pdata[i];
-
- haveinbox = haveinbox || !strcasecmp (fi->full_name, "INBOX");
-
- if (fi->flags & (CAMEL_IMAP_FOLDER_MARKED | CAMEL_IMAP_FOLDER_UNMARKED))
- store->capabilities |= IMAP_CAPABILITY_useful_lsub;
- camel_folder_info_free (fi);
- }
-
- /* if the namespace is under INBOX, check INBOX explicitly */
- if (!strncasecmp (store->namespace, "INBOX", 5) && !camel_exception_is_set (ex)) {
- gboolean just_subscribed = FALSE;
- gboolean need_subscribe = FALSE;
-
- recheck:
- g_ptr_array_set_size (folders, 0);
- get_folders_online (store, "INBOX", folders, TRUE, ex);
-
- for (i = 0; i < folders->len; i++) {
- CamelFolderInfo *fi = folders->pdata[i];
-
- /* this should always be TRUE if folders->len > 0 */
- if (!strcasecmp (fi->full_name, "INBOX")) {
- haveinbox = TRUE;
-
- /* if INBOX is marked as \NoSelect then it is probably
- because it has not been subscribed to */
- if (!need_subscribe)
- need_subscribe = fi->flags & CAMEL_FOLDER_NOSELECT;
- }
-
- camel_folder_info_free (fi);
- }
-
- need_subscribe = !haveinbox || need_subscribe;
- if (need_subscribe && !just_subscribed && !camel_exception_is_set (ex)) {
- /* in order to avoid user complaints, force a subscription to INBOX */
- response = camel_imap_command (store, NULL, ex, "SUBSCRIBE INBOX");
- if (response != NULL) {
- /* force a re-check which will pre-fill the summary and
- also get any folder flags present on the INBOX */
- camel_imap_response_free (store, response);
- just_subscribed = TRUE;
- goto recheck;
- }
- }
- }
-
- g_ptr_array_free (folders, TRUE);
- }
-
- path = g_strdup_printf ("%s/journal", store->storage_path);
- disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
- g_free (path);
-
- done:
- /* save any changes we had */
- camel_store_summary_save((CamelStoreSummary *)store->summary);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- if (camel_exception_is_set (ex))
- camel_service_disconnect (service, TRUE, NULL);
- else if (camel_disco_diary_empty (disco_store->diary))
- imap_store_refresh_folders (store, ex);
-
- return !camel_exception_is_set (ex);
-}
-
-static gboolean
-imap_connect_offline (CamelService *service, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (service);
- char *path;
-
- path = g_strdup_printf ("%s/journal", store->storage_path);
- disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
- g_free (path);
- if (!disco_store->diary)
- return FALSE;
-
- imap_store_refresh_folders (store, ex);
-
- store->connected = !camel_exception_is_set (ex);
- return store->connected;
-}
-
-static gboolean
-imap_disconnect_offline (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelDiscoStore *disco = CAMEL_DISCO_STORE (service);
-
- store->connected = FALSE;
- if (store->current_folder) {
- camel_object_unref (CAMEL_OBJECT (store->current_folder));
- store->current_folder = NULL;
- }
-
- if (store->authtypes) {
- g_hash_table_foreach_remove (store->authtypes,
- free_key, NULL);
- g_hash_table_destroy (store->authtypes);
- store->authtypes = NULL;
- }
-
- if (store->namespace && !(store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE)) {
- g_free (store->namespace);
- store->namespace = NULL;
- }
-
- if (disco->diary) {
- camel_object_unref (CAMEL_OBJECT (disco->diary));
- disco->diary = NULL;
- }
-
- return TRUE;
-}
-
-static gboolean
-imap_disconnect_online (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelImapResponse *response;
-
- if (store->connected && clean) {
- response = camel_imap_command (store, NULL, NULL, "LOGOUT");
- camel_imap_response_free (store, response);
- }
-
- 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;
- }
-
- imap_disconnect_offline (service, clean, ex);
-
- return TRUE;
-}
-
-
-static gboolean
-imap_summary_is_dirty (CamelFolderSummary *summary)
-{
- CamelMessageInfo *info;
- int max, i;
-
- max = camel_folder_summary_count (summary);
- for (i = 0; i < max; i++) {
- info = camel_folder_summary_index (summary, i);
- if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-imap_noop (CamelStore *store, CamelException *ex)
-{
- CamelImapStore *imap_store = (CamelImapStore *) store;
- CamelDiscoStore *disco = (CamelDiscoStore *) store;
- CamelImapResponse *response;
- CamelFolder *current_folder;
-
- if (camel_disco_store_status (disco) != CAMEL_DISCO_STORE_ONLINE)
- return;
-
- CAMEL_SERVICE_LOCK (imap_store, connect_lock);
-
- current_folder = imap_store->current_folder;
- if (current_folder && imap_summary_is_dirty (current_folder->summary)) {
- /* let's sync the flags instead. NB: must avoid folder lock */
- ((CamelFolderClass *)((CamelObject *)current_folder)->klass)->sync(current_folder, FALSE, ex);
- } else {
- response = camel_imap_command (imap_store, NULL, ex, "NOOP");
- if (response)
- camel_imap_response_free (imap_store, response);
- }
-
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
-}
-
-static guint
-hash_folder_name (gconstpointer key)
-{
- if (strcasecmp (key, "INBOX") == 0)
- return g_str_hash ("INBOX");
- else
- return g_str_hash (key);
-}
-
-static gint
-compare_folder_name (gconstpointer a, gconstpointer b)
-{
- gconstpointer aname = a, bname = b;
-
- if (strcasecmp (a, "INBOX") == 0)
- aname = "INBOX";
- if (strcasecmp (b, "INBOX") == 0)
- bname = "INBOX";
- return g_str_equal (aname, bname);
-}
-
-static CamelFolder *
-no_such_folder (const char *name, CamelException *ex)
-{
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("No such folder %s"), name);
- return NULL;
-}
-
-static int
-get_folder_status (CamelImapStore *imap_store, const char *folder_name, const char *type)
-{
- CamelImapResponse *response;
- char *status, *p;
- int out;
-
- /* FIXME: we assume the server is STATUS-capable */
-
- response = camel_imap_command (imap_store, NULL, NULL,
- "STATUS %F (%s)",
- folder_name,
- type);
-
- if (!response) {
- CamelException ex;
-
- camel_exception_init (&ex);
- if (imap_check_folder_still_extant (imap_store, folder_name, &ex) == FALSE) {
- imap_folder_effectively_unsubscribed (imap_store, folder_name, &ex);
- imap_forget_folder (imap_store, folder_name, &ex);
- }
- camel_exception_clear (&ex);
- return -1;
- }
-
- status = camel_imap_response_extract (imap_store, response,
- "STATUS", NULL);
- if (!status)
- return -1;
-
- p = camel_strstrcase (status, type);
- if (p)
- out = strtoul (p + strlen (type), NULL, 10);
- else
- out = -1;
-
- g_free (status);
- return out;
-}
-
-static CamelFolder *
-get_folder_online (CamelStore *store, const char *folder_name,
- guint32 flags, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelImapResponse *response;
- CamelFolder *new_folder;
- char *folder_dir, *storage_path;
-
- if (!camel_imap_store_connected (imap_store, ex))
- return NULL;
-
- if (!strcasecmp (folder_name, "INBOX"))
- folder_name = "INBOX";
-
- /* Lock around the whole lot to check/create atomically */
- CAMEL_SERVICE_LOCK (imap_store, connect_lock);
- if (imap_store->current_folder) {
- camel_object_unref (CAMEL_OBJECT (imap_store->current_folder));
- imap_store->current_folder = NULL;
- }
- response = camel_imap_command (imap_store, NULL, NULL, "SELECT %F", folder_name);
- if (!response) {
- char *folder_real;
-
- if (!flags & CAMEL_STORE_FOLDER_CREATE) {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- return no_such_folder (folder_name, ex);
- }
-
- folder_real = camel_imap_store_summary_path_to_full(imap_store->summary, folder_name, store->dir_sep);
-
- response = camel_imap_command (imap_store, NULL, ex, "CREATE %S", folder_real);
-
- if (response) {
- camel_imap_store_summary_add_from_full(imap_store->summary, folder_real, store->dir_sep);
-
- camel_imap_response_free (imap_store, response);
-
- response = camel_imap_command (imap_store, NULL, NULL, "SELECT %F", folder_name);
- }
- g_free(folder_real);
- if (!response) {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- return NULL;
- }
- }
-
- storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- folder_dir = e_path_to_physical (storage_path, folder_name);
- g_free(storage_path);
- new_folder = camel_imap_folder_new (store, folder_name, folder_dir, ex);
- g_free (folder_dir);
- if (new_folder) {
- CamelException local_ex;
-
- imap_store->current_folder = new_folder;
- camel_object_ref (CAMEL_OBJECT (new_folder));
- camel_exception_init (&local_ex);
- camel_imap_folder_selected (new_folder, response, &local_ex);
-
- if (camel_exception_is_set (&local_ex)) {
- camel_exception_xfer (ex, &local_ex);
- camel_object_unref (CAMEL_OBJECT (imap_store->current_folder));
- imap_store->current_folder = NULL;
- camel_object_unref (CAMEL_OBJECT (new_folder));
- new_folder = NULL;
- }
- }
- camel_imap_response_free_without_processing (imap_store, response);
-
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
-
- return new_folder;
-}
-
-static CamelFolder *
-get_folder_offline (CamelStore *store, const char *folder_name,
- guint32 flags, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelFolder *new_folder;
- char *folder_dir, *storage_path;
-
- if (!imap_store->connected &&
- !camel_service_connect (CAMEL_SERVICE (store), ex))
- return NULL;
-
- if (!strcasecmp (folder_name, "INBOX"))
- folder_name = "INBOX";
-
- storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- folder_dir = e_path_to_physical (storage_path, folder_name);
- g_free(storage_path);
- if (!folder_dir || access (folder_dir, F_OK) != 0) {
- g_free (folder_dir);
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("No such folder %s"), folder_name);
- return NULL;
- }
-
- new_folder = camel_imap_folder_new (store, folder_name, folder_dir, ex);
- g_free (folder_dir);
-
- return new_folder;
-}
-
-static void
-delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelImapResponse *response;
-
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
- return;
-
- /* make sure this folder isn't currently SELECTed */
- response = camel_imap_command (imap_store, NULL, ex, "SELECT INBOX");
- if (response) {
- camel_imap_response_free_without_processing (imap_store, response);
-
- CAMEL_SERVICE_LOCK (imap_store, connect_lock);
-
- if (imap_store->current_folder)
- camel_object_unref (CAMEL_OBJECT (imap_store->current_folder));
- /* no need to actually create a CamelFolder for INBOX */
- imap_store->current_folder = NULL;
-
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- } else
- return;
-
- response = camel_imap_command (imap_store, NULL, ex, "DELETE %F",
- folder_name);
-
- if (response) {
- camel_imap_response_free (imap_store, response);
- imap_forget_folder (imap_store, folder_name, ex);
- }
-}
-
-static void
-manage_subscriptions (CamelStore *store, const char *old_name, gboolean subscribe)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelStoreInfo *si;
- int olen = strlen(old_name);
- const char *path;
- int i, count;
-
- count = camel_store_summary_count((CamelStoreSummary *)imap_store->summary);
- for (i=0;i<count;i++) {
- si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i);
- if (si) {
- path = camel_store_info_path(imap_store->summary, si);
- if (strncmp(path, old_name, olen) == 0) {
- if (subscribe)
- subscribe_folder(store, path, NULL);
- else
- unsubscribe_folder(store, path, NULL);
- }
- camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
- }
- }
-}
-
-static void
-rename_folder_info (CamelImapStore *imap_store, const char *old_name, const char *new_name)
-{
- int i, count;
- CamelStoreInfo *si;
- int olen = strlen(old_name);
- const char *path;
- char *npath, *nfull;
-
- count = camel_store_summary_count((CamelStoreSummary *)imap_store->summary);
- for (i=0;i<count;i++) {
- si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i);
- if (si == NULL)
- continue;
- path = camel_store_info_path(imap_store->summary, si);
- if (strncmp(path, old_name, olen) == 0) {
- if (strlen(path) > olen)
- npath = g_strdup_printf("%s/%s", new_name, path+olen+1);
- else
- npath = g_strdup(new_name);
- nfull = camel_imap_store_summary_path_to_full(imap_store->summary, npath, imap_store->dir_sep);
-
- /* workaround for broken server (courier uses '.') that doesn't rename
- subordinate folders as required by rfc 2060 */
- if (imap_store->dir_sep == '.') {
- CamelImapResponse *response;
-
- response = camel_imap_command (imap_store, NULL, NULL, "RENAME %F %S", path, nfull);
- if (response)
- camel_imap_response_free (imap_store, response);
- }
-
- camel_store_info_set_string((CamelStoreSummary *)imap_store->summary, si, CAMEL_STORE_INFO_PATH, npath);
- camel_store_info_set_string((CamelStoreSummary *)imap_store->summary, si, CAMEL_IMAP_STORE_INFO_FULL_NAME, nfull);
-
- camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
- g_free(nfull);
- g_free(npath);
- }
- camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
- }
-}
-
-static void
-rename_folder (CamelStore *store, const char *old_name, const char *new_name_in, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelImapResponse *response;
- char *oldpath, *newpath, *storage_path, *new_name;
-
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
- return;
-
- /* make sure this folder isn't currently SELECTed - it's
- actually possible to rename INBOX but if you do another
- INBOX will immediately be created by the server */
- response = camel_imap_command (imap_store, NULL, ex, "SELECT INBOX");
- if (response) {
- camel_imap_response_free_without_processing (imap_store, response);
-
- CAMEL_SERVICE_LOCK (imap_store, connect_lock);
-
- if (imap_store->current_folder)
- camel_object_unref (CAMEL_OBJECT (imap_store->current_folder));
- /* no need to actually create a CamelFolder for INBOX */
- imap_store->current_folder = NULL;
-
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- } else
- return;
-
- imap_store->renaming = TRUE;
-
- if (store->flags & CAMEL_STORE_SUBSCRIPTIONS)
- manage_subscriptions(store, old_name, FALSE);
-
- new_name = camel_imap_store_summary_path_to_full(imap_store->summary, new_name_in, store->dir_sep);
- response = camel_imap_command (imap_store, NULL, ex, "RENAME %F %S", old_name, new_name);
-
- if (!response) {
- if (store->flags & CAMEL_STORE_SUBSCRIPTIONS)
- manage_subscriptions(store, old_name, TRUE);
- g_free(new_name);
- imap_store->renaming = FALSE;
- return;
- }
-
- camel_imap_response_free (imap_store, response);
-
- /* rename summary, and handle broken server */
- rename_folder_info(imap_store, old_name, new_name_in);
-
- if (store->flags & CAMEL_STORE_SUBSCRIPTIONS)
- manage_subscriptions(store, new_name_in, TRUE);
-
- storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- oldpath = e_path_to_physical (storage_path, old_name);
- newpath = e_path_to_physical (storage_path, new_name_in);
- g_free(storage_path);
-
- /* So do we care if this didn't work? Its just a cache? */
- if (rename (oldpath, newpath) == -1) {
- g_warning ("Could not rename message cache '%s' to '%s': %s: cache reset",
- oldpath, newpath, strerror (errno));
- }
-
- g_free (oldpath);
- g_free (newpath);
- g_free(new_name);
-
- imap_store->renaming = FALSE;
-}
-
-static CamelFolderInfo *
-create_folder (CamelStore *store, const char *parent_name,
- const char *folder_name, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- char *full_name, *resp, *thisone, *parent_real, *real_name;
- CamelImapResponse *response;
- CamelException internal_ex;
- CamelFolderInfo *root = NULL;
- gboolean need_convert;
- int i = 0, flags;
-
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
- return NULL;
- if (!parent_name)
- parent_name = "";
-
- if (strchr (folder_name, imap_store->dir_sep)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_PATH,
- _("The folder name \"%s\" is invalid because "
- "it containes the character \"%c\""),
- folder_name, imap_store->dir_sep);
- return NULL;
- }
-
- /* check if the parent allows inferiors */
-
- /* FIXME: use storesummary directly */
- parent_real = camel_imap_store_summary_full_from_path(imap_store->summary, parent_name);
- if (parent_real == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_STATE,
- _("Unknown parent folder: %s"), parent_name);
- return NULL;
- }
-
- need_convert = FALSE;
- response = camel_imap_command (imap_store, NULL, ex, "LIST \"\" %S",
- parent_real);
- if (!response) /* whoa, this is bad */ {
- g_free(parent_real);
- return NULL;
- }
-
- /* FIXME: does not handle unexpected circumstances very well */
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i];
-
- if (!imap_parse_list_response (imap_store, resp, &flags, NULL, &thisone))
- continue;
-
- if (strcmp (thisone, parent_name) == 0) {
- if (flags & CAMEL_FOLDER_NOINFERIORS)
- need_convert = TRUE;
- break;
- }
- }
-
- camel_imap_response_free (imap_store, response);
-
- camel_exception_init (&internal_ex);
-
- /* if not, check if we can delete it and recreate it */
- if (need_convert) {
- char *name;
-
- if (get_folder_status (imap_store, parent_name, "MESSAGES")) {
- camel_exception_set (ex, CAMEL_EXCEPTION_FOLDER_INVALID_STATE,
- _("The parent folder is not allowed to contain subfolders"));
- g_free(parent_real);
- return NULL;
- }
-
- /* delete the old parent and recreate it */
- delete_folder (store, parent_name, &internal_ex);
- if (camel_exception_is_set (&internal_ex)) {
- camel_exception_xfer (ex, &internal_ex);
- return NULL;
- }
-
- /* add the dirsep to the end of parent_name */
- name = g_strdup_printf ("%s%c", parent_real, imap_store->dir_sep);
- response = camel_imap_command (imap_store, NULL, ex, "CREATE %S",
- name);
- g_free (name);
-
- if (!response) {
- g_free(parent_real);
- return NULL;
- } else
- camel_imap_response_free (imap_store, response);
-
- root = imap_build_folder_info(imap_store, parent_name);
- }
-
- /* ok now we can create the folder */
- real_name = camel_imap_store_summary_path_to_full(imap_store->summary, folder_name, store->dir_sep);
- full_name = imap_concat (imap_store, parent_real, real_name);
- g_free(real_name);
- response = camel_imap_command (imap_store, NULL, ex, "CREATE %S", full_name);
-
- if (response) {
- CamelImapStoreInfo *si;
- CamelFolderInfo *fi;
-
- camel_imap_response_free (imap_store, response);
-
- si = camel_imap_store_summary_add_from_full(imap_store->summary, full_name, store->dir_sep);
- camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
- fi = imap_build_folder_info(imap_store, camel_store_info_path(imap_store->summary, si));
- if (root) {
- root->child = fi;
- fi->parent = root;
- } else {
- root = fi;
- }
- camel_object_trigger_event (CAMEL_OBJECT (store), "folder_created", root);
- } else if (root) {
- /* need to re-recreate the folder we just deleted */
- camel_object_trigger_event (CAMEL_OBJECT (store), "folder_created", root);
- camel_folder_info_free(root);
- root = NULL;
- }
-
- g_free (full_name);
- g_free(parent_real);
-
- return root;
-}
-
-static CamelFolderInfo *
-parse_list_response_as_folder_info (CamelImapStore *imap_store,
- const char *response)
-{
- CamelFolderInfo *fi;
- int flags;
- char sep, *dir;
- CamelURL *url;
- CamelImapStoreInfo *si;
- guint32 newflags;
-
- if (!imap_parse_list_response (imap_store, response, &flags, &sep, &dir))
- return NULL;
-
- /* FIXME: should use imap_build_folder_info, note the differences with param setting tho */
-
- si = camel_imap_store_summary_add_from_full(imap_store->summary, dir, sep?sep:'/');
- newflags = (si->info.flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) | (flags & ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED);
- if (si->info.flags != newflags) {
- si->info.flags = newflags;
- camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
- }
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->flags = flags;
- fi->name = g_strdup(camel_store_info_name(imap_store->summary, si));
- fi->path = g_strdup_printf("/%s", camel_store_info_path(imap_store->summary, si));
- fi->full_name = g_strdup(fi->path+1);
-
- url = camel_url_new (imap_store->base_url, NULL);
- camel_url_set_path(url, fi->path);
-
- if (flags & CAMEL_FOLDER_NOSELECT || fi->name[0] == 0)
- camel_url_set_param (url, "noselect", "yes");
- fi->url = camel_url_to_string (url, 0);
- camel_url_free (url);
-
- /* FIXME: redundant */
- if (flags & CAMEL_IMAP_FOLDER_UNMARKED)
- fi->unread_message_count = -1;
-
- return fi;
-}
-
-/* this is used when lsub doesn't provide very useful information */
-static GPtrArray *
-get_subscribed_folders (CamelImapStore *imap_store, const char *top, CamelException *ex)
-{
- GPtrArray *names, *folders;
- int i, toplen = strlen (top);
- CamelStoreInfo *si;
- CamelImapResponse *response;
- CamelFolderInfo *fi;
- char *result;
- int haveinbox = FALSE;
-
- folders = g_ptr_array_new ();
- names = g_ptr_array_new ();
- for (i=0;(si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i));i++) {
- if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
- g_ptr_array_add(names, (char *)camel_imap_store_info_full_name(imap_store->summary, si));
- haveinbox = haveinbox || strcasecmp(camel_imap_store_info_full_name(imap_store->summary, si), "INBOX") == 0;
- }
- camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
- }
-
- if (!haveinbox)
- g_ptr_array_add (names, "INBOX");
-
- for (i = 0; i < names->len; i++) {
- response = camel_imap_command (imap_store, NULL, ex,
- "LIST \"\" %S",
- names->pdata[i]);
- if (!response)
- break;
-
- result = camel_imap_response_extract (imap_store, response, "LIST", NULL);
- if (!result) {
- camel_store_summary_remove_path((CamelStoreSummary *)imap_store->summary, names->pdata[i]);
- g_ptr_array_remove_index_fast (names, i);
- i--;
- continue;
- }
-
- fi = parse_list_response_as_folder_info (imap_store, result);
- if (!fi)
- continue;
-
- if (strncmp (top, fi->full_name, toplen) != 0) {
- camel_folder_info_free (fi);
- continue;
- }
-
- g_ptr_array_add (folders, fi);
- }
-
- g_ptr_array_free (names, TRUE);
-
- return folders;
-}
-
-static int imap_match_pattern(char dir_sep, const char *pattern, const char *name)
-{
- char p, n;
-
- p = *pattern++;
- n = *name++;
- while (n && p) {
- if (n == p) {
- p = *pattern++;
- n = *name++;
- } else if (p == '%') {
- if (n != dir_sep) {
- n = *name++;
- } else {
- p = *pattern++;
- }
- } else if (p == '*') {
- return TRUE;
- } else
- return FALSE;
- }
-
- return n == 0 && (p == '%' || p == 0);
-}
-
-static void
-get_folders_online (CamelImapStore *imap_store, const char *pattern,
- GPtrArray *folders, gboolean lsub, CamelException *ex)
-{
- CamelImapResponse *response;
- CamelFolderInfo *fi;
- char *list;
- int i, count;
- GHashTable *present;
- CamelStoreInfo *si;
-
- response = camel_imap_command (imap_store, NULL, ex,
- "%s \"\" %S", lsub ? "LSUB" : "LIST",
- pattern);
- if (!response)
- return;
-
- present = g_hash_table_new(g_str_hash, g_str_equal);
- for (i = 0; i < response->untagged->len; i++) {
- list = response->untagged->pdata[i];
- fi = parse_list_response_as_folder_info (imap_store, list);
- if (fi) {
- g_ptr_array_add(folders, fi);
- g_hash_table_insert(present, fi->full_name, fi);
- }
- }
- camel_imap_response_free (imap_store, response);
-
- /* update our summary to match the server */
- count = camel_store_summary_count((CamelStoreSummary *)imap_store->summary);
- for (i=0;i<count;i++) {
- si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i);
- if (si == NULL)
- continue;
-
- if (imap_match_pattern(((CamelStore *)imap_store)->dir_sep, pattern, camel_imap_store_info_full_name(imap_store->summary, si))) {
- if (g_hash_table_lookup(present, camel_store_info_path(imap_store->summary, si)) != NULL) {
- if (lsub && (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
- si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
- }
- } else {
- if (lsub) {
- if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
- si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
- }
- } else {
- camel_store_summary_remove((CamelStoreSummary *)imap_store->summary, si);
- count--;
- i--;
- }
- }
- }
- camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
- }
- g_hash_table_destroy(present);
-}
-
-#if 0
-static void
-dumpfi(CamelFolderInfo *fi)
-{
- int depth;
- CamelFolderInfo *n = fi;
-
- if (fi == NULL)
- return;
-
- depth = 0;
- while (n->parent) {
- depth++;
- n = n->parent;
- }
-
- while (fi) {
- printf("%-40s %-30s %*s\n", fi->path, fi->full_name, depth*2+strlen(fi->url), fi->url);
- if (fi->child)
- dumpfi(fi->child);
- fi = fi->sibling;
- }
-}
-#endif
-
-static void
-get_folder_counts(CamelImapStore *imap_store, CamelFolderInfo *fi, CamelException *ex)
-{
- GSList *q;
- CamelFolder *folder;
-
- /* non-recursive breath first search */
-
- q = g_slist_append(NULL, fi);
-
- while (q) {
- fi = q->data;
- q = g_slist_remove_link(q, q);
-
- while (fi) {
- /* ignore noselect folders, and check only inbox if we only check inbox */
- if ((fi->flags & CAMEL_FOLDER_NOSELECT) == 0
- && ( (imap_store->parameters & IMAP_PARAM_CHECK_ALL)
- || strcasecmp(fi->full_name, "inbox") == 0) ) {
-
- CAMEL_SERVICE_LOCK (imap_store, connect_lock);
- /* For the current folder, poke it to check for new
- * messages and then report that number, rather than
- * doing a STATUS command.
- */
- if (imap_store->current_folder && strcmp(imap_store->current_folder->full_name, fi->full_name) == 0) {
- /* we bypass the folder locking otherwise we can deadlock. we use the command lock for
- any operations anyway so this is 'safe'. See comment above imap_store_refresh_folders() for info */
- CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(imap_store->current_folder))->refresh_info(imap_store->current_folder, ex);
- fi->unread_message_count = camel_folder_get_unread_message_count (imap_store->current_folder);
- } else {
- fi->unread_message_count = get_folder_status (imap_store, fi->full_name, "UNSEEN");
- /* if we have this folder open, and the unread count has changed, update */
- folder = camel_object_bag_get(CAMEL_STORE(imap_store)->folders, fi->full_name);
- if (folder && fi->unread_message_count != camel_folder_get_unread_message_count(folder)) {
- CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->refresh_info(folder, ex);
- fi->unread_message_count = camel_folder_get_unread_message_count(folder);
- }
- if (folder)
- camel_object_unref(folder);
-
- }
-
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- } else {
- /* since its cheap, get it if they're open */
- folder = camel_object_bag_get(CAMEL_STORE(imap_store)->folders, fi->full_name);
- if (folder) {
- fi->unread_message_count = camel_folder_get_unread_message_count(folder);
- camel_object_unref(folder);
- } else
- fi->unread_message_count = -1;
- }
-
- if (fi->child)
- q = g_slist_append(q, fi->child);
- fi = fi->sibling;
- }
- }
-}
-
-/* imap needs to treat inbox case insensitive */
-/* we'll assume the names are normalised already */
-static guint folder_hash(const void *ap)
-{
- const char *a = ap;
-
- if (strcasecmp(a, "INBOX") == 0)
- a = "INBOX";
-
- return g_str_hash(a);
-}
-
-static int folder_eq(const void *ap, const void *bp)
-{
- const char *a = ap;
- const char *b = bp;
-
- if (strcasecmp(a, "INBOX") == 0)
- a = "INBOX";
- if (strcasecmp(b, "INBOX") == 0)
- b = "INBOX";
-
- return g_str_equal(a, b);
-}
-
-static GPtrArray *
-get_folders(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- GSList *p = NULL;
- GHashTable *infos;
- int i;
- GPtrArray *folders, *folders_out;
- CamelFolderInfo *fi;
- char *name;
- int depth = 0;
- int haveinbox = 0;
- static int imap_max_depth = 0;
-
- if (!camel_imap_store_connected (imap_store, ex))
- return NULL;
-
- /* allow megalomaniacs to override the max of 10 */
- if (imap_max_depth == 0) {
- name = getenv("CAMEL_IMAP_MAX_DEPTH");
- if (name) {
- imap_max_depth = atoi (name);
- imap_max_depth = MIN (MAX (imap_max_depth, 0), 2);
- } else
- imap_max_depth = 10;
- }
-
- infos = g_hash_table_new(folder_hash, folder_eq);
-
- /* get starting point & strip trailing '/' */
- if (top[0] == 0) {
- if (imap_store->namespace) {
- top = imap_store->namespace;
- i = strlen(top)-1;
- name = g_malloc(i+2);
- strcpy(name, top);
- while (i>0 && name[i] == store->dir_sep)
- name[i--] = 0;
- } else
- name = g_strdup("");
- } else {
- name = camel_imap_store_summary_full_from_path(imap_store->summary, top);
- if (name == NULL)
- name = camel_imap_store_summary_path_to_full(imap_store->summary, top, store->dir_sep);
- }
-
- d(printf("\n\nList '%s' %s\n", name, flags&CAMEL_STORE_FOLDER_INFO_RECURSIVE?"RECURSIVE":"NON-RECURSIVE"));
-
- folders_out = g_ptr_array_new();
- folders = g_ptr_array_new();
-
- /* first get working list of names */
- get_folders_online (imap_store, name[0]?name:"%", folders, flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, ex);
- if (camel_exception_is_set(ex))
- goto fail;
- for (i=0; i<folders->len && !haveinbox; i++) {
- fi = folders->pdata[i];
- haveinbox = (strcasecmp(fi->full_name, "INBOX")) == 0;
- }
-
- if (!haveinbox && top == imap_store->namespace) {
- get_folders_online (imap_store, "INBOX", folders,
- flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, ex);
-
- if (camel_exception_is_set (ex))
- goto fail;
- }
-
- for (i=0; i<folders->len; i++)
- p = g_slist_prepend(p, folders->pdata[i]);
-
- g_ptr_array_set_size(folders, 0);
-
- /* p is a reversed list of pending folders for the next level, q is the list of folders for this */
- while (p) {
- GSList *q = g_slist_reverse(p);
-
- p = NULL;
- while (q) {
- fi = q->data;
-
- q = g_slist_remove_link(q, q);
- g_ptr_array_add(folders_out, fi);
-
- d(printf("Checking folder '%s'\n", fi->full_name));
-
- /* First if we're not recursive mode on the top level, and we know it has or doesn't
- or can't have children, no need to go further - a bit ugly */
- if ( top == imap_store->namespace
- && (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0
- && (fi->flags & (CAMEL_FOLDER_CHILDREN|CAMEL_IMAP_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS)) != 0) {
- /* do nothing */
- }
- /* Otherwise, if this has (or might have) children, scan it */
- else if ( (fi->flags & (CAMEL_IMAP_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS)) == 0
- || (fi->flags & CAMEL_FOLDER_CHILDREN) != 0) {
- char *n, *real;
-
- real = camel_imap_store_summary_full_from_path(imap_store->summary, fi->full_name);
- n = imap_concat(imap_store, real?real:fi->full_name, "%");
- get_folders_online(imap_store, n, folders, flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, ex);
- g_free(n);
- g_free(real);
-
- if (folders->len > 0)
- fi->flags |= CAMEL_FOLDER_CHILDREN;
-
- for (i=0;i<folders->len;i++) {
- fi = folders->pdata[i];
- if (g_hash_table_lookup(infos, fi->full_name) == NULL) {
- g_hash_table_insert(infos, fi->full_name, fi);
- if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) && depth<imap_max_depth)
- p = g_slist_prepend(p, fi);
- else
- g_ptr_array_add(folders_out, fi);
- } else {
- camel_folder_info_free(fi);
- }
- }
- g_ptr_array_set_size(folders, 0);
- }
- }
- depth++;
- }
-
- g_ptr_array_free(folders, TRUE);
- g_hash_table_destroy(infos);
- g_free(name);
-
- return folders_out;
-fail:
- g_ptr_array_free(folders, TRUE);
- g_ptr_array_free(folders_out, TRUE);
- g_hash_table_destroy(infos);
- g_free(name);
-
- return NULL;
-}
-
-static CamelFolderInfo *
-get_folder_info_online (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelFolderInfo *tree;
- GPtrArray *folders;
-
- if (top == NULL)
- top = "";
-
- if ((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
- && !(imap_store->capabilities & IMAP_CAPABILITY_useful_lsub)
- && (imap_store->parameters & IMAP_PARAM_CHECK_ALL))
- folders = get_subscribed_folders(imap_store, top, ex);
- else
- folders = get_folders(store, top, flags, ex);
-
- if (folders == NULL)
- return NULL;
-
- tree = camel_folder_info_build(folders, top, '/', TRUE);
- g_ptr_array_free(folders, TRUE);
-
- if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST))
- get_folder_counts(imap_store, tree, ex);
-
- d(dumpfi(tree));
- camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
-
- return tree;
-}
-
-static gboolean
-get_one_folder_offline (const char *physical_path, const char *path, gpointer data)
-{
- GPtrArray *folders = data;
- CamelImapStore *imap_store = folders->pdata[0];
- CamelFolderInfo *fi;
- CamelStoreInfo *si;
-
- if (*path != '/')
- return TRUE;
-
- /* folder_info_build will insert parent nodes as necessary and mark
- * them as noselect, which is information we actually don't have at
- * the moment. So let it do the right thing by bailing out if it's
- * not a folder we're explicitly interested in.
- */
-
- si = camel_store_summary_path((CamelStoreSummary *)imap_store->summary, path+1);
- if (si) {
- if ((((CamelStore *)imap_store)->flags & CAMEL_STORE_SUBSCRIPTIONS) == 0
- || (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)) {
- fi = imap_build_folder_info(imap_store, path+1);
- fi->flags = si->flags;
- if (si->flags & CAMEL_FOLDER_NOSELECT) {
- CamelURL *url = camel_url_new(fi->url, NULL);
-
- camel_url_set_param (url, "noselect", "yes");
- g_free(fi->url);
- fi->url = camel_url_to_string (url, 0);
- camel_url_free (url);
- }
- g_ptr_array_add (folders, fi);
- }
- camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
- }
-
- return TRUE;
-}
-
-static CamelFolderInfo *
-get_folder_info_offline (CamelStore *store, const char *top,
- guint32 flags, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelFolderInfo *fi;
- GPtrArray *folders;
- char *storage_path;
-
- if (!imap_store->connected &&
- !camel_service_connect (CAMEL_SERVICE (store), ex))
- return NULL;
-
- if ((store->flags & CAMEL_STORE_SUBSCRIPTIONS) &&
- !(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) {
- camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex);
- return NULL;
- }
-
- /* FIXME: obey other flags */
-
- folders = g_ptr_array_new ();
-
- /* A kludge to avoid having to pass a struct to the callback */
- g_ptr_array_add (folders, imap_store);
- storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- if (!e_path_find_folders (storage_path, get_one_folder_offline, folders)) {
- camel_disco_store_check_online (CAMEL_DISCO_STORE (imap_store), ex);
- fi = NULL;
- } else {
- g_ptr_array_remove_index_fast (folders, 0);
- fi = camel_folder_info_build (folders, "", '/', TRUE);
- }
- g_free(storage_path);
-
- g_ptr_array_free (folders, TRUE);
- return fi;
-}
-
-static gboolean
-folder_subscribed (CamelStore *store, const char *folder_name)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelStoreInfo *si;
- int truth = FALSE;
-
- si = camel_store_summary_path((CamelStoreSummary *)imap_store->summary, folder_name);
- if (si) {
- truth = (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0;
- camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
- }
-
- return truth;
-}
-
-/* Note: folder_name must match a folder as listed with get_folder_info() -> full_name */
-static void
-subscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelImapResponse *response;
- CamelFolderInfo *fi;
- CamelStoreInfo *si;
-
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
- return;
- if (!camel_imap_store_connected (imap_store, ex))
- return;
-
- response = camel_imap_command (imap_store, NULL, ex,
- "SUBSCRIBE %F", folder_name);
- if (!response)
- return;
- camel_imap_response_free (imap_store, response);
-
- si = camel_store_summary_path((CamelStoreSummary *)imap_store->summary, folder_name);
- if (si) {
- if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
- si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
- camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
- }
- camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
- }
-
- if (imap_store->renaming) {
- /* we don't need to emit a "folder_subscribed" signal
- if we are in the process of renaming folders, so we
- are done here... */
- return;
- }
-
- fi = imap_build_folder_info(imap_store, folder_name);
- camel_object_trigger_event (CAMEL_OBJECT (store), "folder_subscribed", fi);
- camel_folder_info_free (fi);
-}
-
-static void
-unsubscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelImapResponse *response;
-
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
- return;
- if (!camel_imap_store_connected (imap_store, ex))
- return;
-
- response = camel_imap_command (imap_store, NULL, ex,
- "UNSUBSCRIBE %F", folder_name);
- if (!response)
- return;
- camel_imap_response_free (imap_store, response);
-
- imap_folder_effectively_unsubscribed (imap_store, folder_name, ex);
-}
-
-#if 0
-static gboolean
-folder_flags_have_changed (CamelFolder *folder)
-{
- CamelMessageInfo *info;
- int i, max;
-
- max = camel_folder_summary_count (folder->summary);
- for (i = 0; i < max; i++) {
- info = camel_folder_summary_index (folder->summary, i);
- if (!info)
- continue;
- if (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-#endif
-
-
-gboolean
-camel_imap_store_connected (CamelImapStore *store, CamelException *ex)
-{
- if (store->istream == NULL || !store->connected)
- return camel_service_connect (CAMEL_SERVICE (store), ex);
- return TRUE;
-}
-
-
-/* FIXME: please god, when will the hurting stop? Thus function is so
- fucking broken it's not even funny. */
-ssize_t
-camel_imap_store_readline (CamelImapStore *store, char **dest, CamelException *ex)
-{
- CamelStreamBuffer *stream;
- char linebuf[1024];
- GByteArray *ba;
- ssize_t nread;
-
- g_return_val_if_fail (CAMEL_IS_IMAP_STORE (store), -1);
- g_return_val_if_fail (dest, -1);
-
- *dest = NULL;
-
- /* Check for connectedness. Failed (or cancelled) operations will
- * close the connection. We can't expect a read to have any
- * meaning if we reconnect, so always set an exception.
- */
-
- if (!camel_imap_store_connected (store, ex)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_NOT_CONNECTED,
- g_strerror (errno));
- return -1;
- }
-
- stream = CAMEL_STREAM_BUFFER (store->istream);
-
- ba = g_byte_array_new ();
- while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf))) > 0) {
- g_byte_array_append (ba, linebuf, nread);
- if (linebuf[nread - 1] == '\n')
- break;
- }
-
- if (nread <= 0) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Server unexpectedly disconnected: %s"),
- g_strerror (errno));
-
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- g_byte_array_free (ba, TRUE);
- return -1;
- }
-
- if (camel_verbose_debug) {
- fprintf (stderr, "received: ");
- fwrite (ba->data, 1, ba->len, stderr);
- }
-
- /* camel-imap-command.c:imap_read_untagged expects the CRLFs
- to be stripped off and be nul-terminated *sigh* */
- nread = ba->len - 1;
- ba->data[nread] = '\0';
- if (ba->data[nread - 1] == '\r') {
- ba->data[nread - 1] = '\0';
- nread--;
- }
-
- *dest = ba->data;
- g_byte_array_free (ba, FALSE);
-
- return nread;
-}
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
deleted file mode 100644
index b45fb2110e..0000000000
--- a/camel/providers/imap/camel-imap-store.h
+++ /dev/null
@@ -1,148 +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@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_STORE_H
-#define CAMEL_IMAP_STORE_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#include "camel-imap-types.h"
-#include <camel/camel-disco-store.h>
-
-#ifdef ENABLE_THREADS
-#include <e-util/e-msgport.h>
-
-typedef struct _CamelImapMsg CamelImapMsg;
-
-struct _CamelImapMsg {
- EMsg msg;
-
- void (*receive)(CamelImapStore *store, struct _CamelImapMsg *m);
- void (*free)(CamelImapStore *store, struct _CamelImapMsg *m);
-};
-
-CamelImapMsg *camel_imap_msg_new(void (*receive)(CamelImapStore *store, struct _CamelImapMsg *m),
- void (*free)(CamelImapStore *store, struct _CamelImapMsg *m),
- size_t size);
-void camel_imap_msg_queue(CamelImapStore *store, CamelImapMsg *msg);
-
-#endif
-
-#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 CAMEL_IS_IMAP_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_STORE_TYPE))
-
-enum {
- CAMEL_IMAP_STORE_ARG_FIRST = CAMEL_DISCO_STORE_ARG_FIRST + 100,
- CAMEL_IMAP_STORE_ARG_NAMESPACE,
- CAMEL_IMAP_STORE_ARG_OVERRIDE_NAMESPACE,
- CAMEL_IMAP_STORE_ARG_CHECK_ALL,
- CAMEL_IMAP_STORE_ARG_FILTER_INBOX
-};
-
-#define CAMEL_IMAP_STORE_NAMESPACE (CAMEL_IMAP_STORE_ARG_NAMESPACE | CAMEL_ARG_STR)
-#define CAMEL_IMAP_STORE_OVERRIDE_NAMESPACE (CAMEL_IMAP_STORE_ARG_OVERRIDE_NAMESPACE | CAMEL_ARG_INT)
-#define CAMEL_IMAP_STORE_CHECK_ALL (CAMEL_IMAP_STORE_ARG_CHECK_ALL | CAMEL_ARG_INT)
-#define CAMEL_IMAP_STORE_FILTER_INBOX (CAMEL_IMAP_STORE_ARG_FILTER_INBOX | CAMEL_ARG_INT)
-
-/* CamelFolderInfo flags */
-#define CAMEL_IMAP_FOLDER_MARKED (1<<16)
-#define CAMEL_IMAP_FOLDER_UNMARKED (1<<17)
-#define CAMEL_IMAP_FOLDER_NOCHILDREN (1<<18)
-
-
-typedef enum {
- IMAP_LEVEL_UNKNOWN,
- IMAP_LEVEL_IMAP4,
- IMAP_LEVEL_IMAP4REV1
-} CamelImapServerLevel;
-
-#define IMAP_CAPABILITY_IMAP4 (1 << 0)
-#define IMAP_CAPABILITY_IMAP4REV1 (1 << 1)
-#define IMAP_CAPABILITY_STATUS (1 << 2)
-#define IMAP_CAPABILITY_NAMESPACE (1 << 3)
-#define IMAP_CAPABILITY_UIDPLUS (1 << 4)
-#define IMAP_CAPABILITY_LITERALPLUS (1 << 5)
-#define IMAP_CAPABILITY_STARTTLS (1 << 6)
-#define IMAP_CAPABILITY_useful_lsub (1 << 7)
-#define IMAP_CAPABILITY_utf8_search (1 << 8)
-
-#define IMAP_PARAM_OVERRIDE_NAMESPACE (1 << 0)
-#define IMAP_PARAM_CHECK_ALL (1 << 1)
-#define IMAP_PARAM_FILTER_INBOX (1 << 2)
-
-struct _CamelImapStore {
- CamelDiscoStore parent_object;
-
- CamelStream *istream;
- CamelStream *ostream;
-
- struct _CamelImapStoreSummary *summary;
-
- /* Information about the command channel / connection status */
- gboolean connected;
- gboolean preauthed;
- char tag_prefix;
- guint32 command;
- CamelFolder *current_folder;
-
- /* Information about the server */
- CamelImapServerLevel server_level;
- guint32 capabilities, parameters;
- /* NB: namespace should be handled by summary->namespace */
- char *namespace, dir_sep, *base_url, *storage_path;
- GHashTable *authtypes;
-
- gboolean renaming;
-
-#ifdef ENABLE_THREADS
- EThread *async_thread;
-#endif
-};
-
-
-typedef struct {
- CamelDiscoStoreClass parent_class;
-
-} CamelImapStoreClass;
-
-
-/* Standard Camel function */
-CamelType camel_imap_store_get_type (void);
-
-
-gboolean camel_imap_store_connected (CamelImapStore *store, CamelException *ex);
-
-ssize_t camel_imap_store_readline (CamelImapStore *store, char **dest, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAP_STORE_H */
diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c
deleted file mode 100644
index dba1134fa1..0000000000
--- a/camel/providers/imap/camel-imap-summary.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- * Dan Winship <danw@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "camel-imap-summary.h"
-#include "camel-file-utils.h"
-
-#define CAMEL_IMAP_SUMMARY_VERSION (0x300)
-
-static int summary_header_load (CamelFolderSummary *, FILE *);
-static int summary_header_save (CamelFolderSummary *, FILE *);
-
-static CamelMessageInfo *message_info_load (CamelFolderSummary *s, FILE *in);
-static int message_info_save (CamelFolderSummary *s, FILE *out,
- CamelMessageInfo *info);
-static CamelMessageContentInfo *content_info_load (CamelFolderSummary *s, FILE *in);
-static int content_info_save (CamelFolderSummary *s, FILE *out,
- CamelMessageContentInfo *info);
-
-static void camel_imap_summary_class_init (CamelImapSummaryClass *klass);
-static void camel_imap_summary_init (CamelImapSummary *obj);
-
-static CamelFolderSummaryClass *camel_imap_summary_parent;
-
-CamelType
-camel_imap_summary_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(
- camel_folder_summary_get_type(), "CamelImapSummary",
- sizeof (CamelImapSummary),
- sizeof (CamelImapSummaryClass),
- (CamelObjectClassInitFunc) camel_imap_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_summary_init,
- NULL);
- }
-
- return type;
-}
-
-static void
-camel_imap_summary_class_init (CamelImapSummaryClass *klass)
-{
- CamelFolderSummaryClass *cfs_class = (CamelFolderSummaryClass *) klass;
-
- camel_imap_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs (camel_folder_summary_get_type()));
-
- cfs_class->summary_header_load = summary_header_load;
- cfs_class->summary_header_save = summary_header_save;
- cfs_class->message_info_load = message_info_load;
- cfs_class->message_info_save = message_info_save;
- cfs_class->content_info_load = content_info_load;
- cfs_class->content_info_save = content_info_save;
-}
-
-static void
-camel_imap_summary_init (CamelImapSummary *obj)
-{
- CamelFolderSummary *s = (CamelFolderSummary *)obj;
-
- /* subclasses need to set the right instance data sizes */
- s->message_info_size = sizeof(CamelImapMessageInfo);
- s->content_info_size = sizeof(CamelImapMessageContentInfo);
-
- /* and a unique file version */
- s->version += CAMEL_IMAP_SUMMARY_VERSION;
-}
-
-/**
- * camel_imap_summary_new:
- * @filename: the file to store the summary in.
- *
- * This will create a new CamelImapSummary object and read in the
- * summary data from disk, if it exists.
- *
- * Return value: A new CamelImapSummary object.
- **/
-CamelFolderSummary *
-camel_imap_summary_new (const char *filename)
-{
- CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (
- camel_object_new (camel_imap_summary_get_type ()));
-
- camel_folder_summary_set_build_content (summary, TRUE);
- camel_folder_summary_set_filename (summary, filename);
-
- if (camel_folder_summary_load (summary) == -1) {
- camel_folder_summary_clear (summary);
- camel_folder_summary_touch (summary);
- }
-
- return summary;
-}
-
-
-static int
-summary_header_load (CamelFolderSummary *s, FILE *in)
-{
- CamelImapSummary *ims = CAMEL_IMAP_SUMMARY (s);
-
- if (camel_imap_summary_parent->summary_header_load (s, in) == -1)
- return -1;
-
- return camel_file_util_decode_uint32 (in, &ims->validity);
-}
-
-static int
-summary_header_save (CamelFolderSummary *s, FILE *out)
-{
- CamelImapSummary *ims = CAMEL_IMAP_SUMMARY(s);
-
- if (camel_imap_summary_parent->summary_header_save (s, out) == -1)
- return -1;
-
- return camel_file_util_encode_uint32 (out, ims->validity);
-}
-
-
-static CamelMessageInfo *
-message_info_load (CamelFolderSummary *s, FILE *in)
-{
- CamelMessageInfo *info;
- CamelImapMessageInfo *iinfo;
-
- info = camel_imap_summary_parent->message_info_load (s, in);
- if (info) {
- iinfo = (CamelImapMessageInfo *)info;
-
- if (camel_file_util_decode_uint32 (in, &iinfo->server_flags) == -1)
- goto error;
- }
-
- return info;
-error:
- camel_folder_summary_info_free (s, info);
- return NULL;
-}
-
-static int
-message_info_save (CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
-{
- CamelImapMessageInfo *iinfo = (CamelImapMessageInfo *)info;
-
- if (camel_imap_summary_parent->message_info_save (s, out, info) == -1)
- return -1;
-
- return camel_file_util_encode_uint32 (out, iinfo->server_flags);
-}
-
-
-static CamelMessageContentInfo *
-content_info_load (CamelFolderSummary *s, FILE *in)
-{
- if (fgetc (in))
- return camel_imap_summary_parent->content_info_load (s, in);
- else
- return camel_folder_summary_content_info_new (s);
-}
-
-static int
-content_info_save (CamelFolderSummary *s, FILE *out,
- CamelMessageContentInfo *info)
-{
- if (info->type) {
- fputc (1, out);
- return camel_imap_summary_parent->content_info_save (s, out, info);
- } else
- return fputc (0, out);
-}
-
-void
-camel_imap_summary_add_offline (CamelFolderSummary *summary, const char *uid,
- CamelMimeMessage *message,
- const CamelMessageInfo *info)
-{
- CamelMessageInfo *mi;
- CamelFlag *flag;
- CamelTag *tag;
-
- /* Create summary entry */
- mi = camel_folder_summary_info_new_from_message (summary, message);
-
- /* Copy flags 'n' tags */
- mi->flags = info->flags;
- flag = info->user_flags;
- while (flag) {
- camel_flag_set (&mi->user_flags, flag->name, TRUE);
- flag = flag->next;
- }
- tag = info->user_tags;
- while (tag) {
- camel_tag_set (&mi->user_tags, tag->name, tag->value);
- tag = tag->next;
- }
-
- /* Set uid and add to summary */
- camel_message_info_set_uid (mi, g_strdup (uid));
- camel_folder_summary_add (summary, mi);
-}
-
-void
-camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, const char *uid,
- const CamelMessageInfo *info)
-{
- CamelMessageInfo *mi;
- CamelMessageContentInfo *ci;
-
- /* Create summary entry */
- mi = camel_folder_summary_info_new (summary);
- ci = camel_folder_summary_content_info_new (summary);
-
- camel_message_info_dup_to (info, mi);
- mi->content = ci;
-
- /* copy our private fields */
- ((CamelImapMessageInfo *)mi)->server_flags =
- ((CamelImapMessageInfo *)info)->server_flags;
-
- /* Set uid and add to summary */
- camel_message_info_set_uid (mi, g_strdup (uid));
- camel_folder_summary_add (summary, mi);
-}
diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h
deleted file mode 100644
index 817e884408..0000000000
--- a/camel/providers/imap/camel-imap-summary.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- * Dan Winship <danw@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_IMAP_SUMMARY_H
-#define _CAMEL_IMAP_SUMMARY_H
-
-#include "camel-imap-types.h"
-#include <camel/camel-folder-summary.h>
-#include <camel/camel-exception.h>
-
-#define CAMEL_IMAP_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_imap_summary_get_type (), CamelImapSummary)
-#define CAMEL_IMAP_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imap_summary_get_type (), CamelImapSummaryClass)
-#define CAMEL_IS_IMAP_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_imap_summary_get_type ())
-
-#define CAMEL_IMAP_SERVER_FLAGS (CAMEL_MESSAGE_ANSWERED | \
- CAMEL_MESSAGE_DELETED | \
- CAMEL_MESSAGE_DRAFT | \
- CAMEL_MESSAGE_FLAGGED | \
- CAMEL_MESSAGE_SEEN)
-
-#define CAMEL_IMAP_MESSAGE_RECENT (1 << 8)
-
-typedef struct _CamelImapSummaryClass CamelImapSummaryClass;
-
-typedef struct _CamelImapMessageContentInfo {
- CamelMessageContentInfo info;
-
-} CamelImapMessageContentInfo;
-
-typedef struct _CamelImapMessageInfo {
- CamelMessageInfo info;
-
- guint32 server_flags;
-} CamelImapMessageInfo;
-
-struct _CamelImapSummary {
- CamelFolderSummary parent;
-
- guint32 validity;
-};
-
-struct _CamelImapSummaryClass {
- CamelFolderSummaryClass parent_class;
-
-};
-
-CamelType camel_imap_summary_get_type (void);
-CamelFolderSummary *camel_imap_summary_new (const char *filename);
-
-void camel_imap_summary_add_offline (CamelFolderSummary *summary,
- const char *uid,
- CamelMimeMessage *message,
- const CamelMessageInfo *info);
-
-void camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary,
- const char *uid,
- const CamelMessageInfo *info);
-
-#endif /* ! _CAMEL_IMAP_SUMMARY_H */
-
diff --git a/camel/providers/imap/camel-imap-types.h b/camel/providers/imap/camel-imap-types.h
deleted file mode 100644
index c5ea41acff..0000000000
--- a/camel/providers/imap/camel-imap-types.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-types.h: IMAP types */
-
-/*
- * Copyright (C) 2001 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_IMAP_TYPES_H
-#define CAMEL_IMAP_TYPES_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-types.h"
-
-typedef struct _CamelImapFolder CamelImapFolder;
-typedef struct _CamelImapMessageCache CamelImapMessageCache;
-typedef struct _CamelImapResponse CamelImapResponse;
-typedef struct _CamelImapSearch CamelImapSearch;
-typedef struct _CamelImapStore CamelImapStore;
-typedef struct _CamelImapSummary CamelImapSummary;
-
-#endif /* CAMEL_IMAP_TYPES_H */
diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c
deleted file mode 100644
index 879cc23cca..0000000000
--- a/camel/providers/imap/camel-imap-utils.c
+++ /dev/null
@@ -1,1261 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include "camel-imap-utils.h"
-#include "camel-imap-summary.h"
-#include "camel-imap-store.h"
-#include "camel-folder.h"
-#include "camel-string-utils.h"
-#include "camel-utf8.h"
-
-#define d(x)
-
-const char *
-imap_next_word (const char *buf)
-{
- const char *word;
-
- /* skip over current word */
- word = buf;
- while (*word && *word != ' ')
- word++;
-
- /* skip over white space */
- while (*word && *word == ' ')
- word++;
-
- return word;
-}
-
-
-static void
-imap_namespace_destroy (struct _namespace *namespace)
-{
- struct _namespace *node, *next;
-
- node = namespace;
- while (node) {
- next = node->next;
- g_free (node->prefix);
- g_free (node);
- node = next;
- }
-}
-
-void
-imap_namespaces_destroy (struct _namespaces *namespaces)
-{
- if (namespaces) {
- imap_namespace_destroy (namespaces->personal);
- imap_namespace_destroy (namespaces->other);
- imap_namespace_destroy (namespaces->shared);
- g_free (namespaces);
- }
-}
-
-static gboolean
-imap_namespace_decode (const char **in, struct _namespace **namespace)
-{
- struct _namespace *list, *tail, *node;
- const char *inptr;
- char *astring;
- size_t len;
-
- inptr = *in;
-
- list = NULL;
- tail = (struct _namespace *) &list;
-
- if (strncasecmp (inptr, "NIL", 3) != 0) {
- if (*inptr++ != '(')
- goto exception;
-
- while (*inptr && *inptr != ')') {
- if (*inptr++ != '(')
- goto exception;
-
- node = g_new (struct _namespace, 1);
- node->next = NULL;
-
- /* get the namespace prefix */
- astring = imap_parse_astring (&inptr, &len);
- if (!astring) {
- g_free (node);
- goto exception;
- }
-
- /* decode IMAP's modified UTF-7 into UTF-8 */
- node->prefix = imap_mailbox_decode (astring, len);
- g_free (astring);
- if (!node->prefix) {
- g_free (node);
- goto exception;
- }
-
- tail->next = node;
- tail = node;
-
- /* get the namespace directory delimiter */
- inptr = imap_next_word (inptr);
-
- if (!strncasecmp (inptr, "NIL", 3)) {
- inptr = imap_next_word (inptr);
- node->delim = '\0';
- } else if (*inptr++ == '"') {
- if (*inptr == '\\')
- inptr++;
-
- node->delim = *inptr++;
-
- if (*inptr++ != '"')
- goto exception;
- } else
- goto exception;
-
- if (*inptr == ' ') {
- /* parse extra flags... for now we
- don't save them, but in the future
- we may want to? */
- while (*inptr == ' ')
- inptr++;
-
- while (*inptr && *inptr != ')') {
- /* this should be a QSTRING or ATOM */
- inptr = imap_next_word (inptr);
- if (*inptr == '(') {
- /* skip over the param list */
- imap_skip_list (&inptr);
- }
-
- while (*inptr == ' ')
- inptr++;
- }
- }
-
- if (*inptr++ != ')')
- goto exception;
-
- /* there shouldn't be spaces according to the
- ABNF grammar, but we all know how closely
- people follow specs */
- while (*inptr == ' ')
- inptr++;
- }
-
- if (*inptr == ')')
- inptr++;
- } else {
- inptr += 3;
- }
-
- *in = inptr;
- *namespace = list;
-
- return TRUE;
-
- exception:
-
- /* clean up any namespaces we may have allocated */
- imap_namespace_destroy (list);
-
- return FALSE;
-}
-
-#if d(!)0
-static void
-namespace_dump (struct _namespace *namespace)
-{
- struct _namespace *node;
-
- if (namespace) {
- printf ("(");
- node = namespace;
- while (node) {
- printf ("(\"%s\" ", node->prefix);
- if (node->delim)
- printf ("\"%c\")", node->delim);
- else
- printf ("NUL)");
-
- node = node->next;
- if (node)
- printf (" ");
- }
-
- printf (")");
- } else {
- printf ("NIL");
- }
-}
-
-static void
-namespaces_dump (struct _namespaces *namespaces)
-{
- printf ("namespace dump: ");
- namespace_dump (namespaces->personal);
- printf (" ");
- namespace_dump (namespaces->other);
- printf (" ");
- namespace_dump (namespaces->shared);
- printf ("\n");
-}
-#endif
-
-struct _namespaces *
-imap_parse_namespace_response (const char *response)
-{
- struct _namespaces *namespaces;
- const char *inptr;
-
- d(printf ("parsing: %s\n", response));
-
- if (*response != '*')
- return NULL;
-
- inptr = imap_next_word (response);
- if (strncasecmp (inptr, "NAMESPACE", 9) != 0)
- return NULL;
-
- inptr = imap_next_word (inptr);
-
- namespaces = g_new (struct _namespaces, 1);
- namespaces->personal = NULL;
- namespaces->other = NULL;
- namespaces->shared = NULL;
-
- if (!imap_namespace_decode (&inptr, &namespaces->personal))
- goto exception;
-
- if (*inptr != ' ')
- goto exception;
-
- while (*inptr == ' ')
- inptr++;
-
- if (!imap_namespace_decode (&inptr, &namespaces->other))
- goto exception;
-
- if (*inptr != ' ')
- goto exception;
-
- while (*inptr == ' ')
- inptr++;
-
- if (!imap_namespace_decode (&inptr, &namespaces->shared))
- goto exception;
-
- d(namespaces_dump (namespaces));
-
- return namespaces;
-
- exception:
-
- imap_namespaces_destroy (namespaces);
-
- return NULL;
-}
-
-/**
- * imap_parse_list_response:
- * @store: the IMAP store whose list response we're parsing
- * @buf: the LIST or LSUB response
- * @flags: a pointer to a variable to store the flags in, or %NULL
- * @sep: a pointer to a variable to store the hierarchy separator in, or %NULL
- * @folder: a pointer to a variable to store the folder name in, or %NULL
- *
- * Parses a LIST or LSUB response and returns the desired parts of it.
- * If @folder is non-%NULL, its value must be freed by the caller.
- *
- * Return value: whether or not the response was successfully parsed.
- **/
-gboolean
-imap_parse_list_response (CamelImapStore *store, const char *buf, int *flags, char *sep, char **folder)
-{
- gboolean is_lsub = FALSE;
- const char *word;
- size_t len;
-
- if (*buf != '*')
- return FALSE;
-
- word = imap_next_word (buf);
- if (strncasecmp (word, "LIST", 4) && strncasecmp (word, "LSUB", 4))
- return FALSE;
-
- /* check if we are looking at an LSUB response */
- if (word[1] == 'S' || word[1] == 's')
- is_lsub = TRUE;
-
- /* get the flags */
- word = imap_next_word (word);
- if (*word != '(')
- return FALSE;
-
- if (flags)
- *flags = 0;
-
- word++;
- while (*word != ')') {
- len = strcspn (word, " )");
- if (flags) {
- if (!strncasecmp (word, "\\NoInferiors", len))
- *flags |= CAMEL_FOLDER_NOINFERIORS;
- else if (!strncasecmp (word, "\\NoSelect", len))
- *flags |= CAMEL_FOLDER_NOSELECT;
- else if (!strncasecmp (word, "\\Marked", len))
- *flags |= CAMEL_IMAP_FOLDER_MARKED;
- else if (!strncasecmp (word, "\\Unmarked", len))
- *flags |= CAMEL_IMAP_FOLDER_UNMARKED;
- else if (!strncasecmp (word, "\\HasChildren", len))
- *flags |= CAMEL_FOLDER_CHILDREN;
- else if (!strncasecmp (word, "\\HasNoChildren", len))
- *flags |= CAMEL_IMAP_FOLDER_NOCHILDREN;
- }
-
- word += len;
- while (*word == ' ')
- word++;
- }
-
- /* get the directory separator */
- word = imap_next_word (word);
- if (!strncmp (word, "NIL", 3)) {
- if (sep)
- *sep = '\0';
- } else if (*word++ == '"') {
- if (*word == '\\')
- word++;
- if (sep)
- *sep = *word;
- word++;
- if (*word++ != '"')
- return FALSE;
- } else
- return FALSE;
-
- if (folder) {
- char *astring;
-
- /* get the folder name */
- word = imap_next_word (word);
- astring = imap_parse_astring (&word, &len);
- if (!astring)
- return FALSE;
-
- *folder = astring;
-#if 0
- char *mailbox;
-
- mailbox = imap_mailbox_decode (astring, strlen (astring));
- g_free (astring);
- if (!mailbox)
- return FALSE;
-
- /* Kludge around Courier imap's LSUB response for INBOX when it
- * isn't subscribed to.
- *
- * Ignore any \Noselect flags for INBOX when parsing
- * an LSUB response to work around the following response:
- *
- * * LSUB (\Noselect \HasChildren) "." "INBOX"
- *
- * Fixes bug #28929 (albeight in a very dodgy way imho, but what
- * can ya do when ya got the ignorance of marketing breathing
- * down your neck?)
- */
- if (is_lsub && flags && !strcasecmp (mailbox, "INBOX"))
- *flags &= ~CAMEL_FOLDER_NOSELECT;
-
- *folder = mailbox;
-#endif
- }
-
- return TRUE;
-}
-
-
-/**
- * imap_parse_folder_name:
- * @store:
- * @folder_name:
- *
- * Return an array of folder paths representing the folder heirarchy.
- * For example:
- * Full/Path/"to / from"/Folder
- * Results in:
- * Full, Full/Path, Full/Path/"to / from", Full/Path/"to / from"/Folder
- **/
-char **
-imap_parse_folder_name (CamelImapStore *store, const char *folder_name)
-{
- GPtrArray *heirarchy;
- char **paths;
- const char *p;
-
- p = folder_name;
- if (*p == store->dir_sep)
- p++;
-
- heirarchy = g_ptr_array_new ();
-
- while (*p) {
- if (*p == '"') {
- p++;
- while (*p && *p != '"')
- p++;
- if (*p)
- p++;
- continue;
- }
-
- if (*p == store->dir_sep)
- g_ptr_array_add (heirarchy, g_strndup (folder_name, p - folder_name));
-
- p++;
- }
-
- g_ptr_array_add (heirarchy, g_strdup (folder_name));
- g_ptr_array_add (heirarchy, NULL);
-
- paths = (char **) heirarchy->pdata;
- g_ptr_array_free (heirarchy, FALSE);
-
- return paths;
-}
-
-char *
-imap_create_flag_list (guint32 flags)
-{
- GString *gstr;
- char *flag_list;
-
- gstr = g_string_new ("(");
-
- if (flags & CAMEL_MESSAGE_ANSWERED)
- g_string_append (gstr, "\\Answered ");
- if (flags & CAMEL_MESSAGE_DELETED)
- g_string_append (gstr, "\\Deleted ");
- if (flags & CAMEL_MESSAGE_DRAFT)
- g_string_append (gstr, "\\Draft ");
- if (flags & CAMEL_MESSAGE_FLAGGED)
- g_string_append (gstr, "\\Flagged ");
- if (flags & CAMEL_MESSAGE_SEEN)
- g_string_append (gstr, "\\Seen ");
-
- if (gstr->str[gstr->len - 1] == ' ')
- gstr->str[gstr->len - 1] = ')';
- else
- g_string_append_c (gstr, ')');
-
- flag_list = gstr->str;
- g_string_free (gstr, FALSE);
- return flag_list;
-}
-
-guint32
-imap_parse_flag_list (char **flag_list_p)
-{
- char *flag_list = *flag_list_p;
- guint32 flags = 0;
- int len;
-
- if (*flag_list++ != '(') {
- *flag_list_p = NULL;
- return 0;
- }
-
- while (*flag_list && *flag_list != ')') {
- len = strcspn (flag_list, " )");
- if (!strncasecmp (flag_list, "\\Answered", len))
- flags |= CAMEL_MESSAGE_ANSWERED;
- else if (!strncasecmp (flag_list, "\\Deleted", len))
- flags |= CAMEL_MESSAGE_DELETED;
- else if (!strncasecmp (flag_list, "\\Draft", len))
- flags |= CAMEL_MESSAGE_DRAFT;
- else if (!strncasecmp (flag_list, "\\Flagged", len))
- flags |= CAMEL_MESSAGE_FLAGGED;
- else if (!strncasecmp (flag_list, "\\Seen", len))
- flags |= CAMEL_MESSAGE_SEEN;
- else if (!strncasecmp (flag_list, "\\Recent", len))
- flags |= CAMEL_IMAP_MESSAGE_RECENT;
-
- flag_list += len;
- if (*flag_list == ' ')
- flag_list++;
- }
-
- if (*flag_list++ != ')') {
- *flag_list_p = NULL;
- return 0;
- }
-
- *flag_list_p = flag_list;
- return flags;
-}
-
-/*
- From rfc2060
-
-ATOM_CHAR ::= <any CHAR except atom_specials>
-
-atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards /
- quoted_specials
-
-CHAR ::= <any 7-bit US-ASCII character except NUL,
- 0x01 - 0x7f>
-
-CTL ::= <any ASCII control character and DEL,
- 0x00 - 0x1f, 0x7f>
-
-SPACE ::= <ASCII SP, space, 0x20>
-
-list_wildcards ::= "%" / "*"
-
-quoted_specials ::= <"> / "\"
-*/
-
-static unsigned char imap_atom_specials[256] = {
-/* 00 */0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 10 */0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 20 */0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
-/* 30 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 40 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 50 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
-/* 60 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 70 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-#define imap_is_atom_char(c) ((imap_atom_specials[(c)&0xff] & 0x01) != 0)
-
-gboolean
-imap_is_atom(const char *in)
-{
- register unsigned char c;
- register const char *p = in;
-
- while ((c = (unsigned char)*p)) {
- if (!imap_is_atom_char(c))
- return FALSE;
- p++;
- }
-
- /* check for empty string */
- return p!=in;
-}
-
-/**
- * imap_parse_string_generic:
- * @str_p: a pointer to a string
- * @len: a pointer to a size_t to return the length in
- * @type: type of string (#IMAP_STRING, #IMAP_ASTRING, or #IMAP_NSTRING)
- * to parse.
- *
- * This parses an IMAP "string" (quoted string or literal), "nstring"
- * (NIL or string), or "astring" (atom or string) starting at *@str_p.
- * On success, *@str_p will point to the first character after the end
- * of the string, and *@len will contain the length of the returned
- * string. On failure, *@str_p will be set to %NULL.
- *
- * This assumes that the string is in the form returned by
- * camel_imap_command(): that line breaks are indicated by LF rather
- * than CRLF.
- *
- * Return value: the parsed string, or %NULL if a NIL or no string
- * was parsed. (In the former case, *@str_p will be %NULL; in the
- * latter, it will point to the character after the NIL.)
- **/
-char *
-imap_parse_string_generic (const char **str_p, size_t *len, int type)
-{
- const char *str = *str_p;
- char *out;
-
- if (!str)
- return NULL;
- else if (*str == '"') {
- char *p;
- size_t size;
-
- str++;
- size = strcspn (str, "\"") + 1;
- p = out = g_malloc (size);
-
- /* a quoted string cannot be broken into multiple lines */
- while (*str && *str != '"' && *str != '\n') {
- if (*str == '\\')
- str++;
- *p++ = *str++;
- if (p - out == size) {
- out = g_realloc (out, size * 2);
- p = out + size;
- size *= 2;
- }
- }
- if (*str != '"') {
- *str_p = NULL;
- g_free (out);
- return NULL;
- }
- *p = '\0';
- *str_p = str + 1;
- *len = strlen (out);
- return out;
- } else if (*str == '{') {
- *len = strtoul (str + 1, (char **)&str, 10);
- if (*str++ != '}' || *str++ != '\n' || strlen (str) < *len) {
- *str_p = NULL;
- return NULL;
- }
-
- out = g_strndup (str, *len);
- *str_p = str + *len;
- return out;
- } else if (type == IMAP_NSTRING && !strncasecmp (str, "nil", 3)) {
- *str_p += 3;
- *len = 0;
- return NULL;
- } else if (type == IMAP_ASTRING && imap_is_atom_char ((unsigned char)*str)) {
- while (imap_is_atom_char ((unsigned char) *str))
- str++;
-
- *len = str - *str_p;
- out = g_strndup (*str_p, *len);
- *str_p += *len;
- return out;
- } else {
- *str_p = NULL;
- return NULL;
- }
-}
-
-static inline void
-skip_char (const char **in, char ch)
-{
- if (*in && **in == ch)
- *in = *in + 1;
- else
- *in = NULL;
-}
-
-/* Skip atom, string, or number */
-static void
-skip_asn (const char **str_p)
-{
- const char *str = *str_p;
-
- if (!str)
- return;
- else if (*str == '"') {
- while (*++str && *str != '"') {
- if (*str == '\\') {
- str++;
- if (!*str)
- break;
- }
- }
- if (*str == '"')
- *str_p = str + 1;
- else
- *str_p = NULL;
- } else if (*str == '{') {
- unsigned long len;
-
- len = strtoul (str + 1, (char **) &str, 10);
- if (*str != '}' || *(str + 1) != '\n' ||
- strlen (str + 2) < len) {
- *str_p = NULL;
- return;
- }
- *str_p = str + 2 + len;
- } else {
- /* We assume the string is well-formed and don't
- * bother making sure it's a valid atom.
- */
- while (*str && *str != ')' && *str != ' ')
- str++;
- *str_p = str;
- }
-}
-
-void
-imap_skip_list (const char **str_p)
-{
- skip_char (str_p, '(');
- while (*str_p && **str_p != ')') {
- if (**str_p == '(')
- imap_skip_list (str_p);
- else
- skip_asn (str_p);
- if (*str_p && **str_p == ' ')
- skip_char (str_p, ' ');
- }
- skip_char (str_p, ')');
-}
-
-static int
-parse_params (const char **parms_p, CamelContentType *type)
-{
- const char *parms = *parms_p;
- char *name, *value;
- size_t len;
-
- if (!strncasecmp (parms, "nil", 3)) {
- *parms_p += 3;
- return 0;
- }
-
- if (*parms++ != '(')
- return -1;
-
- while (parms && *parms != ')') {
- name = imap_parse_nstring (&parms, &len);
- skip_char (&parms, ' ');
- value = imap_parse_nstring (&parms, &len);
-
- if (name && value)
- camel_content_type_set_param (type, name, value);
- g_free (name);
- g_free (value);
-
- if (parms && *parms == ' ')
- parms++;
- }
-
- if (!parms || *parms++ != ')')
- return -1;
-
- *parms_p = parms;
-
- return 0;
-}
-
-
-static CamelMessageContentInfo *
-imap_body_decode (const char **in, CamelMessageContentInfo *ci, CamelFolder *folder, GPtrArray *cis)
-{
- const char *inptr = *in;
- CamelMessageContentInfo *child = NULL;
- char *type, *subtype, *id = NULL;
- CamelContentType *ctype = NULL;
- char *description = NULL;
- char *encoding = NULL;
- size_t len;
- size_t size;
- char *p;
-
- if (*inptr++ != '(')
- return NULL;
-
- if (ci == NULL) {
- ci = camel_folder_summary_content_info_new (folder->summary);
- g_ptr_array_add (cis, ci);
- }
-
- if (*inptr == '(') {
- /* body_type_mpart */
- CamelMessageContentInfo *tail, *children = NULL;
-
- tail = (CamelMessageContentInfo *) &children;
-
- do {
- if (!(child = imap_body_decode (&inptr, NULL, folder, cis)))
- return NULL;
-
- child->parent = ci;
- tail->next = child;
- tail = child;
- } while (*inptr == '(');
-
- if (*inptr++ != ' ')
- return NULL;
-
- if (!strncasecmp (inptr, "nil", 3) != 0) {
- subtype = imap_parse_string (&inptr, &len);
- } else {
- subtype = NULL;
- inptr += 3;
- }
-
- ctype = camel_content_type_new ("multipart", subtype ? subtype : "mixed");
- g_free (subtype);
-
- if (*inptr++ != ')') {
- camel_content_type_unref (ctype);
- return NULL;
- }
-
- ci->type = ctype;
- ci->childs = children;
- } else {
- /* body_type_1part */
- if (strncasecmp (inptr, "nil", 3) != 0) {
- type = imap_parse_string (&inptr, &len);
- if (inptr == NULL)
- return NULL;
- } else {
- return NULL;
- }
-
- if (*inptr++ != ' ') {
- g_free (type);
- return NULL;
- }
-
- if (strncasecmp (inptr, "nil", 3) != 0) {
- subtype = imap_parse_string (&inptr, &len);
- if (inptr == NULL) {
- g_free (type);
- return NULL;
- }
- } else {
- if (!strcasecmp (type, "text"))
- subtype = g_strdup ("plain");
- else
- subtype = NULL;
- inptr += 3;
- }
-
- camel_strdown (type);
- camel_strdown (subtype);
- ctype = camel_content_type_new (type, subtype);
- g_free (subtype);
- g_free (type);
-
- if (*inptr++ != ' ')
- goto exception;
-
- /* content-type params */
- if (parse_params (&inptr, ctype) == -1)
- goto exception;
-
- if (*inptr++ != ' ')
- goto exception;
-
- /* content-id */
- if (strncasecmp (inptr, "nil", 3) != 0) {
- id = imap_parse_string (&inptr, &len);
- if (inptr == NULL)
- goto exception;
- } else
- inptr += 3;
-
- if (*inptr++ != ' ')
- goto exception;
-
- /* description */
- if (strncasecmp (inptr, "nil", 3) != 0) {
- description = imap_parse_string (&inptr, &len);
- if (inptr == NULL)
- goto exception;
- } else
- inptr += 3;
-
- if (*inptr++ != ' ')
- goto exception;
-
- /* encoding */
- if (strncasecmp (inptr, "nil", 3) != 0) {
- encoding = imap_parse_string (&inptr, &len);
- if (inptr == NULL)
- goto exception;
- } else
- inptr += 3;
-
- if (*inptr++ != ' ')
- goto exception;
-
- /* size */
- size = strtoul ((const char *) inptr, &p, 10);
- inptr = (const unsigned char *) p;
-
- if (camel_content_type_is (ctype, "message", "rfc822")) {
- /* body_type_msg */
- if (*inptr++ != ' ')
- goto exception;
-
- /* envelope */
- imap_skip_list (&inptr);
-
- if (*inptr++ != ' ')
- goto exception;
-
- /* body */
- if (!(child = imap_body_decode (&inptr, NULL, folder, cis)))
- goto exception;
- child->parent = ci;
-
- if (*inptr++ != ' ')
- goto exception;
-
- /* lines */
- strtoul ((const char *) inptr, &p, 10);
- inptr = (const unsigned char *) p;
- } else if (camel_content_type_is (ctype, "text", "*")) {
- if (*inptr++ != ' ')
- goto exception;
-
- /* lines */
- strtoul ((const char *) inptr, &p, 10);
- inptr = (const unsigned char *) p;
- } else {
- /* body_type_basic */
- }
-
- if (*inptr++ != ')')
- goto exception;
-
- ci->type = ctype;
- ci->id = id;
- ci->description = description;
- ci->encoding = encoding;
- ci->size = size;
- ci->childs = child;
- }
-
- *in = inptr;
-
- return ci;
-
- exception:
-
- camel_content_type_unref (ctype);
- g_free (id);
- g_free (description);
- g_free (encoding);
-
- return NULL;
-}
-
-
-/**
- * imap_parse_body:
- * @body_p: pointer to the start of an IMAP "body"
- * @folder: an imap folder
- * @ci: a CamelMessageContentInfo to fill in
- *
- * This fills in @ci with data from *@body_p. On success *@body_p
- * will point to the character after the body. On failure, it will be
- * set to %NULL and @ci will be unchanged.
- **/
-void
-imap_parse_body (const char **body_p, CamelFolder *folder,
- CamelMessageContentInfo *ci)
-{
- const char *inptr = *body_p;
- CamelMessageContentInfo *child;
- GPtrArray *children;
- int i;
-
- if (!inptr || *inptr != '(') {
- *body_p = NULL;
- return;
- }
-
- children = g_ptr_array_new ();
-
- if (!(imap_body_decode (&inptr, ci, folder, children))) {
- for (i = 0; i < children->len; i++) {
- child = children->pdata[i];
-
- /* content_info_free will free all the child
- * nodes, but we don't want that. */
- child->next = NULL;
- child->parent = NULL;
- child->childs = NULL;
-
- camel_folder_summary_content_info_free (folder->summary, child);
- }
- *body_p = NULL;
- } else {
- *body_p = inptr;
- }
-
- g_ptr_array_free (children, TRUE);
-}
-
-
-/**
- * imap_quote_string:
- * @str: the string to quote, which must not contain CR or LF
- *
- * Return value: an IMAP "quoted" corresponding to the string, which
- * the caller must free.
- **/
-char *
-imap_quote_string (const char *str)
-{
- const char *p;
- char *quoted, *q;
- int len;
-
- g_assert (strchr (str, '\r') == NULL);
-
- len = strlen (str);
- p = str;
- while ((p = strpbrk (p, "\"\\"))) {
- len++;
- p++;
- }
-
- quoted = q = g_malloc (len + 3);
- *q++ = '"';
- for (p = str; *p; ) {
- if (strchr ("\"\\", *p))
- *q++ = '\\';
- *q++ = *p++;
- }
- *q++ = '"';
- *q = '\0';
-
- return quoted;
-}
-
-
-static inline unsigned long
-get_summary_uid_numeric (CamelFolderSummary *summary, int index)
-{
- CamelMessageInfo *info;
- unsigned long uid;
-
- info = camel_folder_summary_index (summary, index);
- uid = strtoul (camel_message_info_uid (info), NULL, 10);
- camel_folder_summary_info_free (summary, info);
- return uid;
-}
-
-/* the max number of chars that an unsigned 32-bit int can be is 10 chars plus 1 for a possible : */
-#define UID_SET_FULL(setlen, maxlen) (maxlen > 0 ? setlen + 11 >= maxlen : FALSE)
-
-/**
- * imap_uid_array_to_set:
- * @summary: summary for the folder the UIDs come from
- * @uids: a (sorted) array of UIDs
- * @uid: uid index to start at
- * @maxlen: max length of the set string (or -1 for infinite)
- * @lastuid: index offset of the last uid used
- *
- * Creates an IMAP "set" up to @maxlen bytes long, covering the listed
- * UIDs starting at index @uid and not covering any UIDs that are in
- * @summary but not in @uids. It doesn't actually require that all (or
- * any) of the UIDs be in @summary.
- *
- * After calling, @lastuid will be set the index of the first uid
- * *not* included in the returned set string.
- *
- * Note: @uids MUST be in sorted order for this code to work properly.
- *
- * Return value: the set, which the caller must free with g_free()
- **/
-char *
-imap_uid_array_to_set (CamelFolderSummary *summary, GPtrArray *uids, int uid, ssize_t maxlen, int *lastuid)
-{
- unsigned long last_uid, next_summary_uid, this_uid;
- gboolean range = FALSE;
- int si, scount;
- GString *gset;
- char *set;
-
- g_return_val_if_fail (uids->len > uid, NULL);
-
- gset = g_string_new (uids->pdata[uid]);
- last_uid = strtoul (uids->pdata[uid], NULL, 10);
- next_summary_uid = 0;
- scount = camel_folder_summary_count (summary);
-
- for (uid++, si = 0; uid < uids->len && !UID_SET_FULL (gset->len, maxlen); uid++) {
- /* Find the next UID in the summary after the one we
- * just wrote out.
- */
- for ( ; last_uid >= next_summary_uid && si < scount; si++)
- next_summary_uid = get_summary_uid_numeric (summary, si);
- if (last_uid >= next_summary_uid)
- next_summary_uid = (unsigned long) -1;
-
- /* Now get the next UID from @uids */
- this_uid = strtoul (uids->pdata[uid], NULL, 10);
- if (this_uid == next_summary_uid || this_uid == last_uid + 1)
- range = TRUE;
- else {
- if (range) {
- g_string_append_printf (gset, ":%lu", last_uid);
- range = FALSE;
- }
- g_string_append_printf (gset, ",%lu", this_uid);
- }
-
- last_uid = this_uid;
- }
-
- if (range)
- g_string_append_printf (gset, ":%lu", last_uid);
-
- *lastuid = uid;
-
- set = gset->str;
- g_string_free (gset, FALSE);
-
- return set;
-}
-
-/**
- * imap_uid_set_to_array:
- * @summary: summary for the folder the UIDs come from
- * @uids: a pointer to the start of an IMAP "set" of UIDs
- *
- * Fills an array with the UIDs corresponding to @uids and @summary.
- * There can be text after the uid set in @uids, which will be
- * ignored.
- *
- * If @uids specifies a range of UIDs that extends outside the range
- * of @summary, the function will assume that all of the "missing" UIDs
- * do exist.
- *
- * Return value: the array of uids, which the caller must free with
- * imap_uid_array_free(). (Or %NULL if the uid set can't be parsed.)
- **/
-GPtrArray *
-imap_uid_set_to_array (CamelFolderSummary *summary, const char *uids)
-{
- GPtrArray *arr;
- char *p, *q;
- unsigned long uid, suid;
- int si, scount;
-
- arr = g_ptr_array_new ();
- scount = camel_folder_summary_count (summary);
-
- p = (char *)uids;
- si = 0;
- do {
- uid = strtoul (p, &q, 10);
- if (p == q)
- goto lose;
- g_ptr_array_add (arr, g_strndup (p, q - p));
-
- if (*q == ':') {
- /* Find the summary entry for the UID after the one
- * we just saw.
- */
- while (++si < scount) {
- suid = get_summary_uid_numeric (summary, si);
- if (suid > uid)
- break;
- }
- if (si >= scount)
- suid = uid + 1;
-
- uid = strtoul (q + 1, &p, 10);
- if (p == q + 1)
- goto lose;
-
- /* Add each summary UID until we find one
- * larger than the end of the range
- */
- while (suid <= uid) {
- g_ptr_array_add (arr, g_strdup_printf ("%lu", suid));
- if (++si < scount)
- suid = get_summary_uid_numeric (summary, si);
- else
- suid++;
- }
- } else
- p = q;
- } while (*p++ == ',');
-
- return arr;
-
- lose:
- g_warning ("Invalid uid set %s", uids);
- imap_uid_array_free (arr);
- return NULL;
-}
-
-/**
- * imap_uid_array_free:
- * @arr: an array returned from imap_uid_set_to_array()
- *
- * Frees @arr
- **/
-void
-imap_uid_array_free (GPtrArray *arr)
-{
- int i;
-
- for (i = 0; i < arr->len; i++)
- g_free (arr->pdata[i]);
- g_ptr_array_free (arr, TRUE);
-}
-
-char *
-imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix)
-{
- size_t len;
-
- len = strlen (prefix);
- if (len == 0 || prefix[len - 1] == imap_store->dir_sep)
- return g_strdup_printf ("%s%s", prefix, suffix);
- else
- return g_strdup_printf ("%s%c%s", prefix, imap_store->dir_sep, suffix);
-}
-
-char *
-imap_mailbox_encode (const unsigned char *in, size_t inlen)
-{
- char *buf;
-
- buf = g_alloca (inlen + 1);
- memcpy (buf, in, inlen);
- buf[inlen] = 0;
-
- return camel_utf8_utf7 (buf);
-}
-
-char *
-imap_mailbox_decode (const unsigned char *in, size_t inlen)
-{
- char *buf;
-
- buf = g_alloca (inlen + 1);
- memcpy (buf, in, inlen);
- buf[inlen] = 0;
-
- return camel_utf7_utf8 (buf);
-}
diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h
deleted file mode 100644
index e8f570137f..0000000000
--- a/camel/providers/imap/camel-imap-utils.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef CAMEL_IMAP_UTILS_H
-#define CAMEL_IMAP_UTILS_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <sys/types.h>
-
-#include "camel-folder-summary.h"
-#include "camel-imap-types.h"
-
-const char *imap_next_word (const char *buf);
-
-struct _namespace {
- struct _namespace *next;
- char *prefix;
- char delim;
-};
-
-struct _namespaces {
- struct _namespace *personal;
- struct _namespace *other;
- struct _namespace *shared;
-};
-
-void imap_namespaces_destroy (struct _namespaces *namespaces);
-struct _namespaces *imap_parse_namespace_response (const char *response);
-
-gboolean imap_parse_list_response (CamelImapStore *store, const char *buf, int *flags,
- char *sep, char **folder);
-
-char **imap_parse_folder_name (CamelImapStore *store, const char *folder_name);
-
-char *imap_create_flag_list (guint32 flags);
-guint32 imap_parse_flag_list (char **flag_list);
-
-
-enum { IMAP_STRING, IMAP_NSTRING, IMAP_ASTRING };
-
-char *imap_parse_string_generic (const char **str_p, size_t *len, int type);
-
-#define imap_parse_string(str_p, len_p) \
- imap_parse_string_generic (str_p, len_p, IMAP_STRING)
-#define imap_parse_nstring(str_p, len_p) \
- imap_parse_string_generic (str_p, len_p, IMAP_NSTRING)
-#define imap_parse_astring(str_p, len_p) \
- imap_parse_string_generic (str_p, len_p, IMAP_ASTRING)
-
-void imap_parse_body (const char **body_p, CamelFolder *folder,
- CamelMessageContentInfo *ci);
-
-gboolean imap_is_atom (const char *in);
-char *imap_quote_string (const char *str);
-
-void imap_skip_list (const char **str_p);
-
-char *imap_uid_array_to_set (CamelFolderSummary *summary, GPtrArray *uids, int uid, ssize_t maxlen, int *lastuid);
-GPtrArray *imap_uid_set_to_array (CamelFolderSummary *summary, const char *uids);
-void imap_uid_array_free (GPtrArray *arr);
-
-char *imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix);
-char *imap_namespace_concat (CamelImapStore *store, const char *name);
-
-char *imap_mailbox_encode (const unsigned char *in, size_t inlen);
-char *imap_mailbox_decode (const unsigned char *in, size_t inlen);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAP_UTILS_H */
diff --git a/camel/providers/imap/camel-imap-wrapper.c b/camel/providers/imap/camel-imap-wrapper.c
deleted file mode 100644
index 2cb07b3012..0000000000
--- a/camel/providers/imap/camel-imap-wrapper.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; -*- */
-/* camel-imap-wrapper.c: data wrapper for offline IMAP data */
-
-/*
- * Author: Dan Winship <danw@ximian.com>
- *
- * Copyright 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-
-#include "camel-imap-folder.h"
-#include "camel-imap-wrapper.h"
-#include "camel-imap-private.h"
-#include "camel-exception.h"
-#include "camel-stream-filter.h"
-#include "camel-mime-filter-basic.h"
-#include "camel-mime-filter-crlf.h"
-#include "camel-mime-filter-charset.h"
-#include "camel-mime-part.h"
-
-static CamelDataWrapperClass *parent_class = NULL;
-
-/* Returns the class for a CamelDataWrapper */
-#define CDW_CLASS(so) CAMEL_DATA_WRAPPER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static ssize_t write_to_stream (CamelDataWrapper *imap_wrapper, CamelStream *stream);
-
-static void
-camel_imap_wrapper_class_init (CamelImapWrapperClass *camel_imap_wrapper_class)
-{
- CamelDataWrapperClass *camel_data_wrapper_class =
- CAMEL_DATA_WRAPPER_CLASS (camel_imap_wrapper_class);
-
- parent_class = CAMEL_DATA_WRAPPER_CLASS (camel_type_get_global_classfuncs (camel_data_wrapper_get_type ()));
-
- /* virtual method override */
- camel_data_wrapper_class->write_to_stream = write_to_stream;
-}
-
-static void
-camel_imap_wrapper_finalize (CamelObject *object)
-{
- CamelImapWrapper *imap_wrapper = CAMEL_IMAP_WRAPPER (object);
-
- if (imap_wrapper->folder)
- camel_object_unref (CAMEL_OBJECT (imap_wrapper->folder));
- if (imap_wrapper->uid)
- g_free (imap_wrapper->uid);
- if (imap_wrapper->part)
- g_free (imap_wrapper->part_spec);
-
-#ifdef ENABLE_THREADS
- g_mutex_free (imap_wrapper->priv->lock);
-#endif
- g_free (imap_wrapper->priv);
-}
-
-static void
-camel_imap_wrapper_init (gpointer object, gpointer klass)
-{
- CamelImapWrapper *imap_wrapper = CAMEL_IMAP_WRAPPER (object);
-
- imap_wrapper->priv = g_new0 (struct _CamelImapWrapperPrivate, 1);
-#ifdef ENABLE_THREADS
- imap_wrapper->priv->lock = g_mutex_new ();
-#endif
-}
-
-CamelType
-camel_imap_wrapper_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register (
- CAMEL_DATA_WRAPPER_TYPE,
- "CamelImapWrapper",
- sizeof (CamelImapWrapper),
- sizeof (CamelImapWrapperClass),
- (CamelObjectClassInitFunc) camel_imap_wrapper_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_wrapper_init,
- (CamelObjectFinalizeFunc) camel_imap_wrapper_finalize);
- }
-
- return type;
-}
-
-
-static void
-imap_wrapper_hydrate (CamelImapWrapper *imap_wrapper, CamelStream *stream)
-{
- CamelDataWrapper *data_wrapper = (CamelDataWrapper *) imap_wrapper;
-
- camel_object_ref (stream);
- data_wrapper->stream = stream;
- data_wrapper->offline = FALSE;
-
- camel_object_unref (imap_wrapper->folder);
- imap_wrapper->folder = NULL;
- g_free (imap_wrapper->uid);
- imap_wrapper->uid = NULL;
- g_free (imap_wrapper->part_spec);
- imap_wrapper->part = NULL;
-}
-
-
-static ssize_t
-write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- CamelImapWrapper *imap_wrapper = CAMEL_IMAP_WRAPPER (data_wrapper);
-
- CAMEL_IMAP_WRAPPER_LOCK (imap_wrapper, lock);
- if (data_wrapper->offline) {
- CamelStream *datastream;
-
- datastream = camel_imap_folder_fetch_data (
- imap_wrapper->folder, imap_wrapper->uid,
- imap_wrapper->part_spec, FALSE, NULL);
- if (!datastream) {
- CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
- errno = ENETUNREACH;
- return -1;
- }
-
- imap_wrapper_hydrate (imap_wrapper, datastream);
- camel_object_unref (datastream);
- }
- CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
-
- return parent_class->write_to_stream (data_wrapper, stream);
-}
-
-
-CamelDataWrapper *
-camel_imap_wrapper_new (CamelImapFolder *imap_folder, CamelContentType *type,
- const char *uid, const char *part_spec,
- CamelMimePart *part)
-{
- CamelImapWrapper *imap_wrapper;
- CamelStream *stream;
-
- imap_wrapper = (CamelImapWrapper *)camel_object_new(camel_imap_wrapper_get_type());
-
- camel_data_wrapper_set_mime_type_field (CAMEL_DATA_WRAPPER (imap_wrapper), type);
- ((CamelDataWrapper *)imap_wrapper)->offline = TRUE;
-
- imap_wrapper->folder = imap_folder;
- camel_object_ref (imap_folder);
- imap_wrapper->uid = g_strdup (uid);
- imap_wrapper->part_spec = g_strdup (part_spec);
-
- /* Don't ref this, it's our parent. */
- imap_wrapper->part = part;
-
- /* Try the cache. */
- stream = camel_imap_folder_fetch_data (imap_folder, uid, part_spec,
- TRUE, NULL);
- if (stream) {
- imap_wrapper_hydrate (imap_wrapper, stream);
- camel_object_unref (stream);
- }
-
- return (CamelDataWrapper *)imap_wrapper;
-}
diff --git a/camel/providers/imap/camel-imap-wrapper.h b/camel/providers/imap/camel-imap-wrapper.h
deleted file mode 100644
index 4f7ca5097a..0000000000
--- a/camel/providers/imap/camel-imap-wrapper.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-wrapper.h: data wrapper for offline IMAP data */
-
-/*
- * Copyright 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_WRAPPER_H
-#define CAMEL_IMAP_WRAPPER_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <camel/camel-data-wrapper.h>
-#include "camel-imap-types.h"
-
-#define CAMEL_IMAP_WRAPPER_TYPE (camel_imap_wrapper_get_type ())
-#define CAMEL_IMAP_WRAPPER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_WRAPPER_TYPE, CamelImapWrapper))
-#define CAMEL_IMAP_WRAPPER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAP_WRAPPER_TYPE, CamelImapWrapperClass))
-#define CAMEL_IS_IMAP_WRAPPER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_WRAPPER_TYPE))
-
-typedef struct
-{
- CamelDataWrapper parent_object;
-
- struct _CamelImapWrapperPrivate *priv;
-
- CamelImapFolder *folder;
- char *uid, *part_spec;
- CamelMimePart *part;
-} CamelImapWrapper;
-
-typedef struct {
- CamelDataWrapperClass parent_class;
-
-} CamelImapWrapperClass;
-
-/* Standard Camel function */
-CamelType camel_imap_wrapper_get_type (void);
-
-/* Constructor */
-CamelDataWrapper *camel_imap_wrapper_new (CamelImapFolder *imap_folder,
- CamelContentType *type,
- const char *uid,
- const char *part_spec,
- CamelMimePart *part);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_DATA_WRAPPER_H */
diff --git a/camel/providers/imap/libcamelimap.urls b/camel/providers/imap/libcamelimap.urls
deleted file mode 100644
index c301c0ffac..0000000000
--- a/camel/providers/imap/libcamelimap.urls
+++ /dev/null
@@ -1 +0,0 @@
-imap
diff --git a/camel/providers/imapp/.cvsignore b/camel/providers/imapp/.cvsignore
deleted file mode 100644
index 3fa8afaa38..0000000000
--- a/camel/providers/imapp/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.deps
-Makefile
-Makefile.in
-.libs
-.deps
-*.lo
-*.la
-*.bb
-*.bbg
-*.da
-*.gcov
diff --git a/camel/providers/imapp/Makefile.am b/camel/providers/imapp/Makefile.am
deleted file mode 100644
index 7ce8c65fcd..0000000000
--- a/camel/providers/imapp/Makefile.am
+++ /dev/null
@@ -1,45 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelimappincludedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamelimapp.la
-camel_provider_DATA = libcamelimapp.urls
-
-INCLUDES = -I.. \
- -I$(srcdir)/.. \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/e-util \
- -I$(top_srcdir) \
- $(CAMEL_CFLAGS) \
- $(GNOME_INCLUDEDIR) \
- $(GTK_INCLUDEDIR) \
- -DG_LOG_DOMAIN=\"camel-imapp-provider\"
-
-libcamelimapp_la_SOURCES = \
- camel-imapp-utils.c \
- camel-imapp-engine.c \
- camel-imapp-stream.c \
- camel-imapp-store.c \
- camel-imapp-folder.c \
- camel-imapp-provider.c \
- camel-imapp-store-summary.c \
- camel-imapp-driver.c \
- camel-imapp-summary.c
-
-libcamelimappinclude_HEADERS = \
- camel-imapp-utils.h \
- camel-imapp-engine.h \
- camel-imapp-stream.h \
- camel-imapp-store.h \
- camel-imapp-folder.h \
- camel-imapp-store-summary.h \
- camel-imapp-driver.h \
- camel-imapp-summary.h
-
-libcamelimapp_la_LDFLAGS = -avoid-version -module
-
-#noinst_HEADERS = \
-# camel-imap-private.h
-
-EXTRA_DIST = libcamelimapp.urls
diff --git a/camel/providers/imapp/camel-imapp-driver.c b/camel/providers/imapp/camel-imapp-driver.c
deleted file mode 100644
index 106e98fbb3..0000000000
--- a/camel/providers/imapp/camel-imapp-driver.c
+++ /dev/null
@@ -1,771 +0,0 @@
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#include "camel-imapp-driver.h"
-#include "camel-imapp-utils.h"
-#include "camel-imapp-folder.h"
-#include "camel-imapp-engine.h"
-#include "camel-imapp-summary.h"
-#include "camel-imapp-exception.h"
-
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-stream-null.h>
-
-#include <camel/camel-folder-summary.h>
-#include <camel/camel-store.h>
-#include <camel/camel-mime-utils.h>
-#include <camel/camel-sasl.h>
-
-#define d(x) x
-
-static int driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata);
-static int driver_resp_expunge(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata);
-static int driver_resp_exists(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata);
-static int driver_resp_list(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata);
-
-static void driver_status(CamelIMAPPEngine *ie, struct _status_info *sinfo, CamelIMAPPDriver *sdata);
-
-static void
-class_init(CamelIMAPPDriverClass *ieclass)
-{
-}
-
-static void
-object_init(CamelIMAPPDriver *ie, CamelIMAPPDriverClass *ieclass)
-{
- ie->summary = g_ptr_array_new();
- e_dlist_init(&ie->body_fetch);
- e_dlist_init(&ie->body_fetch_done);
-}
-
-static void
-object_finalise(CamelIMAPPDriver *ie, CamelIMAPPDriverClass *ieclass)
-{
- if (ie->folder)
- camel_object_unref((CamelObject *)ie->folder);
- if (ie->engine)
- camel_object_unref((CamelObject *)ie->engine);
- if (ie->summary)
- g_ptr_array_free(ie->summary, TRUE);
-}
-
-CamelType
-camel_imapp_driver_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register (
- camel_object_get_type (),
- "CamelIMAPPDriver",
- sizeof (CamelIMAPPDriver),
- sizeof (CamelIMAPPDriverClass),
- (CamelObjectClassInitFunc) class_init,
- NULL,
- (CamelObjectInitFunc) object_init,
- (CamelObjectFinalizeFunc) object_finalise);
- }
-
- return type;
-}
-
-CamelIMAPPDriver *
-camel_imapp_driver_new(CamelIMAPPStream *stream)
-{
- CamelIMAPPDriver *driver;
- CamelIMAPPEngine *ie;
-
- driver = CAMEL_IMAPP_DRIVER (camel_object_new (CAMEL_IMAPP_DRIVER_TYPE));
- ie = driver->engine = camel_imapp_engine_new(stream);
-
- camel_imapp_engine_add_handler(ie, "FETCH", (CamelIMAPPEngineFunc)driver_resp_fetch, driver);
- camel_imapp_engine_add_handler(ie, "EXPUNGE", (CamelIMAPPEngineFunc)driver_resp_expunge, driver);
- camel_imapp_engine_add_handler(ie, "EXISTS", (CamelIMAPPEngineFunc)driver_resp_exists, driver);
- camel_imapp_engine_add_handler(ie, "LIST", (CamelIMAPPEngineFunc)driver_resp_list, driver);
- camel_object_hook_event(ie, "status", (CamelObjectEventHookFunc)driver_status, driver);
-
- return driver;
-}
-
-void
-camel_imapp_driver_set_sasl_factory(CamelIMAPPDriver *id, CamelIMAPPSASLFunc get_sasl, void *sasl_data)
-{
- id->get_sasl = get_sasl;
- id->get_sasl_data = sasl_data;
-}
-
-void
-camel_imapp_driver_set_login_query(CamelIMAPPDriver *id, CamelIMAPPLoginFunc get_login, void *login_data)
-{
- id->get_login = get_login;
- id->get_login_data = login_data;
-}
-
-void
-camel_imapp_driver_login(CamelIMAPPDriver *id)
-/* throws SERVICE_CANT_AUTHENTICATE, SYSTEM_IO */
-{
- CamelIMAPPCommand * volatile ic = NULL;
-
- /* connect? */
- /* camel_imapp_engine_connect() */
- /* or above? */
-
- CAMEL_TRY {
- CamelSasl *sasl;
-
- if (id->get_sasl
- && (sasl = id->get_sasl(id, id->get_sasl_data))) {
- ic = camel_imapp_engine_command_new(id->engine, "AUTHENTICATE", NULL, "AUTHENTICATE %A", sasl);
- camel_object_unref(sasl);
- } else {
- char *user, *pass;
-
- g_assert(id->get_login);
- id->get_login(id, &user, &pass, id->get_login_data);
- ic = camel_imapp_engine_command_new(id->engine, "LOGIN", NULL, "LOGIN %s %s", user, pass);
- g_free(user);
- g_free(pass);
- }
-
- camel_imapp_engine_command_queue(id->engine, ic);
- while (camel_imapp_engine_iterate(id->engine, ic) > 0)
- ;
-
- if (ic->status->result != IMAP_OK)
- camel_exception_throw(CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, "Login failed: %s", ic->status->text);
- camel_imapp_engine_command_free(id->engine, ic);
- } CAMEL_CATCH(ex) {
- if (ic)
- camel_imapp_engine_command_free(id->engine, ic);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-}
-
-void
-camel_imapp_driver_select(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder)
-{
- CamelIMAPPSelectResponse *sr;
- CamelIMAPPCommand * volatile ic = NULL;
- CamelIMAPPCommand * volatile ic2 = NULL;
- guint32 count;
- CamelFolderSummary *summary;
-
- if (id->folder) {
- if (folder == id->folder)
- return;
- camel_imapp_driver_sync(id, FALSE, id->folder);
- if (camel_folder_change_info_changed(id->folder->changes)) {
- camel_object_trigger_event(id->folder, "folder_changed", id->folder->changes);
- camel_folder_change_info_clear(id->folder->changes);
- }
- camel_object_unref(id->folder);
- id->folder = NULL;
- }
-
- summary = ((CamelFolder *)folder)->summary;
-
- ic = camel_imapp_engine_command_new(id->engine, "SELECT", NULL, "SELECT %t", folder->raw_name);
- camel_imapp_engine_command_queue(id->engine, ic);
- while (camel_imapp_engine_iterate(id->engine, ic)>0)
- ;
- camel_imapp_engine_command_free(id->engine, ic);
-
- id->folder = folder;
- camel_object_ref(folder);
-
- count = camel_folder_summary_count(summary);
- if (count > 0 && count <= id->exists) {
- ic = camel_imapp_engine_command_new(id->engine, "FETCH", NULL,
- "FETCH 1:%u (UID FLAGS)", count);
- camel_imapp_engine_command_queue(id->engine, ic);
- if (count < id->exists) {
- ic2 = camel_imapp_engine_command_new(id->engine, "FETCH", NULL,
- "FETCH %u:* (UID FLAGS ENVELOPE)", count+1);
- camel_imapp_engine_command_queue(id->engine, ic2);
- } else {
- ic2 = NULL;
- }
-
- while (camel_imapp_engine_iterate(id->engine, ic2?ic2:ic)>0)
- ;
-
- camel_imapp_engine_command_free(id->engine, ic);
- if (ic2)
- camel_imapp_engine_command_free(id->engine, ic2);
- } else {
- ic = camel_imapp_engine_command_new(id->engine, "FETCH", NULL,
- "FETCH 1:* (UID FLAGS ENVELOPE)");
- camel_imapp_engine_command_queue(id->engine, ic);
- while (camel_imapp_engine_iterate(id->engine, ic)>0)
- ;
- camel_imapp_engine_command_free(id->engine, ic);
- }
-
- /* TODO: need to set exists/etc in summary */
- folder->exists = id->exists;
- folder->uidvalidity = id->uidvalidity;
-
- printf("saving summary '%s'\n", summary->summary_path);
- camel_folder_summary_save(summary);
-
- if (camel_folder_change_info_changed(id->folder->changes)) {
- camel_object_trigger_event(id->folder, "folder_changed", id->folder->changes);
- camel_folder_change_info_clear(id->folder->changes);
- }
-}
-
-static void
-imapp_driver_check(CamelIMAPPDriver *id)
-{
- guint32 count;
- CamelIMAPPCommand *ic;
-
- /* FIXME: exception handling */
-
- if (id->folder->exists != id->exists) {
- count = camel_folder_summary_count(((CamelFolder *)id->folder)->summary);
- if (count < id->exists) {
- printf("fetching new messages\n");
- ic = camel_imapp_engine_command_new(id->engine, "FETCH", NULL,
- "FETCH %u:* (UID FLAGS ENVELOPE)", count+1);
- camel_imapp_engine_command_queue(id->engine, ic);
- while (camel_imapp_engine_iterate(id->engine, ic)>0)
- ;
- camel_imapp_engine_command_free(id->engine, ic);
- } else if (count > id->exists) {
- printf("folder shrank with no expunge notificaitons!? uh, dunno what to do\n");
- }
- }
-
- printf("checking for change info changes\n");
- if (camel_folder_change_info_changed(id->folder->changes)) {
- printf("got somechanges! added=%d changed=%d removed=%d\n",
- id->folder->changes->uid_added->len,
- id->folder->changes->uid_changed->len,
- id->folder->changes->uid_removed->len);
- camel_object_trigger_event(id->folder, "folder_changed", id->folder->changes);
- camel_folder_change_info_clear(id->folder->changes);
- }
-}
-
-void
-camel_imapp_driver_update(CamelIMAPPDriver *id, CamelIMAPPFolder *folder)
-{
- if (id->folder == folder) {
- CamelIMAPPCommand *ic;
-
- /* this will automagically update flags & expunge items */
- ic = camel_imapp_engine_command_new(id->engine, "NOOP", NULL, "NOOP");
- camel_imapp_engine_command_queue(id->engine, ic);
- while (camel_imapp_engine_iterate(id->engine, ic)>0)
- ;
- camel_imapp_engine_command_free(id->engine, ic);
-
- imapp_driver_check(id);
- } else {
- camel_imapp_driver_select(id, folder);
- }
-}
-
-/* FIXME: this is basically a copy of the same in camel-imapp-utils.c */
-static struct {
- char *name;
- guint32 flag;
-} flag_table[] = {
- { "\\ANSWERED", CAMEL_MESSAGE_ANSWERED },
- { "\\DELETED", CAMEL_MESSAGE_DELETED },
- { "\\DRAFT", CAMEL_MESSAGE_DRAFT },
- { "\\FLAGGED", CAMEL_MESSAGE_FLAGGED },
- { "\\SEEN", CAMEL_MESSAGE_SEEN },
- /* { "\\RECENT", CAMEL_IMAPP_MESSAGE_RECENT }, */
-};
-
-/*
- flags 00101000
- sflags 01001000
- ^ 01100000
-~flags 11010111
-& 01000000
-
-&flags 00100000
-*/
-
-static void
-imapp_write_flags(CamelIMAPPDriver *id, guint32 orset, gboolean on, CamelFolderSummary *summary)
-{
- guint32 i, j, count;
- CamelIMAPPMessageInfo *info;
- CamelIMAPPCommand *ic = NULL;
- struct _uidset_state ss;
- GSList *commands = NULL;
-
- /* FIXME: exception handling */
-
- count = camel_folder_summary_count(summary);
- for (j=0;j<sizeof(flag_table)/sizeof(flag_table[0]);j++) {
- int flush;
-
- if ((orset & flag_table[j].flag) == 0)
- continue;
-
- printf("checking/storing %s flags '%s'\n", on?"on":"off", flag_table[j].name);
-
- flush = 0;
- imapp_uidset_init(&ss, id->engine);
- for (i=0;i<count;i++) {
- info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, i);
- if (info) {
- guint32 flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS;
- guint32 sflags = info->server_flags & CAMEL_IMAPP_SERVER_FLAGS;
-
- if ( (on && (((flags ^ sflags) & flags) & flag_table[j].flag))
- || (!on && (((flags ^ sflags) & ~flags) & flag_table[j].flag))) {
- if (ic == NULL)
- ic = camel_imapp_engine_command_new(id->engine, "STORE", NULL, "UID STORE ");
- flush = imapp_uidset_add(&ss, ic, camel_message_info_uid(info));
- }
- camel_folder_summary_info_free(summary, (CamelMessageInfo *)info);
- }
-
- if (i == count-1 && ic != NULL)
- flush |= imapp_uidset_done(&ss, ic);
-
- if (flush) {
- flush = 0;
- camel_imapp_engine_command_add(id->engine, ic, " %tFLAGS.SILENT (%t)", on?"+":"-", flag_table[j].name);
- camel_imapp_engine_command_queue(id->engine, ic);
- commands = g_slist_prepend(commands, ic);
- ic = NULL;
- }
- }
- }
-
- /* flush off any requests we may have outstanding */
- /* TODO: for max benefit, should have this routine do both on and off flags in one go */
- while (commands) {
- GSList *next = commands->next;
-
- ic = commands->data;
- g_slist_free_1(commands);
- commands = next;
-
- while (camel_imapp_engine_iterate(id->engine, ic)>0)
- ;
- camel_imapp_engine_command_free(id->engine, ic);
- }
-}
-
-void
-camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, CamelIMAPPFolder *folder)
-{
- CamelFolderSummary *summary;
- guint i, count, on_orset, off_orset;
- CamelIMAPPMessageInfo *info;
- CamelIMAPPCommand *ic;
-
- /* FIXME: exception handling */
-
- camel_imapp_driver_update(id, folder);
-
- summary = ((CamelFolder *)folder)->summary;
- count = camel_folder_summary_count(summary);
- /* find out which flags have turned on, which have tunred off */
- off_orset = on_orset = 0;
- for (i=0;i<count;i++) {
- guint32 flags, sflags;
-
- info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, i);
- if (info == NULL)
- continue;
- flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS;
- sflags = info->server_flags & CAMEL_IMAPP_SERVER_FLAGS;
- if (flags != sflags) {
- off_orset |= ( flags ^ sflags ) & ~flags;
- on_orset |= (flags ^ sflags) & flags;
- }
- camel_folder_summary_info_free(summary, (CamelMessageInfo *)info);
- }
-
- if (on_orset || off_orset) {
- /* turn on or off all messages matching */
- if (on_orset)
- imapp_write_flags(id, on_orset, TRUE, summary);
- if (off_orset)
- imapp_write_flags(id, off_orset, FALSE, summary);
-
- /* success (no exception), make sure we match what we're supposed to */
- for (i=0;i<count;i++) {
- guint32 flags, sflags;
-
- info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, i);
- if (info == NULL)
- continue;
- info->server_flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS;
- camel_folder_summary_info_free(summary, (CamelMessageInfo *)info);
- }
- camel_folder_summary_touch(summary);
- /* could save summary here, incase of failure? */
- }
-
- if (expunge) {
- ic = camel_imapp_engine_command_new(id->engine, "EXPUNGE", NULL, "EXPUNGE");
- camel_imapp_engine_command_queue(id->engine, ic);
- while (camel_imapp_engine_iterate(id->engine, ic)>0)
- ;
- camel_imapp_engine_command_free(id->engine, ic);
- }
-
- printf("saving summary '%s'\n", summary->summary_path);
- camel_folder_summary_save(summary);
-
- if (camel_folder_change_info_changed(id->folder->changes)) {
- camel_object_trigger_event(id->folder, "folder_changed", id->folder->changes);
- camel_folder_change_info_clear(id->folder->changes);
- }
-}
-
-struct _fetch_data {
- struct _fetch_data *next;
- struct _fetch_data *prev;
-
- CamelStream *data;
- const char *uid;
- const char *section;
-};
-
-CamelStream *
-camel_imapp_driver_fetch(CamelIMAPPDriver *id, CamelIMAPPFolder *folder, const char *uid, const char *section)
-{
- struct _fetch_data fd;
- CamelIMAPPCommand *ic;
-
- fd.data = NULL;
- fd.uid = uid;
- fd.section = section;
- e_dlist_addtail(&id->body_fetch, (EDListNode *)&fd);
-
- CAMEL_TRY {
- camel_imapp_driver_select(id, folder);
-
- ic = camel_imapp_engine_command_new(id->engine, "FETCH", NULL, "UID FETCH %t (BODY.PEEK[%t])", uid, section);
- camel_imapp_engine_command_queue(id->engine, ic);
- while (camel_imapp_engine_iterate(id->engine, ic)>0)
- ;
- camel_imapp_engine_command_free(id->engine, ic);
- imapp_driver_check(id);
- } CAMEL_CATCH(e) {
- /* FIXME: do exception properly */
- } CAMEL_DONE;
-
- e_dlist_remove((EDListNode *)&fd);
-
- return fd.data;
-}
-
-GPtrArray *
-camel_imapp_driver_list(CamelIMAPPDriver *id, const char *name, guint32 flags)
-{
- CamelIMAPPCommand * volatile ic;
- GPtrArray *res;
-
- g_assert(id->list_commands == NULL);
- g_assert(id->list_result == NULL);
-
- /* FIXME: make sure we only have a single list running at a time */
- /* sem_wait(id->list_sem); */
-
- /* FIXME: namespace stuff (done in store code?) */
-
- /* FIXME: if name != "", we need to also do list "name.%" (. == sep) */
-
- id->list_result = g_ptr_array_new();
- id->list_flags = flags;
- CAMEL_TRY {
- ic = camel_imapp_engine_command_new(id->engine, "LIST", NULL, "LIST \"\" %f", name[0]?name:"%");
- camel_imapp_engine_command_queue(id->engine, ic);
- while (ic) {
- while (camel_imapp_engine_iterate(id->engine, ic)>0)
- ;
- camel_imapp_engine_command_free(id->engine, ic);
-
- if (id->list_commands) {
- GSList *top = id->list_commands;
-
- id->list_commands = top->next;
- ic = top->data;
- g_slist_free_1(top);
- } else {
- ic = NULL;
- }
- }
- } CAMEL_CATCH(e) {
- GSList *top = id->list_commands;
- int i;
-
- camel_imapp_engine_command_free(id->engine, ic);
-
- while (top) {
- GSList *topn = top->next;
-
- camel_imapp_engine_command_free(id->engine, ic);
- g_slist_free_1(top);
- top = topn;
- }
- id->list_commands = NULL;
-
- res = id->list_result;
- for (i=0;i<res->len;i++)
- imap_free_list(res->pdata[i]);
- g_ptr_array_free(res, TRUE);
- id->list_result = NULL;
-
- camel_exception_throw_ex(e);
- } CAMEL_DONE;
-
- res = id->list_result;
- id->list_result = NULL;
-
- /* sem_post(id->list_sem); */
-
- return res;
-}
-
-static int
-driver_resp_list(CamelIMAPPEngine *ie, guint32 idx, CamelIMAPPDriver *id)
-{
- struct _list_info *linfo;
-
- /* FIXME: exceptions */
-
- linfo = imap_parse_list(ie->stream);
- printf("store list: '%s' ('%c')\n", linfo->name, linfo->separator);
- if (id->list_result) {
- if ((linfo->flags & CAMEL_FOLDER_NOINFERIORS) == 0
- && (id->list_flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)
- && linfo->separator) {
- int depth = 0;
- char *p = linfo->name;
- char c = linfo->separator;
-
- /* this is expensive ... but if we've listed this deep we're going slow anyway */
- while (*p && depth < 10) {
- if (*p == c)
- depth++;
- p++;
- }
-
- if (depth < 10
- && (linfo->name[0] == 0 || linfo->name[strlen(linfo->name)-1] != c)) {
- CamelIMAPPCommand *ic;
-
- ic = camel_imapp_engine_command_new(id->engine, "LIST", NULL, "LIST \"\" %t%c%%", linfo->name, c);
- id->list_commands = g_slist_prepend(id->list_commands, ic);
- camel_imapp_engine_command_queue(id->engine, ic);
- }
- }
- /* FIXME: dont add to list if name ends in separator */
- g_ptr_array_add(id->list_result, linfo);
- } else {
- g_warning("unexpected list response\n");
- imap_free_list(linfo);
- }
-
- return camel_imapp_engine_skip(ie);
-}
-
-/* ********************************************************************** */
-
-static void
-driver_status(CamelIMAPPEngine *ie, struct _status_info *sinfo, CamelIMAPPDriver *sdata)
-{
- printf("got status response ...\n");
- switch(sinfo->condition) {
- case IMAP_READ_WRITE:
- printf("folder is read-write\n");
- break;
- case IMAP_READ_ONLY:
- printf("folder is read-only\n");
- break;
- case IMAP_UIDVALIDITY:
- sdata->uidvalidity = sinfo->u.uidvalidity;
- break;
-#if 0
- /* not defined yet ... */
- case IMAP_UIDNEXT:
- printf("got uidnext for folder: %d\n", sinfo->u.uidnext);
- break;
-#endif
- case IMAP_UNSEEN:
- sdata->unseen = sinfo->u.unseen;
- break;
- case IMAP_PERMANENTFLAGS:
- sdata->permanentflags = sinfo->u.permanentflags;
- break;
- case IMAP_ALERT:
- printf("ALERT!: %s\n", sinfo->text);
- break;
- case IMAP_PARSE:
- printf("PARSE: %s\n", sinfo->text);
- break;
- default:
- break;
- }
-}
-
-static int
-driver_resp_exists(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
-{
- /* should this be an event instead? */
-
- sdata->exists = id;
-
- return camel_imapp_engine_skip(ie);
-}
-
-static int
-driver_resp_expunge(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
-{
- printf("got expunge response %u\n", id);
- if (sdata->folder != NULL) {
- CamelMessageInfo *info;
- CamelFolderSummary *summary = ((CamelFolder *)sdata->folder)->summary;
-
- info = camel_folder_summary_index(summary, id-1);
- if (info) {
- printf("expunging msg %d\n", id);
- camel_folder_summary_remove(summary, info);
- camel_folder_summary_info_free(summary, info);
- camel_folder_change_info_remove_uid(sdata->folder->changes, camel_message_info_uid(info));
- } else {
- printf("can not find msg %u from expunge\n", id);
- }
- }
-
- return camel_imapp_engine_skip(ie);
-}
-
-static int
-driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
-{
- struct _fetch_info *finfo = NULL;
- CamelMessageInfo *info, *uinfo;
- unsigned int i;
- CamelFolderSummary *summary;
-
- printf("got fetch response %d\n", id);
-
- if (sdata->folder == NULL)
- goto done;
-
- summary = ((CamelFolder *)sdata->folder)->summary;
-
- finfo = imap_parse_fetch(ie->stream);
- imap_dump_fetch(finfo);
-
- info = camel_folder_summary_index(summary, id-1);
- if (info == NULL) {
- if (finfo->uid == NULL) {
- printf("got fetch response for currently unknown message %u\n", id);
- goto done;
- }
- uinfo = camel_folder_summary_uid(summary, finfo->uid);
- if (uinfo) {
- /* we have a problem ... index mismatch */
- printf("index mismatch, uid '%s' not at index '%u'\n",
- finfo->uid, id);
- camel_folder_summary_info_free(summary, uinfo);
- }
- /* pad out the summary till we have enough indexes */
- for (i=camel_folder_summary_count(summary);i<id;i++) {
- info = camel_folder_summary_info_new(summary);
- if (i == id-1) {
- printf("inserting new info @ %u\n", i);
- camel_message_info_set_uid(info, g_strdup(finfo->uid));
- } else {
- char uidtmp[32];
-
- sprintf(uidtmp, "blank-%u", i);
- camel_message_info_set_uid(info, g_strdup(uidtmp));
- printf("inserting empty uid %s\n", uidtmp);
- }
-
- camel_folder_summary_add(summary, info);
- }
- info = camel_folder_summary_index(summary, id-1);
- g_assert(info != NULL);
- } else {
- if (finfo->uid) {
- /* FIXME: need to handle blank-* uids, somehow */
- while (info && strcmp(camel_message_info_uid(info), finfo->uid) != 0) {
- printf("index mismatch, uid '%s' not at index '%u', got '%s' instead (removing)\n",
- finfo->uid, id, camel_message_info_uid(info));
-
- camel_folder_change_info_remove_uid(sdata->folder->changes, camel_message_info_uid(info));
- camel_folder_summary_remove(summary, info);
- camel_folder_summary_info_free(summary, info);
- info = camel_folder_summary_index(summary, id-1);
- }
- } else {
- printf("got info for unknown message %u\n", id);
- }
- }
-
- if (info) {
- if (finfo->got & FETCH_MINFO) {
- /* if we only use ENVELOPE? */
- camel_message_info_set_subject(info, g_strdup(camel_message_info_subject(finfo->minfo)));
- camel_message_info_set_from(info, g_strdup(camel_message_info_from(finfo->minfo)));
- camel_message_info_set_to(info, g_strdup(camel_message_info_to(finfo->minfo)));
- camel_message_info_set_cc(info, g_strdup(camel_message_info_cc(finfo->minfo)));
- info->date_sent = finfo->minfo->date_sent;
- camel_folder_change_info_add_uid(sdata->folder->changes, camel_message_info_uid(info));
- printf("adding change info uid '%s'\n", camel_message_info_uid(info));
- }
-
- if (finfo->got & FETCH_FLAGS) {
- if ((info->flags & CAMEL_IMAPP_SERVER_FLAGS) != (finfo->flags & CAMEL_IMAPP_SERVER_FLAGS)) {
- camel_folder_change_info_change_uid(sdata->folder->changes, camel_message_info_uid(info));
- info->flags = (info->flags & ~(CAMEL_IMAPP_SERVER_FLAGS)) | (finfo->flags & CAMEL_IMAPP_SERVER_FLAGS);
- camel_folder_summary_touch(summary);
- }
- ((CamelIMAPPMessageInfo *)info)->server_flags = finfo->flags & CAMEL_IMAPP_SERVER_FLAGS;
- }
-
- if ((finfo->got & (FETCH_BODY|FETCH_UID)) == (FETCH_BODY|FETCH_UID)) {
- struct _fetch_data *fd, *fn;
-
- fd = (struct _fetch_data *)sdata->body_fetch.head;
- fn = fd->next;
- while (fn) {
- if (!strcmp(finfo->uid, fd->uid) && !strcmp(finfo->section, fd->section)) {
- if (fd->data)
- camel_object_unref(fd->data);
- fd->data = finfo->body;
- camel_object_ref(fd->data);
- e_dlist_remove((EDListNode *)fd);
- e_dlist_addtail(&sdata->body_fetch_done, (EDListNode *)fd);
- break;
- }
- fd = fn;
- fn = fn->next;
- }
- }
-
- camel_folder_summary_info_free(summary, info);
- } else {
- printf("dont know what to do with message\n");
- }
- done:
- imap_free_fetch(finfo);
-
- return camel_imapp_engine_skip(ie);
-}
diff --git a/camel/providers/imapp/camel-imapp-driver.h b/camel/providers/imapp/camel-imapp-driver.h
deleted file mode 100644
index 3124700619..0000000000
--- a/camel/providers/imapp/camel-imapp-driver.h
+++ /dev/null
@@ -1,81 +0,0 @@
-
-#ifndef _CAMEL_IMAPP_DRIVER_H
-#define _CAMEL_IMAPP_DRIVER_H
-
-#include <camel/camel-object.h>
-#include "camel-imapp-stream.h"
-#include <e-util/e-msgport.h>
-
-#define CAMEL_IMAPP_DRIVER_TYPE (camel_imapp_driver_get_type ())
-#define CAMEL_IMAPP_DRIVER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_DRIVER_TYPE, CamelIMAPPDriver))
-#define CAMEL_IMAPP_DRIVER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_DRIVER_TYPE, CamelIMAPPDriverClass))
-#define CAMEL_IS_IMAP_DRIVER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPP_DRIVER_TYPE))
-
-typedef struct _CamelIMAPPDriver CamelIMAPPDriver;
-typedef struct _CamelIMAPPDriverClass CamelIMAPPDriverClass;
-
-typedef int (*CamelIMAPPDriverFunc)(struct _CamelIMAPPDriver *driver, void *data);
-typedef struct _CamelSasl * (*CamelIMAPPSASLFunc)(struct _CamelIMAPPDriver *driver, void *data);
-typedef void (*CamelIMAPPLoginFunc)(struct _CamelIMAPPDriver *driver, char **login, char **pass, void *data);
-
-struct _CamelMimeMessage;
-
-struct _CamelIMAPPDriver {
- CamelObject parent_object;
-
- struct _CamelIMAPPEngine *engine;
-
- struct _CamelIMAPPFolder *folder;
-
- /* current folder stuff */
- GPtrArray *summary;
- guint32 uidvalidity;
- guint32 exists;
- guint32 recent;
- guint32 unseen;
- guint32 permanentflags;
-
- /* list stuff */
- GPtrArray *list_result;
- GSList *list_commands;
- guint32 list_flags;
-
- /* sem_t list_sem; for controlled access to list variables */
-
- /* this is so the node is always in a list - easier exception management */
- EDList body_fetch;
- EDList body_fetch_done;
-
- /* factory to get an appropriate sasl mech */
- CamelIMAPPSASLFunc get_sasl;
- void *get_sasl_data;
-
- /* callbacks, get login username/pass */
- CamelIMAPPLoginFunc get_login;
- void *get_login_data;
-};
-
-struct _CamelIMAPPDriverClass {
- CamelObjectClass parent_class;
-};
-
-CamelType camel_imapp_driver_get_type (void);
-
-CamelIMAPPDriver * camel_imapp_driver_new(CamelIMAPPStream *stream);
-
-void camel_imapp_driver_set_sasl_factory(CamelIMAPPDriver *id, CamelIMAPPSASLFunc get_sasl, void *sasl_data);
-void camel_imapp_driver_set_login_query(CamelIMAPPDriver *id, CamelIMAPPLoginFunc get_login, void *login_data);
-
-void camel_imapp_driver_login(CamelIMAPPDriver *id);
-
-void camel_imapp_driver_select(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder);
-void camel_imapp_driver_update(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder);
-void camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, struct _CamelIMAPPFolder *folder);
-
-struct _CamelStream * camel_imapp_driver_fetch(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder, const char *uid, const char *body);
-GPtrArray * camel_imapp_driver_list(CamelIMAPPDriver *id, const char *name, guint32 flags);
-
-struct _CamelStream *camel_imapp_driver_get(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder, const char *uid);
-void camel_imapp_driver_append(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder, struct _CamelDataWrapper *);
-
-#endif
diff --git a/camel/providers/imapp/camel-imapp-engine.c b/camel/providers/imapp/camel-imapp-engine.c
deleted file mode 100644
index df14903c5a..0000000000
--- a/camel/providers/imapp/camel-imapp-engine.c
+++ /dev/null
@@ -1,1180 +0,0 @@
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include "camel-imapp-engine.h"
-#include "camel-imapp-stream.h"
-#include "camel-imapp-utils.h"
-#include "camel-imapp-exception.h"
-
-#include <camel/camel-folder-summary.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-stream-null.h>
-#include <camel/camel-data-wrapper.h>
-#include <camel/camel-sasl.h>
-
-#include <ctype.h>
-
-#define e(x)
-#define c(x) /* command build debug */
-
-static void imap_engine_command_addv(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const char *fmt, va_list ap);
-static void imap_engine_command_complete(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic);
-
-struct _handler {
- CamelIMAPPEngineFunc func;
- void *data;
- char name[1];
-};
-
-static void
-class_init(CamelIMAPPEngineClass *ieclass)
-{
- ieclass->tagprefix = 'A';
-
- camel_object_class_add_event((CamelObjectClass *)ieclass, "status", NULL);
-}
-
-static void
-object_init(CamelIMAPPEngine *ie, CamelIMAPPEngineClass *ieclass)
-{
- ie->handlers = g_hash_table_new(g_str_hash, g_str_equal);
- e_dlist_init(&ie->active);
- e_dlist_init(&ie->queue);
- e_dlist_init(&ie->done);
-
- ie->tagprefix = ieclass->tagprefix;
- ieclass->tagprefix++;
- if (ieclass->tagprefix > 'Z')
- ieclass->tagprefix = 'A';
- ie->tagprefix = 'A';
-
- ie->state = IMAP_ENGINE_DISCONNECT;
-}
-
-static void
-handler_free(void *key, void *mem, void *data)
-{
- g_free(mem);
-}
-
-static void
-object_finalise(CamelIMAPPEngine *ie, CamelIMAPPEngineClass *ieclass)
-{
- /* FIXME: need to free the commands ... */
- while (camel_imapp_engine_iterate(ie, NULL) > 0)
- ;
-
- g_hash_table_foreach(ie->handlers, (GHFunc)handler_free, NULL);
- g_hash_table_destroy(ie->handlers);
-}
-
-CamelType
-camel_imapp_engine_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register (
- camel_object_get_type (),
- "CamelIMAPPEngine",
- sizeof (CamelIMAPPEngine),
- sizeof (CamelIMAPPEngineClass),
- (CamelObjectClassInitFunc) class_init,
- NULL,
- (CamelObjectInitFunc) object_init,
- (CamelObjectFinalizeFunc) object_finalise);
- }
-
- return type;
-}
-
-/* FIXME: check this, just taken from old code, not rfc */
-struct {
- char *name;
- guint32 flag;
-} capa_table[] = {
- { "IMAP4", IMAP_CAPABILITY_IMAP4 },
- { "IMAP4REV1", IMAP_CAPABILITY_IMAP4REV1 },
- { "STATUS", IMAP_CAPABILITY_STATUS } ,
- { "NAMESPACE", IMAP_CAPABILITY_NAMESPACE },
- { "UIDPLUS", IMAP_CAPABILITY_UIDPLUS },
- { "LITERAL+", IMAP_CAPABILITY_LITERALPLUS },
- { "STARTTLS", IMAP_CAPABILITY_STARTTLS },
-};
-
-
-/*
-capability_data ::= "CAPABILITY" SPACE [1#capability SPACE] "IMAP4rev1"
- [SPACE 1#capability]
- ;; IMAP4rev1 servers which offer RFC 1730
- ;; compatibility MUST list "IMAP4" as the first
- ;; capability.
-*/
-static int resp_capability(CamelIMAPPEngine *ie, guint32 id, void *data)
-{
- int tok, len, i;
- unsigned char *token, *p, c;
-
- /* FIXME: handle auth types */
-
- printf("got capability response:\n");
- while (1) {
- tok = camel_imapp_stream_token(ie->stream, &token, &len);
- switch(tok) {
- case IMAP_TOK_TOKEN:
- p = token;
- while ((c = *p))
- *p++ = toupper(c);
- case IMAP_TOK_INT:
- printf(" cap: '%s'\n", token);
- for (i=0;i<(int)(sizeof(capa_table)/sizeof(capa_table[0]));i++)
- if (strcmp(token, capa_table[i].name))
- ie->capa |= capa_table[i].flag;
- break;
- case '\n':
- return 0;
- case IMAP_TOK_ERROR:
- case IMAP_TOK_PROTOCOL:
- camel_imapp_engine_skip(ie);
- return -1;
- default:
- printf("Unknown Response token %02x '%c'\n", tok, isprint(tok)?tok:'.');
- }
- } while (tok != '\n');
-
- return 0;
-}
-
-/* expunge command, id is expunged seq number */
-/* message_data ::= nz_number SPACE ("EXPUNGE" /
- ("FETCH" SPACE msg_att)) */
-static int resp_expunge(CamelIMAPPEngine *ie, guint32 id, void *data)
-{
- printf("message expunged: %d\n", id);
-
- return camel_imapp_engine_skip(ie);
-}
-
-static int resp_flags(CamelIMAPPEngine *ie, guint32 id, void *data)
-{
- guint32 flags;
-
- imap_parse_flags(ie->stream, &flags);
-
- printf("flags: %08x\n", flags);
-
- return camel_imapp_engine_skip(ie);
-}
-
-/* exists count */
-static int resp_exists(CamelIMAPPEngine *ie, guint32 id, void *data)
-{
- printf("messages exist: %d\n", id);
-
- if (ie->select_response)
- ie->select_response->exists = id;
-
- return camel_imapp_engine_skip(ie);
-}
-
-static int resp_recent(CamelIMAPPEngine *ie, guint32 id, void *data)
-{
- printf("messages recent: %d\n", id);
-
- if (ie->select_response)
- ie->select_response->recent = id;
-
- return camel_imapp_engine_skip(ie);
-}
-
-static int resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
-{
- struct _fetch_info *finfo;
-
- finfo = imap_parse_fetch(ie->stream);
- imap_dump_fetch(finfo);
- imap_free_fetch(finfo);
-
- return camel_imapp_engine_skip(ie);
-}
-
-#if 0
-static int resp_list(CamelIMAPPEngine *ie, guint32 id, void *data)
-{
- struct _list_info *linfo;
-
- linfo = imap_parse_list(ie->stream);
- printf("list: '%s' (%c)\n", linfo->name, linfo->separator);
- imap_free_list(linfo);
-
- return camel_imapp_engine_skip(ie);
-}
-#endif
-
-CamelIMAPPEngine *
-camel_imapp_engine_new(CamelIMAPPStream *stream)
-{
- CamelIMAPPEngine * volatile engine;
-
- engine = CAMEL_IMAPP_ENGINE (camel_object_new (CAMEL_IMAPP_ENGINE_TYPE));
- engine->stream = stream;
- camel_object_ref((CamelObject *)stream);
-
- camel_imapp_engine_add_handler(engine, "CAPABILITY", resp_capability, engine);
-
- /* mailbox_data */
- camel_imapp_engine_add_handler(engine, "FLAGS", (CamelIMAPPEngineFunc)resp_flags, engine);
- camel_imapp_engine_add_handler(engine, "EXISTS", (CamelIMAPPEngineFunc)resp_exists, engine);
- camel_imapp_engine_add_handler(engine, "RECENT", (CamelIMAPPEngineFunc)resp_recent, engine);
-
-#if 0
- camel_imapp_engine_add_handler(engine, "LIST", (CamelIMAPPEngineFunc)resp_list, engine);
- camel_imapp_engine_add_handler(engine, "LSUB", (CamelIMAPPEngineFunc)resp_list, engine);
-#endif
- /* message_data */
- camel_imapp_engine_add_handler(engine, "EXPUNGE", (CamelIMAPPEngineFunc)resp_expunge, engine);
- camel_imapp_engine_add_handler(engine, "FETCH", (CamelIMAPPEngineFunc)resp_fetch, engine);
-
- /* TODO: move this to a driver:connect call? */
- CAMEL_TRY {
- unsigned char *token;
- unsigned int len;
- int tok;
-
- tok = camel_imapp_stream_token(stream, &token, &len);
- if (tok == '*') {
- struct _status_info *sinfo = imap_parse_status(stream);
-
- switch (sinfo->result) {
- case IMAP_OK:
- engine->state = IMAP_ENGINE_CONNECT;
- printf("Server connected ok: %s\n", sinfo->text);
- break;
- case IMAP_PREAUTH:
- printf("pre-authenticated ...\n");
- engine->state = IMAP_ENGINE_AUTH;
- break;
- default:
- imap_free_status(sinfo);
- camel_exception_throw(1, "Server refused connection: %s", sinfo->text);
- break;
- }
- imap_free_status(sinfo);
- } else {
- engine->state = IMAP_ENGINE_CONNECT;
- printf("unknwon server greeting, ignored\n");
- camel_imapp_engine_skip(engine);
- }
- camel_imapp_engine_capabilities(engine);
- } CAMEL_CATCH(ex) {
- printf("connection failed: %s\n", ex->desc);
- camel_object_unref((CamelObject *)engine);
- engine = NULL;
- } CAMEL_DONE;
-
- return engine;
-}
-
-void
-camel_imapp_engine_add_handler(CamelIMAPPEngine *imap, const char *response, CamelIMAPPEngineFunc func, void *data)
-{
- struct _handler *h;
- const unsigned char *p;
- unsigned char *o, c;
-
- h = g_malloc0(sizeof(*h) + strlen(response));
- h->func = func;
- h->data = data;
-
- p = response;
- o = h->name;
- while ((c = *p++))
- *o++ = toupper(c);
- *o = 0;
-
- g_hash_table_insert(imap->handlers, h->name, h);
-}
-
-int
-camel_imapp_engine_capabilities(CamelIMAPPEngine *ie)
-{
- CamelIMAPPCommand *ic;
-
- /* reset capabilities */
- ie->capa = 0;
-
- ic = camel_imapp_engine_command_new(ie, "CAPABILITY", NULL, "CAPABILITY");
- camel_imapp_engine_command_queue(ie, ic);
- while (camel_imapp_engine_iterate(ie, ic)>0)
- ;
- camel_imapp_engine_command_free(ie, ic);
-
- return 0;
-}
-
-/* skip the rest of the line of tokens */
-int
-camel_imapp_engine_skip(CamelIMAPPEngine *imap)
-{
- int tok;
- unsigned char *token;
- unsigned int len;
-
- do {
- tok = camel_imapp_stream_token(imap->stream, &token, &len);
- if (tok == IMAP_TOK_LITERAL) {
- camel_imapp_stream_set_literal(imap->stream, len);
- while ((tok = camel_imapp_stream_getl(imap->stream, &token, &len)) > 0) {
- printf("Skip literal data '%.*s'\n", (int)len, token);
- }
- }
- } while (tok != '\n' && tok >= 0);
-
- if (tok < 0)
- return -1;
-
- return 0;
-}
-
-/* handle any untagged responses */
-static int
-iterate_untagged(CamelIMAPPEngine *imap)
-{
- unsigned int id, len;
- unsigned char *token, *p, c;
- int tok;
- struct _handler *h;
- struct _status_info *sinfo;
-
- e(printf("got untagged response\n"));
- id = 0;
- tok = camel_imapp_stream_token(imap->stream, &token, &len);
- if (tok == IMAP_TOK_INT) {
- id = strtoul(token, NULL, 10);
- tok = camel_imapp_stream_token(imap->stream, &token, &len);
- }
-
- if (tok == '\n')
- camel_exception_throw(1, "truncated server response");
-
- e(printf("Have token '%s' id %d\n", token, id));
- p = token;
- while ((c = *p))
- *p++ = toupper(c);
-
- /* first, check for generic unsolicited response */
- h = g_hash_table_lookup(imap->handlers, token);
- if (h) {
- tok = h->func(imap, id, h->data);
- if (tok < 0)
- return tok;
- return 1;
- }
-
- /* TODO: apart from bye/preauth, these could be callbacks/events? */
-
- /* now, check for status responses */
- switch (imap_tokenise(token, len)) {
- case IMAP_BYE:
- case IMAP_OK:
- case IMAP_NO:
- case IMAP_BAD:
- case IMAP_PREAUTH:
- /* TODO: validate which ones of these can happen as unsolicited responses */
- /* TODO: handle bye/preauth differently */
- /* FIXME: free sinfo */
- camel_imapp_stream_ungettoken(imap->stream, tok, token, len);
- sinfo = imap_parse_status(imap->stream);
- camel_object_trigger_event(imap, "status", sinfo);
- imap_free_status(sinfo);
-#if 0
- switch(sinfo->condition) {
- case IMAP_READ_WRITE:
- printf("folder is read-write\n");
- break;
- case IMAP_READ_ONLY:
- printf("folder is read-only\n");
- break;
- case IMAP_UIDVALIDITY:
- if (imap->select_response)
- imap->select_response->uidvalidity = sinfo->u.uidvalidity;
- break;
-#if 0
- /* not defined yet ... */
- case IMAP_UIDNEXT:
- printf("got uidnext for folder: %d\n", sinfo->u.uidnext);
- break;
-#endif
- case IMAP_UNSEEN:
- if (imap->select_response)
- imap->select_response->unseen = sinfo->u.unseen;
- break;
- case IMAP_PERMANENTFLAGS:
- if (imap->select_response)
- imap->select_response->permanentflags = sinfo->u.permanentflags;
- break;
- case IMAP_ALERT:
- printf("ALERT!: %s\n", sinfo->text);
- break;
- case IMAP_PARSE:
- printf("PARSE: %s\n", sinfo->text);
- break;
- default:
- break;
- }
-#endif
- break;
- default:
- printf("unknown token: %s\n", token);
- camel_imapp_engine_skip(imap);
- /* unknown response, just ignore it */
- }
-
- return 1;
-}
-
-/* handle any continuation requests
- either data continuations, or auth continuation */
-int
-iterate_continuation(CamelIMAPPEngine *imap)
-{
- CamelIMAPPCommand *ic;
- CamelIMAPPCommandPart *cp;
-
- printf("got continuation response\n");
-
- ic = imap->literal;
- imap->literal = NULL;
- if (ic == NULL) {
- camel_imapp_engine_skip(imap);
- printf("got continuation response with no outstanding continuation requests?\n");
- return 1;
- }
-
- printf("got continuation response for data\n");
- cp = ic->current;
- switch(cp->type & CAMEL_IMAPP_COMMAND_MASK) {
- case CAMEL_IMAPP_COMMAND_DATAWRAPPER:
- printf("writing data wrapper to literal\n");
- camel_data_wrapper_write_to_stream((CamelDataWrapper *)cp->ob, (CamelStream *)imap->stream);
- break;
- case CAMEL_IMAPP_COMMAND_STREAM:
- printf("writing stream to literal\n");
- camel_stream_write_to_stream((CamelStream *)cp->ob, (CamelStream *)imap->stream);
- break;
- case CAMEL_IMAPP_COMMAND_AUTH: {
- CamelException *ex = camel_exception_new();
- char *resp;
- unsigned char *token;
- int tok, len;
-
- tok = camel_imapp_stream_token(imap->stream, &token, &len);
- resp = camel_sasl_challenge_base64((CamelSasl *)cp->ob, token, ex);
- if (camel_exception_is_set(ex))
- camel_exception_throw_ex(ex);
- camel_exception_free(ex);
-
- printf("got auth continuation, feeding token '%s' back to auth mech\n", resp);
-
- camel_stream_write((CamelStream *)imap->stream, resp, strlen(resp));
-
- /* we want to keep getting called until we get a status reponse from the server
- ignore what sasl tells us */
- imap->literal = ic;
-
- break; }
- default:
- /* should we just ignore? */
- camel_exception_throw(1, "continuation response for non-continuation request");
- }
-
- camel_imapp_engine_skip(imap);
-
- cp = cp->next;
- if (cp->next) {
- ic->current = cp;
- printf("next part of command \"A%05u: %s\"\n", ic->tag, cp->data);
- camel_stream_printf((CamelStream *)imap->stream, "%s\r\n", cp->data);
- if (cp->type & CAMEL_IMAPP_COMMAND_CONTINUATION) {
- imap->literal = ic;
- } else {
- g_assert(cp->next->next == NULL);
- }
- } else {
- printf("%p: queueing continuation\n", ic);
- camel_stream_printf((CamelStream *)imap->stream, "\r\n");
- }
-
- if (imap->literal == NULL) {
- ic = (CamelIMAPPCommand *)e_dlist_remhead(&imap->queue);
- if (ic) {
- printf("found outstanding op, queueing\n");
- camel_imapp_engine_command_queue(imap, ic);
- }
- }
-
- return 1;
-}
-
-/* handle a completion line */
-int
-iterate_completion(CamelIMAPPEngine *imap, unsigned char *token)
-{
- CamelIMAPPCommand *ic;
- unsigned int tag;
-
- if (token[0] != imap->tagprefix)
- camel_exception_throw(1, "Server sent unexpected response: %s", token);
-
- tag = strtoul(token+1, NULL, 10);
- ic = camel_imapp_engine_command_find_tag(imap, tag);
- if (ic) {
- printf("Got completion response for command %05u '%s'\n", ic->tag, ic->name);
- printf("%p: removing command from qwueue, we were at '%s'\n", ic, ic->current->data);
- printf("%p: removing command\n", ic);
- e_dlist_remove((EDListNode *)ic);
- e_dlist_addtail(&imap->done, (EDListNode *)ic);
- if (imap->literal == ic)
- imap->literal = NULL;
- ic->status = imap_parse_status(imap->stream);
- printf("got response code: %s\n", ic->status->text);
-
- /* TODO: remove this stuff and use a completion handler? */
- /* TODO: handle 'SELECT' command cleanup here */
- /* FIXME: have this use tokeniser, have this handle close/logout/select etc as well */
- /* ok response from login/authenticate, then we're in happy land */
- if ((!strcmp(ic->name, "LOGIN") || !strcmp(ic->name, "AUTHENTICATE"))
- && ic->status->result == IMAP_OK)
- imap->state = IMAP_ENGINE_AUTH;
-
- if (ic->complete)
- ic->complete(imap, ic, ic->complete_data);
- } else {
- camel_exception_throw(1, "got response tag unexpectedly: %s", token);
- }
-
- if (imap->literal != NULL) {
- printf("Warning: continuation command '%s' finished with outstanding continuation\n", imap->literal->name);
- ic = imap->literal;
- /* set the command complete with a failure code? */
- e_dlist_remove((EDListNode *)ic);
- e_dlist_addtail(&imap->done, (EDListNode *)ic);
- imap->literal = NULL;
- }
-
- ic = (CamelIMAPPCommand *)e_dlist_remhead(&imap->queue);
- if (ic) {
- printf("found outstanding op, queueing\n");
- camel_imapp_engine_command_queue(imap, ic);
- }
-
- return 1;
-}
-
-
-/* Do work if there's any to do */
-int
-camel_imapp_engine_iterate(CamelIMAPPEngine *imap, CamelIMAPPCommand *icwait)
-/* throws IO,PARSE exception */
-{
- unsigned int len;
- unsigned char *token;
- int tok;
-
- if ((icwait && icwait->status != NULL) || e_dlist_empty(&imap->active))
- return 0;
-
- /* handle exceptions here? */
-
- /* lock here? */
-
- tok = camel_imapp_stream_token(imap->stream, &token, &len);
- if (tok == '*')
- iterate_untagged(imap);
- else if (tok == IMAP_TOK_TOKEN)
- iterate_completion(imap, token);
- else if (tok == '+')
- iterate_continuation(imap);
- else
- camel_exception_throw(1, "unexpected server response: %s", token);
-
- if (e_dlist_empty(&imap->active))
- return 0;
-
- return 1;
-}
-
-CamelIMAPPCommand *
-camel_imapp_engine_command_new(CamelIMAPPEngine *imap, const char *name, const char *select, const char *fmt, ...)
-{
- CamelIMAPPCommand *ic;
- va_list ap;
-
- ic = g_malloc0(sizeof(*ic));
- ic->tag = imap->tag++;
- ic->name = name;
- ic->mem = (CamelStreamMem *)camel_stream_mem_new();
- ic->select = g_strdup(select);
- e_dlist_init(&ic->parts);
-
- if (fmt && fmt[0]) {
- va_start(ap, fmt);
- imap_engine_command_addv(imap, ic, fmt, ap);
- va_end(ap);
- }
-
- return ic;
-}
-
-void
-camel_imapp_engine_command_add(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const char *fmt, ...)
-{
- va_list ap;
-
- g_assert(ic->mem); /* gets reset on queue */
-
- if (fmt && fmt[0]) {
- va_start(ap, fmt);
- imap_engine_command_addv(imap, ic, fmt, ap);
- va_end(ap);
- }
-}
-
-void
-camel_imapp_engine_command_complete(CamelIMAPPEngine *imap, struct _CamelIMAPPCommand *ic, CamelIMAPPCommandFunc func, void *data)
-{
- ic->complete = func;
- ic->complete_data = data;
-}
-
-/* FIXME: make imap command's refcounted */
-void
-camel_imapp_engine_command_free (CamelIMAPPEngine *imap, CamelIMAPPCommand *ic)
-{
- CamelIMAPPCommandPart *cp, *cn;
-
- if (ic == NULL)
- return;
-
- /* validity check - we cant' free items still in any queue ... */
- /* maybe we should just have another queue to keep them? */
- {
- CamelIMAPPCommand *iw;
- int found = 0;
-
- iw = (CamelIMAPPCommand *)imap->active.head;
- while (iw->next) {
- if (iw == ic) {
- found = 1;
- g_warning("command '%s' still in active queue", iw->name);
- break;
- }
- iw = iw->next;
- }
- iw = (CamelIMAPPCommand *)imap->queue.head;
- while (iw->next) {
- if (iw == ic) {
- found = 1;
- g_warning("command '%s' still in waiting queue", iw->name);
- break;
- }
- iw = iw->next;
- }
- iw = (CamelIMAPPCommand *)imap->done.head;
- while (iw->next) {
- if (iw == ic) {
- found = 1;
- break;
- }
- iw = iw->next;
- }
- if (!found) {
- g_warning("command '%s' not found anywhere", ic->name);
- abort();
- }
- }
-
- e_dlist_remove((EDListNode *)ic);
-
- if (ic->mem)
- camel_object_unref((CamelObject *)ic->mem);
- imap_free_status(ic->status);
- g_free(ic->select);
-
- cp = (CamelIMAPPCommandPart *)ic->parts.head;
- cn = cp->next;
- while (cn) {
- g_free(cp->data);
- if (cp->ob)
- camel_object_unref(cp->ob);
- g_free(cp);
- cp = cn;
- cn = cn->next;
- }
-
- g_free(ic);
-}
-
-/* FIXME: error handling */
-void
-camel_imapp_engine_command_queue(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic)
-{
- CamelIMAPPCommandPart *cp;
-
- if (ic->mem)
- imap_engine_command_complete(imap, ic);
-
- /* FIXME: remove select stuff */
-
- /* see if we need to pre-queue a select command to select the right folder first */
- if (ic->select && (imap->last_select == NULL || strcmp(ic->select, imap->last_select) != 0)) {
- CamelIMAPPCommand *select;
-
- /* of course ... we can't do anything like store/search if we have to select
- first, because it'll mess up all the sequence numbers ... hrm ... bugger */
-
- select = camel_imapp_engine_command_new(imap, "SELECT", NULL, "SELECT %s", ic->select);
- g_free(imap->last_select);
- imap->last_select = g_strdup(ic->select);
- camel_imapp_engine_command_queue(imap, select);
- /* how does it get freed? handle inside engine? */
- }
-
- /* first, check if command can be sent yet ... queue if not */
- if (imap->literal != NULL) {
- printf("%p: queueing while literal active\n", ic);
- e_dlist_addtail(&imap->queue, (EDListNode *)ic);
- return;
- }
-
- cp = (CamelIMAPPCommandPart *)ic->parts.head;
- g_assert(cp);
- ic->current = cp;
-
- /* how to handle exceptions here? */
-
- printf("queueing command \"%c%05u %s\"\n", imap->tagprefix, ic->tag, cp->data);
- camel_stream_printf((CamelStream *)imap->stream, "%c%05u %s\r\n", imap->tagprefix, ic->tag, cp->data);
-
- if (cp->type & CAMEL_IMAPP_COMMAND_CONTINUATION) {
- printf("%p: active literal\n", ic);
- g_assert(cp->next);
- imap->literal = ic;
- e_dlist_addtail(&imap->active, (EDListNode *)ic);
- } else {
- printf("%p: active non-literal\n", ic);
- g_assert(cp->next && cp->next->next == NULL);
- e_dlist_addtail(&imap->active, (EDListNode *)ic);
- }
-}
-
-CamelIMAPPCommand *
-camel_imapp_engine_command_find (CamelIMAPPEngine *imap, const char *name)
-{
- CamelIMAPPCommand *ic, *in;
-
- ic = imap->literal;
- if (ic && strcmp(ic->name, name) == 0)
- return ic;
-
- /* first, try active */
- ic = (CamelIMAPPCommand *)imap->active.head;
- in = ic->next;
- while (in) {
- if (strcmp(ic->name, name) == 0)
- return ic;
- ic = in;
- in = in->next;
- }
-
- return NULL;
-}
-
-CamelIMAPPCommand *
-camel_imapp_engine_command_find_tag(CamelIMAPPEngine *imap, unsigned int tag)
-{
- CamelIMAPPCommand *ic, *in;
-
- ic = imap->literal;
- if (ic && ic->tag == tag)
- return ic;
-
- ic = (CamelIMAPPCommand *)imap->active.head;
- in = ic->next;
- while (in) {
- if (ic->tag == tag)
- return ic;
- ic = in;
- in = in->next;
- }
-
- return NULL;
-}
-
-/* ********************************************************************** */
-
-CamelIMAPPSelectResponse *
-camel_imapp_engine_select(CamelIMAPPEngine *imap, const char *name)
-{
- CamelIMAPPSelectResponse * volatile resp;
- CamelIMAPPCommand * volatile ic = NULL;
-
- resp = g_malloc0(sizeof(*resp));
- imap->select_response = resp;
-
- CAMEL_TRY {
- ic = camel_imapp_engine_command_new(imap, "SELECT", NULL, "SELECT %s", name);
- camel_imapp_engine_command_queue(imap, ic);
- while (camel_imapp_engine_iterate(imap, ic) > 0)
- ;
-
- if (ic->status->result != IMAP_OK)
- camel_exception_throw(1, "select failed: %s", ic->status->text);
- resp->status = ic->status;
- ic->status = NULL;
- } CAMEL_CATCH (e) {
- camel_imapp_engine_command_free(imap, ic);
- camel_imapp_engine_select_free(imap, resp);
- imap->select_response = NULL;
- camel_exception_throw_ex(e);
- } CAMEL_DONE;
-
- camel_imapp_engine_command_free(imap, ic);
- imap->select_response = NULL;
-
- return resp;
-}
-
-void
-camel_imapp_engine_select_free(CamelIMAPPEngine *imap, CamelIMAPPSelectResponse *select)
-{
- if (select) {
- imap_free_status(select->status);
- g_free(select);
- }
-}
-
-/* ********************************************************************** */
-
-static void
-imap_engine_command_add_part(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, camel_imapp_command_part_t type, CamelObject *ob)
-{
- CamelIMAPPCommandPart *cp;
- CamelStreamNull *null;
- unsigned int ob_size = 0;
-
- switch(type & CAMEL_IMAPP_COMMAND_MASK) {
- case CAMEL_IMAPP_COMMAND_DATAWRAPPER:
- case CAMEL_IMAPP_COMMAND_STREAM:
- null = (CamelStreamNull *)camel_stream_null_new();
- if ( (type & CAMEL_IMAPP_COMMAND_MASK) == CAMEL_IMAPP_COMMAND_DATAWRAPPER) {
- camel_data_wrapper_write_to_stream((CamelDataWrapper *)ob, (CamelStream *)null);
- } else {
- camel_stream_reset((CamelStream *)ob);
- camel_stream_write_to_stream((CamelStream *)ob, (CamelStream *)null);
- camel_stream_reset((CamelStream *)ob);
- }
- type |= CAMEL_IMAPP_COMMAND_CONTINUATION;
- camel_object_ref(ob);
- ob_size = null->written;
- camel_object_unref((CamelObject *)null);
- camel_stream_printf((CamelStream *)ic->mem, "{%u}", ob_size);
- break;
- case CAMEL_IMAPP_COMMAND_AUTH:
- /* we presume we'll need to get additional data only if we're not authenticated yet */
- camel_object_ref(ob);
- camel_stream_printf((CamelStream *)ic->mem, "%s", ((CamelSasl *)ob)->mech);
- if (!camel_sasl_authenticated((CamelSasl *)ob))
- type |= CAMEL_IMAPP_COMMAND_CONTINUATION;
- break;
- default:
- ob_size = 0;
- }
-
- cp = g_malloc0(sizeof(*cp));
- cp->type = type;
- cp->ob_size = ob_size;
- cp->ob = ob;
- cp->data_size = ic->mem->buffer->len;
- cp->data = g_malloc(cp->data_size+1);
- memcpy(cp->data, ic->mem->buffer->data, cp->data_size);
- cp->data[cp->data_size] = 0;
-
- camel_stream_reset((CamelStream *)ic->mem);
- /* FIXME: hackish? */
- g_byte_array_set_size(ic->mem->buffer, 0);
-
- e_dlist_addtail(&ic->parts, (EDListNode *)cp);
-}
-
-static int len(EDList *list)
-{
- int count = 0;
- EDListNode *n = list->head;
-
- while (n->next) {
- n = n->next;
- count++;
- }
- return count;
-}
-
-static void
-imap_engine_command_complete(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic)
-{
- c(printf("completing command buffer is [%d] '%.*s'\n", ic->mem->buffer->len, (int)ic->mem->buffer->len, ic->mem->buffer->data));
- c(printf("command has %d parts\n", len(&ic->parts)));
- if (ic->mem->buffer->len > 0)
- imap_engine_command_add_part(imap, ic, CAMEL_IMAPP_COMMAND_SIMPLE, NULL);
-
- c(printf("command has %d parts\n", len(&ic->parts)));
-
- camel_object_unref((CamelObject *)ic->mem);
- ic->mem = NULL;
-}
-
-static void
-imap_engine_command_addv(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const char *fmt, va_list ap)
-{
- const unsigned char *p, *ps, *start;
- unsigned char c;
- unsigned int width;
- char ch;
- int llong;
- int left;
- int fill;
- int zero;
- char *s;
- int d;
- long int l;
- guint32 f;
- CamelStream *S;
- CamelDataWrapper *D;
- CamelSasl *A;
- char buffer[16];
-
- c(printf("adding command, fmt = '%s'\n", fmt));
-
- p = fmt;
- ps = fmt;
- while ( ( c = *p++ ) ) {
- switch(c) {
- case '%':
- if (*p == '%') {
- camel_stream_write((CamelStream *)ic->mem, ps, p-ps);
- p++;
- ps = p;
- } else {
- camel_stream_write((CamelStream *)ic->mem, ps, p-ps-1);
- start = p-1;
- width = 0;
- left = FALSE;
- fill = FALSE;
- zero = FALSE;
- llong = FALSE;
-
- do {
- c = *p++;
- if (c == '0')
- zero = TRUE;
- else if ( c== '-')
- left = TRUE;
- else
- break;
- } while (c);
-
- do {
- if (isdigit(c))
- width = width * 10 + (c-'0');
- else
- break;
- } while ((c = *p++));
-
- if (c == 'l') {
- llong = TRUE;
- c = *p++;
- }
-
- switch(c) {
- case 'A': /* auth object - sasl auth, treat as special kind of continuation */
- A = va_arg(ap, CamelSasl *);
- imap_engine_command_add_part(imap, ic, CAMEL_IMAPP_COMMAND_AUTH, (CamelObject *)A);
- break;
- case 'S': /* stream */
- S = va_arg(ap, CamelStream *);
- c(printf("got stream '%p'\n", S));
- imap_engine_command_add_part(imap, ic, CAMEL_IMAPP_COMMAND_STREAM, (CamelObject *)S);
- break;
- case 'D': /* datawrapper */
- D = va_arg(ap, CamelDataWrapper *);
- c(printf("got data wrapper '%p'\n", D));
- imap_engine_command_add_part(imap, ic, CAMEL_IMAPP_COMMAND_DATAWRAPPER, (CamelObject *)D);
- break;
- case 't': /* token */
- s = va_arg(ap, char *);
- camel_stream_write((CamelStream *)ic->mem, s, strlen(s));
- break;
- case 's': /* simple string */
- s = va_arg(ap, char *);
- c(printf("got string '%s'\n", s));
- /* FIXME: escpae chars, convert to literal or literal+, etc */
- camel_stream_printf((CamelStream *)ic->mem, "\"%s\"", s);
- break;
- case 'f': /* imap folder name */
- s = va_arg(ap, char *);
- c(printf("got folder '%s'\n", s));
- /* FIXME: encode folder name */
- /* FIXME: namespace? */
- camel_stream_printf((CamelStream *)ic->mem, "\"%s\"", s?s:"");
- break;
- case 'F': /* IMAP flags set */
- f = va_arg(ap, guint32);
- imap_write_flags((CamelStream *)ic->mem, f);
- break;
- case 'c':
- d = va_arg(ap, int);
- ch = d;
- camel_stream_write((CamelStream *)ic->mem, &ch, 1);
- break;
- case 'd': /* int/unsigned */
- case 'u':
- if (llong) {
- l = va_arg(ap, long int);
- c(printf("got long int '%d'\n", (int)l));
- memcpy(buffer, start, p-start);
- buffer[p-start] = 0;
- camel_stream_printf((CamelStream *)ic->mem, buffer, l);
- } else {
- d = va_arg(ap, int);
- c(printf("got int '%d'\n", d));
- memcpy(buffer, start, p-start);
- buffer[p-start] = 0;
- camel_stream_printf((CamelStream *)ic->mem, buffer, d);
- }
- break;
- }
-
- ps = p;
- }
- break;
- case '\\': /* only for \\ really, we dont support \n\r etc at all */
- c = *p;
- if (c) {
- g_assert(c == '\\');
- camel_stream_write((CamelStream *)ic->mem, ps, p-ps);
- p++;
- ps = p;
- }
- }
- }
-
- camel_stream_write((CamelStream *)ic->mem, ps, p-ps-1);
-}
-
-
-/* here temporarily while its experimental */
-
-
-#ifdef ENABLE_THREADS
-#include <pthread.h>
-
-static pthread_key_t handler_key = 0;
-
-void camel_exception_setup(void)
-{
- pthread_key_create(&handler_key, NULL);
-}
-
-#else
-/* this is per-thread in threaded mode */
-static struct _CamelExceptionEnv *handler = NULL;
-
-void camel_exception_setup(void)
-{
-}
-#endif
-
-void
-camel_exception_try(struct _CamelExceptionEnv *env)
-{
-#ifdef ENABLE_THREADS
- struct _CamelExceptionEnv *handler;
-
- handler = pthread_getspecific(handler_key);
-#endif
- env->parent = handler;
- handler = env;
- env->ex = NULL;
-
-#ifdef ENABLE_THREADS
- pthread_setspecific(handler_key, handler);
-#endif
-}
-
-void
-camel_exception_throw_ex(CamelException *ex)
-{
- struct _CamelExceptionEnv *env;
-#ifdef ENABLE_THREADS
- struct _CamelExceptionEnv *handler;
-
- handler = pthread_getspecific(handler_key);
-#endif
- printf("throwing exception '%s'\n", ex->desc);
-
- env = handler;
- if (env != NULL) {
- env->ex = ex;
- handler = env->parent;
-#ifdef ENABLE_THREADS
- pthread_setspecific(handler_key, handler);
-#endif
- longjmp(env->env, ex->id);
- } else {
- g_warning("Uncaught exception: %s\n", ex->desc);
- /* we just crash and burn, this is a code problem */
- /* we dont use g_assert_not_reached() since its not a noreturn function */
- abort();
- }
-}
-
-void
-camel_exception_throw(int id, char *fmt, ...)
-{
- CamelException *ex;
- va_list ap;
-
- ex = camel_exception_new();
- ex->id = id;
- va_start(ap, fmt);
- ex->desc = g_strdup_vprintf(fmt, ap);
- va_end(ap);
-
- camel_exception_throw_ex(ex);
-}
-
-void
-camel_exception_drop(struct _CamelExceptionEnv *env)
-{
-#ifdef ENABLE_THREADS
- pthread_setspecific(handler_key, env->parent);
-#else
- handler = env->parent;
-#endif
-}
-
-void
-camel_exception_done(struct _CamelExceptionEnv *env)
-{
-#ifdef ENABLE_THREADS
- pthread_setspecific(handler_key, env->parent);
-#else
- handler = env->parent;
-#endif
- if (env->ex != NULL) {
- camel_exception_free(env->ex);
- }
-}
diff --git a/camel/providers/imapp/camel-imapp-engine.h b/camel/providers/imapp/camel-imapp-engine.h
deleted file mode 100644
index 5f74d0654a..0000000000
--- a/camel/providers/imapp/camel-imapp-engine.h
+++ /dev/null
@@ -1,155 +0,0 @@
-
-#ifndef _CAMEL_IMAPP_ENGINE_H
-#define _CAMEL_IMAPP_ENGINE_H
-
-#include <camel/camel-object.h>
-
-#include "camel-imapp-stream.h"
-#include <e-util/e-msgport.h>
-#include "camel-imapp-folder.h"
-
-#define CAMEL_IMAPP_ENGINE_TYPE (camel_imapp_engine_get_type ())
-#define CAMEL_IMAPP_ENGINE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_ENGINE_TYPE, CamelIMAPPEngine))
-#define CAMEL_IMAPP_ENGINE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_ENGINE_TYPE, CamelIMAPPEngineClass))
-#define CAMEL_IS_IMAP_ENGINE(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPP_ENGINE_TYPE))
-
-typedef struct _CamelIMAPPEngine CamelIMAPPEngine;
-typedef struct _CamelIMAPPEngineClass CamelIMAPPEngineClass;
-
-typedef struct _CamelIMAPPCommandPart CamelIMAPPCommandPart;
-typedef struct _CamelIMAPPCommand CamelIMAPPCommand;
-
-typedef enum {
- CAMEL_IMAPP_COMMAND_SIMPLE = 0,
- CAMEL_IMAPP_COMMAND_DATAWRAPPER,
- CAMEL_IMAPP_COMMAND_STREAM,
- CAMEL_IMAPP_COMMAND_AUTH,
- CAMEL_IMAPP_COMMAND_MASK = 0xff,
- CAMEL_IMAPP_COMMAND_CONTINUATION = 0x8000 /* does this command expect continuation? */
-} camel_imapp_command_part_t;
-
-struct _CamelIMAPPCommandPart {
- struct _CamelIMAPPCommandPart *next;
- struct _CamelIMAPPCommandPart *prev;
-
- struct _CamelIMAPPCommand *parent;
-
- int data_size;
- char *data;
-
- camel_imapp_command_part_t type;
-
- int ob_size;
- CamelObject *ob;
-};
-
-typedef int (*CamelIMAPPEngineFunc)(struct _CamelIMAPPEngine *engine, guint32 id, void *data);
-typedef void (*CamelIMAPPCommandFunc)(struct _CamelIMAPPEngine *engine, struct _CamelIMAPPCommand *, void *data);
-
-/* FIXME: make this refcounted */
-struct _CamelIMAPPCommand {
- struct _CamelIMAPPCommand *next;
- struct _CamelIMAPPCommand *prev;
-
- const char *name; /* command name/type (e.g. FETCH) */
-
- /* FIXME: remove this select stuff */
- char *select; /* if we need to run against a specific folder */
- struct _status_info *status; /* status for command, indicates it is complete if != NULL */
-
- unsigned int tag;
-
- struct _CamelStreamMem *mem; /* for building the part */
- EDList parts;
- CamelIMAPPCommandPart *current;
-
- CamelIMAPPCommandFunc complete;
- void *complete_data;
-};
-
-typedef struct _CamelIMAPPSelectResponse CamelIMAPPSelectResponse;
-
-struct _CamelIMAPPSelectResponse {
- struct _status_info *status;
- guint32 exists;
- guint32 recent;
- guint32 uidvalidity;
- guint32 unseen;
- guint32 permanentflags;
-};
-
-enum {
- IMAP_CAPABILITY_IMAP4 = (1 << 0),
- IMAP_CAPABILITY_IMAP4REV1 = (1 << 1),
- IMAP_CAPABILITY_STATUS = (1 << 2),
- IMAP_CAPABILITY_NAMESPACE = (1 << 3),
- IMAP_CAPABILITY_UIDPLUS = (1 << 4),
- IMAP_CAPABILITY_LITERALPLUS = (1 << 5),
- IMAP_CAPABILITY_STARTTLS = (1 << 6),
-};
-
-/* currently selected states */
-typedef enum _camel_imapp_engine_state_t {
- IMAP_ENGINE_DISCONNECT, /* only happens during shutdown */
- IMAP_ENGINE_CONNECT, /* connected, not authenticated */
- IMAP_ENGINE_AUTH, /* connected, and authenticated */
- IMAP_ENGINE_SELECT, /* and selected, select holds selected folder */
-} camel_imapp_engine_state_t;
-
-struct _CamelIMAPPEngine {
- CamelObject parent_object;
-
- CamelIMAPPStream *stream;
-
- camel_imapp_engine_state_t state;
-
- guint32 capa; /* capabilities for this server, refresh with :capabilities() */
-
- GHashTable *handlers;
-
- unsigned char tagprefix; /* out tag prefix 'A' 'B' ... 'Z' */
- unsigned int tag; /* next command tag */
-
- char *select; /* *currently* selected folder */
- char *last_select; /* last selected or to-be selected folder (e.g. outstanding queued select) */
- CamelIMAPPCommand *literal;/* current literal op */
- EDList active; /* active queue */
- EDList queue; /* outstanding queue */
- EDList done; /* done queue, awaiting reclamation */
-
- /* keep track of running a select */
- struct _CamelIMAPPSelectResponse *select_response;
-};
-
-struct _CamelIMAPPEngineClass {
- CamelObjectClass parent_class;
-
- unsigned char tagprefix;
-
- /* Events:
- status(struct _status_info *);
- */
-};
-
-CamelType camel_imapp_engine_get_type (void);
-
-CamelIMAPPEngine *camel_imapp_engine_new(CamelIMAPPStream *stream);
-
-void camel_imapp_engine_add_handler(CamelIMAPPEngine *imap, const char *response, CamelIMAPPEngineFunc func, void *data);
-int camel_imapp_engine_iterate(CamelIMAPPEngine *imap, CamelIMAPPCommand *wait); /* throws PARSE,IO exception */
-int camel_imapp_engine_skip(CamelIMAPPEngine *imap);
-int camel_imapp_engine_capabilities(CamelIMAPPEngine *imap);
-
-CamelIMAPPCommand *camel_imapp_engine_command_new (CamelIMAPPEngine *imap, const char *name, const char *select, const char *fmt, ...);
-void camel_imapp_engine_command_complete(CamelIMAPPEngine *imap, struct _CamelIMAPPCommand *, CamelIMAPPCommandFunc func, void *data);
-void camel_imapp_engine_command_add (CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const char *fmt, ...);
-void camel_imapp_engine_command_free (CamelIMAPPEngine *imap, CamelIMAPPCommand *ic);
-void camel_imapp_engine_command_queue(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic); /* throws IO exception */
-CamelIMAPPCommand *camel_imapp_engine_command_find (CamelIMAPPEngine *imap, const char *name);
-CamelIMAPPCommand *camel_imapp_engine_command_find_tag(CamelIMAPPEngine *imap, unsigned int tag);
-
-/* util functions */
-CamelIMAPPSelectResponse *camel_imapp_engine_select(CamelIMAPPEngine *imap, const char *name);
-void camel_imapp_engine_select_free(CamelIMAPPEngine *imap, CamelIMAPPSelectResponse *select);
-
-#endif
diff --git a/camel/providers/imapp/camel-imapp-exception.h b/camel/providers/imapp/camel-imapp-exception.h
deleted file mode 100644
index 5e18b6c815..0000000000
--- a/camel/providers/imapp/camel-imapp-exception.h
+++ /dev/null
@@ -1,35 +0,0 @@
-
-/* This implements 'real' exceptions that work a bit like c++/java exceptions */
-
-/* Still experimental code */
-
-#ifndef __CAMEL_IMAPP_EXCEPTION_H
-#define __CAMEL_IMAPP_EXCEPTION_H
-
-#include <setjmp.h>
-#include "camel/camel-exception.h"
-
-struct _CamelExceptionEnv {
- struct _CamelExceptionEnv *parent;
- CamelException *ex;
- jmp_buf env;
-};
-
-#define CAMEL_TRY { struct _CamelExceptionEnv __env; camel_exception_try(&__env); if (setjmp(__env.env) == 0)
-#define CAMEL_IGNORE camel_exception_done(&__env); }
-#define CAMEL_CATCH(x) { CamelException *x; x=__env.ex; if (x != NULL)
-#define CAMEL_DONE } camel_exception_done(&__env); }
-#define CAMEL_DROP() camel_exception_drop(&__env)
-
-void camel_exception_setup(void);
-
-/* internal functions, use macro's above */
-void camel_exception_try(struct _CamelExceptionEnv *env);
-void camel_exception_done(struct _CamelExceptionEnv *env);
-void camel_exception_drop(struct _CamelExceptionEnv *env);
-
-/* user functions */
-void camel_exception_throw_ex(CamelException *ex) __attribute__ ((noreturn));
-void camel_exception_throw(int id, char *fmt, ...) __attribute__ ((noreturn));
-
-#endif
diff --git a/camel/providers/imapp/camel-imapp-fetch-stream.c b/camel/providers/imapp/camel-imapp-fetch-stream.c
deleted file mode 100644
index bf18aac57b..0000000000
--- a/camel/providers/imapp/camel-imapp-fetch-stream.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Author:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <glib.h>
-
-#include <camel/camel-stream-mem.h>
-
-#include "camel-imapp-stream.h"
-#include "camel-imapp-exception.h"
-
-#define t(x)
-#define io(x) x
-
-static CamelObjectClass *parent_class = NULL;
-
-/* Returns the class for a CamelStream */
-#define CS_CLASS(so) CAMEL_IMAPP_FETCH_STREAM_CLASS(CAMEL_OBJECT_GET_CLASS(so))
-
-static ssize_t
-stream_read(CamelStream *stream, char *buffer, size_t n)
-{
- CamelIMAPPFetchStream *is = (CamelIMAPPFetchStream *)stream;
- ssize_t max;
-
- /* make sure we have all the data read in */
- while (camel_imapp_engine_iterate(is->engine, is->command)>0)
- ;
-
- if (is->literal == 0 || n == 0)
- return 0;
-
- max = is->end - is->ptr;
- if (max > 0) {
- max = MIN(max, is->literal);
- max = MIN(max, n);
- memcpy(buffer, is->ptr, max);
- is->ptr += max;
- } else {
- max = MIN(is->literal, n);
- max = camel_stream_read(is->source, buffer, max);
- if (max <= 0)
- return max;
- }
-
- is->literal -= max;
-
- return max;
-}
-
-static ssize_t
-stream_write(CamelStream *stream, const char *buffer, size_t n)
-{
- CamelIMAPPFetchStream *is = (CamelIMAPPFetchStream *)stream;
-
- return camel_stream_write(is->source, buffer, n);
-}
-
-static int
-stream_close(CamelStream *stream)
-{
- /* nop? */
- return 0;
-}
-
-static int
-stream_flush(CamelStream *stream)
-{
- /* nop? */
- return 0;
-}
-
-static gboolean
-stream_eos(CamelStream *stream)
-{
- CamelIMAPPFetchStream *is = (CamelIMAPPFetchStream *)stream;
-
- return is->literal == 0;
-}
-
-static int
-stream_reset(CamelStream *stream)
-{
- /* nop? reset literal mode? */
- return 0;
-}
-
-static void
-camel_imapp_fetch_stream_class_init (CamelStreamClass *camel_imapp_fetch_stream_class)
-{
- CamelStreamClass *camel_stream_class = (CamelStreamClass *)camel_imapp_fetch_stream_class;
-
- parent_class = camel_type_get_global_classfuncs( CAMEL_OBJECT_TYPE );
-
- /* virtual method definition */
- camel_stream_class->read = stream_read;
- camel_stream_class->write = stream_write;
- camel_stream_class->close = stream_close;
- camel_stream_class->flush = stream_flush;
- camel_stream_class->eos = stream_eos;
- camel_stream_class->reset = stream_reset;
-}
-
-static void
-camel_imapp_fetch_stream_init(CamelIMAPPFetchStream *is, CamelIMAPPFetchStreamClass *isclass)
-{
- ;
-}
-
-static void
-camel_imapp_fetch_stream_finalise(CamelIMAPPFetchStream *is)
-{
- if (is->engine)
- camel_object_unref(is->engine);
-}
-
-CamelType
-camel_imapp_fetch_stream_get_type (void)
-{
- static CamelType camel_imapp_fetch_stream_type = CAMEL_INVALID_TYPE;
-
- if (camel_imapp_fetch_stream_type == CAMEL_INVALID_TYPE) {
- setup_table();
- camel_imapp_fetch_stream_type = camel_type_register( camel_stream_get_type(),
- "CamelIMAPPFetchStream",
- sizeof( CamelIMAPPFetchStream ),
- sizeof( CamelIMAPPFetchStreamClass ),
- (CamelObjectClassInitFunc) camel_imapp_fetch_stream_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imapp_fetch_stream_init,
- (CamelObjectFinalizeFunc) camel_imapp_fetch_stream_finalise );
- }
-
- return camel_imapp_fetch_stream_type;
-}
-
-/**
- * camel_imapp_fetch_stream_new:
- *
- * Return value: the stream
- **/
-CamelStream *
-camel_imapp_fetch_stream_new(CamelIMAPPEngine *ie, const char *uid, const char *body)
-{
- CamelIMAPPFetchStream *is;
-
- is = (CamelIMAPPFetchStream *)camel_object_new(camel_imapp_fetch_stream_get_type ());
- is->engine = ie;
- camel_object_ref(ie);
-
- is->command = camel_imapp_engine_command_new(ie, "FETCH", NULL, "FETCH %t (BODY[%t]<0.4096>", uid, body);
- camel_imapp_engine_command_queue(ie, command);
-
- return (CamelStream *)is;
-}
-
diff --git a/camel/providers/imapp/camel-imapp-fetch-stream.h b/camel/providers/imapp/camel-imapp-fetch-stream.h
deleted file mode 100644
index c9281ff64f..0000000000
--- a/camel/providers/imapp/camel-imapp-fetch-stream.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_IMAPP_FETCH_STREAM_H
-#define _CAMEL_IMAPP_FETCH_STREAM_H
-
-#include <camel/camel-stream.h>
-
-#define CAMEL_IMAPP_FETCH_STREAM(obj) CAMEL_CHECK_CAST (obj, camel_imapp_fetch_stream_get_type (), CamelIMAPPFetchStream)
-#define CAMEL_IMAPP_FETCH_STREAM_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imapp_fetch_stream_get_type (), CamelIMAPPFetchStreamClass)
-#define CAMEL_IS_IMAP_FETCH_STREAM(obj) CAMEL_CHECK_TYPE (obj, camel_imapp_fetch_stream_get_type ())
-
-typedef struct _CamelIMAPPFetchStreamClass CamelIMAPPFetchStreamClass;
-typedef struct _CamelIMAPPFetchStream CamelIMAPPFetchStream;
-
-struct _CamelIMAPPFetchStream {
- CamelStream parent;
-
- struct _CamelIMAPPEngine *engine;
-};
-
-struct _CamelIMAPPFetchStreamClass {
- CamelStreamClass parent_class;
-};
-
-CamelType camel_imapp_fetch_stream_get_type (void);
-
-CamelStream *camel_imapp_fetch_stream_new (struct _CamelIMAPPEngine *src, const char *uid, const char *spec);
-
-#endif /* ! _CAMEL_IMAPP_FETCH_STREAM_H */
diff --git a/camel/providers/imapp/camel-imapp-folder.c b/camel/providers/imapp/camel-imapp-folder.c
deleted file mode 100644
index 967ab541f6..0000000000
--- a/camel/providers/imapp/camel-imapp-folder.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-folder.c : class for a imap folder */
-
-/*
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-
-#include "camel/camel-exception.h"
-#include "camel/camel-stream-mem.h"
-#include "camel/camel-stream-filter.h"
-#include "camel/camel-mime-message.h"
-#include "camel/camel-operation.h"
-#include "camel/camel-data-cache.h"
-#include "camel/camel-session.h"
-#include "camel/camel-file-utils.h"
-
-#include "camel-imapp-store.h"
-#include "camel-imapp-folder.h"
-#include "camel-imapp-summary.h"
-#include "camel-imapp-exception.h"
-
-#include <e-util/md5-utils.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#define d(x)
-
-#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(o)))
-static CamelFolderClass *parent_class;
-
-static void imap_finalize (CamelObject *object);
-static void imap_refresh_info (CamelFolder *folder, CamelException *ex);
-static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
-static CamelMimeMessage *imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex);
-
-static void
-imap_folder_class_init (CamelIMAPPFolderClass *camel_imapp_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_imapp_folder_class);
-
- parent_class = CAMEL_FOLDER_CLASS(camel_folder_get_type());
-
- /* virtual method overload */
- camel_folder_class->refresh_info = imap_refresh_info;
- camel_folder_class->sync = imap_sync;
-
- camel_folder_class->get_message = imap_get_message;
- /*camel_folder_class->set_message_flags = imap_set_message_flags;*/
-}
-
-static void
-imap_folder_init(CamelObject *o, CamelObjectClass *klass)
-{
- CamelFolder *folder = (CamelFolder *)o;
- CamelIMAPPFolder *ifolder = (CamelIMAPPFolder *)o;
-
- folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY |
- CAMEL_FOLDER_HAS_SEARCH_CAPABILITY);
-
- folder->permanent_flags = CAMEL_MESSAGE_ANSWERED |
- CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT |
- CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_USER;
-
- /* FIXME: this is just a skeleton */
-
- ifolder->changes = camel_folder_change_info_new();
-}
-
-CamelType
-camel_imapp_folder_get_type (void)
-{
- static CamelType camel_imapp_folder_type = CAMEL_INVALID_TYPE;
-
- if (!camel_imapp_folder_type) {
- camel_imapp_folder_type = camel_type_register (CAMEL_FOLDER_TYPE, "CamelIMAPPFolder",
- sizeof (CamelIMAPPFolder),
- sizeof (CamelIMAPPFolderClass),
- (CamelObjectClassInitFunc) imap_folder_class_init,
- NULL,
- imap_folder_init,
- (CamelObjectFinalizeFunc) imap_finalize);
- }
-
- return camel_imapp_folder_type;
-}
-
-void
-imap_finalize (CamelObject *object)
-{
- CamelIMAPPFolder *folder = (CamelIMAPPFolder *)object;
-
- camel_folder_change_info_free(folder->changes);
-}
-
-CamelFolder *
-camel_imapp_folder_new(CamelStore *store, const char *path)
-{
- CamelFolder *folder;
- char *root;
-
- d(printf("opening imap folder '%s'\n", path));
-
- folder = CAMEL_FOLDER (camel_object_new (CAMEL_IMAPP_FOLDER_TYPE));
- camel_folder_construct(folder, store, path, path);
-
- ((CamelIMAPPFolder *)folder)->raw_name = g_strdup(path);
-
- folder->summary = camel_imapp_summary_new();
-
- root = camel_session_get_storage_path(((CamelService *)store)->session, (CamelService *)store, NULL);
- if (root) {
- char *base = g_build_filename(root, path, NULL);
- char *file = g_build_filename(base, ".ev-summary", NULL);
-
- camel_mkdir(base, 0777);
- g_free(base);
-
- camel_folder_summary_set_filename(folder->summary, file);
- printf("loading summary from '%s' (root=%s)\n", file, root);
- g_free(file);
- camel_folder_summary_load(folder->summary);
- g_free(root);
- }
-
- return folder;
-}
-
-void
-camel_imapp_folder_open(CamelIMAPPFolder *folder, CamelException *ex)
-{
- /* */
-}
-
-void
-camel_imapp_folder_delete(CamelIMAPPFolder *folder, CamelException *ex)
-{
-}
-
-void
-camel_imapp_folder_rename(CamelIMAPPFolder *folder, const char *new, CamelException *ex)
-{
-}
-
-void
-camel_imapp_folder_close(CamelIMAPPFolder *folder, CamelException *ex)
-{
-}
-
-static void
-imap_refresh_info (CamelFolder *folder, CamelException *ex)
-{
- printf("imapp refresh info?\n");
-}
-
-static void
-imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
- camel_imapp_driver_sync(((CamelIMAPPStore *)(folder->parent_store))->driver, expunge, (CamelIMAPPFolder *) folder);
-}
-
-static CamelMimeMessage *
-imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
-{
- CamelMimeMessage * volatile msg = NULL;
- CamelStream * volatile stream = NULL;
-
- printf("get message '%s'\n", uid);
-
- CAMEL_TRY {
- /* simple implementation, just get whole message in 1 go */
- stream = camel_imapp_driver_fetch(((CamelIMAPPStore *)(folder->parent_store))->driver, (CamelIMAPPFolder *)folder, uid, "");
- camel_stream_reset(stream);
- msg = camel_mime_message_new();
- if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)msg, stream) != -1) {
- /* do we care? */
- }
- } CAMEL_CATCH(e) {
- if (msg)
- camel_object_unref(msg);
- msg = NULL;
- camel_exception_xfer(ex, e);
- } CAMEL_DONE;
-
- if (stream)
- camel_object_unref(stream);
-
- return msg;
-}
-
-
-/* Algorithm for selecting a folder:
-
- - If uidvalidity == old uidvalidity
- and exsists == old exists
- and recent == old recent
- and unseen == old unseen
- Assume our summary is correct
- for each summary item
- mark the summary item as 'old/not updated'
- rof
- fetch flags from 1:*
- for each fetch response
- info = summary[index]
- if info.uid != uid
- info = summary_by_uid[uid]
- fi
- if info == NULL
- create new info @ index
- fi
- if got.flags
- update flags
- fi
- if got.header
- update based on header
- mark as retrieved
- else if got.body
- update based on imap body
- mark as retrieved
- fi
-
- Async fetch response:
- info = summary[index]
- if info == null
- if uid == null
- force resync/select?
- info = empty @ index
- else if uid && info.uid != uid
- force a resync?
- return
- fi
-
- if got.flags {
- info.flags = flags
- }
- if got.header {
- info.init(header)
- info.empty = false
- }
-
-info.state - 2 bit field in flags
- 0 = empty, nothing set
- 1 = uid & flags set
- 2 = update required
- 3 = up to date
-*/
-
diff --git a/camel/providers/imapp/camel-imapp-folder.h b/camel/providers/imapp/camel-imapp-folder.h
deleted file mode 100644
index 329c66b7fc..0000000000
--- a/camel/providers/imapp/camel-imapp-folder.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-folder.h : Class for a IMAP folder */
-
-/*
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_IMAPP_FOLDER_H
-#define CAMEL_IMAPP_FOLDER_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <camel/camel-folder.h>
-
-#define CAMEL_IMAPP_FOLDER_TYPE (camel_imapp_folder_get_type ())
-#define CAMEL_IMAPP_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_FOLDER_TYPE, CamelIMAPPFolder))
-#define CAMEL_IMAPP_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_FOLDER_TYPE, CamelIMAPPFolderClass))
-#define CAMEL_IS_IMAP_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPP_FOLDER_TYPE))
-
-typedef struct _CamelIMAPPFolder {
- CamelFolder parent_object;
-
- char *raw_name;
- CamelFolderChangeInfo *changes;
-
- guint32 exists;
- guint32 recent;
- guint32 uidvalidity;
- guint32 unseen;
- guint32 permanentflags;
-} CamelIMAPPFolder;
-
-typedef struct _CamelIMAPPFolderClass {
- CamelFolderClass parent_class;
-} CamelIMAPPFolderClass;
-
-/* Standard Camel function */
-CamelType camel_imapp_folder_get_type (void);
-
-/* public methods */
-CamelFolder *camel_imapp_folder_new(CamelStore *parent, const char *path);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAPP_FOLDER_H */
diff --git a/camel/providers/imapp/camel-imapp-provider.c b/camel/providers/imapp/camel-imapp-provider.c
deleted file mode 100644
index 6b0cdd2d43..0000000000
--- a/camel/providers/imapp/camel-imapp-provider.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-pop3-provider.c: pop3 provider registration code */
-
-/*
- * Authors :
- * Dan Winship <danw@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "camel/camel-provider.h"
-#include "camel/camel-session.h"
-#include "camel/camel-url.h"
-#include "camel/camel-sasl.h"
-
-#include "camel-imapp-store.h"
-
-CamelProviderConfEntry imapp_conf_entries[] = {
- { CAMEL_PROVIDER_CONF_SECTION_START, NULL, NULL,
- N_("Message storage") },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider imapp_provider = {
- "imapp",
-
- N_("IMAP+"),
-
- N_("Experimental IMAP 4(.1) client\n"
- "This is untested and unsupported code, you want to use plain imap instead.\n\n"
- " !!! DO NOT USE THIS FOR PRODUCTION EMAIL !!!\n"),
- "mail",
-
- CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
- CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL,
-
- CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH,
-
- imapp_conf_entries,
-
- /* ... */
-};
-
-CamelServiceAuthType camel_imapp_password_authtype = {
- N_("Password"),
-
- N_("This option will connect to the IMAP server using a "
- "plaintext password."),
-
- "",
- TRUE
-};
-
-void
-camel_imapp_module_init(CamelSession *session)
-{
- extern void camel_exception_setup(void);
-
- imapp_provider.object_types[CAMEL_PROVIDER_STORE] = camel_imapp_store_get_type();
- imapp_provider.url_hash = camel_url_hash;
- imapp_provider.url_equal = camel_url_equal;
-
- imapp_provider.authtypes = g_list_prepend(imapp_provider.authtypes, camel_sasl_authtype_list(FALSE));
- imapp_provider.authtypes = g_list_prepend(imapp_provider.authtypes, &camel_imapp_password_authtype);
-
- /* blah ... could just use it in object setup? */
- /* TEMPORARY */
- camel_exception_setup();
-
- camel_session_register_provider(session, &imapp_provider);
-}
-
-void
-camel_provider_module_init(CamelSession *session)
-{
- camel_imapp_module_init(session);
-}
diff --git a/camel/providers/imapp/camel-imapp-store-summary.c b/camel/providers/imapp/camel-imapp-store-summary.c
deleted file mode 100644
index a3ad57fb11..0000000000
--- a/camel/providers/imapp/camel-imapp-store-summary.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * Copyright (C) 2002 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include "camel-imapp-store-summary.h"
-
-#include "camel/camel-file-utils.h"
-
-#include "camel-string-utils.h"
-#include "e-util/md5-utils.h"
-#include "e-util/e-memory.h"
-
-#include "camel-private.h"
-#include "camel-utf8.h"
-
-#define d(x)
-#define io(x) /* io debug */
-
-#define CAMEL_IMAPP_STORE_SUMMARY_VERSION_0 (0)
-
-#define CAMEL_IMAPP_STORE_SUMMARY_VERSION (0)
-
-#define _PRIVATE(o) (((CamelIMAPPStoreSummary *)(o))->priv)
-
-static int summary_header_load(CamelStoreSummary *, FILE *);
-static int summary_header_save(CamelStoreSummary *, FILE *);
-
-/*static CamelStoreInfo * store_info_new(CamelStoreSummary *, const char *);*/
-static CamelStoreInfo * store_info_load(CamelStoreSummary *, FILE *);
-static int store_info_save(CamelStoreSummary *, FILE *, CamelStoreInfo *);
-static void store_info_free(CamelStoreSummary *, CamelStoreInfo *);
-
-static const char *store_info_string(CamelStoreSummary *, const CamelStoreInfo *, int);
-static void store_info_set_string(CamelStoreSummary *, CamelStoreInfo *, int, const char *);
-
-static void camel_imapp_store_summary_class_init (CamelIMAPPStoreSummaryClass *klass);
-static void camel_imapp_store_summary_init (CamelIMAPPStoreSummary *obj);
-static void camel_imapp_store_summary_finalise (CamelObject *obj);
-
-static CamelStoreSummaryClass *camel_imapp_store_summary_parent;
-
-static void
-camel_imapp_store_summary_class_init (CamelIMAPPStoreSummaryClass *klass)
-{
- CamelStoreSummaryClass *ssklass = (CamelStoreSummaryClass *)klass;
-
- ssklass->summary_header_load = summary_header_load;
- ssklass->summary_header_save = summary_header_save;
-
- /*ssklass->store_info_new = store_info_new;*/
- ssklass->store_info_load = store_info_load;
- ssklass->store_info_save = store_info_save;
- ssklass->store_info_free = store_info_free;
-
- ssklass->store_info_string = store_info_string;
- ssklass->store_info_set_string = store_info_set_string;
-}
-
-static void
-camel_imapp_store_summary_init (CamelIMAPPStoreSummary *s)
-{
- /*struct _CamelIMAPPStoreSummaryPrivate *p;
-
- p = _PRIVATE(s) = g_malloc0(sizeof(*p));*/
-
- ((CamelStoreSummary *)s)->store_info_size = sizeof(CamelIMAPPStoreInfo);
- s->version = CAMEL_IMAPP_STORE_SUMMARY_VERSION;
-}
-
-static void
-camel_imapp_store_summary_finalise (CamelObject *obj)
-{
- /*struct _CamelIMAPPStoreSummaryPrivate *p;*/
- /*CamelIMAPPStoreSummary *s = (CamelIMAPPStoreSummary *)obj;*/
-
- /*p = _PRIVATE(obj);
- g_free(p);*/
-}
-
-CamelType
-camel_imapp_store_summary_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- camel_imapp_store_summary_parent = (CamelStoreSummaryClass *)camel_store_summary_get_type();
- type = camel_type_register((CamelType)camel_imapp_store_summary_parent, "CamelIMAPPStoreSummary",
- sizeof (CamelIMAPPStoreSummary),
- sizeof (CamelIMAPPStoreSummaryClass),
- (CamelObjectClassInitFunc) camel_imapp_store_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imapp_store_summary_init,
- (CamelObjectFinalizeFunc) camel_imapp_store_summary_finalise);
- }
-
- return type;
-}
-
-/**
- * camel_imapp_store_summary_new:
- *
- * Create a new CamelIMAPPStoreSummary object.
- *
- * Return value: A new CamelIMAPPStoreSummary widget.
- **/
-CamelIMAPPStoreSummary *
-camel_imapp_store_summary_new (void)
-{
- CamelIMAPPStoreSummary *new = CAMEL_IMAPP_STORE_SUMMARY ( camel_object_new (camel_imapp_store_summary_get_type ()));
-
- return new;
-}
-
-/**
- * camel_imapp_store_summary_full_name:
- * @s:
- * @path:
- *
- * Retrieve a summary item by full name.
- *
- * A referenced to the summary item is returned, which may be
- * ref'd or free'd as appropriate.
- *
- * Return value: The summary item, or NULL if the @full_name name
- * is not available.
- * It must be freed using camel_store_summary_info_free().
- **/
-CamelIMAPPStoreInfo *
-camel_imapp_store_summary_full_name(CamelIMAPPStoreSummary *s, const char *full_name)
-{
- int count, i;
- CamelIMAPPStoreInfo *info;
-
- count = camel_store_summary_count((CamelStoreSummary *)s);
- for (i=0;i<count;i++) {
- info = (CamelIMAPPStoreInfo *)camel_store_summary_index((CamelStoreSummary *)s, i);
- if (info) {
- if (strcmp(info->full_name, full_name) == 0)
- return info;
- camel_store_summary_info_free((CamelStoreSummary *)s, (CamelStoreInfo *)info);
- }
- }
-
- return NULL;
-}
-
-char *
-camel_imapp_store_summary_full_to_path(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep)
-{
- char *path, *p;
- int c;
- const char *f;
-
- if (dir_sep != '/') {
- p = path = alloca(strlen(full_name)*3+1);
- f = full_name;
- while ( (c = *f++ & 0xff) ) {
- if (c == dir_sep)
- *p++ = '/';
- else if (c == '/' || c == '%')
- p += sprintf(p, "%%%02X", c);
- else
- *p++ = c;
- }
- *p = 0;
- } else
- path = (char *)full_name;
-
- return camel_utf7_utf8(path);
-}
-
-static guint32 hexnib(guint32 c)
-{
- if (c >= '0' && c <= '9')
- return c-'0';
- else if (c>='A' && c <= 'Z')
- return c-'A'+10;
- else
- return 0;
-}
-
-char *
-camel_imapp_store_summary_path_to_full(CamelIMAPPStoreSummary *s, const char *path, char dir_sep)
-{
- unsigned char *full, *f;
- guint32 c, v = 0;
- const char *p;
- int state=0;
- char *subpath, *last = NULL;
- CamelStoreInfo *si;
- CamelIMAPPStoreNamespace *ns;
-
- /* check to see if we have a subpath of path already defined */
- subpath = alloca(strlen(path)+1);
- strcpy(subpath, path);
- do {
- si = camel_store_summary_path((CamelStoreSummary *)s, subpath);
- if (si == NULL) {
- last = strrchr(subpath, '/');
- if (last)
- *last = 0;
- }
- } while (si == NULL && last);
-
- /* path is already present, use the raw version we have */
- if (si && strlen(subpath) == strlen(path)) {
- f = g_strdup(camel_imapp_store_info_full_name(s, si));
- camel_store_summary_info_free((CamelStoreSummary *)s, si);
- return f;
- }
-
- ns = camel_imapp_store_summary_namespace_find_path(s, path);
-
- f = full = alloca(strlen(path)*2+1);
- if (si)
- p = path + strlen(subpath);
- else if (ns)
- p = path + strlen(ns->path);
- else
- p = path;
-
- while ( (c = camel_utf8_getc((const unsigned char **)&p)) ) {
- switch(state) {
- case 0:
- if (c == '%')
- state = 1;
- else {
- if (c == '/')
- c = dir_sep;
- camel_utf8_putc(&f, c);
- }
- break;
- case 1:
- state = 2;
- v = hexnib(c)<<4;
- break;
- case 2:
- state = 0;
- v |= hexnib(c);
- camel_utf8_putc(&f, v);
- break;
- }
- }
- camel_utf8_putc(&f, c);
-
- /* merge old path part if required */
- f = camel_utf8_utf7(full);
- if (si) {
- full = g_strdup_printf("%s%s", camel_imapp_store_info_full_name(s, si), f);
- g_free(f);
- camel_store_summary_info_free((CamelStoreSummary *)s, si);
- f = full;
- } else if (ns) {
- full = g_strdup_printf("%s%s", ns->full_name, f);
- g_free(f);
- f = full;
- }
-
- return f;
-}
-
-CamelIMAPPStoreInfo *
-camel_imapp_store_summary_add_from_full(CamelIMAPPStoreSummary *s, const char *full, char dir_sep)
-{
- CamelIMAPPStoreInfo *info;
- char *pathu8, *prefix;
- int len;
- char *full_name;
- CamelIMAPPStoreNamespace *ns;
-
- d(printf("adding full name '%s' '%c'\n", full, dir_sep));
-
- len = strlen(full);
- full_name = alloca(len+1);
- strcpy(full_name, full);
- if (full_name[len-1] == dir_sep)
- full_name[len-1] = 0;
-
- info = camel_imapp_store_summary_full_name(s, full_name);
- if (info) {
- camel_store_summary_info_free((CamelStoreSummary *)s, (CamelStoreInfo *)info);
- d(printf(" already there\n"));
- return info;
- }
-
- ns = camel_imapp_store_summary_namespace_find_full(s, full_name);
- if (ns) {
- d(printf("(found namespace for '%s' ns '%s') ", full_name, ns->path));
- len = strlen(ns->full_name);
- if (len >= strlen(full_name)) {
- pathu8 = g_strdup(ns->path);
- } else {
- if (full_name[len] == ns->sep)
- len++;
-
- prefix = camel_imapp_store_summary_full_to_path(s, full_name+len, ns->sep);
- if (*ns->path) {
- pathu8 = g_strdup_printf ("%s/%s", ns->path, prefix);
- g_free (prefix);
- } else {
- pathu8 = prefix;
- }
- }
- d(printf(" (pathu8 = '%s')", pathu8));
- } else {
- d(printf("(Cannot find namespace for '%s')\n", full_name));
- pathu8 = camel_imapp_store_summary_full_to_path(s, full_name, dir_sep);
- }
-
- info = (CamelIMAPPStoreInfo *)camel_store_summary_add_from_path((CamelStoreSummary *)s, pathu8);
- if (info) {
- d(printf(" '%s' -> '%s'\n", pathu8, full_name));
- camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_IMAPP_STORE_INFO_FULL_NAME, full_name);
- } else
- d(printf(" failed\n"));
-
- return info;
-}
-
-/* should this be const? */
-/* TODO: deprecate/merge this function with path_to_full */
-char *
-camel_imapp_store_summary_full_from_path(CamelIMAPPStoreSummary *s, const char *path)
-{
- CamelIMAPPStoreNamespace *ns;
- char *name = NULL;
-
- ns = camel_imapp_store_summary_namespace_find_path(s, path);
- if (ns)
- name = camel_imapp_store_summary_path_to_full(s, path, ns->sep);
-
- d(printf("looking up path %s -> %s\n", path, name?name:"not found"));
-
- return name;
-}
-
-/* TODO: this api needs some more work */
-CamelIMAPPStoreNamespace *camel_imapp_store_summary_namespace_new(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep)
-{
- CamelIMAPPStoreNamespace *ns;
- char *p;
- int len;
-
- ns = g_malloc0(sizeof(*ns));
- ns->full_name = g_strdup(full_name);
- len = strlen(ns->full_name)-1;
- if (len >= 0 && ns->full_name[len] == dir_sep)
- ns->full_name[len] = 0;
- ns->sep = dir_sep;
-
- p = ns->path = camel_imapp_store_summary_full_to_path(s, ns->full_name, dir_sep);
- while (*p) {
- if (*p == '/')
- *p = '.';
- p++;
- }
-
- return ns;
-}
-
-void camel_imapp_store_summary_namespace_set(CamelIMAPPStoreSummary *s, CamelIMAPPStoreNamespace *ns)
-{
- static void namespace_clear(CamelStoreSummary *s);
-
- d(printf("Setting namesapce to '%s' '%c' -> '%s'\n", ns->full_name, ns->sep, ns->path));
- namespace_clear((CamelStoreSummary *)s);
- s->namespace = ns;
- camel_store_summary_touch((CamelStoreSummary *)s);
-}
-
-CamelIMAPPStoreNamespace *
-camel_imapp_store_summary_namespace_find_path(CamelIMAPPStoreSummary *s, const char *path)
-{
- int len;
- CamelIMAPPStoreNamespace *ns;
-
- /* NB: this currently only compares against 1 namespace, in future compare against others */
- ns = s->namespace;
- while (ns) {
- len = strlen(ns->path);
- if (len == 0
- || (strncmp(ns->path, path, len) == 0
- && (path[len] == '/' || path[len] == 0)))
- break;
- ns = NULL;
- }
-
- /* have a default? */
- return ns;
-}
-
-CamelIMAPPStoreNamespace *
-camel_imapp_store_summary_namespace_find_full(CamelIMAPPStoreSummary *s, const char *full)
-{
- int len;
- CamelIMAPPStoreNamespace *ns;
-
- /* NB: this currently only compares against 1 namespace, in future compare against others */
- ns = s->namespace;
- while (ns) {
- len = strlen(ns->full_name);
- d(printf("find_full: comparing namespace '%s' to name '%s'\n", ns->full_name, full));
- if (len == 0
- || (strncmp(ns->full_name, full, len) == 0
- && (full[len] == ns->sep || full[len] == 0)))
- break;
- ns = NULL;
- }
-
- /* have a default? */
- return ns;
-}
-
-static void
-namespace_free(CamelStoreSummary *s, CamelIMAPPStoreNamespace *ns)
-{
- g_free(ns->path);
- g_free(ns->full_name);
- g_free(ns);
-}
-
-static void
-namespace_clear(CamelStoreSummary *s)
-{
- CamelIMAPPStoreSummary *is = (CamelIMAPPStoreSummary *)s;
-
- if (is->namespace)
- namespace_free(s, is->namespace);
- is->namespace = NULL;
-}
-
-static CamelIMAPPStoreNamespace *
-namespace_load(CamelStoreSummary *s, FILE *in)
-{
- CamelIMAPPStoreNamespace *ns;
- guint32 sep = '/';
-
- ns = g_malloc0(sizeof(*ns));
- if (camel_file_util_decode_string(in, &ns->path) == -1
- || camel_file_util_decode_string(in, &ns->full_name) == -1
- || camel_file_util_decode_uint32(in, &sep) == -1) {
- namespace_free(s, ns);
- ns = NULL;
- } else {
- ns->sep = sep;
- }
-
- return ns;
-}
-
-static int
-namespace_save(CamelStoreSummary *s, FILE *in, CamelIMAPPStoreNamespace *ns)
-{
- if (camel_file_util_encode_string(in, ns->path) == -1
- || camel_file_util_encode_string(in, ns->full_name) == -1
- || camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-summary_header_load(CamelStoreSummary *s, FILE *in)
-{
- CamelIMAPPStoreSummary *is = (CamelIMAPPStoreSummary *)s;
- gint32 version, capabilities, count;
-
- namespace_clear(s);
-
- if (camel_imapp_store_summary_parent->summary_header_load((CamelStoreSummary *)s, in) == -1
- || camel_file_util_decode_fixed_int32(in, &version) == -1)
- return -1;
-
- is->version = version;
-
- if (version < CAMEL_IMAPP_STORE_SUMMARY_VERSION_0) {
- g_warning("Store summary header version too low");
- return -1;
- }
-
- /* note file format can be expanded to contain more namespaces, but only 1 at the moment */
- if (camel_file_util_decode_fixed_int32(in, &capabilities) == -1
- || camel_file_util_decode_fixed_int32(in, &count) == -1
- || count > 1)
- return -1;
-
- is->capabilities = capabilities;
- if (count == 1) {
- if ((is->namespace = namespace_load(s, in)) == NULL)
- return -1;
- }
-
- return 0;
-}
-
-static int
-summary_header_save(CamelStoreSummary *s, FILE *out)
-{
- CamelIMAPPStoreSummary *is = (CamelIMAPPStoreSummary *)s;
- guint32 count;
-
- count = is->namespace?1:0;
-
- /* always write as latest version */
- if (camel_imapp_store_summary_parent->summary_header_save((CamelStoreSummary *)s, out) == -1
- || camel_file_util_encode_fixed_int32(out, CAMEL_IMAPP_STORE_SUMMARY_VERSION) == -1
- || camel_file_util_encode_fixed_int32(out, is->capabilities) == -1
- || camel_file_util_encode_fixed_int32(out, count) == -1)
- return -1;
-
- if (is->namespace && namespace_save(s, out, is->namespace) == -1)
- return -1;
-
- return 0;
-}
-
-static CamelStoreInfo *
-store_info_load(CamelStoreSummary *s, FILE *in)
-{
- CamelIMAPPStoreInfo *mi;
-
- mi = (CamelIMAPPStoreInfo *)camel_imapp_store_summary_parent->store_info_load(s, in);
- if (mi) {
- if (camel_file_util_decode_string(in, &mi->full_name) == -1) {
- camel_store_summary_info_free(s, (CamelStoreInfo *)mi);
- mi = NULL;
- }
- }
-
- return (CamelStoreInfo *)mi;
-}
-
-static int
-store_info_save(CamelStoreSummary *s, FILE *out, CamelStoreInfo *mi)
-{
- CamelIMAPPStoreInfo *isi = (CamelIMAPPStoreInfo *)mi;
-
- if (camel_imapp_store_summary_parent->store_info_save(s, out, mi) == -1
- || camel_file_util_encode_string(out, isi->full_name) == -1)
- return -1;
-
- return 0;
-}
-
-static void
-store_info_free(CamelStoreSummary *s, CamelStoreInfo *mi)
-{
- CamelIMAPPStoreInfo *isi = (CamelIMAPPStoreInfo *)mi;
-
- g_free(isi->full_name);
- camel_imapp_store_summary_parent->store_info_free(s, mi);
-}
-
-static const char *
-store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, int type)
-{
- CamelIMAPPStoreInfo *isi = (CamelIMAPPStoreInfo *)mi;
-
- /* FIXME: Locks? */
-
- g_assert (mi != NULL);
-
- switch (type) {
- case CAMEL_IMAPP_STORE_INFO_FULL_NAME:
- return isi->full_name;
- default:
- return camel_imapp_store_summary_parent->store_info_string(s, mi, type);
- }
-}
-
-static void
-store_info_set_string(CamelStoreSummary *s, CamelStoreInfo *mi, int type, const char *str)
-{
- CamelIMAPPStoreInfo *isi = (CamelIMAPPStoreInfo *)mi;
-
- g_assert(mi != NULL);
-
- switch(type) {
- case CAMEL_IMAPP_STORE_INFO_FULL_NAME:
- d(printf("Set full name %s -> %s\n", isi->full_name, str));
- CAMEL_STORE_SUMMARY_LOCK(s, summary_lock);
- g_free(isi->full_name);
- isi->full_name = g_strdup(str);
- CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock);
- break;
- default:
- camel_imapp_store_summary_parent->store_info_set_string(s, mi, type, str);
- break;
- }
-}
diff --git a/camel/providers/imapp/camel-imapp-store-summary.h b/camel/providers/imapp/camel-imapp-store-summary.h
deleted file mode 100644
index 154fe8798e..0000000000
--- a/camel/providers/imapp/camel-imapp-store-summary.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2002 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef _CAMEL_IMAPP_STORE_SUMMARY_H
-#define _CAMEL_IMAPP_STORE_SUMMARY_H
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#include <camel/camel-object.h>
-#include <camel/camel-store-summary.h>
-
-#define CAMEL_IMAPP_STORE_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_imapp_store_summary_get_type (), CamelIMAPPStoreSummary)
-#define CAMEL_IMAPP_STORE_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imapp_store_summary_get_type (), CamelIMAPPStoreSummaryClass)
-#define CAMEL_IS_IMAP_STORE_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_imapp_store_summary_get_type ())
-
-typedef struct _CamelIMAPPStoreSummary CamelIMAPPStoreSummary;
-typedef struct _CamelIMAPPStoreSummaryClass CamelIMAPPStoreSummaryClass;
-
-typedef struct _CamelIMAPPStoreInfo CamelIMAPPStoreInfo;
-
-enum {
- CAMEL_IMAPP_STORE_INFO_FULL_NAME = CAMEL_STORE_INFO_LAST,
- CAMEL_IMAPP_STORE_INFO_LAST,
-};
-
-struct _CamelIMAPPStoreInfo {
- CamelStoreInfo info;
- char *full_name;
-};
-
-typedef struct _CamelIMAPPStoreNamespace CamelIMAPPStoreNamespace;
-
-struct _CamelIMAPPStoreNamespace {
- char *path; /* display path */
- char *full_name; /* real name */
- char sep; /* directory separator */
-};
-
-struct _CamelIMAPPStoreSummary {
- CamelStoreSummary summary;
-
- struct _CamelIMAPPStoreSummaryPrivate *priv;
-
- /* header info */
- guint32 version; /* version of base part of file */
- guint32 capabilities;
- CamelIMAPPStoreNamespace *namespace; /* eventually to be a list */
-};
-
-struct _CamelIMAPPStoreSummaryClass {
- CamelStoreSummaryClass summary_class;
-};
-
-CamelType camel_imapp_store_summary_get_type (void);
-CamelIMAPPStoreSummary *camel_imapp_store_summary_new (void);
-
-/* TODO: this api needs some more work, needs to support lists */
-CamelIMAPPStoreNamespace *camel_imapp_store_summary_namespace_new(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep);
-void camel_imapp_store_summary_namespace_set(CamelIMAPPStoreSummary *s, CamelIMAPPStoreNamespace *ns);
-CamelIMAPPStoreNamespace *camel_imapp_store_summary_namespace_find_path(CamelIMAPPStoreSummary *s, const char *path);
-CamelIMAPPStoreNamespace *camel_imapp_store_summary_namespace_find_full(CamelIMAPPStoreSummary *s, const char *full_name);
-
-/* converts to/from utf8 canonical nasmes */
-char *camel_imapp_store_summary_full_to_path(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep);
-char *camel_imapp_store_summary_path_to_full(CamelIMAPPStoreSummary *s, const char *path, char dir_sep);
-
-CamelIMAPPStoreInfo *camel_imapp_store_summary_full_name(CamelIMAPPStoreSummary *s, const char *full_name);
-CamelIMAPPStoreInfo *camel_imapp_store_summary_add_from_full(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep);
-
-/* a convenience lookup function. always use this if path known */
-char *camel_imapp_store_summary_full_from_path(CamelIMAPPStoreSummary *s, const char *path);
-
-/* helper macro's */
-#define camel_imapp_store_info_full_name(s, i) (camel_store_info_string((CamelStoreSummary *)s, (const CamelStoreInfo *)i, CAMEL_IMAPP_STORE_INFO_FULL_NAME))
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* ! _CAMEL_IMAPP_STORE_SUMMARY_H */
diff --git a/camel/providers/imapp/camel-imapp-store.c b/camel/providers/imapp/camel-imapp-store.c
deleted file mode 100644
index 9123102a03..0000000000
--- a/camel/providers/imapp/camel-imapp-store.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-store.c : class for a imap store */
-
-/*
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2000-2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "camel/camel-operation.h"
-
-#include "camel/camel-stream-buffer.h"
-#include "camel/camel-session.h"
-#include "camel/camel-exception.h"
-#include "camel/camel-url.h"
-#include "camel/camel-sasl.h"
-#include "camel/camel-data-cache.h"
-#include "camel/camel-tcp-stream.h"
-#include "camel/camel-tcp-stream-raw.h"
-#ifdef HAVE_SSL
-#include "camel/camel-tcp-stream-ssl.h"
-#endif
-
-#include "camel-imapp-store-summary.h"
-#include "camel-imapp-store.h"
-#include "camel-imapp-folder.h"
-#include "camel-imapp-engine.h"
-#include "camel-imapp-exception.h"
-#include "camel-imapp-utils.h"
-#include "camel-imapp-driver.h"
-
-/* Specified in RFC 2060 section 2.1 */
-#define IMAP_PORT 143
-
-static CamelStoreClass *parent_class = NULL;
-
-static void finalize (CamelObject *object);
-
-static void imap_construct(CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex);
-/* static char *imap_get_name(CamelService *service, gboolean brief);*/
-static gboolean imap_connect (CamelService *service, CamelException *ex);
-static gboolean imap_disconnect (CamelService *service, gboolean clean, CamelException *ex);
-static GList *imap_query_auth_types (CamelService *service, CamelException *ex);
-
-static void imap_init_trash (CamelStore *store);
-static CamelFolder *imap_get_trash (CamelStore *store, CamelException *ex);
-
-static CamelFolder *imap_get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex);
-static CamelFolder *imap_get_inbox (CamelStore *store, CamelException *ex);
-static void imap_rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
-static CamelFolderInfo *imap_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
-static void imap_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex);
-static void imap_rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex);
-static CamelFolderInfo *imap_create_folder(CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex);
-
-static int store_resp_list(CamelIMAPPEngine *ie, guint32 id, void *data);
-
-/* yet to see if this should go global or not */
-void camel_imapp_store_folder_selected(CamelIMAPPStore *store, CamelIMAPPFolder *folder, CamelIMAPPSelectResponse *select);
-
-static void
-camel_imapp_store_class_init (CamelIMAPPStoreClass *camel_imapp_store_class)
-{
- CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_imapp_store_class);
- CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS(camel_imapp_store_class);
-
- parent_class = CAMEL_STORE_CLASS(camel_type_get_global_classfuncs(camel_store_get_type()));
-
- /* virtual method overload */
- camel_service_class->construct = imap_construct;
- /*camel_service_class->get_name = imap_get_name;*/
- camel_service_class->query_auth_types = imap_query_auth_types;
- camel_service_class->connect = imap_connect;
- camel_service_class->disconnect = imap_disconnect;
-
- camel_store_class->init_trash = imap_init_trash;
- camel_store_class->get_trash = imap_get_trash;
-
- camel_store_class->get_folder = imap_get_folder;
- camel_store_class->get_inbox = imap_get_inbox;
-
- camel_store_class->create_folder = imap_create_folder;
- camel_store_class->rename_folder = imap_rename_folder;
- camel_store_class->delete_folder = imap_delete_folder;
- camel_store_class->get_folder_info = imap_get_folder_info;
-}
-
-static void
-camel_imapp_store_init (gpointer object, gpointer klass)
-{
- CamelIMAPPStore *istore = object;
-}
-
-CamelType
-camel_imapp_store_get_type (void)
-{
- static CamelType camel_imapp_store_type = CAMEL_INVALID_TYPE;
-
- if (!camel_imapp_store_type) {
- camel_imapp_store_type = camel_type_register(CAMEL_STORE_TYPE,
- "CamelIMAPPStore",
- sizeof (CamelIMAPPStore),
- sizeof (CamelIMAPPStoreClass),
- (CamelObjectClassInitFunc) camel_imapp_store_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imapp_store_init,
- finalize);
- }
-
- return camel_imapp_store_type;
-}
-
-static void
-finalize (CamelObject *object)
-{
- CamelIMAPPStore *imap_store = CAMEL_IMAPP_STORE (object);
-
- /* force disconnect so we dont have it run later, after we've cleaned up some stuff */
- /* SIGH */
-
- camel_service_disconnect((CamelService *)imap_store, TRUE, NULL);
-
- if (imap_store->driver)
- camel_object_unref(imap_store->driver);
- if (imap_store->cache)
- camel_object_unref(imap_store->cache);
-}
-
-static void imap_construct(CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
-{
- char *root, *summary;
- CamelIMAPPStore *store = (CamelIMAPPStore *)service;
-
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
- if (camel_exception_is_set(ex))
- return;
-
- CAMEL_TRY {
- store->summary = camel_imapp_store_summary_new();
- root = camel_session_get_storage_path(service->session, service, ex);
- if (root) {
- summary = g_build_filename(root, ".ev-store-summary", NULL);
- camel_store_summary_set_filename((CamelStoreSummary *)store->summary, summary);
- /* FIXME: need to remove params, passwords, etc */
- camel_store_summary_set_uri_base((CamelStoreSummary *)store->summary, service->url);
- camel_store_summary_load((CamelStoreSummary *)store->summary);
- }
- } CAMEL_CATCH(e) {
- camel_exception_xfer(ex, e);
- } CAMEL_DONE;
-}
-
-enum {
- USE_SSL_NEVER,
- USE_SSL_ALWAYS,
- USE_SSL_WHEN_POSSIBLE
-};
-
-#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
-
-static void
-connect_to_server (CamelService *service, int ssl_mode, int try_starttls)
-/* throws IO exception */
-{
- CamelIMAPPStore *store = CAMEL_IMAPP_STORE (service);
- CamelStream * volatile tcp_stream = NULL;
- CamelIMAPPStream * volatile imap_stream = NULL;
- struct hostent *h = NULL;
- int ret, port;
- CamelException *ex;
-
- ex = camel_exception_new();
- CAMEL_TRY {
- /* parent class connect initialization */
- CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex);
- if (ex->id)
- camel_exception_throw_ex(ex);
-
- h = camel_service_gethost(service, ex);
- if (ex->id)
- camel_exception_throw_ex(ex);
-
- port = service->url->port ? service->url->port : IMAP_PORT;
-
-#ifdef HAVE_SSL
- if (camel_url_get_param (service->url, "use_ssl")) {
- if (try_starttls)
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
- else {
- port = service->url->port ? service->url->port : 995;
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-#else
- tcp_stream = camel_tcp_stream_raw_new ();
-#endif /* HAVE_SSL */
-
- ret = camel_tcp_stream_connect (CAMEL_TCP_STREAM (tcp_stream), h, port);
- camel_free_host (h);
- if (ret == -1) {
- if (errno == EINTR)
- camel_exception_throw(CAMEL_EXCEPTION_USER_CANCEL, _("Connection cancelled"));
- else
- camel_exception_throw(CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port, strerror(errno));
- }
-
- imap_stream = (CamelIMAPPStream *)camel_imapp_stream_new(tcp_stream);
- store->driver = camel_imapp_driver_new(imap_stream);
-
- camel_object_unref(imap_stream);
- camel_object_unref(tcp_stream);
- } CAMEL_CATCH(e) {
- if (tcp_stream)
- camel_object_unref(tcp_stream);
- if (imap_stream)
- camel_object_unref((CamelObject *)imap_stream);
- camel_exception_throw_ex(e);
- } CAMEL_DONE;
-
- camel_exception_free(ex);
-}
-
-#if 0
-
-/* leave this stuff out for now */
-
-
-static struct {
- char *value;
- int mode;
-} ssl_options[] = {
- { "", USE_SSL_ALWAYS },
- { "always", USE_SSL_ALWAYS },
- { "when-possible", USE_SSL_WHEN_POSSIBLE },
- { "never", USE_SSL_NEVER },
- { NULL, USE_SSL_NEVER },
-};
-
-static gboolean
-connect_to_server_wrapper (CamelService *service, CamelException *ex)
-{
-#ifdef HAVE_SSL
- const char *use_ssl;
- int i, ssl_mode;
-
- use_ssl = camel_url_get_param (service->url, "use_ssl");
- if (use_ssl) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, use_ssl))
- break;
- ssl_mode = ssl_options[i].mode;
- } else
- ssl_mode = USE_SSL_NEVER;
-
- if (ssl_mode == USE_SSL_ALWAYS) {
- /* First try the ssl port */
- if (!connect_to_server (service, ssl_mode, FALSE, ex)) {
- if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
- /* The ssl port seems to be unavailable, lets try STARTTLS */
- camel_exception_clear (ex);
- return connect_to_server (service, ssl_mode, TRUE, ex);
- } else {
- return FALSE;
- }
- }
-
- return TRUE;
- } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
- /* If the server supports STARTTLS, use it */
- return connect_to_server (service, ssl_mode, TRUE, ex);
- } else {
- /* User doesn't care about SSL */
- return connect_to_server (service, ssl_mode, FALSE, ex);
- }
-#else
- return connect_to_server (service, USE_SSL_NEVER, FALSE, ex);
-#endif
-}
-#endif
-
-extern CamelServiceAuthType camel_imapp_password_authtype;
-extern CamelServiceAuthType camel_imapp_apop_authtype;
-
-static GList *
-imap_query_auth_types (CamelService *service, CamelException *ex)
-{
- /*CamelIMAPPStore *store = CAMEL_IMAPP_STORE (service);*/
- GList *types = NULL;
-
- types = CAMEL_SERVICE_CLASS (parent_class)->query_auth_types (service, ex);
- if (types == NULL)
- return NULL;
-
-#if 0
- if (connect_to_server_wrapper (service, NULL)) {
- types = g_list_concat(types, g_list_copy(store->engine->auth));
- imap_disconnect (service, TRUE, NULL);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to POP server on %s"),
- service->url->host);
- }
-#endif
- return types;
-}
-
-static void
-store_get_pass(CamelIMAPPStore *store)
-{
- if (((CamelService *)store)->url->passwd == NULL) {
- char *prompt;
- CamelException ex;
-
- camel_exception_init(&ex);
-
- prompt = g_strdup_printf (_("%sPlease enter the IMAP password for %s@%s"),
- store->login_error?store->login_error:"",
- ((CamelService *)store)->url->user,
- ((CamelService *)store)->url->host);
- ((CamelService *)store)->url->passwd = camel_session_get_password(camel_service_get_session((CamelService *)store),
- prompt, FALSE, TRUE, (CamelService*)store, "password", &ex);
- g_free (prompt);
- if (camel_exception_is_set(&ex))
- camel_exception_throw_ex(&ex);
- }
-}
-
-static struct _CamelSasl *
-store_get_sasl(struct _CamelIMAPPDriver *driver, CamelIMAPPStore *store)
-{
- store_get_pass(store);
-
- if (((CamelService *)store)->url->authmech)
- return camel_sasl_new("imap", ((CamelService *)store)->url->authmech, (CamelService *)store);
-
- return NULL;
-}
-
-static void
-store_get_login(struct _CamelIMAPPDriver *driver, char **login, char **pass, CamelIMAPPStore *store)
-{
- store_get_pass(store);
-
- *login = g_strdup(((CamelService *)store)->url->user);
- *pass = g_strdup(((CamelService *)store)->url->passwd);
-}
-
-static gboolean
-imap_connect (CamelService *service, CamelException *ex)
-{
- CamelIMAPPStore *store = (CamelIMAPPStore *)service;
- volatile int ret = FALSE;
-
- CAMEL_TRY {
- volatile int retry = TRUE;
-
- if (store->cache == NULL) {
- char *root;
-
- root = camel_session_get_storage_path(service->session, service, ex);
- if (root) {
- store->cache = camel_data_cache_new(root, 0, ex);
- g_free(root);
- if (store->cache) {
- /* Default cache expiry - 1 week or not visited in a day */
- camel_data_cache_set_expire_age(store->cache, 60*60*24*7);
- camel_data_cache_set_expire_access(store->cache, 60*60*24);
- }
- }
- if (camel_exception_is_set(ex))
- camel_exception_throw_ex(ex);
- }
-
- connect_to_server(service, USE_SSL_NEVER, FALSE);
-
- camel_imapp_driver_set_sasl_factory(store->driver, (CamelIMAPPSASLFunc)store_get_sasl, store);
- camel_imapp_driver_set_login_query(store->driver, (CamelIMAPPLoginFunc)store_get_login, store);
- store->login_error = NULL;
-
- do {
- CAMEL_TRY {
- if (store->driver->engine->state != IMAP_ENGINE_AUTH)
- camel_imapp_driver_login(store->driver);
- ret = TRUE;
- retry = FALSE;
- } CAMEL_CATCH(e) {
- g_free(store->login_error);
- store->login_error = NULL;
- switch (e->id) {
- case CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE:
- store->login_error = g_strdup_printf("%s\n\n", e->desc);
- camel_session_forget_password(service->session, service, "password", ex);
- camel_url_set_passwd(service->url, NULL);
- break;
- default:
- camel_exception_throw_ex(e);
- break;
- }
- } CAMEL_DONE;
- } while (retry);
- } CAMEL_CATCH(e) {
- camel_exception_xfer(ex, e);
- camel_service_disconnect(service, TRUE, NULL);
- ret = FALSE;
- } CAMEL_DONE;
-
- g_free(store->login_error);
- store->login_error = NULL;
-
- return ret;
-}
-
-static gboolean
-imap_disconnect (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelIMAPPStore *store = CAMEL_IMAPP_STORE (service);
-
- /* FIXME: logout */
-
- if (!CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, clean, ex))
- return FALSE;
-
- /* logout/disconnect */
- if (store->driver) {
- camel_object_unref(store->driver);
- store->driver = NULL;
- }
-
- return TRUE;
-}
-
-static void
-imap_init_trash (CamelStore *store)
-{
- /* no-op */
- ;
-}
-
-static CamelFolder *
-imap_get_trash (CamelStore *store, CamelException *ex)
-{
- /* no-op */
- return NULL;
-}
-
-static CamelFolder *
-imap_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
-{
- CamelIMAPPStore *istore = (CamelIMAPPStore *)store;
- CamelIMAPPFolder * volatile folder = NULL;
-
- /* ??? */
-
- /* 1. create the folder */
- /* 2. run select? */
- /* 3. update the folder */
-
- CAMEL_TRY {
- folder = (CamelIMAPPFolder *)camel_imapp_folder_new(store, folder_name);
- camel_imapp_driver_select(istore->driver, folder);
- } CAMEL_CATCH (e) {
- if (folder) {
- camel_object_unref(folder);
- folder = NULL;
- }
- camel_exception_xfer(ex, e);
- } CAMEL_DONE;
-
- return (CamelFolder *)folder;
-}
-
-static CamelFolder *
-imap_get_inbox(CamelStore *store, CamelException *ex)
-{
- camel_exception_setv(ex, 1, "get_inbox::unimplemented");
-
- return NULL;
-}
-
-/* 8 bit, string compare */
-static int folders_build_cmp(const void *app, const void *bpp)
-{
- struct _list_info *a = *((struct _list_info **)app);
- struct _list_info *b = *((struct _list_info **)bpp);
- unsigned char *ap = (unsigned char *)(a->name);
- unsigned char *bp = (unsigned char *)(b->name);
-
- printf("qsort, cmp '%s' <> '%s'\n", ap, bp);
-
- while (*ap && *ap == *bp) {
- ap++;
- bp++;
- }
-
- if (*ap < *bp)
- return -1;
- else if (*ap > *bp)
- return 1;
- return 0;
-}
-
-/* FIXME: this should go via storesummary? */
-static CamelFolderInfo *
-folders_build_info(CamelURL *base, struct _list_info *li)
-{
- char *path, *full_name, *name;
- CamelFolderInfo *fi;
-
- full_name = imapp_list_get_path(li);
- name = strrchr(full_name, '/');
- if (name)
- name++;
- else
- name = full_name;
-
- path = alloca(strlen(full_name)+2);
- sprintf(path, "/%s", full_name);
- camel_url_set_path(base, path);
-
- fi = g_malloc0(sizeof(*fi));
- fi->url = camel_url_to_string(base, CAMEL_URL_HIDE_ALL);
- fi->name = g_strdup(name);
- fi->full_name = full_name;
- fi->path = g_strdup(path);
- fi->unread_message_count = -1;
- fi->flags = li->flags;
-
- /* TODO: could look up count here ... */
- /* ?? */
- /*folder = camel_object_bag_get(store->folders, "INBOX");*/
-
- return fi;
-}
-
-/*
- a
- a/b
- a/b/c
- a/d
- b
- c/d
-
-*/
-
-/* note, pname is the raw name, not the folderinfo name */
-/* note also this free's as we go, since we never go 'backwards' */
-static CamelFolderInfo *
-folders_build_rec(CamelURL *base, GPtrArray *folders, int *ip, CamelFolderInfo *pfi, char *pname)
-{
- int plen = 0;
- CamelFolderInfo *last = NULL, *first = NULL;
-
- if (pfi)
- plen = strlen(pname);
-
- for(;(*ip)<(int)folders->len;) {
- CamelFolderInfo *fi;
- struct _list_info *li;
-
- li = folders->pdata[*ip];
- printf("checking '%s' is child of '%s'\n", li->name, pname);
-
- /* is this a child of the parent? */
- if (pfi != NULL
- && (strncmp(pname, li->name, strlen(pname)) != 0
- || li->name[plen] != li->separator)) {
- printf(" nope\n");
- break;
- }
- printf(" yep\n");
-
- /* is this not an immediate child of the parent? */
-#if 0
- char *p;
- if (pfi != NULL
- && li->separator != 0
- && (p = strchr(li->name + plen + 1, li->separator)) != NULL) {
- if (last == NULL) {
- struct _list_info tli;
-
- tli.flags = CAMEL_FOLDER_NOSELECT|CAMEL_FOLDER_CHILDREN;
- tli.separator = li->separator;
- tli.name = g_strndup(li->name, p-li->name+1);
- fi = folders_build_info(base, &tli);
- fi->parent = pfi;
- if (pfi && pfi->child == NULL)
- pfi->child = fi;
- i = folders_build_rec(folders, i, fi, tli.name);
- break;
- }
- }
-#endif
-
- fi = folders_build_info(base, li);
- fi->parent = pfi;
- if (last != NULL)
- last->sibling = fi;
- last = fi;
- if (first == NULL)
- first = fi;
-
- (*ip)++;
- fi->child = folders_build_rec(base, folders, ip, fi, li->name);
- imap_free_list(li);
- }
-
- return first;
-}
-
-static void
-folder_info_dump(CamelFolderInfo *fi, int depth)
-{
- char *s;
-
- s = alloca(depth+1);
- memset(s, ' ', depth);
- s[depth] = 0;
- while (fi) {
- printf("%s%s (%s)\n", s, fi->name, fi->url);
- if (fi->child)
- folder_info_dump(fi->child, depth+2);
- fi = fi->sibling;
- }
-
-}
-
-static CamelFolderInfo *
-imap_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelIMAPPStore *istore = (CamelIMAPPStore *)store;
- CamelFolderInfo * fi= NULL;
- char *name;
-
- /* FIXME: temporary, since this is not a disco store */
- if (istore->driver == NULL
- && !camel_service_connect((CamelService *)store, ex))
- return NULL;
-
- name = (char *)top;
- if (name == NULL || name[0] == 0) {
- /* namespace? */
- name = "";
- }
-
- name = "";
-
- CAMEL_TRY {
- CamelURL *base;
- int i;
- GPtrArray *folders;
-
- /* FIXME: subscriptions? lsub? */
- folders = camel_imapp_driver_list(istore->driver, name, flags);
-
- /* this greatly simplifies the tree algorithm ... but it might
- be faster just to use a hashtable to find parents? */
- qsort(folders->pdata, folders->len, sizeof(folders->pdata[0]), folders_build_cmp);
-
- i = 0;
- base = camel_url_copy(((CamelService *)store)->url);
- fi = folders_build_rec(base, folders, &i, NULL, NULL);
- camel_url_free(base);
- g_ptr_array_free(folders, TRUE);
- } CAMEL_CATCH(e) {
- camel_exception_xfer(ex, e);
- } CAMEL_DONE;
-
- printf("built folder info:\n");
- folder_info_dump(fi, 2);
-
- return fi;
-
-#if 0
- if (top == NULL || !g_ascii_strcasecmp(top, "inbox")) {
- CamelURL *uri = camel_url_copy(((CamelService *)store)->url);
-
- camel_url_set_path(uri, "/INBOX");
- fi = g_malloc0(sizeof(*fi));
- fi->url = camel_url_to_string(uri, CAMEL_URL_HIDE_ALL);
- camel_url_free(uri);
- fi->name = g_strdup("INBOX");
- fi->full_name = g_strdup("INBOX");
- fi->path = g_strdup("/INBOX");
- fi->unread_message_count = -1;
- fi->flags = 0;
-
- folder = camel_object_bag_get(store->folders, "INBOX");
- if (folder) {
- /*if (!cflags & FAST)*/
- camel_imapp_driver_update(istore->driver, (CamelIMAPPFolder *)folder);
- fi->unread_message_count = camel_folder_get_unread_message_count(folder);
- camel_object_unref(folder);
- }
- } else {
- camel_exception_setv(ex, 1, "not implemented");
- }
-#endif
- return fi;
-
-#if 0
- istore->pending_list = g_ptr_array_new();
-
- CAMEL_TRY {
- ic = camel_imapp_engine_command_new(istore->driver->engine, "LIST", NULL, "LIST \"\" %f", top);
- camel_imapp_engine_command_queue(istore->driver->engine, ic);
- while (camel_imapp_engine_iterate(istore->driver->engine, ic) > 0)
- ;
-
- if (ic->status->result != IMAP_OK)
- camel_exception_throw(1, "list failed: %s", ic->status->text);
- } CAMEL_CATCH (e) {
- camel_exception_xfer(ex, e);
- } CAMEL_DONE;
-
- camel_imapp_engine_command_free(istore->driver->engine, ic);
-
- printf("got folder list:\n");
- for (i=0;i<(int)istore->pending_list->len;i++) {
- struct _list_info *linfo = istore->pending_list->pdata[i];
-
- printf("%s (%c)\n", linfo->name, linfo->separator);
- imap_free_list(linfo);
- }
- istore->pending_list = NULL;
-
- return NULL;
-#endif
-}
-
-static void
-imap_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex)
-{
- camel_exception_setv(ex, 1, "delete_folder::unimplemented");
-}
-
-static void
-imap_rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex)
-{
- camel_exception_setv(ex, 1, "rename_folder::unimplemented");
-}
-
-static CamelFolderInfo *
-imap_create_folder(CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex)
-{
- camel_exception_setv(ex, 1, "create_folder::unimplemented");
- return NULL;
-}
-
-/* ********************************************************************** */
-#if 0
-static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
-{
- struct _fetch_info *finfo;
- CamelIMAPPStore *istore = data;
- CamelMessageInfo *info;
- struct _pending_fetch *pending;
-
- finfo = imap_parse_fetch(ie->stream);
- if (istore->selected) {
- if ((finfo->got & FETCH_UID) == 0) {
- printf("didn't get uid in fetch response?\n");
- } else {
- info = camel_folder_summary_index(((CamelFolder *)istore->selected)->summary, id-1);
- /* exists, check/update */
- if (info) {
- if (strcmp(finfo->uid, camel_message_info_uid(info)) != 0) {
- printf("summary at index %d has uid %s expected %s\n", id, camel_message_info_uid(info), finfo->uid);
- /* uid mismatch??? try do it based on uid instead? try to reorder? i dont know? */
- camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
- info = camel_folder_summary_uid(((CamelFolder *)istore->selected)->summary, finfo->uid);
- }
- }
-
- if (info) {
- if (finfo->got & (FETCH_FLAGS)) {
- printf("updating flags for uid '%s'\n", finfo->uid);
- info->flags = finfo->flags;
- camel_folder_change_info_change_uid(istore->selected->changes, finfo->uid);
- }
- if (finfo->got & FETCH_MINFO) {
- printf("got envelope unexpectedly?\n");
- }
- /* other things go here, like body fetches */
- } else {
- pending = g_hash_table_lookup(istore->pending_fetch_table, finfo->uid);
-
- /* we need to create a new info, we only care about flags and minfo */
-
- if (pending)
- info = pending->info;
- else {
- info = camel_folder_summary_info_new(((CamelFolder *)istore->selected)->summary);
- camel_message_info_set_uid(info, g_strdup(finfo->uid));
- }
-
- if (finfo->got & FETCH_FLAGS)
- info->flags = finfo->flags;
-
- if (finfo->got & FETCH_MINFO) {
- /* if we only use ENVELOPE? */
- camel_message_info_set_subject(info, g_strdup(camel_message_info_subject(finfo->minfo)));
- camel_message_info_set_from(info, g_strdup(camel_message_info_from(finfo->minfo)));
- camel_message_info_set_to(info, g_strdup(camel_message_info_to(finfo->minfo)));
- camel_message_info_set_cc(info, g_strdup(camel_message_info_cc(finfo->minfo)));
- info->date_sent = finfo->minfo->date_sent;
- camel_folder_summary_add(((CamelFolder *)istore->selected)->summary, info);
- camel_folder_change_info_add_uid(istore->selected->changes, finfo->uid);
- if (pending) {
- e_dlist_remove((EDListNode *)pending);
- g_hash_table_remove(istore->pending_fetch_table, finfo->uid);
- /*e_memchunk_free(istore->pending_fetch_chunks, pending);*/
- }
- } else if (finfo->got & FETCH_HEADER) {
- /* if we only use HEADER? */
- CamelMimeParser *mp;
-
- if (pending == NULL)
- camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
- mp = camel_mime_parser_new();
- camel_mime_parser_init_with_stream(mp, finfo->header);
- info = camel_folder_summary_info_new_from_parser(((CamelFolder *)istore->selected)->summary, mp);
- camel_object_unref(mp);
- camel_message_info_set_uid(info, g_strdup(finfo->uid));
-
- camel_folder_summary_add(((CamelFolder *)istore->selected)->summary, info);
- camel_folder_change_info_add_uid(istore->selected->changes, finfo->uid);
- if (pending) {
- /* FIXME: use a dlist */
- e_dlist_remove((EDListNode *)pending);
- g_hash_table_remove(istore->pending_fetch_table, camel_message_info_uid(pending->info));
- camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, pending->info);
- /*e_memchunk_free(istore->pending_fetch_chunks, pending);*/
- }
- } else if (finfo->got & FETCH_FLAGS) {
- if (pending == NULL) {
- pending = e_memchunk_alloc(istore->pending_fetch_chunks);
- pending->info = info;
- g_hash_table_insert(istore->pending_fetch_table, (char *)camel_message_info_uid(info), pending);
- e_dlist_addtail(&istore->pending_fetch_list, (EDListNode *)pending);
- }
- } else {
- if (pending == NULL)
- camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
- printf("got unexpected fetch response?\n");
- imap_dump_fetch(finfo);
- }
- }
- }
- } else {
- printf("unexpected fetch response, no folder selected?\n");
- }
- /*imap_dump_fetch(finfo);*/
- imap_free_fetch(finfo);
-
- return camel_imapp_engine_skip(ie);
-}
-#endif
-
-/* ********************************************************************** */
-
-/* should be moved to imapp-utils?
- stuff in imapp-utils should be moved to imapp-parse? */
-
-/* ********************************************************************** */
-
-#if 0
-void
-camel_imapp_store_folder_selected(CamelIMAPPStore *store, CamelIMAPPFolder *folder, CamelIMAPPSelectResponse *select)
-{
- CamelIMAPPCommand * volatile ic = NULL;
- CamelIMAPPStore *istore = (CamelIMAPPStore *)store;
- int i;
- struct _uidset_state ss;
- GPtrArray *fetch;
- CamelMessageInfo *info;
- struct _pending_fetch *fw, *fn;
-
- printf("imap folder selected\n");
-
- if (select->uidvalidity == folder->uidvalidity
- && select->exists == folder->exists
- && select->recent == folder->recent
- && select->unseen == folder->unseen) {
- /* no work to do? */
- return;
- }
-
- istore->pending_fetch_table = g_hash_table_new(g_str_hash, g_str_equal);
- istore->pending_fetch_chunks = e_memchunk_new(256, sizeof(struct _pending_fetch));
-
- /* perform an update - flags first (and see what we have) */
- CAMEL_TRY {
- ic = camel_imapp_engine_command_new(istore->engine, "FETCH", NULL, "FETCH 1:%d (UID FLAGS)", select->exists);
- camel_imapp_engine_command_queue(istore->engine, ic);
- while (camel_imapp_engine_iterate(istore->engine, ic) > 0)
- ;
-
- if (ic->status->result != IMAP_OK)
- camel_exception_throw(1, "fetch failed: %s", ic->status->text);
-
- /* pending_fetch_list now contains any new messages */
- /* FIXME: how do we work out no-longer present messages? */
- printf("now fetching info for messages?\n");
- uidset_init(&ss, store->engine);
- ic = camel_imapp_engine_command_new(istore->engine, "FETCH", NULL, "UID FETCH ");
- fw = (struct _pending_fetch *)istore->pending_fetch_list.head;
- fn = fw->next;
- while (fn) {
- info = fw->info;
- /* if the uid set fills, then flush the command out */
- if (uidset_add(&ss, ic, camel_message_info_uid(info))
- || (fn->next == NULL && uidset_done(&ss, ic))) {
- camel_imapp_engine_command_add(istore->engine, ic, " (FLAGS RFC822.HEADER)");
- camel_imapp_engine_command_queue(istore->engine, ic);
- while (camel_imapp_engine_iterate(istore->engine, ic) > 0)
- ;
- if (ic->status->result != IMAP_OK)
- camel_exception_throw(1, "fetch failed: %s", ic->status->text);
- /* if not end ... */
- camel_imapp_engine_command_free(istore->engine, ic);
- ic = camel_imapp_engine_command_new(istore->engine, "FETCH", NULL, "UID FETCH ");
- }
- fw = fn;
- fn = fn->next;
- }
-
- printf("The pending list should now be empty: %s\n", e_dlist_empty(&istore->pending_fetch_list)?"TRUE":"FALSE");
- for (i=0;i<10;i++) {
- info = camel_folder_summary_index(((CamelFolder *)istore->selected)->summary, i);
- if (info) {
- printf("message info [%d] =\n", i);
- camel_message_info_dump(info);
- camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
- }
- }
- } CAMEL_CATCH (e) {
- /* FIXME: cleanup */
- camel_exception_throw_ex(e);
- } CAMEL_DONE;
-
- g_hash_table_destroy(istore->pending_fetch_table);
- istore->pending_fetch_table = NULL;
- e_memchunk_destroy(istore->pending_fetch_chunks);
-
- camel_imapp_engine_command_free(istore->engine, ic);
-}
-#endif
-
-#if 0
-/*char *uids[] = {"1", "2", "4", "5", "6", "7", "9", "11", "12", 0};*/
-/*char *uids[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", 0};*/
-char *uids[] = {"1", "3", "5", "7", "9", "11", "12", "13", "14", "15", "20", "21", "24", "25", "26", 0};
-
-void
-uidset_test(CamelIMAPPEngine *ie)
-{
- struct _uidset_state ss;
- CamelIMAPPCommand *ic;
- int i;
-
- /*ic = camel_imapp_engine_command_new(ie, 0, "FETCH", NULL, "FETCH ");*/
- uidset_init(&ss, 0, 0);
- for (i=0;uids[i];i++) {
- if (uidset_add(&ss, uids[i])) {
- printf("\n[%d] flushing uids\n", i);
- }
- }
-
- if (uidset_done(&ss)) {
- printf("\nflushing uids\n");
- }
-}
-#endif
diff --git a/camel/providers/imapp/camel-imapp-store.h b/camel/providers/imapp/camel-imapp-store.h
deleted file mode 100644
index 97b7afd1d1..0000000000
--- a/camel/providers/imapp/camel-imapp-store.h
+++ /dev/null
@@ -1,77 +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: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAPP_STORE_H
-#define CAMEL_IMAPP_STORE_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <camel/camel-types.h>
-#include <camel/camel-store.h>
-#include "camel-imapp-driver.h"
-#include "e-util/e-memory.h"
-
-#define CAMEL_IMAPP_STORE_TYPE (camel_imapp_store_get_type ())
-#define CAMEL_IMAPP_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_STORE_TYPE, CamelIMAPPStore))
-#define CAMEL_IMAPP_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_STORE_TYPE, CamelIMAPPStoreClass))
-#define CAMEL_IS_IMAP_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPP_STORE_TYPE))
-
-struct _pending_fetch {
- struct _pending_fetch *next;
- struct _pending_fetch *prev;
-
- CamelMessageInfo *info;
-};
-
-typedef struct {
- CamelStore parent_object;
-
- struct _CamelIMAPPStoreSummary *summary; /* in-memory list of folders */
- struct _CamelIMAPPDriver *driver; /* IMAP processing engine */
- struct _CamelDataCache *cache;
-
- /* if we had a login error, what to show to user */
- char *login_error;
-
- GPtrArray *pending_list;
-} CamelIMAPPStore;
-
-typedef struct {
- CamelStoreClass parent_class;
-
-} CamelIMAPPStoreClass;
-
-/* Standard Camel function */
-CamelType camel_imapp_store_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAPP_STORE_H */
-
-
diff --git a/camel/providers/imapp/camel-imapp-stream.c b/camel/providers/imapp/camel-imapp-stream.c
deleted file mode 100644
index 20876beae2..0000000000
--- a/camel/providers/imapp/camel-imapp-stream.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Author:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <glib.h>
-
-#include <camel/camel-stream-mem.h>
-
-#include "camel-imapp-stream.h"
-#include "camel-imapp-exception.h"
-
-#define t(x)
-#define io(x) x
-
-static void setup_table(void);
-
-static CamelObjectClass *parent_class = NULL;
-
-/* Returns the class for a CamelStream */
-#define CS_CLASS(so) CAMEL_IMAPP_STREAM_CLASS(CAMEL_OBJECT_GET_CLASS(so))
-
-#define CAMEL_IMAPP_STREAM_SIZE (4096)
-#define CAMEL_IMAPP_STREAM_TOKEN (4096) /* maximum token size */
-
-static int
-stream_fill(CamelIMAPPStream *is)
-{
- int left = 0;
-
- if (is->source) {
- left = is->end - is->ptr;
- memcpy(is->buf, is->ptr, left);
- is->end = is->buf + left;
- is->ptr = is->buf;
- left = camel_stream_read(is->source, is->end, CAMEL_IMAPP_STREAM_SIZE - (is->end - is->buf));
- if (left > 0) {
- is->end += left;
- io(printf("camel_imapp_read: buffer is '%.*s'\n", is->end - is->ptr, is->ptr));
- return is->end - is->ptr;
- } else {
- io(printf("camel_imapp_read: -1\n"));
- return -1;
- }
- }
-
- printf("camel_imapp_read: -1\n");
-
- return -1;
-}
-
-static ssize_t
-stream_read(CamelStream *stream, char *buffer, size_t n)
-{
- CamelIMAPPStream *is = (CamelIMAPPStream *)stream;
- ssize_t max;
-
- if (is->literal == 0 || n == 0)
- return 0;
-
- max = is->end - is->ptr;
- if (max > 0) {
- max = MIN(max, is->literal);
- max = MIN(max, n);
- memcpy(buffer, is->ptr, max);
- is->ptr += max;
- } else {
- max = MIN(is->literal, n);
- max = camel_stream_read(is->source, buffer, max);
- if (max <= 0)
- return max;
- }
-
- is->literal -= max;
-
- return max;
-}
-
-static ssize_t
-stream_write(CamelStream *stream, const char *buffer, size_t n)
-{
- CamelIMAPPStream *is = (CamelIMAPPStream *)stream;
-
- return camel_stream_write(is->source, buffer, n);
-}
-
-static int
-stream_close(CamelStream *stream)
-{
- /* nop? */
- return 0;
-}
-
-static int
-stream_flush(CamelStream *stream)
-{
- /* nop? */
- return 0;
-}
-
-static gboolean
-stream_eos(CamelStream *stream)
-{
- CamelIMAPPStream *is = (CamelIMAPPStream *)stream;
-
- return is->literal == 0;
-}
-
-static int
-stream_reset(CamelStream *stream)
-{
- /* nop? reset literal mode? */
- return 0;
-}
-
-static void
-camel_imapp_stream_class_init (CamelStreamClass *camel_imapp_stream_class)
-{
- CamelStreamClass *camel_stream_class = (CamelStreamClass *)camel_imapp_stream_class;
-
- parent_class = camel_type_get_global_classfuncs( CAMEL_OBJECT_TYPE );
-
- /* virtual method definition */
- camel_stream_class->read = stream_read;
- camel_stream_class->write = stream_write;
- camel_stream_class->close = stream_close;
- camel_stream_class->flush = stream_flush;
- camel_stream_class->eos = stream_eos;
- camel_stream_class->reset = stream_reset;
-}
-
-static void
-camel_imapp_stream_init(CamelIMAPPStream *is, CamelIMAPPStreamClass *isclass)
-{
- /* +1 is room for appending a 0 if we need to for a token */
- is->ptr = is->end = is->buf = g_malloc(CAMEL_IMAPP_STREAM_SIZE+1);
- is->tokenptr = is->tokenbuf = g_malloc(CAMEL_IMAPP_STREAM_SIZE+1);
- is->tokenend = is->tokenbuf + CAMEL_IMAPP_STREAM_SIZE;
-}
-
-static void
-camel_imapp_stream_finalise(CamelIMAPPStream *is)
-{
- g_free(is->buf);
- if (is->source)
- camel_object_unref((CamelObject *)is->source);
-}
-
-CamelType
-camel_imapp_stream_get_type (void)
-{
- static CamelType camel_imapp_stream_type = CAMEL_INVALID_TYPE;
-
- if (camel_imapp_stream_type == CAMEL_INVALID_TYPE) {
- setup_table();
- camel_imapp_stream_type = camel_type_register( camel_stream_get_type(),
- "CamelIMAPPStream",
- sizeof( CamelIMAPPStream ),
- sizeof( CamelIMAPPStreamClass ),
- (CamelObjectClassInitFunc) camel_imapp_stream_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imapp_stream_init,
- (CamelObjectFinalizeFunc) camel_imapp_stream_finalise );
- }
-
- return camel_imapp_stream_type;
-}
-
-/**
- * camel_imapp_stream_new:
- *
- * Returns a NULL stream. A null stream is always at eof, and
- * always returns success for all reads and writes.
- *
- * Return value: the stream
- **/
-CamelStream *
-camel_imapp_stream_new(CamelStream *source)
-{
- CamelIMAPPStream *is;
-
- is = (CamelIMAPPStream *)camel_object_new(camel_imapp_stream_get_type ());
- camel_object_ref((CamelObject *)source);
- is->source = source;
-
- return (CamelStream *)is;
-}
-
-
-/*
- From rfc2060
-
-ATOM_CHAR ::= <any CHAR except atom_specials>
-
-atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards /
- quoted_specials
-
-CHAR ::= <any 7-bit US-ASCII character except NUL,
- 0x01 - 0x7f>
-
-CTL ::= <any ASCII control character and DEL,
- 0x00 - 0x1f, 0x7f>
-
-SPACE ::= <ASCII SP, space, 0x20>
-
-list_wildcards ::= "%" / "*"
-
-quoted_specials ::= <"> / "\"
-*/
-
-static unsigned char imap_specials[256] = {
-/* 00 */0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 10 */0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 20 */0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
-/* 30 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 40 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 50 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
-/* 60 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 70 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-#define imap_is_atom(c) ((imap_specials[(c)&0xff] & 0x01) != 0)
-#define imap_is_simple(c) ((imap_specials[(c)&0xff] & 0x02) != 0)
-#define imap_not_id(c) ((imap_specials[(c)&0xff] & 0x04) != 0)
-
-/* could be pregenerated, but this is cheap */
-static struct {
- unsigned char *chars;
- unsigned char mask;
-} is_masks[] = {
- { "\n*()[]+", 2 },
- { " \r\n()[]+", 4 },
-};
-
-static void setup_table(void)
-{
- int i;
- unsigned char *p, c;
-
- for (i=0;i<(int)(sizeof(is_masks)/sizeof(is_masks[0]));i++) {
- p = is_masks[i].chars;
- while ((c = *p++))
- imap_specials[c] |= is_masks[i].mask;
- }
-}
-
-#if 0
-
-static int
-skip_ws(CamelIMAPPStream *is, unsigned char *pp, unsigned char *pe)
-{
- register unsigned char c, *p;
- unsigned char *e;
-
- p = is->ptr;
- e = is->end;
-
- do {
- while (p >= e ) {
- is->ptr = p;
- if (stream_fill(is) == IMAP_TOK_ERROR)
- return IMAP_TOK_ERROR;
- p = is->ptr;
- e = is->end;
- }
- c = *p++;
- } while (c == ' ' || c == '\r');
-
- is->ptr = p;
- is->end = e;
-
- return c;
-}
-#endif
-
-/* FIXME: these should probably handle it themselves,
- and get rid of the token interface? */
-int
-camel_imapp_stream_atom(CamelIMAPPStream *is, unsigned char **data, unsigned int *lenp)
-{
- unsigned char *p, c;
-
- /* this is only 'approximate' atom */
- switch(camel_imapp_stream_token(is, data, lenp)) {
- case IMAP_TOK_TOKEN:
- p = *data;
- while ((c = *p))
- *p++ = toupper(c);
- case IMAP_TOK_INT:
- return 0;
- case IMAP_TOK_ERROR:
- return IMAP_TOK_ERROR;
- default:
- camel_exception_throw(1, "expecting atom");
- printf("expecting atom!\n");
- return IMAP_TOK_PROTOCOL;
- }
-}
-
-/* gets an atom, a quoted_string, or a literal */
-int
-camel_imapp_stream_astring(CamelIMAPPStream *is, unsigned char **data)
-{
- unsigned char *p, *start;
- unsigned int len, inlen;
-
- switch(camel_imapp_stream_token(is, data, &len)) {
- case IMAP_TOK_TOKEN:
- case IMAP_TOK_INT:
- case IMAP_TOK_STRING:
- return 0;
- case IMAP_TOK_LITERAL:
- /* FIXME: just grow buffer */
- if (len >= CAMEL_IMAPP_STREAM_TOKEN) {
- camel_exception_throw(1, "astring: literal too long");
- printf("astring too long\n");
- return IMAP_TOK_PROTOCOL;
- }
- p = is->tokenptr;
- camel_imapp_stream_set_literal(is, len);
- do {
- len = camel_imapp_stream_getl(is, &start, &inlen);
- if (len < 0)
- return len;
- memcpy(p, start, inlen);
- p += inlen;
- } while (len > 0);
- *data = is->tokenptr;
- return 0;
- case IMAP_TOK_ERROR:
- /* wont get unless no exception hanlder*/
- return IMAP_TOK_ERROR;
- default:
- camel_exception_throw(1, "expecting astring");
- printf("expecting astring!\n");
- return IMAP_TOK_PROTOCOL;
- }
-}
-
-/* check for NIL or (small) quoted_string or literal */
-int
-camel_imapp_stream_nstring(CamelIMAPPStream *is, unsigned char **data)
-{
- unsigned char *p, *start;
- unsigned int len, inlen;
-
- switch(camel_imapp_stream_token(is, data, &len)) {
- case IMAP_TOK_STRING:
- return 0;
- case IMAP_TOK_LITERAL:
- /* FIXME: just grow buffer */
- if (len >= CAMEL_IMAPP_STREAM_TOKEN) {
- camel_exception_throw(1, "nstring: literal too long");
- return IMAP_TOK_PROTOCOL;
- }
- p = is->tokenptr;
- camel_imapp_stream_set_literal(is, len);
- do {
- len = camel_imapp_stream_getl(is, &start, &inlen);
- if (len < 0)
- return len;
- memcpy(p, start, inlen);
- p += inlen;
- } while (len > 0);
- *data = is->tokenptr;
- return 0;
- case IMAP_TOK_TOKEN:
- p = *data;
- if (toupper(p[0]) == 'N' && toupper(p[1]) == 'I' && toupper(p[2]) == 'L' && p[3] == 0) {
- *data = NULL;
- return 0;
- }
- default:
- camel_exception_throw(1, "expecting nstring");
- return IMAP_TOK_PROTOCOL;
- case IMAP_TOK_ERROR:
- /* we'll never get this unless there are no exception handlers anyway */
- return IMAP_TOK_ERROR;
-
- }
-}
-
-/* parse an nstring as a stream */
-int
-camel_imapp_stream_nstring_stream(CamelIMAPPStream *is, CamelStream **stream)
-/* throws IO,PARSE exception */
-{
- unsigned char *token;
- unsigned int len;
- int ret = 0;
- CamelStream * volatile mem = NULL;
-
- *stream = NULL;
-
- CAMEL_TRY {
- switch(camel_imapp_stream_token(is, &token, &len)) {
- case IMAP_TOK_STRING:
- mem = camel_stream_mem_new_with_buffer(token, len);
- *stream = mem;
- break;
- case IMAP_TOK_LITERAL:
- /* if len is big, we could automatically use a file backing */
- camel_imapp_stream_set_literal(is, len);
- mem = camel_stream_mem_new();
- if (camel_stream_write_to_stream((CamelStream *)is, mem) == -1)
- camel_exception_throw(1, "nstring: io error: %s", strerror(errno));
- camel_stream_reset(mem);
- *stream = mem;
- break;
- case IMAP_TOK_TOKEN:
- if (toupper(token[0]) == 'N' && toupper(token[1]) == 'I' && toupper(token[2]) == 'L' && token[3] == 0) {
- *stream = NULL;
- break;
- }
- default:
- ret = -1;
- camel_exception_throw(1, "nstring: token not string");
- }
- } CAMEL_CATCH(ex) {
- if (mem)
- camel_object_unref((CamelObject *)mem);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- /* never reaches here anyway */
- return ret;
-}
-
-guint32
-camel_imapp_stream_number(CamelIMAPPStream *is)
-{
- unsigned char *token;
- unsigned int len;
-
- if (camel_imapp_stream_token(is, &token, &len) != IMAP_TOK_INT) {
- camel_exception_throw(1, "expecting number");
- return 0;
- }
-
- return strtoul(token, 0, 10);
-}
-
-int
-camel_imapp_stream_text(CamelIMAPPStream *is, unsigned char **text)
-{
- GByteArray *build = g_byte_array_new();
- unsigned char *token;
- unsigned int len;
- int tok;
-
- CAMEL_TRY {
- while (is->unget > 0) {
- switch (is->unget_tok) {
- case IMAP_TOK_TOKEN:
- case IMAP_TOK_STRING:
- case IMAP_TOK_INT:
- g_byte_array_append(build, is->unget_token, is->unget_len);
- g_byte_array_append(build, " ", 1);
- default: /* invalid, but we'll ignore */
- break;
- }
- is->unget--;
- }
-
- do {
- tok = camel_imapp_stream_gets(is, &token, &len);
- if (tok < 0)
- camel_exception_throw(1, "io error: %s", strerror(errno));
- if (len)
- g_byte_array_append(build, token, len);
- } while (tok > 0);
- } CAMEL_CATCH(ex) {
- *text = NULL;
- g_byte_array_free(build, TRUE);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- g_byte_array_append(build, "", 1);
- *text = build->data;
- g_byte_array_free(build, FALSE);
-
- return 0;
-}
-
-/* Get one token from the imap stream */
-camel_imapp_token_t
-/* throws IO,PARSE exception */
-camel_imapp_stream_token(CamelIMAPPStream *is, unsigned char **data, unsigned int *len)
-{
- register unsigned char c, *p, *o, *oe;
- unsigned char *e;
- unsigned int literal;
- int digits;
-
- if (is->unget > 0) {
- is->unget--;
- *data = is->unget_token;
- *len = is->unget_len;
- /*printf("token UNGET '%c' %s\n", is->unget_tok, is->unget_token);*/
- return is->unget_tok;
- }
-
- if (is->literal > 0)
- g_warning("stream_token called with literal %d", is->literal);
-
- p = is->ptr;
- e = is->end;
-
- /* skip whitespace/prefill buffer */
- do {
- while (p >= e ) {
- is->ptr = p;
- if (stream_fill(is) == IMAP_TOK_ERROR)
- goto io_error;
- p = is->ptr;
- e = is->end;
- }
- c = *p++;
- } while (c == ' ' || c == '\r');
-
- /*strchr("\n*()[]+", c)*/
- if (imap_is_simple(c)) {
- is->ptr = p;
- t(printf("token '%c'\n", c));
- return c;
- } else if (c == '{') {
- literal = 0;
- *data = p;
- while (1) {
- while (p < e) {
- c = *p++;
- if (isdigit(c) && literal < (UINT_MAX/10)) {
- literal = literal * 10 + (c - '0');
- } else if (c == '}') {
- while (1) {
- while (p < e) {
- c = *p++;
- if (c == '\n') {
- *len = literal;
- is->ptr = p;
- is->literal = literal;
- t(printf("token LITERAL %d\n", literal));
- return IMAP_TOK_LITERAL;
- }
- }
- is->ptr = p;
- if (stream_fill(is) == IMAP_TOK_ERROR)
- goto io_error;
- p = is->ptr;
- e = is->end;
- }
- } else {
- if (isdigit(c))
- printf("Protocol error: literal too big\n");
- else
- printf("Protocol error: literal contains invalid char %02x '%c'\n", c, isprint(c)?c:c);
- goto protocol_error;
- }
- }
- is->ptr = p;
- if (stream_fill(is) == IMAP_TOK_ERROR)
- goto io_error;
- p = is->ptr;
- e = is->end;
- }
- } else if (c == '"') {
- o = is->tokenptr;
- oe = is->tokenptr + CAMEL_IMAPP_STREAM_TOKEN - 1;
- while (1) {
- while (p < e) {
- c = *p++;
- if (c == '\\') {
- while (p >= e) {
- is->ptr = p;
- if (stream_fill(is) == IMAP_TOK_ERROR)
- goto io_error;
- p = is->ptr;
- e = is->end;
- }
- c = *p++;
- } else if (c == '\"') {
- is->ptr = p;
- *o = 0;
- *data = is->tokenbuf;
- *len = o - is->tokenbuf;
- t(printf("token STRING '%s'\n", is->tokenbuf));
- return IMAP_TOK_STRING;
- }
-
- if (c == '\n' || c == '\r' || o>=oe) {
- if (o >= oe)
- printf("Protocol error: string too long\n");
- else
- printf("Protocol error: truncated string\n");
- goto protocol_error;
- } else {
- *o++ = c;
- }
- }
- is->ptr = p;
- if (stream_fill(is) == IMAP_TOK_ERROR)
- goto io_error;
- p = is->ptr;
- e = is->end;
- }
- } else {
- o = is->tokenptr;
- oe = is->tokenptr + CAMEL_IMAPP_STREAM_TOKEN - 1;
- digits = isdigit(c);
- *o++ = c;
- while (1) {
- while (p < e) {
- c = *p++;
- /*if (strchr(" \r\n*()[]+", c) != NULL) {*/
- if (imap_not_id(c)) {
- if (c == ' ' || c == '\r')
- is->ptr = p;
- else
- is->ptr = p-1;
- *o = 0;
- *data = is->tokenbuf;
- *len = o - is->tokenbuf;
- t(printf("token TOKEN '%s'\n", is->tokenbuf));
- return digits?IMAP_TOK_INT:IMAP_TOK_TOKEN;
- } else if (o < oe) {
- digits &= isdigit(c);
- *o++ = c;
- } else {
- printf("Protocol error: token too long\n");
- goto protocol_error;
- }
- }
- is->ptr = p;
- if (stream_fill(is) == IMAP_TOK_ERROR)
- goto io_error;
- p = is->ptr;
- e = is->end;
- }
- }
-
- /* Had an i/o erorr */
-io_error:
- printf("Got io error\n");
- camel_exception_throw(1, "io error");
- return IMAP_TOK_ERROR;
-
- /* Protocol error, skip until next lf? */
-protocol_error:
- printf("Got protocol error\n");
-
- if (c == '\n')
- is->ptr = p-1;
- else
- is->ptr = p;
-
- camel_exception_throw(1, "protocol error");
- return IMAP_TOK_PROTOCOL;
-}
-
-void
-camel_imapp_stream_ungettoken(CamelIMAPPStream *is, camel_imapp_token_t tok, unsigned char *token, unsigned int len)
-{
- /*printf("ungettoken: '%c' '%s'\n", tok, token);*/
- is->unget_tok = tok;
- is->unget_token = token;
- is->unget_len = len;
- is->unget++;
-}
-
-/* returns -1 on error, 0 if last lot of data, >0 if more remaining */
-int camel_imapp_stream_gets(CamelIMAPPStream *is, unsigned char **start, unsigned int *len)
-{
- int max;
- unsigned char *end;
-
- *len = 0;
-
- max = is->end - is->ptr;
- if (max == 0) {
- max = stream_fill(is);
- if (max <= 0)
- return max;
- }
-
- *start = is->ptr;
- end = memchr(is->ptr, '\n', max);
- if (end)
- max = (end - is->ptr) + 1;
- *start = is->ptr;
- *len = max;
- is->ptr += max;
-
- return end == NULL?1:0;
-}
-
-void camel_imapp_stream_set_literal(CamelIMAPPStream *is, unsigned int literal)
-{
- is->literal = literal;
-}
-
-/* returns -1 on erorr, 0 if last data, >0 if more data left */
-int camel_imapp_stream_getl(CamelIMAPPStream *is, unsigned char **start, unsigned int *len)
-{
- int max;
-
- *len = 0;
-
- if (is->literal > 0) {
- max = is->end - is->ptr;
- if (max == 0) {
- max = stream_fill(is);
- if (max <= 0)
- return max;
- }
-
- max = MIN(max, is->literal);
- *start = is->ptr;
- *len = max;
- is->ptr += max;
- is->literal -= max;
- }
-
- if (is->literal > 0)
- return 1;
-
- return 0;
-}
diff --git a/camel/providers/imapp/camel-imapp-stream.h b/camel/providers/imapp/camel-imapp-stream.h
deleted file mode 100644
index 802c018672..0000000000
--- a/camel/providers/imapp/camel-imapp-stream.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_IMAPP_STREAM_H
-#define _CAMEL_IMAPP_STREAM_H
-
-#include <camel/camel-stream.h>
-
-#define CAMEL_IMAPP_STREAM(obj) CAMEL_CHECK_CAST (obj, camel_imapp_stream_get_type (), CamelIMAPPStream)
-#define CAMEL_IMAPP_STREAM_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imapp_stream_get_type (), CamelIMAPPStreamClass)
-#define CAMEL_IS_IMAP_STREAM(obj) CAMEL_CHECK_TYPE (obj, camel_imapp_stream_get_type ())
-
-typedef struct _CamelIMAPPStreamClass CamelIMAPPStreamClass;
-typedef struct _CamelIMAPPStream CamelIMAPPStream;
-
-typedef enum {
- IMAP_TOK_PROTOCOL = -2,
- IMAP_TOK_ERROR = -1,
- IMAP_TOK_TOKEN = 256,
- IMAP_TOK_STRING,
- IMAP_TOK_INT,
- IMAP_TOK_LITERAL,
-} camel_imapp_token_t;
-
-struct _CamelIMAPPStream {
- CamelStream parent;
-
- CamelStream *source;
-
- /*int state;*/
- unsigned char *buf, *ptr, *end;
- unsigned int literal;
-
- unsigned int unget;
- camel_imapp_token_t unget_tok;
- unsigned char *unget_token;
- unsigned int unget_len;
-
- unsigned char *tokenbuf, *tokenptr, *tokenend;
-};
-
-struct _CamelIMAPPStreamClass {
- CamelStreamClass parent_class;
-};
-
-CamelType camel_imapp_stream_get_type (void);
-
-CamelStream *camel_imapp_stream_new (CamelStream *source);
-
-camel_imapp_token_t camel_imapp_stream_token (CamelIMAPPStream *is, unsigned char **start, unsigned int *len); /* throws IO,PARSE exception */
-void camel_imapp_stream_ungettoken (CamelIMAPPStream *is, camel_imapp_token_t tok, unsigned char *token, unsigned int len);
-
-void camel_imapp_stream_set_literal (CamelIMAPPStream *is, unsigned int literal);
-int camel_imapp_stream_gets (CamelIMAPPStream *is, unsigned char **start, unsigned int *len);
-int camel_imapp_stream_getl (CamelIMAPPStream *is, unsigned char **start, unsigned int *len);
-
-/* all throw IO,PARSE exceptions */
-
-/* gets an atom, upper-cases */
-int camel_imapp_stream_atom (CamelIMAPPStream *is, unsigned char **start, unsigned int *len);
-/* gets an atom or string */
-int camel_imapp_stream_astring (CamelIMAPPStream *is, unsigned char **start);
-/* gets a NIL or a string, start==NULL if NIL */
-int camel_imapp_stream_nstring (CamelIMAPPStream *is, unsigned char **start);
-/* gets a NIL or string into a stream, stream==NULL if NIL */
-int camel_imapp_stream_nstring_stream(CamelIMAPPStream *is, CamelStream **stream);
-/* gets 'text' */
-int camel_imapp_stream_text (CamelIMAPPStream *is, unsigned char **text);
-
-/* gets a 'number' */
-guint32 camel_imapp_stream_number(CamelIMAPPStream *is);
-
-#endif /* ! _CAMEL_IMAPP_STREAM_H */
diff --git a/camel/providers/imapp/camel-imapp-summary.c b/camel/providers/imapp/camel-imapp-summary.c
deleted file mode 100644
index a0df21bcb0..0000000000
--- a/camel/providers/imapp/camel-imapp-summary.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright(C) 2000 Ximian Inc.
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- * Dan Winship <danw@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "camel-imapp-summary.h"
-#include <camel/camel-file-utils.h>
-
-#define CAMEL_IMAPP_SUMMARY_VERSION (0x1000)
-
-static int summary_header_load(CamelFolderSummary *, FILE *);
-static int summary_header_save(CamelFolderSummary *, FILE *);
-
-static CamelMessageInfo *message_info_load(CamelFolderSummary *s, FILE *in);
-static int message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info);
-
-static void camel_imapp_summary_class_init(CamelIMAPPSummaryClass *klass);
-static void camel_imapp_summary_init (CamelIMAPPSummary *obj);
-
-static CamelFolderSummaryClass *camel_imapp_summary_parent;
-
-CamelType
-camel_imapp_summary_get_type(void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(
- camel_folder_summary_get_type(), "CamelIMAPPSummary",
- sizeof(CamelIMAPPSummary),
- sizeof(CamelIMAPPSummaryClass),
- (CamelObjectClassInitFunc) camel_imapp_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imapp_summary_init,
- NULL);
- }
-
- return type;
-}
-
-static void
-camel_imapp_summary_class_init(CamelIMAPPSummaryClass *klass)
-{
- CamelFolderSummaryClass *cfs_class =(CamelFolderSummaryClass *) klass;
-
- camel_imapp_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type()));
-
- cfs_class->summary_header_load = summary_header_load;
- cfs_class->summary_header_save = summary_header_save;
- cfs_class->message_info_load = message_info_load;
- cfs_class->message_info_save = message_info_save;
-}
-
-static void
-camel_imapp_summary_init(CamelIMAPPSummary *obj)
-{
- CamelFolderSummary *s =(CamelFolderSummary *)obj;
-
- /* subclasses need to set the right instance data sizes */
- s->message_info_size = sizeof(CamelIMAPPMessageInfo);
- s->content_info_size = sizeof(CamelMessageContentInfo);
-
- /* and a unique file version */
- s->version += CAMEL_IMAPP_SUMMARY_VERSION;
-}
-
-/**
- * camel_imapp_summary_new:
- * @filename: the file to store the summary in.
- *
- * This will create a new CamelIMAPPSummary object and read in the
- * summary data from disk, if it exists.
- *
- * Return value: A new CamelIMAPPSummary object.
- **/
-CamelFolderSummary *
-camel_imapp_summary_new(void)
-{
- CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY(camel_object_new(camel_imapp_summary_get_type()));
-
- return summary;
-}
-
-
-static int
-summary_header_load(CamelFolderSummary *s, FILE *in)
-{
- CamelIMAPPSummary *ims = CAMEL_IMAPP_SUMMARY(s);
-
- if (camel_imapp_summary_parent->summary_header_load(s, in) == -1)
- return -1;
-
- return camel_file_util_decode_uint32(in, &ims->uidvalidity);
-}
-
-static int
-summary_header_save(CamelFolderSummary *s, FILE *out)
-{
- CamelIMAPPSummary *ims = CAMEL_IMAPP_SUMMARY(s);
-
- if (camel_imapp_summary_parent->summary_header_save(s, out) == -1)
- return -1;
-
- return camel_file_util_encode_uint32(out, ims->uidvalidity);
-}
-
-
-static CamelMessageInfo *
-message_info_load(CamelFolderSummary *s, FILE *in)
-{
- CamelMessageInfo *info;
- CamelIMAPPMessageInfo *iinfo;
-
- info = camel_imapp_summary_parent->message_info_load(s, in);
- if (info) {
- iinfo =(CamelIMAPPMessageInfo *)info;
-
- if (camel_file_util_decode_uint32(in, &iinfo->server_flags) == -1)
- goto error;
- }
-
- return info;
-error:
- camel_folder_summary_info_free(s, info);
- return NULL;
-}
-
-static int
-message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
-{
- CamelIMAPPMessageInfo *iinfo =(CamelIMAPPMessageInfo *)info;
-
- if (camel_imapp_summary_parent->message_info_save(s, out, info) == -1)
- return -1;
-
- return camel_file_util_encode_uint32(out, iinfo->server_flags);
-}
diff --git a/camel/providers/imapp/camel-imapp-summary.h b/camel/providers/imapp/camel-imapp-summary.h
deleted file mode 100644
index e9783625f4..0000000000
--- a/camel/providers/imapp/camel-imapp-summary.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- * Dan Winship <danw@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_IMAPP_SUMMARY_H
-#define _CAMEL_IMAPP_SUMMARY_H
-
-#include <camel/camel-folder-summary.h>
-#include <camel/camel-exception.h>
-
-#define CAMEL_IMAPP_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_imapp_summary_get_type (), CamelIMAPPSummary)
-#define CAMEL_IMAPP_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imapp_summary_get_type (), CamelIMAPPSummaryClass)
-#define CAMEL_IS_IMAPP_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_imapp_summary_get_type ())
-
-#define CAMEL_IMAPP_SERVER_FLAGS (CAMEL_MESSAGE_ANSWERED | \
- CAMEL_MESSAGE_DELETED | \
- CAMEL_MESSAGE_DRAFT | \
- CAMEL_MESSAGE_FLAGGED | \
- CAMEL_MESSAGE_SEEN)
-
-#define CAMEL_IMAPP_MESSAGE_RECENT (1 << 8)
-
-typedef struct _CamelIMAPPSummaryClass CamelIMAPPSummaryClass;
-typedef struct _CamelIMAPPSummary CamelIMAPPSummary;
-
-typedef struct _CamelIMAPPMessageInfo {
- CamelMessageInfo info;
-
- guint32 server_flags;
-} CamelIMAPPMessageInfo;
-
-struct _CamelIMAPPSummary {
- CamelFolderSummary parent;
-
- guint32 uidvalidity;
-};
-
-struct _CamelIMAPPSummaryClass {
- CamelFolderSummaryClass parent_class;
-
-};
-
-CamelType camel_imapp_summary_get_type (void);
-CamelFolderSummary *camel_imapp_summary_new (void);
-
-#endif /* ! _CAMEL_IMAPP_SUMMARY_H */
-
diff --git a/camel/providers/imapp/camel-imapp-utils.c b/camel/providers/imapp/camel-imapp-utils.c
deleted file mode 100644
index e20499689d..0000000000
--- a/camel/providers/imapp/camel-imapp-utils.c
+++ /dev/null
@@ -1,1339 +0,0 @@
-
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-
-#include <camel/camel-folder-summary.h>
-#include <camel/camel-store.h>
-#include <camel/camel-utf8.h>
-
-#include "camel-imapp-folder.h"
-#include "camel-imapp-stream.h"
-#include "camel-imapp-utils.h"
-#include "camel-imapp-exception.h"
-#include "camel-imapp-engine.h"
-#include "e-util/e-memory.h"
-
-/* high-level parser state */
-#define p(x)
-/* debug */
-#define d(x)
-
-/* ANSI-C code produced by gperf version 2.7 */
-/* Command-line: gperf -H imap_hash -N imap_tokenise -L ANSI-C -o -t -k1,$ imap-tokens.txt */
-struct _imap_keyword { char *name; enum _imap_id id; };
-/*
- gperf input file
- best hash generated using: gperf -o -s-2 -k1,'$' -t -H imap_hash -N imap_tokenise -L ANSI-C
-*/
-
-#define TOTAL_KEYWORDS 23
-#define MIN_WORD_LENGTH 2
-#define MAX_WORD_LENGTH 14
-#define MIN_HASH_VALUE 2
-#define MAX_HASH_VALUE 38
-/* maximum key range = 37, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#endif
-static unsigned int
-imap_hash (register const char *str, register unsigned int len)
-{
- static unsigned char asso_values[] =
- {
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 10, 15, 39, 20, 0,
- 0, 39, 0, 10, 39, 0, 39, 39, 10, 0,
- 0, 39, 0, 10, 5, 10, 39, 39, 39, 0,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39
- };
- return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]];
-}
-
-#ifdef __GNUC__
-__inline
-#endif
-enum _imap_id
-imap_tokenise (register const char *str, register unsigned int len)
-{
- static struct _imap_keyword wordlist[] =
- {
- {""}, {""},
- {"OK", IMAP_OK},
- {""}, {""},
- {"PARSE", IMAP_PARSE},
- {""},
- {"PREAUTH", IMAP_PREAUTH},
- {"ENVELOPE", IMAP_ENVELOPE},
- {"READ-ONLY", IMAP_READ_ONLY},
- {"READ-WRITE", IMAP_READ_WRITE},
- {"RFC822.SIZE", IMAP_RFC822_SIZE},
- {"NO", IMAP_NO},
- {"RFC822.HEADER", IMAP_RFC822_HEADER},
- {"TRYCREATE", IMAP_TRYCREATE},
- {"FLAGS", IMAP_FLAGS},
- {"RFC822.TEXT", IMAP_RFC822_TEXT},
- {"NEWNAME", IMAP_NEWNAME},
- {"BYE", IMAP_BYE},
- {"BODY", IMAP_BODY},
- {"ALERT", IMAP_ALERT},
- {"UIDVALIDITY", IMAP_UIDVALIDITY},
- {"INTERNALDATE", IMAP_INTERNALDATE},
- {""},
- {"PERMANENTFLAGS", IMAP_PERMANENTFLAGS},
- {""},
- {"UNSEEN", IMAP_UNSEEN},
- {""},
- {"BODYSTRUCTURE", IMAP_BODYSTRUCTURE},
- {""}, {""}, {""}, {""},
- {"UID", IMAP_UID},
- {""}, {""}, {""}, {""},
- {"BAD", IMAP_BAD}
- };
-
- if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
- {
- register int key = imap_hash (str, len);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register const char *s = wordlist[key].name;
-
- if (*str == *s && !strcmp (str + 1, s + 1))
- return wordlist[key].id;
- }
- }
- return 0;
-}
-
-/* flag table */
-static struct {
- char *name;
- guint32 flag;
-} flag_table[] = {
- { "\\ANSWERED", CAMEL_MESSAGE_ANSWERED },
- { "\\DELETED", CAMEL_MESSAGE_DELETED },
- { "\\DRAFT", CAMEL_MESSAGE_DRAFT },
- { "\\FLAGGED", CAMEL_MESSAGE_FLAGGED },
- { "\\SEEN", CAMEL_MESSAGE_SEEN },
- { "\\RECENT", CAMEL_IMAPP_MESSAGE_RECENT },
- { "\\*", CAMEL_MESSAGE_USER },
-};
-
-/* utility functions
- shoudl this be part of imapp-driver? */
-/* mabye this should be a stream op? */
-void
-imap_parse_flags(CamelIMAPPStream *stream, guint32 *flagsp)
-/* throws IO,PARSE exception */
-{
- int tok, len, i;
- unsigned char *token, *p, c;
- guint32 flags = 0;
-
- *flagsp = flags;
-
- tok = camel_imapp_stream_token(stream, &token, &len);
- if (tok == '(') {
- do {
- tok = camel_imapp_stream_token(stream, &token, &len);
- if (tok == IMAP_TOK_TOKEN) {
- p = token;
- while ((c=*p))
- *p++ = toupper(c);
- for (i=0;i<(int)(sizeof(flag_table)/sizeof(flag_table[0]));i++)
- if (!strcmp(token, flag_table[i].name))
- flags |= flag_table[i].flag;
- } else if (tok != ')') {
- camel_exception_throw(1, "expecting flag");
- }
- } while (tok != ')');
- } else {
- camel_exception_throw(1, "expecting flag list");
- }
-
- *flagsp = flags;
-}
-
-void
-imap_write_flags(CamelStream *stream, guint32 flags)
-/* throws IO exception */
-{
- int i;
-
- /* all this ugly exception throwing goes away once camel streams throw their own? */
- if (camel_stream_write(stream, "(", 1) == -1)
- camel_exception_throw(1, "io error: %s", strerror(errno));
-
- for (i=0;flags!=0 && i<(int)(sizeof(flag_table)/sizeof(flag_table[0]));i++) {
- if (flag_table[i].flag & flags) {
- if (camel_stream_write(stream, flag_table[i].name, strlen(flag_table[i].name)) == -1)
- camel_exception_throw(1, "io error: %s", strerror(errno));
- flags &= ~flag_table[i].flag;
- if (flags != 0)
- if (camel_stream_write(stream, " ", 1) == -1)
- camel_exception_throw(1, "io error: %s", strerror(errno));
- }
- }
-
- if (camel_stream_write(stream, ")", 1) == -1)
- camel_exception_throw(1, "io error: %s", strerror(errno));
-}
-
-/*
-body ::= "(" body_type_1part / body_type_mpart ")"
-
-body_extension ::= nstring / number / "(" 1#body_extension ")"
- ;; Future expansion. Client implementations
- ;; MUST accept body_extension fields. Server
- ;; implementations MUST NOT generate
- ;; body_extension fields except as defined by
- ;; future standard or standards-track
- ;; revisions of this specification.
-
-body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp
- [SPACE body_fld_lang
- [SPACE 1#body_extension]]]
- ;; MUST NOT be returned on non-extensible
- ;; "BODY" fetch
-
-body_ext_mpart ::= body_fld_param
- [SPACE body_fld_dsp SPACE body_fld_lang
- [SPACE 1#body_extension]]
- ;; MUST NOT be returned on non-extensible
- ;; "BODY" fetch
-
-body_fields ::= body_fld_param SPACE body_fld_id SPACE
- body_fld_desc SPACE body_fld_enc SPACE
- body_fld_octets
-
-body_fld_desc ::= nstring
-
-body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil
-
-body_fld_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
- "QUOTED-PRINTABLE") <">) / string
-
-body_fld_id ::= nstring
-
-body_fld_lang ::= nstring / "(" 1#string ")"
-
-body_fld_lines ::= number
-
-body_fld_md5 ::= nstring
-
-body_fld_octets ::= number
-
-body_fld_param ::= "(" 1#(string SPACE string) ")" / nil
-
-body_type_1part ::= (body_type_basic / body_type_msg / body_type_text)
- [SPACE body_ext_1part]
-
-body_type_basic ::= media_basic SPACE body_fields
- ;; MESSAGE subtype MUST NOT be "RFC822"
-
-body_type_mpart ::= 1*body SPACE media_subtype
- [SPACE body_ext_mpart]
-
-body_type_msg ::= media_message SPACE body_fields SPACE envelope
- SPACE body SPACE body_fld_lines
-
-body_type_text ::= media_text SPACE body_fields SPACE body_fld_lines
-
-envelope ::= "(" env_date SPACE env_subject SPACE env_from
- SPACE env_sender SPACE env_reply_to SPACE env_to
- SPACE env_cc SPACE env_bcc SPACE env_in_reply_to
- SPACE env_message_id ")"
-
-env_bcc ::= "(" 1*address ")" / nil
-
-env_cc ::= "(" 1*address ")" / nil
-
-env_date ::= nstring
-
-env_from ::= "(" 1*address ")" / nil
-
-env_in_reply_to ::= nstring
-
-env_message_id ::= nstring
-
-env_reply_to ::= "(" 1*address ")" / nil
-
-env_sender ::= "(" 1*address ")" / nil
-
-env_subject ::= nstring
-
-env_to ::= "(" 1*address ")" / nil
-
-media_basic ::= (<"> ("APPLICATION" / "AUDIO" / "IMAGE" /
- "MESSAGE" / "VIDEO") <">) / string)
- SPACE media_subtype
- ;; Defined in [MIME-IMT]
-
-media_message ::= <"> "MESSAGE" <"> SPACE <"> "RFC822" <">
- ;; Defined in [MIME-IMT]
-
-media_subtype ::= string
- ;; Defined in [MIME-IMT]
-
-media_text ::= <"> "TEXT" <"> SPACE media_subtype
- ;; Defined in [MIME-IMT]
-
-
-
- ( "type" "subtype" body_fields [envelope body body_fld_lines]
- [body_fld_lines]
-
-
-
- (("TEXT" "PLAIN" ("CHARSET"
- "US-ASCII") NIL NIL "7BIT" 1152 23)("TEXT" "PLAIN"
- ("CHARSET" "US-ASCII" "NAME" "cc.diff")
- "<960723163407.20117h@cac.washington.edu>"
- "Compiler diff" "BASE64" 4554 73) "MIXED"))
-
-*/
-
-/*
-struct _body_fields {
- CamelContentType *ct;
- char *msgid, *desc;
- CamelTransferEncoding encoding;
- guint32 size;
- };*/
-
-void
-imap_free_body(struct _CamelMessageContentInfo *cinfo)
-{
- struct _CamelMessageContentInfo *list, *next;
-
- list = cinfo->childs;
- while (list) {
- next = list->next;
- imap_free_body(list);
- list = next;
- }
-
- if (cinfo->type)
- camel_content_type_unref(cinfo->type);
- g_free(cinfo->id);
- g_free(cinfo->description);
- g_free(cinfo->encoding);
- g_free(cinfo);
-}
-
-void
-imap_parse_param_list(CamelIMAPPStream *is, struct _camel_header_param **plist)
-{
- int tok, len;
- unsigned char *token, *param;
-
- p(printf("body_fld_param\n"));
-
- /* body_fld_param ::= "(" 1#(string SPACE string) ")" / nil */
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == '(') {
- while (1) {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == ')')
- break;
- camel_imapp_stream_ungettoken(is, tok, token, len);
-
- camel_imapp_stream_astring(is, &token);
- param = alloca(strlen(token)+1);
- strcpy(param, token);
- camel_imapp_stream_astring(is, &token);
- camel_header_set_param(plist, param, token);
- }
- } /* else check nil? no need */
-}
-
-struct _CamelContentDisposition *
-imap_parse_ext_optional(CamelIMAPPStream *is)
-{
- int tok, len;
- unsigned char *token;
- struct _CamelContentDisposition * volatile dinfo = NULL;
-
- /* this parses both extension types, from the body_fld_dsp onwards */
- /* although the grammars are different, they can be parsed the same way */
-
- /* body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp
- [SPACE body_fld_lang
- [SPACE 1#body_extension]]]
- ;; MUST NOT be returned on non-extensible
- ;; "BODY" fetch */
-
- /* body_ext_mpart ::= body_fld_param
- [SPACE body_fld_dsp SPACE body_fld_lang
- [SPACE 1#body_extension]]
- ;; MUST NOT be returned on non-extensible
- ;; "BODY" fetch */
-
- CAMEL_TRY {
- /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */
-
- tok = camel_imapp_stream_token(is, &token, &len);
- switch (tok) {
- case '(':
- dinfo = g_malloc0(sizeof(*dinfo));
- dinfo->refcount = 1;
- /* should be string */
- camel_imapp_stream_astring(is, &token);
-
- dinfo->disposition = g_strdup(token);
- imap_parse_param_list(is, &dinfo->params);
- case IMAP_TOK_TOKEN:
- d(printf("body_fld_dsp: NIL\n"));
- break;
- default:
- camel_exception_throw(1, "body_fld_disp: expecting nil or list");
- }
-
- p(printf("body_fld_lang\n"));
-
- /* body_fld_lang ::= nstring / "(" 1#string ")" */
-
- /* we just drop the lang string/list, save it somewhere? */
-
- tok = camel_imapp_stream_token(is, &token, &len);
- switch (tok) {
- case '(':
- while (1) {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == ')') {
- break;
- } else if (tok != IMAP_TOK_STRING) {
- camel_exception_throw(1, "expecting string");
- }
- }
- break;
- case IMAP_TOK_TOKEN:
- d(printf("body_fld_lang = nil\n"));
- /* treat as 'nil' */
- break;
- case IMAP_TOK_STRING:
- /* we have a string */
- break;
- case IMAP_TOK_LITERAL:
- /* we have a literal string */
- camel_imapp_stream_set_literal(is, len);
- while ((tok = camel_imapp_stream_getl(is, &token, &len)) > 0) {
- d(printf("Skip literal data '%.*s'\n", (int)len, token));
- }
- break;
-
- }
- } CAMEL_CATCH(ex) {
- if (dinfo)
- camel_content_disposition_unref(dinfo);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- return dinfo;
-}
-
-struct _CamelMessageContentInfo *
-imap_parse_body_fields(CamelIMAPPStream *is)
-{
- unsigned char *token, *type;
- struct _CamelMessageContentInfo *cinfo;
-
- /* body_fields ::= body_fld_param SPACE body_fld_id SPACE
- body_fld_desc SPACE body_fld_enc SPACE
- body_fld_octets */
-
- p(printf("body_fields\n"));
-
- cinfo = g_malloc0(sizeof(*cinfo));
-
- CAMEL_TRY {
- /* this should be string not astring */
- camel_imapp_stream_astring(is, &token);
- type = alloca(strlen(token)+1);
- strcpy(type, token);
- camel_imapp_stream_astring(is, &token);
- cinfo->type = camel_content_type_new(type, token);
- imap_parse_param_list(is, &cinfo->type->params);
-
- /* body_fld_id ::= nstring */
- camel_imapp_stream_nstring(is, &token);
- cinfo->id = g_strdup(token);
-
- /* body_fld_desc ::= nstring */
- camel_imapp_stream_nstring(is, &token);
- cinfo->description = g_strdup(token);
-
- /* body_fld_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
- "QUOTED-PRINTABLE") <">) / string */
- camel_imapp_stream_astring(is, &token);
- cinfo->encoding = g_strdup(token);
-
- /* body_fld_octets ::= number */
- cinfo->size = camel_imapp_stream_number(is);
- } CAMEL_CATCH(ex) {
- imap_free_body(cinfo);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- return cinfo;
-}
-
-struct _camel_header_address *
-imap_parse_address_list(CamelIMAPPStream *is)
-/* throws PARSE,IO exception */
-{
- int tok, len;
- unsigned char *token, *host, *mbox;
- struct _camel_header_address *list = NULL;
-
- /* "(" 1*address ")" / nil */
-
- CAMEL_TRY {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == '(') {
- while (1) {
- struct _camel_header_address *addr, *group = NULL;
-
- /* address ::= "(" addr_name SPACE addr_adl SPACE addr_mailbox
- SPACE addr_host ")" */
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == ')')
- break;
- if (tok != '(')
- camel_exception_throw(1, "missing '(' for address");
-
- addr = camel_header_address_new();
- addr->type = HEADER_ADDRESS_NAME;
- tok = camel_imapp_stream_nstring(is, &token);
- addr->name = g_strdup(token);
- /* we ignore the route, nobody uses it in the real world */
- tok = camel_imapp_stream_nstring(is, &token);
-
- /* [RFC-822] group syntax is indicated by a special
- form of address structure in which the host name
- field is NIL. If the mailbox name field is also
- NIL, this is an end of group marker (semi-colon in
- RFC 822 syntax). If the mailbox name field is
- non-NIL, this is a start of group marker, and the
- mailbox name field holds the group name phrase. */
-
- tok = camel_imapp_stream_nstring(is, &mbox);
- mbox = g_strdup(mbox);
- tok = camel_imapp_stream_nstring(is, &host);
- if (host == NULL) {
- if (mbox == NULL) {
- group = NULL;
- } else {
- d(printf("adding group '%s'\n", mbox));
- g_free(addr->name);
- addr->name = mbox;
- addr->type = HEADER_ADDRESS_GROUP;
- camel_header_address_list_append(&list, addr);
- group = addr;
- }
- } else {
- addr->v.addr = g_strdup_printf("%s%s%s", mbox?(char *)mbox:"", host?"@":"", host?(char *)host:"");
- g_free(mbox);
- d(printf("adding address '%s'\n", addr->v.addr));
- if (group != NULL)
- camel_header_address_add_member(group, addr);
- else
- camel_header_address_list_append(&list, addr);
- }
- do {
- tok = camel_imapp_stream_token(is, &token, &len);
- } while (tok != ')');
- }
- } else {
- d(printf("empty, nil '%s'\n", token));
- }
- } CAMEL_CATCH(ex) {
- camel_header_address_list_clear(&list);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- return list;
-}
-
-struct _CamelMessageInfo *
-imap_parse_envelope(CamelIMAPPStream *is)
-{
- int tok, len;
- unsigned char *token;
- struct _camel_header_address *addr, *addr_from;
- char *addrstr;
- struct _CamelMessageInfo *minfo;
-
- /* envelope ::= "(" env_date SPACE env_subject SPACE env_from
- SPACE env_sender SPACE env_reply_to SPACE env_to
- SPACE env_cc SPACE env_bcc SPACE env_in_reply_to
- SPACE env_message_id ")" */
-
- p(printf("envelope\n"));
-
- minfo = camel_message_info_new();
-
- CAMEL_TRY {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok != '(')
- camel_exception_throw(1, "envelope: expecting '('");
-
- /* env_date ::= nstring */
- camel_imapp_stream_nstring(is, &token);
- minfo->date_sent = camel_header_decode_date(token, NULL);
-
- /* env_subject ::= nstring */
- tok = camel_imapp_stream_nstring(is, &token);
- /* DUH: this free's it!: camel_message_info_set_subject(minfo, token); */
- e_poolv_set(minfo->strings, CAMEL_MESSAGE_INFO_SUBJECT, token, FALSE);
-
- /* we merge from/sender into from, append should probably merge more smartly? */
-
- /* env_from ::= "(" 1*address ")" / nil */
- addr_from = imap_parse_address_list(is);
-
- /* env_sender ::= "(" 1*address ")" / nil */
- addr = imap_parse_address_list(is);
- if (addr_from) {
- camel_header_address_list_clear(&addr);
-#if 0
- if (addr)
- camel_header_address_list_append_list(&addr_from, &addr);
-#endif
- } else {
- if (addr)
- addr_from = addr;
- }
-
- if (addr_from) {
- addrstr = camel_header_address_list_format(addr_from);
- camel_message_info_set_from(minfo, addrstr);
- camel_header_address_list_clear(&addr_from);
- }
-
- /* we dont keep reply_to */
-
- /* env_reply_to ::= "(" 1*address ")" / nil */
- addr = imap_parse_address_list(is);
- camel_header_address_list_clear(&addr);
-
- /* env_to ::= "(" 1*address ")" / nil */
- addr = imap_parse_address_list(is);
- if (addr) {
- addrstr = camel_header_address_list_format(addr);
- camel_message_info_set_to(minfo, addrstr);
- camel_header_address_list_clear(&addr);
- }
-
- /* env_cc ::= "(" 1*address ")" / nil */
- addr = imap_parse_address_list(is);
- if (addr) {
- addrstr = camel_header_address_list_format(addr);
- camel_message_info_set_cc(minfo, addrstr);
- camel_header_address_list_clear(&addr);
- }
-
- /* we dont keep bcc either */
-
- /* env_bcc ::= "(" 1*address ")" / nil */
- addr = imap_parse_address_list(is);
- camel_header_address_list_clear(&addr);
-
- /* FIXME: need to put in-reply-to into references hash list */
-
- /* env_in_reply_to ::= nstring */
- tok = camel_imapp_stream_nstring(is, &token);
-
- /* FIXME: need to put message-id into message-id hash */
-
- /* env_message_id ::= nstring */
- tok = camel_imapp_stream_nstring(is, &token);
-
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok != ')')
- camel_exception_throw(1, "expecting ')'");
- } CAMEL_CATCH(ex) {
- camel_message_info_free(minfo);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- return minfo;
-}
-
-struct _CamelMessageContentInfo *
-imap_parse_body(CamelIMAPPStream *is)
-{
- int tok, len;
- unsigned char *token;
- struct _CamelMessageContentInfo * volatile cinfo = NULL;
- struct _CamelMessageContentInfo *subinfo, *last;
- struct _CamelContentDisposition * volatile dinfo = NULL;
- struct _CamelMessageInfo * volatile minfo = NULL;
-
- /* body ::= "(" body_type_1part / body_type_mpart ")" */
-
- p(printf("body\n"));
-
- CAMEL_TRY {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok != '(')
- camel_exception_throw(1, "body: expecting '('");
-
- /* 1*body (optional for multiparts) */
- tok = camel_imapp_stream_token(is, &token, &len);
- camel_imapp_stream_ungettoken(is, tok, token, len);
- if (tok == '(') {
- /* body_type_mpart ::= 1*body SPACE media_subtype
- [SPACE body_ext_mpart] */
-
- cinfo = g_malloc0(sizeof(*cinfo));
- last = (struct _CamelMessageContentInfo *)&cinfo->childs;
- do {
- subinfo = imap_parse_body(is);
- last->next = subinfo;
- last = subinfo;
- subinfo->parent = cinfo;
- tok = camel_imapp_stream_token(is, &token, &len);
- camel_imapp_stream_ungettoken(is, tok, token, len);
- } while (tok == '(');
-
- d(printf("media_subtype\n"));
-
- camel_imapp_stream_astring(is, &token);
- cinfo->type = camel_content_type_new("multipart", token);
-
- /* body_ext_mpart ::= body_fld_param
- [SPACE body_fld_dsp SPACE body_fld_lang
- [SPACE 1#body_extension]]
- ;; MUST NOT be returned on non-extensible
- ;; "BODY" fetch */
-
- d(printf("body_ext_mpart\n"));
-
- tok = camel_imapp_stream_token(is, &token, &len);
- camel_imapp_stream_ungettoken(is, tok, token, len);
- if (tok == '(') {
- imap_parse_param_list(is, &cinfo->type->params);
-
- /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */
-
- tok = camel_imapp_stream_token(is, &token, &len);
- camel_imapp_stream_ungettoken(is, tok, token, len);
- if (tok == '(' || tok == IMAP_TOK_TOKEN) {
- dinfo = imap_parse_ext_optional(is);
- /* other extension fields?, soaked up below */
- } else {
- camel_imapp_stream_ungettoken(is, tok, token, len);
- }
- }
- } else {
- /* body_type_1part ::= (body_type_basic / body_type_msg / body_type_text)
- [SPACE body_ext_1part]
-
- body_type_basic ::= media_basic SPACE body_fields
- body_type_text ::= media_text SPACE body_fields SPACE body_fld_lines
- body_type_msg ::= media_message SPACE body_fields SPACE envelope
- SPACE body SPACE body_fld_lines */
-
- d(printf("Single part body\n"));
-
- cinfo = imap_parse_body_fields(is);
-
- d(printf("envelope?\n"));
-
- /* do we have an envelope following */
- tok = camel_imapp_stream_token(is, &token, &len);
- camel_imapp_stream_ungettoken(is, tok, token, len);
- if (tok == '(') {
- /* what do we do with the envelope?? */
- minfo = imap_parse_envelope(is);
- /* what do we do with the message content info?? */
- minfo->content = imap_parse_body(is);
- camel_message_info_free(minfo);
- minfo = NULL;
- d(printf("Scanned envelope - what do i do with it?\n"));
- }
-
- d(printf("fld_lines?\n"));
-
- /* do we have fld_lines following? */
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == IMAP_TOK_INT) {
- d(printf("field lines: %s\n", token));
- tok = camel_imapp_stream_token(is, &token, &len);
- }
- camel_imapp_stream_ungettoken(is, tok, token, len);
-
- /* body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp
- [SPACE body_fld_lang
- [SPACE 1#body_extension]]]
- ;; MUST NOT be returned on non-extensible
- ;; "BODY" fetch */
-
- d(printf("extension data?\n"));
-
- if (tok != ')') {
- camel_imapp_stream_nstring(is, &token);
-
- d(printf("md5: %s\n", token?(char *)token:"NIL"));
-
- /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */
-
- tok = camel_imapp_stream_token(is, &token, &len);
- camel_imapp_stream_ungettoken(is, tok, token, len);
- if (tok == '(' || tok == IMAP_TOK_TOKEN) {
- dinfo = imap_parse_ext_optional(is);
- /* then other extension fields, soaked up below */
- }
- }
- }
-
- /* soak up any other extension fields that may be present */
- /* there should only be simple tokens, no lists */
- do {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok != ')')
- d(printf("Dropping extension data '%s'\n", token));
- } while (tok != ')');
- } CAMEL_CATCH(ex) {
- if (cinfo)
- imap_free_body(cinfo);
- if (dinfo)
- camel_content_disposition_unref(dinfo);
- if (minfo)
- camel_message_info_free(minfo);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- /* FIXME: do something with the disposition, currently we have no way to pass it out? */
- if (dinfo)
- camel_content_disposition_unref(dinfo);
-
- return cinfo;
-}
-
-char *
-imap_parse_section(CamelIMAPPStream *is)
-{
- int tok, len;
- unsigned char *token;
- char * volatile section = NULL;
-
- /* currently we only return the part within the [section] specifier
- any header fields are parsed, but dropped */
-
- /*
- section ::= "[" [section_text /
- (nz_number *["." nz_number] ["." (section_text / "MIME")])] "]"
-
- section_text ::= "HEADER" / "HEADER.FIELDS" [".NOT"]
- SPACE header_list / "TEXT"
- */
-
- CAMEL_TRY {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok != '[')
- camel_exception_throw(1, "section: expecting '['");
-
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == IMAP_TOK_INT || tok == IMAP_TOK_TOKEN)
- section = g_strdup(token);
- else if (tok == ']') {
- section = g_strdup("");
- camel_imapp_stream_ungettoken(is, tok, token, len);
- } else
- camel_exception_throw(1, "section: expecting token");
-
- /* header_list ::= "(" 1#header_fld_name ")"
- header_fld_name ::= astring */
-
- /* we dont need the header specifiers */
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == '(') {
- do {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == IMAP_TOK_STRING || tok == IMAP_TOK_TOKEN || tok == IMAP_TOK_INT) {
- /* ?do something? */
- } else if (tok != ')')
- camel_exception_throw(1, "section: header fields: expecting string");
- } while (tok != ')');
- tok = camel_imapp_stream_token(is, &token, &len);
- }
-
- if (tok != ']')
- camel_exception_throw(1, "section: expecting ']'");
- } CAMEL_CATCH(ex) {
- g_free(section);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- return section;
-}
-
-void
-imap_free_fetch(struct _fetch_info *finfo)
-{
- if (finfo == NULL)
- return;
-
- if (finfo->body)
- camel_object_unref((CamelObject *)finfo->body);
- if (finfo->text)
- camel_object_unref((CamelObject *)finfo->text);
- if (finfo->header)
- camel_object_unref((CamelObject *)finfo->header);
- if (finfo->minfo)
- camel_message_info_free(finfo->minfo);
- if (finfo->cinfo)
- imap_free_body(finfo->cinfo);
- g_free(finfo->date);
- g_free(finfo->section);
- g_free(finfo->uid);
- g_free(finfo);
-}
-
-extern void camel_content_info_dump(CamelMessageContentInfo *ci, int depth);
-extern void camel_message_info_dump(CamelMessageInfo *mi);
-
-#include <camel/camel-stream-fs.h>
-
-/* debug, dump one out */
-void
-imap_dump_fetch(struct _fetch_info *finfo)
-{
- CamelStream *sout;
- int fd;
-
- printf("Fetch info:\n");
- if (finfo == NULL) {
- printf("Empty\n");
- return;
- }
-
- fd = dup(1);
- sout = camel_stream_fs_new_with_fd(fd);
- if (finfo->body) {
- camel_stream_printf(sout, "Body content:\n");
- camel_stream_write_to_stream(finfo->body, sout);
- }
- if (finfo->text) {
- camel_stream_printf(sout, "Text content:\n");
- camel_stream_write_to_stream(finfo->text, sout);
- }
- if (finfo->header) {
- camel_stream_printf(sout, "Header content:\n");
- camel_stream_write_to_stream(finfo->header, sout);
- }
- if (finfo->minfo) {
- camel_stream_printf(sout, "Message Info:\n");
- camel_message_info_dump(finfo->minfo);
- }
- if (finfo->cinfo) {
- camel_stream_printf(sout, "Content Info:\n");
- camel_content_info_dump(finfo->cinfo, 0);
- }
- if (finfo->got & FETCH_SIZE)
- camel_stream_printf(sout, "Size: %d\n", (int)finfo->size);
- if (finfo->got & FETCH_BODY)
- camel_stream_printf(sout, "Offset: %d\n", (int)finfo->offset);
- if (finfo->got & FETCH_FLAGS)
- camel_stream_printf(sout, "Flags: %08x\n", (int)finfo->flags);
- if (finfo->date)
- camel_stream_printf(sout, "Date: '%s'\n", finfo->date);
- if (finfo->section)
- camel_stream_printf(sout, "Section: '%s'\n", finfo->section);
- if (finfo->date)
- camel_stream_printf(sout, "UID: '%s'\n", finfo->uid);
- camel_object_unref((CamelObject *)sout);
-}
-
-struct _fetch_info *
-imap_parse_fetch(CamelIMAPPStream *is)
-{
- int tok, len;
- unsigned char *token, *p, c;
- struct _fetch_info *finfo;
-
- finfo = g_malloc0(sizeof(*finfo));
-
- CAMEL_TRY {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok != '(')
- camel_exception_throw(1, "fetch: expecting '('");
-
- while ( (tok = camel_imapp_stream_token(is, &token, &len)) == IMAP_TOK_TOKEN ) {
-
- p = token;
- while ((c=*p))
- *p++ = toupper(c);
-
- switch(imap_tokenise(token, len)) {
- case IMAP_ENVELOPE:
- finfo->minfo = imap_parse_envelope(is);
- finfo->got |= FETCH_MINFO;
- break;
- case IMAP_FLAGS:
- imap_parse_flags(is, &finfo->flags);
- finfo->got |= FETCH_FLAGS;
- break;
- case IMAP_INTERNALDATE:
- camel_imapp_stream_nstring(is, &token);
- /* TODO: convert to camel format? */
- finfo->date = g_strdup(token);
- finfo->got |= FETCH_DATE;
- break;
- case IMAP_RFC822_HEADER:
- camel_imapp_stream_nstring_stream(is, &finfo->header);
- finfo->got |= FETCH_HEADER;
- break;
- case IMAP_RFC822_TEXT:
- camel_imapp_stream_nstring_stream(is, &finfo->text);
- finfo->got |= FETCH_TEXT;
- break;
- case IMAP_RFC822_SIZE:
- finfo->size = camel_imapp_stream_number(is);
- finfo->got |= FETCH_SIZE;
- break;
- case IMAP_BODYSTRUCTURE:
- finfo->cinfo = imap_parse_body(is);
- finfo->got |= FETCH_CINFO;
- break;
- case IMAP_BODY:
- tok = camel_imapp_stream_token(is, &token, &len);
- camel_imapp_stream_ungettoken(is, tok, token, len);
- if (tok == '(') {
- finfo->cinfo = imap_parse_body(is);
- finfo->got |= FETCH_CINFO;
- } else if (tok == '[') {
- finfo->section = imap_parse_section(is);
- finfo->got |= FETCH_SECTION;
- tok = camel_imapp_stream_token(is, &token, &len);
- if (token[0] == '<') {
- finfo->offset = strtoul(token+1, NULL, 10);
- } else {
- camel_imapp_stream_ungettoken(is, tok, token, len);
- }
- camel_imapp_stream_nstring_stream(is, &finfo->body);
- finfo->got |= FETCH_BODY;
- } else {
- camel_exception_throw(1, "unknown body response");
- }
- break;
- case IMAP_UID:
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok != IMAP_TOK_INT)
- camel_exception_throw(1, "uid not integer");
- finfo->uid = g_strdup(token);
- finfo->got |= FETCH_UID;
- break;
- default:
- camel_exception_throw(1, "unknown body response");
- }
- }
-
- if (tok != ')')
- camel_exception_throw(1, "missing closing ')' on fetch response");
- } CAMEL_CATCH(ex) {
- imap_free_fetch(finfo);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- return finfo;
-}
-
-/* rfc 2060 section 7.1 Status Responses */
-/* shoudl this start after [ or before the [? token_unget anyone? */
-struct _status_info *
-imap_parse_status(CamelIMAPPStream *is)
-{
- int tok, len;
- unsigned char *token;
- struct _status_info *sinfo;
-
- sinfo = g_malloc0(sizeof(*sinfo));
-
- CAMEL_TRY {
- camel_imapp_stream_atom(is, &token, &len);
-
- /*
- resp_cond_auth ::= ("OK" / "PREAUTH") SPACE resp_text
- ;; Authentication condition
-
- resp_cond_bye ::= "BYE" SPACE resp_text
-
- resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text
- ;; Status condition
- */
-
- sinfo->result = imap_tokenise(token, len);
- switch (sinfo->result) {
- case IMAP_OK:
- case IMAP_NO:
- case IMAP_BAD:
- case IMAP_PREAUTH:
- case IMAP_BYE:
- break;
- default:
- camel_exception_throw(1, "expecting OK/NO/BAD");
- }
-
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == '[') {
- camel_imapp_stream_atom(is, &token, &len);
- sinfo->condition = imap_tokenise(token, len);
-
- /* parse any details */
- switch (sinfo->condition) {
- case IMAP_READ_ONLY:
- case IMAP_READ_WRITE:
- case IMAP_ALERT:
- case IMAP_PARSE:
- case IMAP_TRYCREATE:
- break;
- case IMAP_NEWNAME:
- /* the rfc doesn't specify the bnf for this */
- camel_imapp_stream_astring(is, &token);
- sinfo->u.newname.oldname = g_strdup(token);
- camel_imapp_stream_astring(is, &token);
- sinfo->u.newname.newname = g_strdup(token);
- break;
- case IMAP_PERMANENTFLAGS:
- imap_parse_flags(is, &sinfo->u.permanentflags);
- break;
- case IMAP_UIDVALIDITY:
- sinfo->u.uidvalidity = camel_imapp_stream_number(is);
- break;
- case IMAP_UNSEEN:
- sinfo->u.unseen = camel_imapp_stream_number(is);
- break;
- default:
- sinfo->condition = IMAP_UNKNOWN;
- printf("Got unknown response code: %s: ignored\n", token);
- }
-
- /* ignore anything we dont know about */
- do {
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok == '\n')
- camel_exception_throw(1, "server response truncated");
- } while (tok != ']');
- } else {
- camel_imapp_stream_ungettoken(is, tok, token, len);
- }
-
- /* and take the human readable response */
- camel_imapp_stream_text(is, (unsigned char **)&sinfo->text);
- } CAMEL_CATCH(ex) {
- imap_free_status(sinfo);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- return sinfo;
-}
-
-void
-imap_free_status(struct _status_info *sinfo)
-{
- if (sinfo == NULL)
- return;
-
- switch (sinfo->condition) {
- case IMAP_NEWNAME:
- g_free(sinfo->u.newname.oldname);
- g_free(sinfo->u.newname.newname);
- default:
- break;
- }
-
- g_free(sinfo->text);
- g_free(sinfo);
-}
-
-/* FIXME: use tokeniser? */
-/* FIXME: real flags */
-static struct {
- char *name;
- guint32 flag;
-} list_flag_table[] = {
- { "\\NOINFERIORS", CAMEL_FOLDER_NOINFERIORS },
- { "\\NOSELECT", CAMEL_FOLDER_NOSELECT },
- { "\\MARKED", 1<<8 },
- { "\\UNMARKED", 1<<9 },
-};
-
-struct _list_info *
-imap_parse_list(CamelIMAPPStream *is)
-/* throws io, parse */
-{
- int tok, len, i;
- unsigned char *token, *p, c;
- struct _list_info * volatile linfo;
-
- linfo = g_malloc0(sizeof(*linfo));
-
- CAMEL_TRY {
- /* mailbox_list ::= "(" #("\Marked" / "\Noinferiors" /
- "\Noselect" / "\Unmarked" / flag_extension) ")"
- SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox */
-
- tok = camel_imapp_stream_token(is, &token, &len);
- if (tok != '(')
- camel_exception_throw(1, "list: expecting '('");
-
- while ( (tok = camel_imapp_stream_token(is, &token, &len)) != ')' ) {
- if (tok == IMAP_TOK_STRING || tok == IMAP_TOK_TOKEN) {
- p = token;
- while ((c=*p))
- *p++ = toupper(c);
- for (i=0;i<(int)(sizeof(list_flag_table)/sizeof(list_flag_table[0]));i++)
- if (!strcmp(token, list_flag_table[i].name))
- linfo->flags |= list_flag_table[i].flag;
- } else {
- camel_exception_throw(1, "list: expecting flag or ')'");
- }
- }
-
- camel_imapp_stream_nstring(is, &token);
- linfo->separator = token?*token:0;
- camel_imapp_stream_astring(is, &token);
- linfo->name = g_strdup(token);
- } CAMEL_CATCH(ex) {
- imap_free_list(linfo);
- camel_exception_throw_ex(ex);
- } CAMEL_DONE;
-
- return linfo;
-}
-
-char *
-imapp_list_get_path(struct _list_info *li)
-{
- char *path, *p;
- int c;
- const char *f;
-
- if (li->separator != 0 && li->separator != '/') {
- p = path = alloca(strlen(li->name)*3+1);
- f = li->name;
- while ( (c = *f++ & 0xff) ) {
- if (c == li->separator)
- *p++ = '/';
- else if (c == '/' || c == '%')
- p += sprintf(p, "%%%02X", c);
- else
- *p++ = c;
- }
- *p = 0;
- } else
- path = li->name;
-
- return camel_utf7_utf8(path);
-}
-
-void
-imap_free_list(struct _list_info *linfo)
-{
- if (linfo) {
- g_free(linfo->name);
- g_free(linfo);
- }
-}
-
-
-/* ********************************************************************** */
-/* utility functions */
-
-/* should the rest of imapp-utils go into imapp-parse? */
-
-/* this creates a uid (or sequence number) set directly into the command,
- optionally breaking it into smaller chunks */
-
-void
-imapp_uidset_init(struct _uidset_state *ss, CamelIMAPPEngine *ie)
-{
- ss->ie = ie;
- ss->len = 0;
- ss->start = 0;
- ss->last = 0;
-}
-
-int
-imapp_uidset_done(struct _uidset_state *ss, CamelIMAPPCommand *ic)
-{
- int ret = 0;
-
- if (ss->last != 0 && ss->last != ss->start) {
- camel_imapp_engine_command_add(ss->ie, ic, ":%d", ss->last);
- printf(":%d", ss->last);
- }
-
- ret = ss->last != 0;
-
- ss->start = 0;
- ss->last = 0;
- ss->len = 0;
-
- return ret;
-}
-
-int
-imapp_uidset_add(struct _uidset_state *ss, CamelIMAPPCommand *ic, const char *uid)
-{
- guint32 uidn;
-
- uidn = strtoul(uid, NULL, 10);
- if (uidn == 0)
- return -1;
-
- if (ss->last == 0) {
- camel_imapp_engine_command_add(ss->ie, ic, "%d", uidn);
- printf("%d", uidn);
- ss->len ++;
- ss->start = uidn;
- } else {
- if (ss->last != uidn-1) {
- if (ss->last == ss->start) {
- camel_imapp_engine_command_add(ss->ie, ic, ",%d", uidn);
- printf(",%d", uidn);
- ss->len ++;
- } else {
- camel_imapp_engine_command_add(ss->ie, ic, ":%d,%d", ss->last, uidn);
- printf(":%d,%d", ss->last, uidn);
- ss->len+=2;
- }
- ss->start = uidn;
- }
- }
-
- ss->last = uidn;
-
- if (ss->len > 10) {
- imapp_uidset_done(ss, ic);
- return 1;
- }
-
- return 0;
-}
diff --git a/camel/providers/imapp/camel-imapp-utils.h b/camel/providers/imapp/camel-imapp-utils.h
deleted file mode 100644
index e0974bdc96..0000000000
--- a/camel/providers/imapp/camel-imapp-utils.h
+++ /dev/null
@@ -1,145 +0,0 @@
-
-#ifndef _CAMEL_IMAPP_UTILS_H
-#define _CAMEL_IMAPP_UTILS_H
-
-#include <camel/camel-mime-utils.h>
-
-/* FIXME: the enum should be split up into logical groups, so that testing
- can be done more accurately? */
-
-/* list of strings we know about that can be *quickly* tokenised */
-enum _imap_id {
- IMAP_UNKNOWN = 0,
- IMAP_ALERT,
- IMAP_BYE,
- IMAP_BAD,
- IMAP_NO,
- IMAP_OK,
- IMAP_PREAUTH,
- IMAP_NEWNAME,
- IMAP_PARSE,
- IMAP_PERMANENTFLAGS,
- IMAP_READ_ONLY,
- IMAP_READ_WRITE,
- IMAP_TRYCREATE,
- IMAP_UIDVALIDITY,
- IMAP_UNSEEN,
- IMAP_ENVELOPE,
- IMAP_FLAGS,
- IMAP_INTERNALDATE,
- IMAP_RFC822_HEADER,
- IMAP_RFC822_TEXT,
- IMAP_RFC822_SIZE,
- IMAP_BODYSTRUCTURE,
- IMAP_BODY,
- IMAP_UID,
-};
-
-/* str MUST be in upper case, tokenised using gperf function */
-enum _imap_id imap_tokenise(register const char *str, register unsigned int len);
-
-/* this flag should be part of imapfoldersummary */
-enum {
- CAMEL_IMAPP_MESSAGE_RECENT = (1<<8),
-};
-
-/* ********************************************************************** */
-void imap_parse_flags(CamelIMAPPStream *stream, guint32 *flagsp) /* IO,PARSE */;
-void imap_write_flags(CamelStream *stream, guint32 flags) /* IO */;
-
-/* ********************************************************************** */
-void imap_parse_param_list(CamelIMAPPStream *is, struct _camel_header_param **plist) /* IO,PARSE */;
-struct _CamelContentDisposition *imap_parse_ext_optional(CamelIMAPPStream *is) /* IO,PARSE */;
-struct _CamelMessageContentInfo *imap_parse_body_fields(CamelIMAPPStream *is) /* IO,PARSE */;
-struct _camel_header_address *imap_parse_address_list(CamelIMAPPStream *is) /* IO,PARSE */;
-struct _CamelMessageInfo *imap_parse_envelope(CamelIMAPPStream *is) /* IO, PARSE */;
-struct _CamelMessageContentInfo *imap_parse_body(CamelIMAPPStream *is) /* IO,PARSE */;
-char *imap_parse_section(CamelIMAPPStream *is) /* IO,PARSE */;
-void imap_free_body(struct _CamelMessageContentInfo *cinfo);
-
-/* ********************************************************************** */
-/* all the possible stuff we might get from a fetch request */
-/* this assumes the caller/server doesn't send any one of these types twice */
-struct _fetch_info {
- guint32 got; /* what we got, see below */
- CamelStream *body; /* BODY[.*](<.*>)? */
- CamelStream *text; /* RFC822.TEXT */
- CamelStream *header; /* RFC822.HEADER */
- CamelMessageInfo *minfo; /* ENVELOPE */
- CamelMessageContentInfo *cinfo; /* BODYSTRUCTURE,BODY */
- guint32 size; /* RFC822.SIZE */
- guint32 offset; /* start offset of a BODY[]<offset.length> request */
- guint32 flags; /* FLAGS */
- char *date; /* INTERNALDATE */
- char *section; /* section for a BODY[section] request */
- char *uid; /* UID */
-};
-
-#define FETCH_BODY (1<<0)
-#define FETCH_TEXT (1<<1)
-#define FETCH_HEADER (1<<2)
-#define FETCH_MINFO (1<<3)
-#define FETCH_CINFO (1<<4)
-#define FETCH_SIZE (1<<5)
-#define FETCH_OFFSET (1<<6)
-#define FETCH_FLAGS (1<<7)
-#define FETCH_DATE (1<<8)
-#define FETCH_SECTION (1<<9)
-#define FETCH_UID (1<<10)
-
-struct _fetch_info *imap_parse_fetch(CamelIMAPPStream *is);
-void imap_free_fetch(struct _fetch_info *finfo);
-void imap_dump_fetch(struct _fetch_info *finfo);
-
-/* ********************************************************************** */
-
-struct _status_info {
- enum _imap_id result; /* ok/no/bad/preauth only */
- enum _imap_id condition; /* read-only/read-write/alert/parse/trycreate/newname/permanentflags/uidvalidity/unseen */
-
- union {
- struct {
- char *oldname;
- char *newname;
- } newname;
- guint32 permanentflags;
- guint32 uidvalidity;
- guint32 unseen;
- } u;
-
- char *text;
-};
-
-struct _status_info *imap_parse_status(CamelIMAPPStream *is);
-void imap_free_status(struct _status_info *sinfo);
-
-/* ********************************************************************** */
-
-/* should this just return a FolderInfo?
- should this just return the name & flags & separator by reference? */
-struct _list_info {
- guint32 flags:24;
- char separator;
- char *name;
-};
-
-struct _list_info *imap_parse_list(CamelIMAPPStream *is);
-char *imapp_list_get_path(struct _list_info *li);
-void imap_free_list(struct _list_info *linfo);
-
-/* ********************************************************************** */
-
-struct _uidset_state {
- struct _CamelIMAPPEngine *ie;
- int len;
- guint32 start;
- guint32 last;
-};
-
-struct _CamelIMAPPEngine;
-struct _CamelIMAPPCommand;
-void imapp_uidset_init(struct _uidset_state *ss, struct _CamelIMAPPEngine *ie);
-int imapp_uidset_done(struct _uidset_state *ss, struct _CamelIMAPPCommand *ic);
-int imapp_uidset_add(struct _uidset_state *ss, struct _CamelIMAPPCommand *ic, const char *uid);
-
-#endif
diff --git a/camel/providers/imapp/libcamelimapp.urls b/camel/providers/imapp/libcamelimapp.urls
deleted file mode 100644
index aad1347834..0000000000
--- a/camel/providers/imapp/libcamelimapp.urls
+++ /dev/null
@@ -1 +0,0 @@
-imapp
diff --git a/camel/providers/local/.cvsignore b/camel/providers/local/.cvsignore
deleted file mode 100644
index 3fa8afaa38..0000000000
--- a/camel/providers/local/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.deps
-Makefile
-Makefile.in
-.libs
-.deps
-*.lo
-*.la
-*.bb
-*.bbg
-*.da
-*.gcov
diff --git a/camel/providers/local/Makefile.am b/camel/providers/local/Makefile.am
deleted file mode 100644
index ad07472e85..0000000000
--- a/camel/providers/local/Makefile.am
+++ /dev/null
@@ -1,61 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamellocalincludedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamellocal.la
-camel_provider_DATA = libcamellocal.urls
-
-INCLUDES = -I.. \
- -I$(srcdir)/.. \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/e-util \
- -I$(top_srcdir) \
- $(CAMEL_CFLAGS) \
- $(GNOME_INCLUDEDIR) \
- $(GTK_INCLUDEDIR) \
- -DG_LOG_DOMAIN=\"camel-local-provider\"
-
-libcamellocal_la_SOURCES = \
- camel-local-folder.c \
- camel-local-store.c \
- camel-local-summary.c \
- camel-local-provider.c \
- camel-mh-folder.c \
- camel-mh-store.c \
- camel-mh-summary.c \
- camel-mbox-folder.c \
- camel-mbox-store.c \
- camel-mbox-summary.c \
- camel-maildir-folder.c \
- camel-maildir-store.c \
- camel-maildir-summary.c \
- camel-spool-folder.c \
- camel-spool-store.c \
- camel-spool-summary.c
-
-libcamellocalinclude_HEADERS = \
- camel-local-folder.h \
- camel-local-store.h \
- camel-local-summary.h \
- camel-mh-folder.h \
- camel-mh-store.h \
- camel-mh-summary.h \
- camel-mbox-folder.h \
- camel-mbox-store.h \
- camel-mbox-summary.h \
- camel-maildir-folder.h \
- camel-maildir-store.h \
- camel-maildir-summary.h \
- camel-spool-folder.h \
- camel-spool-store.h \
- camel-spool-summary.h
-
-noinst_HEADERS = \
- camel-local-private.h
-
-libcamellocal_la_LDFLAGS = -avoid-version -module
-
-libcamellocal_la_LIBADD = $(top_builddir)/e-util/libeutil.la
-
-EXTRA_DIST = libcamellocal.urls
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
deleted file mode 100644
index 5bf2142f35..0000000000
--- a/camel/providers/local/camel-local-folder.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 1999-2003 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-
-#ifndef _POSIX_PATH_MAX
-#include <posix1_lim.h>
-#endif
-
-#include "camel-local-folder.h"
-#include "camel-local-store.h"
-#include "camel-stream-fs.h"
-#include "camel-local-summary.h"
-#include "camel-data-wrapper.h"
-#include "camel-mime-message.h"
-#include "camel-stream-filter.h"
-#include "camel-mime-filter-from.h"
-#include "camel-exception.h"
-
-#include "camel-local-private.h"
-
-#include "camel-text-index.h"
-
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-#ifndef PATH_MAX
-#define PATH_MAX _POSIX_PATH_MAX
-#endif
-
-static CamelFolderClass *parent_class;
-static GSList *local_folder_properties;
-
-/* Returns the class for a CamelLocalFolder */
-#define CLOCALF_CLASS(so) CAMEL_LOCAL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CLOCALS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static int local_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args);
-static int local_setv(CamelObject *object, CamelException *ex, CamelArgV *args);
-
-static int local_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex);
-static void local_unlock(CamelLocalFolder *lf);
-
-static char *local_get_full_path (const char *toplevel_dir, const char *full_name);
-static char *local_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext);
-
-static void local_refresh_info(CamelFolder *folder, CamelException *ex);
-
-static void local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex);
-static void local_expunge(CamelFolder *folder, CamelException *ex);
-
-static GPtrArray *local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex);
-static GPtrArray *local_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex);
-static void local_search_free(CamelFolder *folder, GPtrArray * result);
-
-static void local_delete(CamelFolder *folder);
-static void local_rename(CamelFolder *folder, const char *newname);
-
-static void local_finalize(CamelObject * object);
-
-static void
-camel_local_folder_class_init(CamelLocalFolderClass * camel_local_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_local_folder_class);
- CamelObjectClass *oklass = (CamelObjectClass *)camel_local_folder_class;
-
- /* virtual method definition */
-
- /* virtual method overload */
- oklass->getv = local_getv;
- oklass->setv = local_setv;
-
- camel_folder_class->refresh_info = local_refresh_info;
- camel_folder_class->sync = local_sync;
- camel_folder_class->expunge = local_expunge;
-
- camel_folder_class->search_by_expression = local_search_by_expression;
- camel_folder_class->search_by_uids = local_search_by_uids;
- camel_folder_class->search_free = local_search_free;
-
- camel_folder_class->delete = local_delete;
- camel_folder_class->rename = local_rename;
-
- camel_local_folder_class->get_full_path = local_get_full_path;
- camel_local_folder_class->get_meta_path = local_get_meta_path;
-
- camel_local_folder_class->lock = local_lock;
- camel_local_folder_class->unlock = local_unlock;
-}
-
-static void
-local_init(gpointer object, gpointer klass)
-{
- CamelFolder *folder = object;
- CamelLocalFolder *local_folder = object;
-
- folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY |
- CAMEL_FOLDER_HAS_SEARCH_CAPABILITY);
-
- folder->permanent_flags = CAMEL_MESSAGE_ANSWERED |
- CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT |
- CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN |
- CAMEL_MESSAGE_ANSWERED_ALL | CAMEL_MESSAGE_USER;
-
- folder->summary = NULL;
- local_folder->search = NULL;
-
- local_folder->priv = g_malloc0(sizeof(*local_folder->priv));
- local_folder->priv->search_lock = g_mutex_new();
-}
-
-static void
-local_finalize(CamelObject * object)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(object);
- CamelFolder *folder = (CamelFolder *)object;
-
- if (folder->summary) {
- camel_local_summary_sync((CamelLocalSummary *)folder->summary, FALSE, local_folder->changes, NULL);
- camel_object_unref((CamelObject *)folder->summary);
- folder->summary = NULL;
- }
-
- if (local_folder->search) {
- camel_object_unref((CamelObject *)local_folder->search);
- }
-
- if (local_folder->index)
- camel_object_unref((CamelObject *)local_folder->index);
-
- while (local_folder->locked> 0)
- camel_local_folder_unlock(local_folder);
-
- g_free(local_folder->base_path);
- g_free(local_folder->folder_path);
- g_free(local_folder->summary_path);
- g_free(local_folder->index_path);
-
- camel_folder_change_info_free(local_folder->changes);
-
- g_mutex_free(local_folder->priv->search_lock);
-
- g_free(local_folder->priv);
-}
-
-static CamelProperty local_property_list[] = {
- { CAMEL_LOCAL_FOLDER_INDEX_BODY, "index_body", N_("Index message body data") },
-};
-
-CamelType
-camel_local_folder_get_type(void)
-{
- static CamelType camel_local_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_local_folder_type == CAMEL_INVALID_TYPE) {
- int i;
-
- parent_class = (CamelFolderClass *)camel_folder_get_type();
- camel_local_folder_type = camel_type_register(camel_folder_get_type(), "CamelLocalFolder",
- sizeof(CamelLocalFolder),
- sizeof(CamelLocalFolderClass),
- (CamelObjectClassInitFunc) camel_local_folder_class_init,
- NULL,
- (CamelObjectInitFunc) local_init,
- (CamelObjectFinalizeFunc) local_finalize);
-
- for (i=0;i<sizeof(local_property_list)/sizeof(local_property_list[0]);i++) {
- local_property_list[i].description = _(local_property_list[i].description);
- local_folder_properties = g_slist_prepend(local_folder_properties, &local_property_list[i]);
- }
- }
-
- return camel_local_folder_type;
-}
-
-CamelLocalFolder *
-camel_local_folder_construct(CamelLocalFolder *lf, CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex)
-{
- CamelFolderInfo *fi;
- CamelFolder *folder;
- const char *root_dir_path, *name;
- char *tmp, *statepath;
- char folder_path[PATH_MAX];
- struct stat st;
- int forceindex, len;
-
- folder = (CamelFolder *)lf;
-
- name = strrchr(full_name, '/');
- if (name)
- name++;
- else
- name = full_name;
-
- camel_folder_construct(folder, parent_store, full_name, name);
-
- root_dir_path = camel_local_store_get_toplevel_dir(CAMEL_LOCAL_STORE(folder->parent_store));
- /* strip the trailing '/' which is always present */
- len = strlen (root_dir_path);
- tmp = g_alloca (len + 1);
- strcpy (tmp, root_dir_path);
- if (len>1 && tmp[len-1] == '/')
- tmp[len-1] = 0;
-
- lf->base_path = g_strdup(root_dir_path);
-
- /* if the base store points to a file, then use that */
- if (stat(tmp, &st) != -1 && S_ISREG(st.st_mode)) {
- lf->folder_path = g_strdup(tmp);
- /* not really sure to do with these for now? */
- lf->summary_path = g_strdup_printf("%s.ev-summary", tmp);
- lf->index_path = g_strdup_printf("%s.ibex", tmp);
- statepath = g_strdup_printf ("%s.cmeta", tmp);
- } else {
- lf->folder_path = CLOCALF_CLASS (lf)->get_full_path (root_dir_path, full_name);
- lf->summary_path = CLOCALF_CLASS (lf)->get_meta_path (root_dir_path, full_name, ".ev-summary");
- lf->index_path = CLOCALF_CLASS (lf)->get_meta_path (root_dir_path, full_name, ".ibex");
- statepath = CLOCALF_CLASS (lf)->get_meta_path (root_dir_path, full_name, ".cmeta");
- }
- camel_object_set(lf, NULL, CAMEL_OBJECT_STATE_FILE, statepath, NULL);
- g_free (statepath);
-
- lf->flags = flags;
-
- if (camel_object_state_read(lf) == -1) {
- /* FIXME: load defaults? */
- }
-
- /* follow any symlinks to the mailbox */
- if (lstat (lf->folder_path, &st) != -1 && S_ISLNK (st.st_mode) &&
- realpath (lf->folder_path, folder_path) != NULL) {
- g_free (lf->folder_path);
- lf->folder_path = g_strdup (folder_path);
- }
-
- lf->changes = camel_folder_change_info_new();
-
- /* TODO: Remove the following line, it is a temporary workaround to remove
- the old-format 'ibex' files that might be lying around */
- unlink(lf->index_path);
-
- /* FIXME: Need to run indexing off of the setv method */
-#if 1
- forceindex = FALSE;
-#else
- /* if we have no/invalid index file, force it */
- forceindex = camel_text_index_check(lf->index_path) == -1;
- if (flags & CAMEL_STORE_FOLDER_BODY_INDEX) {
- int flag = O_RDWR|O_CREAT;
- if (forceindex)
- flag |= O_TRUNC;
- lf->index = (CamelIndex *)camel_text_index_new(lf->index_path, flag);
- if (lf->index == NULL) {
- /* yes, this isn't fatal at all */
- g_warning("Could not open/create index file: %s: indexing not performed", strerror (errno));
- forceindex = FALSE;
- /* record that we dont have an index afterall */
- flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX;
- }
- } else {
- /* if we do have an index file, remove it (?) */
- if (forceindex == FALSE)
- camel_text_index_remove(lf->index_path);
- forceindex = FALSE;
- }
- lf->flags = flags;
-#endif
-
- folder->summary = (CamelFolderSummary *)CLOCALF_CLASS(lf)->create_summary(lf->summary_path, lf->folder_path, lf->index);
- if (camel_local_summary_load((CamelLocalSummary *)folder->summary, forceindex, ex) == -1) {
- camel_exception_clear(ex);
- }
-
- /*if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) {*/
- /* we sync here so that any hard work setting up the folder isn't lost */
- if (camel_local_summary_sync((CamelLocalSummary *)folder->summary, FALSE, lf->changes, ex) == -1) {
- camel_object_unref (CAMEL_OBJECT (folder));
- return NULL;
- }
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = g_strdup (full_name);
- fi->name = g_strdup (name);
- fi->url = g_strdup_printf("%s:%s#%s", ((CamelService *)parent_store)->url->protocol, ((CamelService *)parent_store)->url->path, full_name);
- fi->unread_message_count = camel_folder_get_unread_message_count(folder);
- camel_folder_info_build_path(fi, '/');
-
- camel_object_trigger_event(CAMEL_OBJECT (parent_store), "folder_created", fi);
- camel_folder_info_free(fi);
-
- return lf;
-}
-
-/* lock the folder, may be called repeatedly (with matching unlock calls),
- with type the same or less than the first call */
-int camel_local_folder_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex)
-{
- if (lf->locked > 0) {
- /* lets be anal here - its important the code knows what its doing */
- g_assert(lf->locktype == type || lf->locktype == CAMEL_LOCK_WRITE);
- } else {
- if (CLOCALF_CLASS(lf)->lock(lf, type, ex) == -1)
- return -1;
- lf->locktype = type;
- }
-
- lf->locked++;
-
- return 0;
-}
-
-/* unlock folder */
-int camel_local_folder_unlock(CamelLocalFolder *lf)
-{
- g_assert(lf->locked>0);
- lf->locked--;
- if (lf->locked == 0)
- CLOCALF_CLASS(lf)->unlock(lf);
-
- return 0;
-}
-
-static int
-local_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
-{
- CamelFolder *folder = (CamelFolder *)object;
- int i;
- guint32 tag;
-
- for (i=0;i<args->argc;i++) {
- CamelArgGet *arg = &args->argv[i];
-
- tag = arg->tag;
-
- switch (tag & CAMEL_ARG_TAG) {
- case CAMEL_OBJECT_ARG_DESCRIPTION:
- if (folder->description == NULL) {
- char *tmp, *path;
-
- /* check some common prefixes to shorten the name */
- tmp = ((CamelService *)folder->parent_store)->url->path;
- if (tmp == NULL)
- goto skip;
-
- path = g_alloca (strlen (tmp) + strlen (folder->full_name) + 1);
- sprintf (path, "%s/%s", tmp, folder->full_name);
-
- if ((tmp = getenv("HOME")) && strncmp(tmp, path, strlen(tmp)) == 0)
- /* $HOME relative path + protocol string */
- folder->description = g_strdup_printf(_("~%s (%s)"), path+strlen(tmp),
- ((CamelService *)folder->parent_store)->url->protocol);
- else if ((tmp = "/var/spool/mail") && strncmp(tmp, path, strlen(tmp)) == 0)
- /* /var/spool/mail relative path + protocol */
- folder->description = g_strdup_printf(_("mailbox:%s (%s)"), path+strlen(tmp),
- ((CamelService *)folder->parent_store)->url->protocol);
- else if ((tmp = "/var/mail") && strncmp(tmp, path, strlen(tmp)) == 0)
- folder->description = g_strdup_printf(_("mailbox:%s (%s)"), path+strlen(tmp),
- ((CamelService *)folder->parent_store)->url->protocol);
- else
- /* a full path + protocol */
- folder->description = g_strdup_printf(_("%s (%s)"), path,
- ((CamelService *)folder->parent_store)->url->protocol);
- }
- *arg->ca_str = folder->description;
- break;
-
- case CAMEL_OBJECT_ARG_PERSISTENT_PROPERTIES:
- case CAMEL_FOLDER_ARG_PROPERTIES: {
- CamelArgGetV props;
-
- props.argc = 1;
- props.argv[0] = *arg;
- ((CamelObjectClass *)parent_class)->getv(object, ex, &props);
- *arg->ca_ptr = g_slist_concat(*arg->ca_ptr, g_slist_copy(local_folder_properties));
-
- break; }
-
- case CAMEL_LOCAL_FOLDER_ARG_INDEX_BODY:
- printf("getv:'%s' flags %08x\n", ((CamelFolder *)object)->full_name, ((CamelLocalFolder *)object)->flags);
-
- /* FIXME: remove this from sotre flags */
- *arg->ca_int = (((CamelLocalFolder *)folder)->flags & CAMEL_STORE_FOLDER_BODY_INDEX) != 0;
- break;
-
- default: skip:
- continue;
- }
-
- arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
- }
-
- return ((CamelObjectClass *)parent_class)->getv(object, ex, args);
-}
-
-static int
-local_setv(CamelObject *object, CamelException *ex, CamelArgV *args)
-{
- int i;
- guint32 tag;
-
- for (i=0;i<args->argc;i++) {
- CamelArg *arg = &args->argv[i];
-
- tag = arg->tag;
-
- switch (tag & CAMEL_ARG_TAG) {
- case CAMEL_LOCAL_FOLDER_ARG_INDEX_BODY:
- /* FIXME: implement */
- /* TODO: When turning on (off?) the index, we want to launch a task for it,
- and make sure we dont have multiple tasks doing the same job */
- if (arg->ca_int)
- ((CamelLocalFolder *)object)->flags |= CAMEL_STORE_FOLDER_BODY_INDEX;
- else
- ((CamelLocalFolder *)object)->flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX;
- break;
- default:
- continue;
- }
-
- arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
- }
-
- return ((CamelObjectClass *)parent_class)->setv(object, ex, args);
-}
-
-static char *
-local_get_full_path (const char *toplevel_dir, const char *full_name)
-{
- return g_strdup_printf ("%s/%s", toplevel_dir, full_name);
-}
-
-static char *
-local_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext)
-{
- return g_strdup_printf ("%s/%s%s", toplevel_dir, full_name, ext);
-}
-
-static int
-local_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex)
-{
- return 0;
-}
-
-static void
-local_unlock(CamelLocalFolder *lf)
-{
- /* nothing */
-}
-
-/* for auto-check to work */
-static void
-local_refresh_info(CamelFolder *folder, CamelException *ex)
-{
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-
- if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1)
- return;
-
- if (camel_folder_change_info_changed(lf->changes)) {
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes);
- camel_folder_change_info_clear(lf->changes);
- }
-}
-
-static void
-local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
- CamelLocalFolder *lf = CAMEL_LOCAL_FOLDER(folder);
-
- d(printf("local sync, expunge=%s\n", expunge?"true":"false"));
-
- if (camel_local_folder_lock(lf, CAMEL_LOCK_WRITE, ex) == -1)
- return;
-
- camel_object_state_write(lf);
-
- /* if sync fails, we'll pass it up on exit through ex */
- camel_local_summary_sync((CamelLocalSummary *)folder->summary, expunge, lf->changes, ex);
- camel_local_folder_unlock(lf);
-
- if (camel_folder_change_info_changed(lf->changes)) {
- camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", lf->changes);
- camel_folder_change_info_clear(lf->changes);
- }
-}
-
-static void
-local_expunge(CamelFolder *folder, CamelException *ex)
-{
- d(printf("expunge\n"));
-
- /* Just do a sync with expunge, serves the same purpose */
- /* call the callback directly, to avoid locking problems */
- CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->sync(folder, TRUE, ex);
-}
-
-static void
-local_delete(CamelFolder *folder)
-{
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-
- if (lf->index)
- camel_index_delete(lf->index);
-
- parent_class->delete(folder);
-}
-
-static void
-local_rename(CamelFolder *folder, const char *newname)
-{
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-
- d(printf("renaming local folder paths to '%s'\n", newname));
-
- /* Sync? */
-
- g_free(lf->folder_path);
- g_free(lf->summary_path);
- g_free(lf->index_path);
- lf->folder_path = g_strdup_printf("%s/%s", lf->base_path, newname);
- lf->summary_path = g_strdup_printf("%s/%s.ev-summary", lf->base_path, newname);
- lf->index_path = g_strdup_printf("%s/%s.ibex", lf->base_path, newname);
-
- /* FIXME: Poke some internals, sigh */
- camel_folder_summary_set_filename(folder->summary, lf->summary_path);
- g_free(((CamelLocalSummary *)folder->summary)->folder_path);
- ((CamelLocalSummary *)folder->summary)->folder_path = g_strdup(lf->folder_path);
-
- parent_class->rename(folder, newname);
-}
-
-static GPtrArray *
-local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
- GPtrArray *summary, *matches;
-
- /* NOTE: could get away without the search lock by creating a new
- search object each time */
-
- CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock);
-
- if (local_folder->search == NULL)
- local_folder->search = camel_folder_search_new();
-
- camel_folder_search_set_folder(local_folder->search, folder);
- camel_folder_search_set_body_index(local_folder->search, local_folder->index);
- summary = camel_folder_get_summary(folder);
- camel_folder_search_set_summary(local_folder->search, summary);
-
- matches = camel_folder_search_execute_expression(local_folder->search, expression, ex);
-
- CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock);
-
- camel_folder_free_summary(folder, summary);
-
- return matches;
-}
-
-static GPtrArray *
-local_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
- GPtrArray *summary, *matches;
- int i;
-
- /* NOTE: could get away without the search lock by creating a new
- search object each time */
-
- summary = g_ptr_array_new();
- for (i=0;i<uids->len;i++) {
- CamelMessageInfo *info;
-
- info = camel_folder_get_message_info(folder, uids->pdata[i]);
- if (info)
- g_ptr_array_add(summary, info);
- }
-
- if (summary->len == 0)
- return summary;
-
- CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock);
-
- if (local_folder->search == NULL)
- local_folder->search = camel_folder_search_new();
-
- camel_folder_search_set_folder(local_folder->search, folder);
- camel_folder_search_set_body_index(local_folder->search, local_folder->index);
- camel_folder_search_set_summary(local_folder->search, summary);
-
- matches = camel_folder_search_execute_expression(local_folder->search, expression, ex);
-
- CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock);
-
- for (i=0;i<summary->len;i++)
- camel_folder_free_message_info(folder, summary->pdata[i]);
- g_ptr_array_free(summary, TRUE);
-
- return matches;
-}
-
-static void
-local_search_free(CamelFolder *folder, GPtrArray * result)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
-
- /* we need to lock this free because of the way search_free_result works */
- /* FIXME: put the lock inside search_free_result */
- CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock);
-
- camel_folder_search_free_result(local_folder->search, result);
-
- CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock);
-}
diff --git a/camel/providers/local/camel-local-folder.h b/camel/providers/local/camel-local-folder.h
deleted file mode 100644
index 73059f03b3..0000000000
--- a/camel/providers/local/camel-local-folder.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Author: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999 Ximian (www.ximian.com/).
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_LOCAL_FOLDER_H
-#define CAMEL_LOCAL_FOLDER_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <camel/camel-folder.h>
-#include <camel/camel-folder-search.h>
-#include <camel/camel-index.h>
-#include "camel-local-summary.h"
-#include "camel-lock.h"
-
-/* #include "camel-store.h" */
-
-#define CAMEL_LOCAL_FOLDER_TYPE (camel_local_folder_get_type ())
-#define CAMEL_LOCAL_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_LOCAL_FOLDER_TYPE, CamelLocalFolder))
-#define CAMEL_LOCAL_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_LOCAL_FOLDER_TYPE, CamelLocalFolderClass))
-#define CAMEL_IS_LOCAL_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_LOCAL_FOLDER_TYPE))
-
-enum {
- CAMEL_LOCAL_FOLDER_ARG_INDEX_BODY = CAMEL_FOLDER_ARG_LAST,
-
- CAMEL_LOCAL_FOLDER_ARG_LAST = CAMEL_FOLDER_ARG_LAST + 0x100
-};
-
-enum {
- CAMEL_LOCAL_FOLDER_INDEX_BODY = CAMEL_LOCAL_FOLDER_ARG_INDEX_BODY | CAMEL_ARG_BOO,
-};
-
-typedef struct {
- CamelFolder parent_object;
- struct _CamelLocalFolderPrivate *priv;
-
- guint32 flags; /* open mode flags */
-
- int locked; /* lock counter */
- CamelLockType locktype; /* what type of lock we have */
-
- char *base_path; /* base path of the local folder */
- char *folder_path; /* the path to the folder itself */
- char *summary_path; /* where the summary lives */
- char *index_path; /* where the index file lives */
-
- CamelIndex *index; /* index for this folder */
- CamelFolderSearch *search; /* used to run searches, we just use the real thing (tm) */
- CamelFolderChangeInfo *changes; /* used to store changes to the folder during processing */
-} CamelLocalFolder;
-
-typedef struct {
- CamelFolderClass parent_class;
-
- /* Virtual methods */
-
- /* path construction, only used at init */
- char * (* get_full_path) (const char *toplevel_dir, const char *full_name);
- char * (* get_meta_path) (const char *toplevel_dir, const char *full_name, const char *ext);
-
- /* summary factory, only used at init */
- CamelLocalSummary *(*create_summary)(const char *path, const char *folder, CamelIndex *index);
-
- /* Lock the folder for my operations */
- int (*lock)(CamelLocalFolder *, CamelLockType type, CamelException *ex);
-
- /* Unlock the folder for my operations */
- void (*unlock)(CamelLocalFolder *);
-} CamelLocalFolderClass;
-
-
-/* public methods */
-/* flags are taken from CAMEL_STORE_FOLDER_* flags */
-CamelLocalFolder *camel_local_folder_construct(CamelLocalFolder *lf, CamelStore *parent_store,
- const char *full_name, guint32 flags, CamelException *ex);
-
-/* Standard Camel function */
-CamelType camel_local_folder_get_type(void);
-
-/* Lock the folder for internal use. May be called repeatedly */
-/* UNIMPLEMENTED */
-int camel_local_folder_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex);
-int camel_local_folder_unlock(CamelLocalFolder *lf);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_LOCAL_FOLDER_H */
diff --git a/camel/providers/local/camel-local-private.h b/camel/providers/local/camel-local-private.h
deleted file mode 100644
index e8e5061fae..0000000000
--- a/camel/providers/local/camel-local-private.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 1999-2003 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#ifndef CAMEL_LOCAL_PRIVATE_H
-#define CAMEL_LOCAL_PRIVATE_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* need a way to configure and save this data, if this header is to
- be installed. For now, dont install it */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pthread.h>
-
-struct _CamelLocalFolderPrivate {
- GMutex *search_lock; /* for locking the search object */
-};
-
-#define CAMEL_LOCAL_FOLDER_LOCK(f, l) (g_mutex_lock(((CamelLocalFolder *)f)->priv->l))
-#define CAMEL_LOCAL_FOLDER_UNLOCK(f, l) (g_mutex_unlock(((CamelLocalFolder *)f)->priv->l))
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_LOCAL_PRIVATE_H */
-
diff --git a/camel/providers/local/camel-local-provider.c b/camel/providers/local/camel-local-provider.c
deleted file mode 100644
index a52dfbde5f..0000000000
--- a/camel/providers/local/camel-local-provider.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2000 Ximian (www.ximian.com).
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-
-#include "camel-provider.h"
-#include "camel-session.h"
-#include "camel-url.h"
-
-#include "camel-mh-store.h"
-#include "camel-mbox-store.h"
-#include "camel-maildir-store.h"
-#include "camel-spool-store.h"
-
-#define d(x)
-
-static CamelProviderConfEntry mh_conf_entries[] = {
- CAMEL_PROVIDER_CONF_DEFAULT_PATH,
- { CAMEL_PROVIDER_CONF_CHECKBOX, "dotfolders", NULL,
- N_("Use the `.folders' folder summary file (exmh)"), "0" },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider mh_provider = {
- "mh",
- N_("MH-format mail directories"),
- N_("For storing local mail in MH-like mail directories."),
- "mail",
- CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL,
- CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
- mh_conf_entries,
- /* ... */
-};
-
-static CamelProviderConfEntry mbox_conf_entries[] = {
- CAMEL_PROVIDER_CONF_DEFAULT_PATH,
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider mbox_provider = {
- "mbox",
- N_("Local delivery"),
- N_("For retrieving (moving) local mail from standard mbox formated spools into folders managed by Evolution."),
- "mail",
- CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL,
- CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
- mbox_conf_entries,
- /* ... */
-};
-
-static CamelProviderConfEntry maildir_conf_entries[] = {
- CAMEL_PROVIDER_CONF_DEFAULT_PATH,
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL,
- N_("Apply filters to new messages in INBOX"), "0" },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider maildir_provider = {
- "maildir",
- N_("Maildir-format mail directories"),
- N_("For storing local mail in maildir directories."),
- "mail",
- CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL,
- CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
- maildir_conf_entries,
- /* ... */
-};
-
-static CamelProviderConfEntry spool_conf_entries[] = {
- CAMEL_PROVIDER_CONF_DEFAULT_PATH,
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL, N_("Apply filters to new messages in INBOX"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "xstatus", NULL, N_("Store status headers in Elm/Pine/Mutt format"), "0" },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider spool_provider = {
- "spool",
- N_("Standard Unix mbox spool or directory"),
- N_("For reading and storing local mail in external standard mbox spool files.\nMay also be used to read a tree of Elm, Pine, or Mutt style folders."),
- "mail",
- CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE,
- CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
- spool_conf_entries,
- /* ... */
-};
-
-/* build a canonical 'path' */
-static char *
-make_can_path(char *p, char *o)
-{
- char c, last, *start = o;
-
- d(printf("canonical '%s' = ", p));
-
- last = 0;
- while ((c = *p++)) {
- if (c!='/'
- || (c=='/' && last != '/'))
- *o++ = c;
- last = c;
- }
- if (o>start && o[-1] == '/')
- o[-1] = 0;
- else
- *o = 0;
-
- d(printf("'%s'\n", start));
-
- return start;
-}
-
-/* 'helper' function for it */
-#define get_can_path(p) ((p == NULL) ? NULL : (make_can_path ((p), g_alloca (strlen (p) + 1))))
-
-static guint
-local_url_hash (const void *v)
-{
- const CamelURL *u = v;
- guint hash = 0;
-
-#define ADD_HASH(s) if (s) hash ^= g_str_hash (s);
-
- ADD_HASH (u->protocol);
- ADD_HASH (u->user);
- ADD_HASH (u->authmech);
- ADD_HASH (u->host);
- if (u->path)
- hash ^= g_str_hash(get_can_path(u->path));
- ADD_HASH (u->path);
- ADD_HASH (u->query);
- hash ^= u->port;
-
- return hash;
-}
-
-static int
-check_equal (char *s1, char *s2)
-{
- if (s1 == NULL) {
- if (s2 == NULL)
- return TRUE;
- else
- return FALSE;
- }
-
- if (s2 == NULL)
- return FALSE;
-
- return strcmp (s1, s2) == 0;
-}
-
-static int
-local_url_equal(const void *v, const void *v2)
-{
- const CamelURL *u1 = v, *u2 = v2;
- char *p1, *p2;
-
- p1 = get_can_path(u1->path);
- p2 = get_can_path(u2->path);
- return check_equal(p1, p2)
- && check_equal(u1->protocol, u2->protocol)
- && check_equal(u1->user, u2->user)
- && check_equal(u1->authmech, u2->authmech)
- && check_equal(u1->host, u2->host)
- && check_equal(u1->query, u2->query)
- && u1->port == u2->port;
-}
-
-void camel_provider_module_init(CamelSession * session)
-{
- char *path;
-
- mh_conf_entries[0].value = ""; /* default path */
- mh_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mh_store_get_type ();
- mh_provider.url_hash = local_url_hash;
- mh_provider.url_equal = local_url_equal;
- camel_session_register_provider(session, &mh_provider);
-
- if (!(path = getenv ("MAIL")))
- path = g_strdup_printf (SYSTEM_MAIL_DIR "/%s", g_get_user_name ());
- mbox_conf_entries[0].value = path; /* default path */
- mbox_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mbox_store_get_type ();
- mbox_provider.url_hash = local_url_hash;
- mbox_provider.url_equal = local_url_equal;
- camel_session_register_provider(session, &mbox_provider);
-
- spool_conf_entries[0].value = path; /* default path - same as mbox */
- spool_provider.object_types[CAMEL_PROVIDER_STORE] = camel_spool_store_get_type ();
- spool_provider.url_hash = local_url_hash;
- spool_provider.url_equal = local_url_equal;
- camel_session_register_provider(session, &spool_provider);
-
- path = getenv ("MAILDIR");
- maildir_conf_entries[0].value = path ? path : ""; /* default path */
- maildir_provider.object_types[CAMEL_PROVIDER_STORE] = camel_maildir_store_get_type ();
- maildir_provider.url_hash = local_url_hash;
- maildir_provider.url_equal = local_url_equal;
- camel_session_register_provider(session, &maildir_provider);
-}
diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c
deleted file mode 100644
index a0eaf9d68f..0000000000
--- a/camel/providers/local/camel-local-store.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include <glib.h>
-
-#include "camel-private.h"
-
-#include "camel-local-store.h"
-#include "camel-exception.h"
-#include "camel-url.h"
-
-#include "camel-local-folder.h"
-#include <camel/camel-text-index.h>
-
-#define d(x)
-
-/* Returns the class for a CamelLocalStore */
-#define CLOCALS_CLASS(so) CAMEL_LOCAL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static void construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex);
-static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex);
-static char *get_name(CamelService *service, gboolean brief);
-static CamelFolder *get_inbox (CamelStore *store, CamelException *ex);
-static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
-static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex);
-static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex);
-static CamelFolderInfo *create_folder(CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex);
-
-static CamelStoreClass *parent_class = NULL;
-
-static void
-camel_local_store_class_init (CamelLocalStoreClass *camel_local_store_class)
-{
- CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_local_store_class);
- CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_local_store_class);
-
- parent_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ()));
-
- /* virtual method overload */
- camel_service_class->construct = construct;
- camel_service_class->get_name = get_name;
- camel_store_class->get_folder = get_folder;
- camel_store_class->get_inbox = get_inbox;
- camel_store_class->get_folder_info = get_folder_info;
- camel_store_class->free_folder_info = camel_store_free_folder_info_full;
-
- camel_store_class->create_folder = create_folder;
- camel_store_class->delete_folder = delete_folder;
- camel_store_class->rename_folder = rename_folder;
-}
-
-static void
-camel_local_store_finalize (CamelLocalStore *local_store)
-{
- if (local_store->toplevel_dir)
- g_free (local_store->toplevel_dir);
-}
-
-CamelType
-camel_local_store_get_type (void)
-{
- static CamelType camel_local_store_type = CAMEL_INVALID_TYPE;
-
- if (camel_local_store_type == CAMEL_INVALID_TYPE) {
- camel_local_store_type = camel_type_register (CAMEL_STORE_TYPE, "CamelLocalStore",
- sizeof (CamelLocalStore),
- sizeof (CamelLocalStoreClass),
- (CamelObjectClassInitFunc) camel_local_store_class_init,
- NULL,
- NULL,
- (CamelObjectFinalizeFunc) camel_local_store_finalize);
- }
-
- return camel_local_store_type;
-}
-
-static void
-construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
-{
- CamelLocalStore *local_store = CAMEL_LOCAL_STORE (service);
- int len;
-
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
- if (camel_exception_is_set (ex))
- return;
-
- len = strlen (service->url->path);
- if (service->url->path[len - 1] != '/')
- local_store->toplevel_dir = g_strdup_printf ("%s/", service->url->path);
- else
- local_store->toplevel_dir = g_strdup (service->url->path);
-}
-
-const char *
-camel_local_store_get_toplevel_dir (CamelLocalStore *store)
-{
- return store->toplevel_dir;
-}
-
-static CamelFolder *
-get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex)
-{
- struct stat st;
- char *path = ((CamelLocalStore *)store)->toplevel_dir;
- char *sub, *slash;
-
- if (path[0] != '/') {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Store root %s is not an absolute path"), path);
- return NULL;
- }
-
- if (stat(path, &st) == 0) {
- if (!S_ISDIR(st.st_mode)) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Store root %s is not a regular directory"), path);
- return NULL;
- }
- return (CamelFolder *) 0xdeadbeef;
- }
-
- if (errno != ENOENT
- || (flags & CAMEL_STORE_FOLDER_CREATE) == 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Cannot get folder: %s: %s"),
- path, g_strerror (errno));
- return NULL;
- }
-
- /* need to create the dir heirarchy */
- sub = g_alloca (strlen (path) + 1);
- strcpy (sub, path);
- slash = sub;
- do {
- slash = strchr (slash + 1, '/');
- if (slash)
- *slash = 0;
- if (stat (sub, &st) == -1) {
- if (errno != ENOENT || mkdir (sub, 0700) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Cannot get folder: %s: %s"),
- path, g_strerror (errno));
- return NULL;
- }
- }
- if (slash)
- *slash = '/';
- } while (slash);
-
- return (CamelFolder *) 0xdeadbeef;
-}
-
-static CamelFolder *
-get_inbox(CamelStore *store, CamelException *ex)
-{
- camel_exception_set(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Local stores do not have an inbox"));
- return NULL;
-}
-
-static char *
-get_name (CamelService *service, gboolean brief)
-{
- char *dir = ((CamelLocalStore*)service)->toplevel_dir;
-
- if (brief)
- return g_strdup (dir);
- else
- return g_strdup_printf (_("Local mail file %s"), dir);
-}
-
-static CamelFolderInfo *
-get_folder_info (CamelStore *store, const char *top,
- guint32 flags, CamelException *ex)
-{
- /* FIXME: This is broken, but it corresponds to what was
- * there before.
- */
-
- d(printf("-- LOCAL STORE -- get folder info: %s\n", top));
-
- return NULL;
-}
-
-static CamelFolderInfo *
-create_folder(CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex)
-{
- char *path = ((CamelLocalStore *)store)->toplevel_dir;
- char *name;
- CamelFolder *folder;
- CamelFolderInfo *info = NULL;
- struct stat st;
-
- /* This is a pretty hacky version of create folder, but should basically work */
-
- if (path[0] != '/') {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Store root %s is not an absolute path"), path);
- return NULL;
- }
-
- if (parent_name)
- name = g_strdup_printf("%s/%s/%s", path, parent_name, folder_name);
- else
- name = g_strdup_printf("%s/%s", path, folder_name);
-
- if (stat(name, &st) == 0 || errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Cannot get folder: %s: %s"),
- name, g_strerror (errno));
- g_free(name);
- return NULL;
- }
-
- g_free(name);
-
- if (parent_name)
- name = g_strdup_printf("%s/%s", parent_name, folder_name);
- else
- name = g_strdup_printf("%s", folder_name);
-
- folder = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder(store, name, CAMEL_STORE_FOLDER_CREATE, ex);
- if (folder) {
- camel_object_unref((CamelObject *)folder);
- info = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder_info(store, name, 0, ex);
-
- /* get_folder(CREATE) will emit a folder_created event for us */
- /*if (info)
- camel_object_trigger_event((CamelObject *)store, "folder_created", info);*/
- }
-
- g_free(name);
-
- return info;
-}
-
-static int xrename(const char *oldp, const char *newp, const char *prefix, const char *suffix, int missingok, CamelException *ex)
-{
- struct stat st;
- char *old = g_strconcat(prefix, oldp, suffix, 0);
- char *new = g_strconcat(prefix, newp, suffix, 0);
- int ret = -1;
- int err = 0;
-
- d(printf("renaming %s%s to %s%s\n", oldp, suffix, newp, suffix));
-
- if (stat(old, &st) == -1) {
- if (missingok && errno == ENOENT) {
- ret = 0;
- } else {
- err = errno;
- ret = -1;
- }
- } else if (S_ISDIR(st.st_mode)) { /* use rename for dirs */
- if (rename(old, new) == 0
- || stat(new, &st) == 0) {
- ret = 0;
- } else {
- err = errno;
- ret = -1;
- }
- } else if (link(old, new) == 0 /* and link for files */
- || (stat(new, &st) == 0 && st.st_nlink == 2)) {
- if (unlink(old) == 0) {
- ret = 0;
- } else {
- err = errno;
- unlink(new);
- ret = -1;
- }
- } else {
- err = errno;
- ret = -1;
- }
-
- if (ret == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not rename folder %s to %s: %s"),
- old, new, g_strerror (err));
- }
-
- g_free(old);
- g_free(new);
- return ret;
-}
-
-/* default implementation, rename all */
-static void
-rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex)
-{
- char *path = CAMEL_LOCAL_STORE (store)->toplevel_dir;
- CamelLocalFolder *folder = NULL;
- char *newibex = g_strdup_printf("%s%s.ibex", path, new);
- char *oldibex = g_strdup_printf("%s%s.ibex", path, old);
-
- /* try to rollback failures, has obvious races */
-
- d(printf("local rename folder '%s' '%s'\n", old, new));
-
- folder = camel_object_bag_get(store->folders, old);
- if (folder && folder->index) {
- if (camel_index_rename(folder->index, newibex) == -1)
- goto ibex_failed;
- } else {
- /* TODO: camel_text_index_rename should find out if we have an active index itself? */
- if (camel_text_index_rename(oldibex, newibex) == -1)
- goto ibex_failed;
- }
-
- if (xrename(old, new, path, ".ev-summary", TRUE, ex))
- goto summary_failed;
-
- if (xrename(old, new, path, "", FALSE, ex))
- goto base_failed;
-
- g_free(newibex);
- g_free(oldibex);
-
- if (folder)
- camel_object_unref(folder);
-
- return;
-
-base_failed:
- xrename(new, old, path, ".ev-summary", TRUE, ex);
-
-summary_failed:
- if (folder) {
- if (folder->index)
- camel_index_rename(folder->index, oldibex);
- } else
- camel_text_index_rename(newibex, oldibex);
-ibex_failed:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not rename '%s': %s"),
- old, g_strerror (errno));
-
- g_free(newibex);
- g_free(oldibex);
-
- if (folder)
- camel_object_unref(folder);
-}
-
-/* default implementation, only delete metadata */
-static void
-delete_folder(CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelFolderInfo *fi;
- CamelException lex;
- CamelFolder *lf;
- char *name;
- char *str;
-
- /* remove metadata only */
- name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
- str = g_strdup_printf("%s.ev-summary", name);
- if (unlink(str) == -1 && errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder summary file `%s': %s"),
- str, g_strerror (errno));
- g_free(str);
- g_free (name);
- return;
- }
- g_free(str);
- str = g_strdup_printf("%s.ibex", name);
- if (camel_text_index_remove(str) == -1 && errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder index file `%s': %s"),
- str, g_strerror (errno));
- g_free(str);
- g_free (name);
- return;
- }
- g_free(str);
-
- camel_exception_init (&lex);
- if ((lf = camel_store_get_folder (store, folder_name, 0, &lex))) {
- camel_object_get (lf, NULL, CAMEL_OBJECT_STATE_FILE, &str, NULL);
- camel_object_set (lf, NULL, CAMEL_OBJECT_STATE_FILE, NULL, NULL);
- camel_object_unref (lf);
- } else {
- camel_exception_clear (&lex);
- }
-
- if (str == NULL)
- str = g_strdup_printf ("%s.cmeta", name);
-
- if (unlink (str) == -1 && errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder meta file `%s': %s"),
- str, g_strerror (errno));
- g_free (name);
- g_free (str);
- return;
- }
-
- g_free (str);
- g_free (name);
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = g_strdup (folder_name);
- fi->name = g_path_get_basename (folder_name);
- fi->url = g_strdup_printf ("%s:%s#%s", ((CamelService *) store)->url->protocol,
- CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
- fi->unread_message_count = -1;
- camel_folder_info_build_path(fi, '/');
-
- camel_object_trigger_event (store, "folder_deleted", fi);
-
- camel_folder_info_free (fi);
-}
diff --git a/camel/providers/local/camel-local-store.h b/camel/providers/local/camel-local-store.h
deleted file mode 100644
index 21d854c562..0000000000
--- a/camel/providers/local/camel-local-store.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-mbox-store.h : class for an mbox store */
-
-/*
- *
- * Copyright (C) 2000 Ximian, Inc. <bertrand@helixcode.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_LOCAL_STORE_H
-#define CAMEL_LOCAL_STORE_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-store.h"
-
-#define CAMEL_LOCAL_STORE_TYPE (camel_local_store_get_type ())
-#define CAMEL_LOCAL_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_LOCAL_STORE_TYPE, CamelLocalStore))
-#define CAMEL_LOCAL_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_LOCAL_STORE_TYPE, CamelLocalStoreClass))
-#define CAMEL_IS_LOCAL_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_LOCAL_STORE_TYPE))
-
-
-typedef struct {
- CamelStore parent_object;
- char *toplevel_dir;
-
-} CamelLocalStore;
-
-
-
-typedef struct {
- CamelStoreClass parent_class;
-
-} CamelLocalStoreClass;
-
-
-/* public methods */
-
-/* Standard Camel function */
-CamelType camel_local_store_get_type (void);
-
-const gchar *camel_local_store_get_toplevel_dir (CamelLocalStore *store);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_LOCAL_STORE_H */
-
-
diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c
deleted file mode 100644
index 42534b361d..0000000000
--- a/camel/providers/local/camel-local-summary.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "camel-local-summary.h"
-#include "camel/camel-mime-message.h"
-#include "camel/camel-stream-null.h"
-
-#define w(x)
-#define io(x)
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-#define CAMEL_LOCAL_SUMMARY_VERSION (0x200)
-
-static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *);
-
-static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi);
-static char *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi);
-
-static int local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex);
-static int local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-static int local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-static CamelMessageInfo *local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
-
-static void camel_local_summary_class_init (CamelLocalSummaryClass *klass);
-static void camel_local_summary_init (CamelLocalSummary *obj);
-static void camel_local_summary_finalise (CamelObject *obj);
-static CamelFolderSummaryClass *camel_local_summary_parent;
-
-CamelType
-camel_local_summary_get_type(void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(camel_folder_summary_get_type(), "CamelLocalSummary",
- sizeof (CamelLocalSummary),
- sizeof (CamelLocalSummaryClass),
- (CamelObjectClassInitFunc) camel_local_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_local_summary_init,
- (CamelObjectFinalizeFunc) camel_local_summary_finalise);
- }
-
- return type;
-}
-
-static void
-camel_local_summary_class_init(CamelLocalSummaryClass *klass)
-{
- CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *) klass;
-
- camel_local_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type()));
-
- sklass->message_info_new = message_info_new;
-
- klass->load = local_summary_load;
- klass->check = local_summary_check;
- klass->sync = local_summary_sync;
- klass->add = local_summary_add;
-
- klass->encode_x_evolution = local_summary_encode_x_evolution;
- klass->decode_x_evolution = local_summary_decode_x_evolution;
-}
-
-static void
-camel_local_summary_init(CamelLocalSummary *obj)
-{
- struct _CamelFolderSummary *s = (CamelFolderSummary *)obj;
-
- /* subclasses need to set the right instance data sizes */
- s->message_info_size = sizeof(CamelMessageInfo);
- s->content_info_size = sizeof(CamelMessageContentInfo);
-
- /* and a unique file version */
- s->version += CAMEL_LOCAL_SUMMARY_VERSION;
-}
-
-static void
-camel_local_summary_finalise(CamelObject *obj)
-{
- CamelLocalSummary *mbs = CAMEL_LOCAL_SUMMARY(obj);
-
- if (mbs->index)
- camel_object_unref((CamelObject *)mbs->index);
- g_free(mbs->folder_path);
-}
-
-void
-camel_local_summary_construct(CamelLocalSummary *new, const char *filename, const char *local_name, CamelIndex *index)
-{
- camel_folder_summary_set_build_content(CAMEL_FOLDER_SUMMARY(new), FALSE);
- camel_folder_summary_set_filename(CAMEL_FOLDER_SUMMARY(new), filename);
- new->folder_path = g_strdup(local_name);
- new->index = index;
- if (index)
- camel_object_ref((CamelObject *)index);
-}
-
-static int
-local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex)
-{
- return camel_folder_summary_load((CamelFolderSummary *)cls);
-}
-
-/* load/check the summary */
-int
-camel_local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex)
-{
- struct stat st;
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
-
- d(printf("Loading summary ...\n"));
-
- if (forceindex
- || stat(s->summary_path, &st) == -1
- || ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->load(cls, forceindex, ex) == -1) {
- w(g_warning("Could not load summary: flags may be reset"));
- camel_folder_summary_clear((CamelFolderSummary *)cls);
- return -1;
- }
-
- return 0;
-}
-
-void camel_local_summary_check_force(CamelLocalSummary *cls)
-{
- cls->check_force = 1;
-}
-
-char *
-camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *info)
-{
- return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->encode_x_evolution(cls, info);
-}
-
-int
-camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info)
-{
- return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->decode_x_evolution(cls, xev, info);
-}
-
-/*#define DOSTATS*/
-#ifdef DOSTATS
-struct _stat_info {
- int mitotal;
- int micount;
- int citotal;
- int cicount;
- int msgid;
- int msgcount;
-};
-
-static void
-do_stat_ci(CamelLocalSummary *cls, struct _stat_info *info, CamelMessageContentInfo *ci)
-{
- info->cicount++;
- info->citotal += ((CamelFolderSummary *)cls)->content_info_size /*+ 4 memchunks are 1/4 byte overhead per mi */;
- if (ci->id)
- info->citotal += strlen(ci->id) + 4;
- if (ci->description)
- info->citotal += strlen(ci->description) + 4;
- if (ci->encoding)
- info->citotal += strlen(ci->encoding) + 4;
- if (ci->type) {
- CamelContentType *ct = ci->type;
- struct _camel_header_param *param;
-
- info->citotal += sizeof(*ct) + 4;
- if (ct->type)
- info->citotal += strlen(ct->type) + 4;
- if (ct->subtype)
- info->citotal += strlen(ct->subtype) + 4;
- param = ct->params;
- while (param) {
- info->citotal += sizeof(*param) + 4;
- if (param->name)
- info->citotal += strlen(param->name)+4;
- if (param->value)
- info->citotal += strlen(param->value)+4;
- param = param->next;
- }
- }
- ci = ci->childs;
- while (ci) {
- do_stat_ci(cls, info, ci);
- ci = ci->next;
- }
-}
-
-static void
-do_stat_mi(CamelLocalSummary *cls, struct _stat_info *info, CamelMessageInfo *mi)
-{
- info->micount++;
- info->mitotal += ((CamelFolderSummary *)cls)->content_info_size /*+ 4*/;
-
- if (mi->subject)
- info->mitotal += strlen(mi->subject) + 4;
- if (mi->to)
- info->mitotal += strlen(mi->to) + 4;
- if (mi->from)
- info->mitotal += strlen(mi->from) + 4;
- if (mi->cc)
- info->mitotal += strlen(mi->cc) + 4;
- if (mi->uid)
- info->mitotal += strlen(mi->uid) + 4;
-
- if (mi->references) {
- info->mitotal += (mi->references->size-1) * sizeof(CamelSummaryMessageID) + sizeof(CamelSummaryReferences) + 4;
- info->msgid += (mi->references->size) * sizeof(CamelSummaryMessageID);
- info->msgcount += mi->references->size;
- }
-
- /* dont have any user flags yet */
-
- if (mi->content) {
- do_stat_ci(cls, info, mi->content);
- }
-}
-
-#endif
-
-int
-camel_local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- int ret;
-
- ret = ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->check(cls, changeinfo, ex);
-
-#ifdef DOSTATS
- if (ret != -1) {
- int i;
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
- struct _stat_info stats = { 0 };
-
- for (i=0;i<camel_folder_summary_count(s);i++) {
- CamelMessageInfo *info = camel_folder_summary_index(s, i);
- do_stat_mi(cls, &stats, info);
- camel_folder_summary_info_free(s, info);
- }
-
- printf("\nMemory used by summary:\n\n");
- printf("Total of %d messages\n", camel_folder_summary_count(s));
- printf("Total: %d bytes (ave %f)\n", stats.citotal + stats.mitotal,
- (double)(stats.citotal+stats.mitotal)/(double)camel_folder_summary_count(s));
- printf("Message Info: %d (ave %f)\n", stats.mitotal, (double)stats.mitotal/(double)stats.micount);
- printf("Content Info; %d (ave %f) count %d\n", stats.citotal, (double)stats.citotal/(double)stats.cicount, stats.cicount);
- printf("message id's: %d (ave %f) count %d\n", stats.msgid, (double)stats.msgid/(double)stats.msgcount, stats.msgcount);
- }
-#endif
- return ret;
-}
-
-int
-camel_local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->sync(cls, expunge, changeinfo, ex);
-}
-
-CamelMessageInfo *
-camel_local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex)
-{
- return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->add(cls, msg, info, ci, ex);
-}
-
-/**
- * camel_local_summary_write_headers:
- * @fd:
- * @header:
- * @xevline:
- * @status:
- * @xstatus:
- *
- * Write a bunch of headers to the file @fd. IF xevline is non NULL, then
- * an X-Evolution header line is created at the end of all of the headers.
- * If @status is non NULL, then a Status header line is also written.
- * The headers written are termianted with a blank line.
- *
- * Return value: -1 on error, otherwise the number of bytes written.
- **/
-int
-camel_local_summary_write_headers(int fd, struct _camel_header_raw *header, const char *xevline, const char *status, const char *xstatus)
-{
- int outlen = 0, len;
- int newfd;
- FILE *out;
-
- /* dum de dum, maybe the whole sync function should just use stdio for output */
- newfd = dup(fd);
- if (newfd == -1)
- return -1;
-
- out = fdopen(newfd, "w");
- if (out == NULL) {
- close(newfd);
- errno = EINVAL;
- return -1;
- }
-
- while (header) {
- if (strcmp(header->name, "X-Evolution") != 0
- && (status == NULL || strcmp(header->name, "Status") != 0)
- && (xstatus == NULL || strcmp(header->name, "X-Status") != 0)) {
- len = fprintf(out, "%s:%s\n", header->name, header->value);
- if (len == -1) {
- fclose(out);
- return -1;
- }
- outlen += len;
- }
- header = header->next;
- }
-
- if (status) {
- len = fprintf(out, "Status: %s\n", status);
- if (len == -1) {
- fclose(out);
- return -1;
- }
- outlen += len;
- }
-
- if (xstatus) {
- len = fprintf(out, "X-Status: %s\n", xstatus);
- if (len == -1) {
- fclose(out);
- return -1;
- }
- outlen += len;
- }
-
- if (xevline) {
- len = fprintf(out, "X-Evolution: %s\n", xevline);
- if (len == -1) {
- fclose(out);
- return -1;
- }
- outlen += len;
- }
-
- len = fprintf(out, "\n");
- if (len == -1) {
- fclose(out);
- return -1;
- }
- outlen += len;
-
- if (fclose(out) == -1)
- return -1;
-
- return outlen;
-}
-
-static int
-local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- /* FIXME: sync index here ? */
- return 0;
-}
-
-static int
-local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- int ret = 0;
-
- ret = camel_folder_summary_save((CamelFolderSummary *)cls);
- if (ret == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not save summary: %s: %s"),
- cls->folder_path, g_strerror (errno));
-
- g_warning ("Could not save summary for %s: %s", cls->folder_path, strerror (errno));
- }
-
- if (cls->index && camel_index_sync(cls->index) == -1)
- g_warning ("Could not sync index for %s: %s", cls->folder_path, strerror (errno));
-
- return ret;
-}
-
-static CamelMessageInfo *
-local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex)
-{
- CamelMessageInfo *mi;
- char *xev;
-
- d(printf("Adding message to summary\n"));
-
- mi = camel_folder_summary_add_from_message((CamelFolderSummary *)cls, msg);
- if (mi) {
- d(printf("Added, uid = %s\n", mi->uid));
- if (info) {
- CamelTag *tag = info->user_tags;
- CamelFlag *flag = info->user_flags;
-
- while (flag) {
- camel_flag_set(&mi->user_flags, flag->name, TRUE);
- flag = flag->next;
- }
-
- while (tag) {
- camel_tag_set(&mi->user_tags, tag->name, tag->value);
- tag = tag->next;
- }
-
- mi->flags = mi->flags | (info->flags & 0xffff);
- if (info->size)
- mi->size = info->size;
- }
-
- /* we need to calculate the size ourselves */
- if (mi->size == 0) {
- CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new();
-
- camel_data_wrapper_write_to_stream((CamelDataWrapper *)msg, (CamelStream *)sn);
- mi->size = sn->written;
- camel_object_unref((CamelObject *)sn);
- }
-
- mi->flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED);
- xev = camel_local_summary_encode_x_evolution(cls, mi);
- camel_medium_set_header((CamelMedium *)msg, "X-Evolution", xev);
- g_free(xev);
- camel_folder_change_info_add_uid(ci, camel_message_info_uid(mi));
- } else {
- d(printf("Failed!\n"));
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to add message to summary: unknown reason"));
- }
- return mi;
-}
-
-static char *
-local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi)
-{
- GString *out = g_string_new("");
- struct _camel_header_param *params = NULL;
- GString *val = g_string_new("");
- CamelFlag *flag = mi->user_flags;
- CamelTag *tag = mi->user_tags;
- char *ret;
- const char *p, *uidstr;
- guint32 uid;
-
- /* FIXME: work out what to do with uid's that aren't stored here? */
- /* FIXME: perhaps make that a mbox folder only issue?? */
- p = uidstr = camel_message_info_uid(mi);
- while (*p && isdigit(*p))
- p++;
- if (*p == 0 && sscanf (uidstr, "%u", &uid) == 1) {
- g_string_printf (out, "%08x-%04x", uid, mi->flags & 0xffff);
- } else {
- g_string_printf (out, "%s-%04x", uidstr, mi->flags & 0xffff);
- }
-
- if (flag || tag) {
- val = g_string_new ("");
-
- if (flag) {
- while (flag) {
- g_string_append (val, flag->name);
- if (flag->next)
- g_string_append_c (val, ',');
- flag = flag->next;
- }
- camel_header_set_param (&params, "flags", val->str);
- g_string_truncate (val, 0);
- }
- if (tag) {
- while (tag) {
- g_string_append (val, tag->name);
- g_string_append_c (val, '=');
- g_string_append (val, tag->value);
- if (tag->next)
- g_string_append_c (val, ',');
- tag = tag->next;
- }
- camel_header_set_param (&params, "tags", val->str);
- }
- g_string_free (val, TRUE);
- camel_header_param_list_format_append (out, params);
- camel_header_param_list_free (params);
- }
- ret = out->str;
- g_string_free (out, FALSE);
-
- return ret;
-}
-
-static int
-local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi)
-{
- struct _camel_header_param *params, *scan;
- guint32 uid, flags;
- char *header;
- int i;
-
- /* check for uid/flags */
- header = camel_header_token_decode(xev);
- if (header && strlen(header) == strlen("00000000-0000")
- && sscanf(header, "%08x-%04x", &uid, &flags) == 2) {
- char uidstr[20];
- if (mi) {
- sprintf(uidstr, "%u", uid);
- camel_message_info_set_uid(mi, g_strdup(uidstr));
- mi->flags = flags;
- }
- } else {
- g_free(header);
- return -1;
- }
- g_free(header);
-
- if (mi == NULL)
- return 0;
-
- /* check for additional data */
- header = strchr(xev, ';');
- if (header) {
- params = camel_header_param_list_decode(header+1);
- scan = params;
- while (scan) {
- if (!strcasecmp(scan->name, "flags")) {
- char **flagv = g_strsplit(scan->value, ",", 1000);
-
- for (i=0;flagv[i];i++) {
- camel_flag_set(&mi->user_flags, flagv[i], TRUE);
- }
- g_strfreev(flagv);
- } else if (!strcasecmp(scan->name, "tags")) {
- char **tagv = g_strsplit(scan->value, ",", 10000);
- char *val;
-
- for (i=0;tagv[i];i++) {
- val = strchr(tagv[i], '=');
- if (val) {
- *val++ = 0;
- camel_tag_set(&mi->user_tags, tagv[i], val);
- val[-1]='=';
- }
- }
- g_strfreev(tagv);
- }
- scan = scan->next;
- }
- camel_header_param_list_free(params);
- }
- return 0;
-}
-
-static CamelMessageInfo *
-message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
-{
- CamelMessageInfo *mi;
- CamelLocalSummary *cls = (CamelLocalSummary *)s;
-
- mi = ((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new(s, h);
- if (mi) {
- const char *xev;
- int doindex = FALSE;
-
- xev = camel_header_raw_find(&h, "X-Evolution", NULL);
- if (xev==NULL || camel_local_summary_decode_x_evolution(cls, xev, mi) == -1) {
- /* to indicate it has no xev header */
- mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
- camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s));
-
- /* shortcut, no need to look it up in the index library */
- doindex = TRUE;
- }
-
- if (cls->index
- && (doindex
- || cls->index_force
- || !camel_index_has_name(cls->index, camel_message_info_uid(mi)))) {
- d(printf("Am indexing message %s\n", camel_message_info_uid(mi)));
- camel_folder_summary_set_index(s, cls->index);
- } else {
- d(printf("Not indexing message %s\n", camel_message_info_uid(mi)));
- camel_folder_summary_set_index(s, NULL);
- }
- }
-
- return mi;
-}
diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h
deleted file mode 100644
index 25d77e62c3..0000000000
--- a/camel/providers/local/camel-local-summary.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_LOCAL_SUMMARY_H
-#define _CAMEL_LOCAL_SUMMARY_H
-
-#include <camel/camel-folder-summary.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-exception.h>
-#include <camel/camel-index.h>
-
-#define CAMEL_LOCAL_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_local_summary_get_type (), CamelLocalSummary)
-#define CAMEL_LOCAL_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_local_summary_get_type (), CamelLocalSummaryClass)
-#define CAMEL_IS_LOCAL_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_local_summary_get_type ())
-
-typedef struct _CamelLocalSummary CamelLocalSummary;
-typedef struct _CamelLocalSummaryClass CamelLocalSummaryClass;
-
-/* extra summary flags */
-enum {
- CAMEL_MESSAGE_FOLDER_NOXEV = 1<<17,
- CAMEL_MESSAGE_FOLDER_XEVCHANGE = 1<<18,
- CAMEL_MESSAGE_FOLDER_NOTSEEN = 1<<19, /* have we seen this in processing this loop? */
-};
-
-struct _CamelLocalSummary {
- CamelFolderSummary parent;
-
- char *folder_path; /* name of matching folder */
-
- CamelIndex *index;
- unsigned int index_force:1; /* do we force index during creation? */
- unsigned int check_force:1; /* does a check force a full check? */
-};
-
-struct _CamelLocalSummaryClass {
- CamelFolderSummaryClass parent_class;
-
- int (*load)(CamelLocalSummary *cls, int forceindex, CamelException *ex);
- int (*check)(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
- int (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
- CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
-
- char *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelMessageInfo *info);
- int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info);
-};
-
-CamelType camel_local_summary_get_type (void);
-void camel_local_summary_construct (CamelLocalSummary *new, const char *filename, const char *local_name, CamelIndex *index);
-
-/* load/check the summary */
-int camel_local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex);
-/* check for new/removed messages */
-int camel_local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *, CamelException *ex);
-/* perform a folder sync or expunge, if needed */
-int camel_local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *, CamelException *ex);
-/* add a new message to the summary */
-CamelMessageInfo *camel_local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
-
-/* force the next check to be a full check/rebuild */
-void camel_local_summary_check_force(CamelLocalSummary *cls);
-
-/* generate an X-Evolution header line */
-char *camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *info);
-int camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info);
-
-/* utility functions - write headers to a file with optional X-Evolution header and/or status header */
-int camel_local_summary_write_headers(int fd, struct _camel_header_raw *header, const char *xevline, const char *status, const char *xstatus);
-
-#endif /* ! _CAMEL_LOCAL_SUMMARY_H */
-
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
deleted file mode 100644
index eca07efbef..0000000000
--- a/camel/providers/local/camel-maildir-folder.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999, 2003 Ximian Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include "camel-maildir-folder.h"
-#include "camel-maildir-store.h"
-#include "camel-stream-fs.h"
-#include "camel-maildir-summary.h"
-#include "camel-data-wrapper.h"
-#include "camel-mime-message.h"
-#include "camel-exception.h"
-
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-static CamelLocalFolderClass *parent_class = NULL;
-
-/* Returns the class for a CamelMaildirFolder */
-#define CMAILDIRF_CLASS(so) CAMEL_MAILDIR_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CMAILDIRS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static CamelLocalSummary *maildir_create_summary(const char *path, const char *folder, CamelIndex *index);
-
-static void maildir_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex);
-static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex);
-
-static void maildir_finalize(CamelObject * object);
-
-static void camel_maildir_folder_class_init(CamelObjectClass * camel_maildir_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_maildir_folder_class);
- CamelLocalFolderClass *lclass = (CamelLocalFolderClass *)camel_maildir_folder_class;
-
- parent_class = CAMEL_LOCAL_FOLDER_CLASS (camel_type_get_global_classfuncs(camel_local_folder_get_type()));
-
- /* virtual method definition */
-
- /* virtual method overload */
- camel_folder_class->append_message = maildir_append_message;
- camel_folder_class->get_message = maildir_get_message;
-
- lclass->create_summary = maildir_create_summary;
-}
-
-static void maildir_init(gpointer object, gpointer klass)
-{
- /*CamelFolder *folder = object;
- CamelMaildirFolder *maildir_folder = object;*/
-}
-
-static void maildir_finalize(CamelObject * object)
-{
- /*CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER(object);*/
-}
-
-CamelType camel_maildir_folder_get_type(void)
-{
- static CamelType camel_maildir_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_maildir_folder_type == CAMEL_INVALID_TYPE) {
- camel_maildir_folder_type = camel_type_register(CAMEL_LOCAL_FOLDER_TYPE, "CamelMaildirFolder",
- sizeof(CamelMaildirFolder),
- sizeof(CamelMaildirFolderClass),
- (CamelObjectClassInitFunc) camel_maildir_folder_class_init,
- NULL,
- (CamelObjectInitFunc) maildir_init,
- (CamelObjectFinalizeFunc) maildir_finalize);
- }
-
- return camel_maildir_folder_type;
-}
-
-CamelFolder *
-camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex)
-{
- CamelFolder *folder;
-
- d(printf("Creating maildir folder: %s\n", full_name));
-
- folder = (CamelFolder *)camel_object_new(CAMEL_MAILDIR_FOLDER_TYPE);
-
- if (parent_store->flags & CAMEL_STORE_FILTER_INBOX
- && strcmp(full_name, ".") == 0)
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
-
- folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder,
- parent_store, full_name, flags, ex);
-
- return folder;
-}
-
-static CamelLocalSummary *maildir_create_summary(const char *path, const char *folder, CamelIndex *index)
-{
- return (CamelLocalSummary *)camel_maildir_summary_new(path, folder, index);
-}
-
-static void
-maildir_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex)
-{
- CamelMaildirFolder *maildir_folder = (CamelMaildirFolder *)folder;
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- CamelStream *output_stream;
- CamelMessageInfo *mi;
- CamelMaildirMessageInfo *mdi;
- char *name, *dest = NULL;
-
- d(printf("Appending message\n"));
-
- /* add it to the summary/assign the uid, etc */
- mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex);
- if (camel_exception_is_set (ex))
- return;
-
- mdi = (CamelMaildirMessageInfo *)mi;
-
- d(printf("Appending message: uid is %s filename is %s\n", camel_message_info_uid(mi), mdi->filename));
-
- /* write it out to tmp, use the uid we got from the summary */
- name = g_strdup_printf ("%s/tmp/%s", lf->folder_path, camel_message_info_uid(mi));
- output_stream = camel_stream_fs_new_with_name (name, O_WRONLY|O_CREAT, 0600);
- if (output_stream == NULL)
- goto fail_write;
-
- if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)message, output_stream) == -1
- || camel_stream_close (output_stream) == -1)
- goto fail_write;
-
- /* now move from tmp to cur (bypass new, does it matter?) */
- dest = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));
- if (rename (name, dest) == 1)
- goto fail_write;
-
- g_free (dest);
- g_free (name);
-
- camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed",
- ((CamelLocalFolder *)maildir_folder)->changes);
- camel_folder_change_info_clear (((CamelLocalFolder *)maildir_folder)->changes);
-
- if (appended_uid)
- *appended_uid = g_strdup(camel_message_info_uid(mi));
-
- return;
-
- fail_write:
-
- /* remove the summary info so we are not out-of-sync with the mh folder */
- camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary),
- camel_message_info_uid (mi));
-
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Maildir append message cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to maildir folder: %s: %s"),
- name, g_strerror (errno));
-
- if (output_stream) {
- camel_object_unref (CAMEL_OBJECT (output_stream));
- unlink (name);
- }
-
- g_free (name);
- g_free (dest);
-}
-
-static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex)
-{
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- CamelStream *message_stream = NULL;
- CamelMimeMessage *message = NULL;
- CamelMessageInfo *info;
- char *name;
- CamelMaildirMessageInfo *mdi;
-
- d(printf("getting message: %s\n", uid));
-
- /* get the message summary info */
- if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), uid, _("No such message"));
- return NULL;
- }
-
- mdi = (CamelMaildirMessageInfo *)info;
-
- /* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */
- name = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi));
-
- camel_folder_summary_info_free(folder->summary, info);
-
- if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s\n %s"),
- name, g_strerror (errno));
- g_free(name);
- return NULL;
- }
-
- message = camel_mime_message_new();
- if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) {
- camel_exception_setv(ex, (errno==EINTR)?CAMEL_EXCEPTION_USER_CANCEL:CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s\n %s"),
- name, _("Invalid message contents"));
- g_free(name);
- camel_object_unref((CamelObject *)message_stream);
- camel_object_unref((CamelObject *)message);
- return NULL;
-
- }
- camel_object_unref((CamelObject *)message_stream);
- g_free(name);
-
- return message;
-}
diff --git a/camel/providers/local/camel-maildir-folder.h b/camel/providers/local/camel-maildir-folder.h
deleted file mode 100644
index c495d9b14d..0000000000
--- a/camel/providers/local/camel-maildir-folder.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999 Ximian Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_MAILDIR_FOLDER_H
-#define CAMEL_MAILDIR_FOLDER_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus } */
-#include "camel-local-folder.h"
-
-#define CAMEL_MAILDIR_FOLDER_TYPE (camel_maildir_folder_get_type ())
-#define CAMEL_MAILDIR_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MAILDIR_FOLDER_TYPE, CamelMaildirFolder))
-#define CAMEL_MAILDIR_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MAILDIR_FOLDER_TYPE, CamelMaildirFolderClass))
-#define CAMEL_IS_MAILDIR_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_MAILDIR_FOLDER_TYPE))
-
-typedef struct {
- CamelLocalFolder parent_object;
-
-} CamelMaildirFolder;
-
-typedef struct {
- CamelLocalFolderClass parent_class;
-
- /* Virtual methods */
-
-} CamelMaildirFolderClass;
-
-/* public methods */
-CamelFolder *camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex);
-
-/* Standard Camel function */
-CamelType camel_maildir_folder_get_type(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* CAMEL_MAILDIR_FOLDER_H */
diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c
deleted file mode 100644
index c84c37158c..0000000000
--- a/camel/providers/local/camel-maildir-store.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <dirent.h>
-
-#include "camel-maildir-store.h"
-#include "camel-maildir-folder.h"
-#include "camel-exception.h"
-#include "camel-url.h"
-#include "camel-private.h"
-
-#define d(x)
-
-static CamelLocalStoreClass *parent_class = NULL;
-
-/* Returns the class for a CamelMaildirStore */
-#define CMAILDIRS_CLASS(so) CAMEL_MAILDIR_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CMAILDIRF_CLASS(so) CAMEL_MAILDIR_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex);
-static CamelFolder *get_inbox (CamelStore *store, CamelException *ex);
-static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex);
-
-static CamelFolderInfo * get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
-
-static void camel_maildir_store_class_init(CamelObjectClass * camel_maildir_store_class)
-{
- CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS(camel_maildir_store_class);
- /*CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_maildir_store_class);*/
-
- parent_class = (CamelLocalStoreClass *)camel_type_get_global_classfuncs(camel_local_store_get_type());
-
- /* virtual method overload, use defaults for most */
- camel_store_class->get_folder = get_folder;
- camel_store_class->get_inbox = get_inbox;
- camel_store_class->delete_folder = delete_folder;
-
- camel_store_class->get_folder_info = get_folder_info;
- camel_store_class->free_folder_info = camel_store_free_folder_info_full;
-}
-
-CamelType camel_maildir_store_get_type(void)
-{
- static CamelType camel_maildir_store_type = CAMEL_INVALID_TYPE;
-
- if (camel_maildir_store_type == CAMEL_INVALID_TYPE) {
- camel_maildir_store_type = camel_type_register(CAMEL_LOCAL_STORE_TYPE, "CamelMaildirStore",
- sizeof(CamelMaildirStore),
- sizeof(CamelMaildirStoreClass),
- (CamelObjectClassInitFunc) camel_maildir_store_class_init,
- NULL,
- NULL,
- NULL);
- }
-
- return camel_maildir_store_type;
-}
-
-static CamelFolder *
-get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex)
-{
- char *name, *tmp, *cur, *new;
- struct stat st;
- CamelFolder *folder = NULL;
-
- if (!((CamelStoreClass *)parent_class)->get_folder(store, folder_name, flags, ex))
- return NULL;
-
- name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
- tmp = g_strdup_printf("%s/tmp", name);
- cur = g_strdup_printf("%s/cur", name);
- new = g_strdup_printf("%s/new", name);
-
- if (stat(name, &st) == -1) {
- if (errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open folder `%s':\n%s"),
- folder_name, g_strerror (errno));
- } else if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Folder `%s' does not exist."), folder_name);
- } else {
- if (mkdir(name, 0700) != 0
- || mkdir(tmp, 0700) != 0
- || mkdir(cur, 0700) != 0
- || mkdir(new, 0700) != 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create folder `%s':\n%s"),
- folder_name, g_strerror (errno));
- rmdir(tmp);
- rmdir(cur);
- rmdir(new);
- rmdir(name);
- } else {
- folder = camel_maildir_folder_new(store, folder_name, flags, ex);
- }
- }
- } else if (!S_ISDIR(st.st_mode)
- || stat(tmp, &st) != 0 || !S_ISDIR(st.st_mode)
- || stat(cur, &st) != 0 || !S_ISDIR(st.st_mode)
- || stat(new, &st) != 0 || !S_ISDIR(st.st_mode)) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("`%s' is not a maildir directory."), name);
- } else {
- folder = camel_maildir_folder_new(store, folder_name, flags, ex);
- }
-
- g_free(name);
- g_free(tmp);
- g_free(cur);
- g_free(new);
-
- return folder;
-}
-
-static CamelFolder *
-get_inbox (CamelStore *store, CamelException *ex)
-{
- return get_folder (store, ".", 0, ex);
-}
-
-static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex)
-{
- char *name, *tmp, *cur, *new;
- struct stat st;
-
- name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
-
- tmp = g_strdup_printf("%s/tmp", name);
- cur = g_strdup_printf("%s/cur", name);
- new = g_strdup_printf("%s/new", name);
-
- if (stat(name, &st) == -1 || !S_ISDIR(st.st_mode)
- || stat(tmp, &st) == -1 || !S_ISDIR(st.st_mode)
- || stat(cur, &st) == -1 || !S_ISDIR(st.st_mode)
- || stat(new, &st) == -1 || !S_ISDIR(st.st_mode)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder `%s': %s"),
- folder_name, errno ? g_strerror (errno) :
- _("not a maildir directory"));
- } else {
- int err = 0;
-
- /* remove subdirs first - will fail if not empty */
- if (rmdir(cur) == -1 || rmdir(new) == -1) {
- err = errno;
- } else {
- DIR *dir;
- struct dirent *d;
-
- /* for tmp (only), its contents is irrelevant */
- dir = opendir(tmp);
- if (dir) {
- while ( (d=readdir(dir)) ) {
- char *name = d->d_name, *file;
-
- if (!strcmp(name, ".") || !strcmp(name, ".."))
- continue;
- file = g_strdup_printf("%s/%s", tmp, name);
- unlink(file);
- g_free(file);
- }
- closedir(dir);
- }
- if (rmdir(tmp) == -1 || rmdir(name) == -1)
- err = errno;
- }
-
- if (err != 0) {
- /* easier just to mkdir all (and let them fail), than remember what we got to */
- mkdir(name, 0700);
- mkdir(cur, 0700);
- mkdir(new, 0700);
- mkdir(tmp, 0700);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder `%s': %s"),
- folder_name, g_strerror (err));
- } else {
- /* and remove metadata */
- ((CamelStoreClass *)parent_class)->delete_folder(store, folder_name, ex);
- }
- }
-
- g_free(name);
- g_free(tmp);
- g_free(cur);
- g_free(new);
-}
-
-static CamelFolderInfo *camel_folder_info_new(const char *url, const char *full, const char *name, int unread)
-{
- CamelFolderInfo *fi;
-
- fi = g_malloc0(sizeof(*fi));
- fi->url = g_strdup(url);
- fi->full_name = g_strdup(full);
- fi->name = g_strdup(name);
- fi->unread_message_count = unread;
- camel_folder_info_build_path(fi, '/');
-
- d(printf("Adding maildir info: '%s' '%s' '%s' '%s'\n", fi->path, fi->name, fi->full_name, fi->url));
-
- return fi;
-}
-
-/* used to find out where we've visited already */
-struct _inode {
- dev_t dnode;
- ino_t inode;
-};
-
-/* returns number of records found at or below this level */
-static int scan_dir(CamelStore *store, GHashTable *visited, char *root, const char *path, guint32 flags, CamelFolderInfo *parent, CamelFolderInfo **fip, CamelException *ex)
-{
- DIR *dir;
- struct dirent *d;
- char *name, *uri, *tmp, *cur, *new;
- const char *base;
- CamelFolderInfo *fi = NULL;
- struct stat st;
- CamelFolder *folder;
- int unread;
-
- /* look for folders matching the right structure, recursively */
- name = g_strdup_printf("%s/%s", root, path);
-
- d(printf("checking dir '%s' part '%s' for maildir content\n", root, path));
-
- tmp = g_strdup_printf("%s/tmp", name);
- cur = g_strdup_printf("%s/cur", name);
- new = g_strdup_printf("%s/new", name);
-
- if (stat(tmp, &st) == 0 && S_ISDIR(st.st_mode)
- && stat(cur, &st) == 0 && S_ISDIR(st.st_mode)
- && stat(new, &st) == 0 && S_ISDIR(st.st_mode)) {
- uri = g_strdup_printf("maildir:%s#%s", root, path);
- } else
- uri = g_strdup_printf("maildir:%s;noselect=yes#%s", root, path);
-
- base = strrchr(path, '/');
- if (base)
- base++;
- else
- base = path;
-
- /* if we have this folder open, get the real unread count */
- folder = camel_object_bag_get(store->folders, path);
- if (folder) {
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- camel_folder_refresh_info(folder, NULL);
- unread = camel_folder_get_unread_message_count(folder);
- camel_object_unref(folder);
- } else {
- unread = -1;
- }
-
- /* if we dont have a folder, then scan the directory and get the unread
- count from there, which is reasonably cheap (on decent filesystem) */
- /* Well we could get this from the summary, but this is more accurate */
- if (folder == NULL
- && (flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) {
- unread = 0;
- dir = opendir(new);
- if (dir) {
- /* we assume that all files here are unread ones */
- while ( (d = readdir(dir)) ) {
- if (d->d_name[0] != '.')
- unread++;
- }
- closedir(dir);
- }
- dir = opendir(cur);
- if (dir) {
- /* any files with flags but not the 'S' (seen) flag are unread */
- while ( (d = readdir(dir)) ) {
- char *p = strstr(d->d_name, ":2,");
-
- if (p && strchr(p, 'S') == NULL)
- unread++;
- }
- closedir(dir);
- }
- }
-
- fi = camel_folder_info_new(uri, path, base, unread);
-
- d(printf("found! uri = %s\n", fi->url));
- d(printf(" full_name = %s\n name = '%s'\n", fi->full_name, fi->name));
-
- fi->parent = parent;
- fi->sibling = *fip;
- *fip = fi;
- g_free(uri);
-
- g_free(tmp);
- g_free(cur);
- g_free(new);
-
- unread = 0;
-
- /* always look further if asked */
- if (((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || parent == NULL)) {
- dir = opendir(name);
- if (dir == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not scan folder `%s': %s"),
- root, g_strerror (errno));
- g_free(name);
- return -1;
- }
-
- while ( (d = readdir(dir)) ) {
- if (strcmp(d->d_name, "tmp") == 0
- || strcmp(d->d_name, "cur") == 0
- || strcmp(d->d_name, "new") == 0
- || strcmp(d->d_name, ".") == 0
- || strcmp(d->d_name, "..") == 0)
- continue;
-
- tmp = g_strdup_printf("%s/%s", name, d->d_name);
- if (stat(tmp, &st) == 0 && S_ISDIR(st.st_mode)) {
- struct _inode in = { st.st_dev, st.st_ino };
-
- /* see if we've visited already */
- if (g_hash_table_lookup(visited, &in) == NULL) {
- struct _inode *inew = g_malloc(sizeof(*inew));
-
- *inew = in;
- g_hash_table_insert(visited, inew, inew);
- new = g_strdup_printf("%s/%s", path, d->d_name);
- if (scan_dir(store, visited, root, new, flags, fi, &fi->child, ex) == -1) {
- g_free(tmp);
- g_free(new);
- closedir(dir);
- return -1;
- }
- g_free(new);
- }
- }
- g_free(tmp);
- }
- closedir(dir);
- }
-
- g_free(name);
-
- return 0;
-}
-
-static guint inode_hash(const void *d)
-{
- const struct _inode *v = d;
-
- return v->inode ^ v->dnode;
-}
-
-static gboolean inode_equal(const void *a, const void *b)
-{
- const struct _inode *v1 = a, *v2 = b;
-
- return v1->inode == v2->inode && v1->dnode == v2->dnode;
-}
-
-static void inode_free(void *k, void *v, void *d)
-{
- g_free(k);
-}
-
-static CamelFolderInfo *
-get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelFolderInfo *fi = NULL;
- CamelLocalStore *local_store = (CamelLocalStore *)store;
- GHashTable *visited;
-
- visited = g_hash_table_new(inode_hash, inode_equal);
-
- if (scan_dir(store, visited, ((CamelService *)local_store)->url->path, top?top:".", flags, NULL, &fi, ex) == -1 && fi != NULL) {
- camel_store_free_folder_info_full(store, fi);
- fi = NULL;
- }
-
- g_hash_table_foreach(visited, inode_free, NULL);
- g_hash_table_destroy(visited);
-
- return fi;
-}
diff --git a/camel/providers/local/camel-maildir-store.h b/camel/providers/local/camel-maildir-store.h
deleted file mode 100644
index f7725bc189..0000000000
--- a/camel/providers/local/camel-maildir-store.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_MAILDIR_STORE_H
-#define CAMEL_MAILDIR_STORE_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus } */
-
-#include "camel-local-store.h"
-
-#define CAMEL_MAILDIR_STORE_TYPE (camel_maildir_store_get_type ())
-#define CAMEL_MAILDIR_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MAILDIR_STORE_TYPE, CamelMaildirStore))
-#define CAMEL_MAILDIR_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MAILDIR_STORE_TYPE, CamelMaildirStoreClass))
-#define CAMEL_IS_MAILDIR_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_MAILDIR_STORE_TYPE))
-
-typedef struct {
- CamelLocalStore parent_object;
-
-} CamelMaildirStore;
-
-typedef struct {
- CamelLocalStoreClass parent_class;
-
-} CamelMaildirStoreClass;
-
-/* public methods */
-
-/* Standard Camel function */
-CamelType camel_maildir_store_get_type(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* CAMEL_MAILDIR_STORE_H */
diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c
deleted file mode 100644
index 37e1ac2ce7..0000000000
--- a/camel/providers/local/camel-maildir-summary.c
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Not Zed <notzed@lostzed.mmc.com.au>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <sys/types.h>
-#include <dirent.h>
-
-#include <ctype.h>
-
-#include "camel-maildir-summary.h"
-#include <camel/camel-mime-message.h>
-#include <camel/camel-operation.h>
-
-#include "camel-private.h"
-#include "e-util/e-memory.h"
-
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-#define CAMEL_MAILDIR_SUMMARY_VERSION (0x2000)
-
-static CamelMessageInfo *message_info_load(CamelFolderSummary *s, FILE *in);
-static CamelMessageInfo *message_info_new(CamelFolderSummary *, struct _camel_header_raw *);
-static void message_info_free(CamelFolderSummary *, CamelMessageInfo *mi);
-
-static int maildir_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex);
-static int maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-static int maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
-
-static char *maildir_summary_next_uid_string(CamelFolderSummary *s);
-static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi);
-static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi);
-
-static void camel_maildir_summary_class_init (CamelMaildirSummaryClass *class);
-static void camel_maildir_summary_init (CamelMaildirSummary *gspaper);
-static void camel_maildir_summary_finalise (CamelObject *obj);
-
-#define _PRIVATE(x) (((CamelMaildirSummary *)(x))->priv)
-
-struct _CamelMaildirSummaryPrivate {
- char *current_file;
- char *hostname;
-
- GHashTable *load_map;
-};
-
-static CamelLocalSummaryClass *parent_class;
-
-CamelType
-camel_maildir_summary_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(camel_local_summary_get_type (), "CamelMaildirSummary",
- sizeof(CamelMaildirSummary),
- sizeof(CamelMaildirSummaryClass),
- (CamelObjectClassInitFunc)camel_maildir_summary_class_init,
- NULL,
- (CamelObjectInitFunc)camel_maildir_summary_init,
- (CamelObjectFinalizeFunc)camel_maildir_summary_finalise);
- }
-
- return type;
-}
-
-static void
-camel_maildir_summary_class_init (CamelMaildirSummaryClass *class)
-{
- CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *) class;
- CamelLocalSummaryClass *lklass = (CamelLocalSummaryClass *)class;
-
- parent_class = (CamelLocalSummaryClass *)camel_type_get_global_classfuncs(camel_local_summary_get_type ());
-
- /* override methods */
- sklass->message_info_load = message_info_load;
- sklass->message_info_new = message_info_new;
- sklass->message_info_free = message_info_free;
- sklass->next_uid_string = maildir_summary_next_uid_string;
-
- lklass->load = maildir_summary_load;
- lklass->check = maildir_summary_check;
- lklass->sync = maildir_summary_sync;
- lklass->add = maildir_summary_add;
- lklass->encode_x_evolution = maildir_summary_encode_x_evolution;
- lklass->decode_x_evolution = maildir_summary_decode_x_evolution;
-}
-
-static void
-camel_maildir_summary_init (CamelMaildirSummary *o)
-{
- struct _CamelFolderSummary *s = (CamelFolderSummary *) o;
- char hostname[256];
-
- o->priv = g_malloc0(sizeof(*o->priv));
- /* set unique file version */
- s->version += CAMEL_MAILDIR_SUMMARY_VERSION;
-
- s->message_info_size = sizeof(CamelMaildirMessageInfo);
- s->content_info_size = sizeof(CamelMaildirMessageContentInfo);
-
-#if defined (DOEPOOLV) || defined (DOESTRV)
- s->message_info_strings = CAMEL_MAILDIR_INFO_LAST;
-#endif
-
- if (gethostname(hostname, 256) == 0) {
- o->priv->hostname = g_strdup(hostname);
- } else {
- o->priv->hostname = g_strdup("localhost");
- }
-}
-
-static void
-camel_maildir_summary_finalise(CamelObject *obj)
-{
- CamelMaildirSummary *o = (CamelMaildirSummary *)obj;
-
- g_free(o->priv->hostname);
- g_free(o->priv);
-}
-
-/**
- * camel_maildir_summary_new:
- *
- * Create a new CamelMaildirSummary object.
- *
- * Return value: A new #CamelMaildirSummary object.
- **/
-CamelMaildirSummary *camel_maildir_summary_new (const char *filename, const char *maildirdir, CamelIndex *index)
-{
- CamelMaildirSummary *o = (CamelMaildirSummary *)camel_object_new(camel_maildir_summary_get_type ());
-
- camel_local_summary_construct((CamelLocalSummary *)o, filename, maildirdir, index);
- return o;
-}
-
-/* the 'standard' maildir flags. should be defined in sorted order. */
-static struct {
- char flag;
- guint32 flagbit;
-} flagbits[] = {
- { 'F', CAMEL_MESSAGE_FLAGGED },
- { 'R', CAMEL_MESSAGE_ANSWERED },
- { 'S', CAMEL_MESSAGE_SEEN },
- { 'T', CAMEL_MESSAGE_DELETED },
-};
-
-/* convert the uid + flags into a unique:info maildir format */
-char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info)
-{
- const char *uid;
- char *p, *buf;
- int i;
-
- uid = camel_message_info_uid (info);
- buf = g_alloca (strlen (uid) + strlen (":2,") + (sizeof (flagbits) / sizeof (flagbits[0])) + 1);
- p = buf + sprintf (buf, "%s:2,", uid);
- for (i = 0; i < sizeof (flagbits) / sizeof (flagbits[0]); i++) {
- if (info->flags & flagbits[i].flagbit)
- *p++ = flagbits[i].flag;
- }
- *p = 0;
-
- return g_strdup(buf);
-}
-
-/* returns 0 if the info matches (or there was none), otherwise we changed it */
-int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name)
-{
- char *p, c;
- guint32 set = 0; /* what we set */
- /*guint32 all = 0;*/ /* all flags */
- int i;
-
- p = strstr(name, ":2,");
- if (p) {
- p+=3;
- while ((c = *p++)) {
- /* we could assume that the flags are in order, but its just as easy not to require */
- for (i=0;i<sizeof(flagbits)/sizeof(flagbits[0]);i++) {
- if (flagbits[i].flag == c && (info->flags & flagbits[i].flagbit) == 0) {
- set |= flagbits[i].flagbit;
- }
- /*all |= flagbits[i].flagbit;*/
- }
- }
-
- /* changed? */
- /*if ((info->flags & all) != set) {*/
- if ((info->flags & set) != set) {
- /* ok, they did change, only add the new flags ('merge flags'?) */
- /*info->flags &= all; if we wanted to set only the new flags, which we probably dont */
- info->flags |= set;
- return 1;
- }
- }
-
- return 0;
-}
-
-/* for maildir, x-evolution isn't used, so dont try and get anything out of it */
-static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi)
-{
- return -1;
-}
-
-static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi)
-{
- return NULL;
-}
-
-/* FIXME:
- both 'new' and 'add' will try and set the filename, this is not ideal ...
-*/
-static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelMessageInfo *mi;
-
- mi = ((CamelLocalSummaryClass *) parent_class)->add(cls, msg, info, changes, ex);
- if (mi) {
- if (info) {
- camel_maildir_info_set_filename(mi, camel_maildir_summary_info_to_name(mi));
- d(printf("Setting filename to %s\n", camel_maildir_info_filename(mi)));
- }
- }
-
- return mi;
-}
-
-static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _camel_header_raw *h)
-{
- CamelMessageInfo *mi, *info;
- CamelMaildirSummary *mds = (CamelMaildirSummary *)s;
- CamelMaildirMessageInfo *mdi;
- const char *uid;
-
- mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new(s, h);
- /* assign the uid and new filename */
- if (mi) {
- mdi = (CamelMaildirMessageInfo *)mi;
-
- uid = camel_message_info_uid(mi);
- if (uid==NULL || uid[0] == 0)
- camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s));
-
- /* handle 'duplicates' */
- info = camel_folder_summary_uid(s, uid);
- if (info) {
- d(printf("already seen uid '%s', just summarising instead\n", uid));
- camel_folder_summary_info_free(s, mi);
- mdi = (CamelMaildirMessageInfo *)mi = info;
- }
-
- /* with maildir we know the real received date, from the filename */
- mi->date_received = strtoul(camel_message_info_uid(mi), NULL, 10);
-
- if (mds->priv->current_file) {
-#if 0
- char *p1, *p2, *p3;
- unsigned long uid;
-#endif
- /* if setting from a file, grab the flags from it */
- camel_maildir_info_set_filename(mi, g_strdup(mds->priv->current_file));
- camel_maildir_summary_name_to_info(mi, mds->priv->current_file);
-
-#if 0
- /* Actually, I dont think all this effort is worth it at all ... */
-
- /* also, see if we can extract the next-id from tne name, and safe-if-fy ourselves against collisions */
- /* we check for something.something_number.something */
- p1 = strchr(mdi->filename, '.');
- if (p1) {
- p2 = strchr(p1+1, '.');
- p3 = strchr(p1+1, '_');
- if (p2 && p3 && p3<p2) {
- uid = strtoul(p3+1, &p1, 10);
- if (p1 == p2 && uid>0)
- camel_folder_summary_set_uid(s, uid);
- }
- }
-#endif
- } else {
- /* if creating a file, set its name from the flags we have */
- camel_maildir_info_set_filename(mdi, camel_maildir_summary_info_to_name(mi));
- d(printf("Setting filename to %s\n", camel_maildir_info_filename(mi)));
- }
- }
-
- return mi;
-}
-
-
-static void message_info_free(CamelFolderSummary *s, CamelMessageInfo *mi)
-{
-#if !defined (DOEPOOLV) && !defined (DOESTRV)
- CamelMaildirMessageInfo *mdi = (CamelMaildirMessageInfo *)mi;
-
- g_free(mdi->filename);
-#endif
- ((CamelFolderSummaryClass *) parent_class)->message_info_free(s, mi);
-}
-
-
-static char *maildir_summary_next_uid_string(CamelFolderSummary *s)
-{
- CamelMaildirSummary *mds = (CamelMaildirSummary *)s;
-
- d(printf("next uid string called?\n"));
-
- /* if we have a current file, then use that to get the uid */
- if (mds->priv->current_file) {
- char *cln;
-
- cln = strchr(mds->priv->current_file, ':');
- if (cln)
- return g_strndup(mds->priv->current_file, cln-mds->priv->current_file);
- else
- return g_strdup(mds->priv->current_file);
- } else {
- /* the first would probably work, but just to be safe, check for collisions */
-#if 0
- return g_strdup_printf("%ld.%d_%u.%s", time(0), getpid(), camel_folder_summary_next_uid(s), mds->priv->hostname);
-#else
- CamelLocalSummary *cls = (CamelLocalSummary *)s;
- char *name = NULL, *uid = NULL;
- struct stat st;
- int retry = 0;
- guint32 nextuid = camel_folder_summary_next_uid(s);
-
- /* we use time.pid_count.hostname */
- do {
- if (retry > 0) {
- g_free(name);
- g_free(uid);
- sleep(2);
- }
- uid = g_strdup_printf("%ld.%d_%u.%s", time(0), getpid(), nextuid, mds->priv->hostname);
- name = g_strdup_printf("%s/tmp/%s", cls->folder_path, uid);
- retry++;
- } while (stat(name, &st) == 0 && retry<3);
-
- /* I dont know what we're supposed to do if it fails to find a unique name?? */
-
- g_free(name);
- return uid;
-#endif
- }
-}
-
-static CamelMessageInfo *
-message_info_load(CamelFolderSummary *s, FILE *in)
-{
- CamelMessageInfo *mi;
- CamelMaildirSummary *mds = (CamelMaildirSummary *)s;
-
- mi = ((CamelFolderSummaryClass *) parent_class)->message_info_load(s, in);
- if (mi) {
- char *name;
-
- if (mds->priv->load_map
- && (name = g_hash_table_lookup(mds->priv->load_map, camel_message_info_uid(mi)))) {
- d(printf("Setting filename of %s to %s\n", camel_message_info_uid(mi), name));
- camel_maildir_info_set_filename(mi, g_strdup(name));
- camel_maildir_summary_name_to_info(mi, name);
- }
- }
-
- return mi;
-}
-
-static int maildir_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex)
-{
- char *cur;
- DIR *dir;
- struct dirent *d;
- CamelMaildirSummary *mds = (CamelMaildirSummary *)cls;
- char *uid;
- EMemPool *pool;
- int ret;
-
- cur = g_strdup_printf("%s/cur", cls->folder_path);
-
- d(printf("pre-loading uid <> filename map\n"));
-
- dir = opendir(cur);
- if (dir == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot open maildir directory path: %s: %s"),
- cls->folder_path, g_strerror (errno));
- g_free(cur);
- return -1;
- }
-
- mds->priv->load_map = g_hash_table_new(g_str_hash, g_str_equal);
- pool = e_mempool_new(1024, 512, E_MEMPOOL_ALIGN_BYTE);
-
- while ( (d = readdir(dir)) ) {
- if (d->d_name[0] == '.')
- continue;
-
- /* map the filename -> uid */
- uid = strchr(d->d_name, ':');
- if (uid) {
- int len = uid-d->d_name;
- uid = e_mempool_alloc(pool, len+1);
- memcpy(uid, d->d_name, len);
- uid[len] = 0;
- g_hash_table_insert(mds->priv->load_map, uid, e_mempool_strdup(pool, d->d_name));
- } else {
- uid = e_mempool_strdup(pool, d->d_name);
- g_hash_table_insert(mds->priv->load_map, uid, uid);
- }
- }
- closedir(dir);
- g_free(cur);
-
- ret = ((CamelLocalSummaryClass *) parent_class)->load(cls, forceindex, ex);
-
- g_hash_table_destroy(mds->priv->load_map);
- mds->priv->load_map = NULL;
- e_mempool_destroy(pool);
-
- return ret;
-}
-
-static int camel_maildir_summary_add(CamelLocalSummary *cls, const char *name, int forceindex)
-{
- CamelMaildirSummary *maildirs = (CamelMaildirSummary *)cls;
- char *filename = g_strdup_printf("%s/cur/%s", cls->folder_path, name);
- int fd;
- CamelMimeParser *mp;
-
- d(printf("summarising: %s\n", name));
-
- fd = open(filename, O_RDONLY);
- if (fd == -1) {
- g_warning ("Cannot summarise/index: %s: %s", filename, strerror (errno));
- g_free(filename);
- return -1;
- }
- mp = camel_mime_parser_new();
- camel_mime_parser_scan_from(mp, FALSE);
- camel_mime_parser_init_with_fd(mp, fd);
- if (cls->index && (forceindex || !camel_index_has_name(cls->index, name))) {
- d(printf("forcing indexing of message content\n"));
- camel_folder_summary_set_index((CamelFolderSummary *)maildirs, cls->index);
- } else {
- camel_folder_summary_set_index((CamelFolderSummary *)maildirs, NULL);
- }
- maildirs->priv->current_file = (char *)name;
- camel_folder_summary_add_from_parser((CamelFolderSummary *)maildirs, mp);
- camel_object_unref((CamelObject *)mp);
- maildirs->priv->current_file = NULL;
- camel_folder_summary_set_index((CamelFolderSummary *)maildirs, NULL);
- g_free(filename);
- return 0;
-}
-
-struct _remove_data {
- CamelLocalSummary *cls;
- CamelFolderChangeInfo *changes;
-};
-
-static void
-remove_summary(char *key, CamelMessageInfo *info, struct _remove_data *rd)
-{
- d(printf("removing message %s from summary\n", key));
- if (rd->cls->index)
- camel_index_delete_name(rd->cls->index, camel_message_info_uid(info));
- if (rd->changes)
- camel_folder_change_info_remove_uid(rd->changes, key);
- camel_folder_summary_remove((CamelFolderSummary *)rd->cls, info);
- camel_folder_summary_info_free((CamelFolderSummary *)rd->cls, info);
-}
-
-static int
-sort_receive_cmp(const void *ap, const void *bp)
-{
- const CamelMessageInfo
- *a = *((CamelMessageInfo **)ap),
- *b = *((CamelMessageInfo **)bp);
-
- if (a->date_received < b->date_received)
- return -1;
- else if (a->date_received > b->date_received)
- return 1;
-
- return 0;
-}
-
-static int
-maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- DIR *dir;
- struct dirent *d;
- char *p;
- CamelMessageInfo *info;
- CamelMaildirMessageInfo *mdi;
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
- GHashTable *left;
- int i, count, total;
- int forceindex;
- char *new, *cur;
- char *uid;
- struct _remove_data rd = { cls, changes };
-
- new = g_strdup_printf("%s/new", cls->folder_path);
- cur = g_strdup_printf("%s/cur", cls->folder_path);
-
- d(printf("checking summary ...\n"));
-
- camel_operation_start(NULL, _("Checking folder consistency"));
-
- /* scan the directory, check for mail files not in the index, or index entries that
- no longer exist */
- dir = opendir(cur);
- if (dir == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot open maildir directory path: %s: %s"),
- cls->folder_path, g_strerror (errno));
- g_free(cur);
- g_free(new);
- camel_operation_end(NULL);
- return -1;
- }
-
- /* keeps track of all uid's that have not been processed */
- left = g_hash_table_new(g_str_hash, g_str_equal);
- count = camel_folder_summary_count((CamelFolderSummary *)cls);
- forceindex = count == 0;
- for (i=0;i<count;i++) {
- info = camel_folder_summary_index((CamelFolderSummary *)cls, i);
- if (info) {
- g_hash_table_insert(left, (char *)camel_message_info_uid(info), info);
- }
- }
-
- /* joy, use this to pre-count the total, so we can report progress meaningfully */
- total = 0;
- count = 0;
- while ( (d = readdir(dir)) )
- total++;
- rewinddir(dir);
-
- while ( (d = readdir(dir)) ) {
- int pc = count * 100 / total;
-
- camel_operation_progress(NULL, pc);
- count++;
-
- /* FIXME: also run stat to check for regular file */
- p = d->d_name;
- if (p[0] == '.')
- continue;
-
- /* map the filename -> uid */
- uid = strchr(d->d_name, ':');
- if (uid)
- uid = g_strndup(d->d_name, uid-d->d_name);
- else
- uid = g_strdup(d->d_name);
-
- info = g_hash_table_lookup(left, uid);
- if (info) {
- camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
- g_hash_table_remove(left, uid);
- }
-
- info = camel_folder_summary_uid((CamelFolderSummary *)cls, uid);
- if (info == NULL) {
- /* must be a message incorporated by another client, this is not a 'recent' uid */
- if (camel_maildir_summary_add(cls, d->d_name, forceindex) == 0)
- if (changes)
- camel_folder_change_info_add_uid(changes, uid);
- } else {
- const char *filename;
-
- if (cls->index && (!camel_index_has_name(cls->index, uid))) {
- /* message_info_new will handle duplicates */
- camel_maildir_summary_add(cls, d->d_name, forceindex);
- }
-
- mdi = (CamelMaildirMessageInfo *)info;
- filename = camel_maildir_info_filename(mdi);
- /* TODO: only store the extension in the mdi->filename struct, not the whole lot */
- if (filename == NULL || strcmp(filename, d->d_name) != 0) {
-#ifdef DOESTRV
-#warning "cannot modify the estrv after its been setup, for mt-safe code"
- CAMEL_SUMMARY_LOCK(s, summary_lock);
- /* need to update the summary hash ref */
- g_hash_table_remove(s->messages_uid, camel_message_info_uid(info));
- info->strings = e_strv_set_ref(info->strings, CAMEL_MAILDIR_INFO_FILENAME, d->d_name);
- info->strings = e_strv_pack(info->strings);
- g_hash_table_insert(s->messages_uid, (char *)camel_message_info_uid(info), info);
- CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-#else
-# ifdef DOEPOOLV
- info->strings = e_poolv_set(info->strings, CAMEL_MAILDIR_INFO_FILENAME, d->d_name, FALSE);
-# else
- g_free(mdi->filename);
- mdi->filename = g_strdup(d->d_name);
-# endif
-#endif
- }
- camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
- }
- g_free(uid);
- }
- closedir(dir);
- g_hash_table_foreach(left, (GHFunc)remove_summary, &rd);
- g_hash_table_destroy(left);
-
- camel_operation_end(NULL);
-
- camel_operation_start(NULL, _("Checking for new messages"));
-
- /* now, scan new for new messages, and copy them to cur, and so forth */
- dir = opendir(new);
- if (dir != NULL) {
- total = 0;
- count = 0;
- while ( (d = readdir(dir)) )
- total++;
- rewinddir(dir);
-
- while ( (d = readdir(dir)) ) {
- char *name, *newname, *destname, *destfilename;
- char *src, *dest;
- int pc = count * 100 / total;
-
- camel_operation_progress(NULL, pc);
- count++;
-
- name = d->d_name;
- if (name[0] == '.')
- continue;
-
- /* already in summary? shouldn't happen, but just incase ... */
- if ((info = camel_folder_summary_uid((CamelFolderSummary *)cls, name))) {
- camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
- newname = destname = camel_folder_summary_next_uid_string(s);
- } else {
- newname = NULL;
- destname = name;
- }
-
- /* copy this to the destination folder, use 'standard' semantics for maildir info field */
- src = g_strdup_printf("%s/%s", new, name);
- destfilename = g_strdup_printf("%s:2,", destname);
- dest = g_strdup_printf("%s/%s", cur, destfilename);
-
- /* FIXME: This should probably use link/unlink */
-
- if (rename(src, dest) == 0) {
- camel_maildir_summary_add(cls, destfilename, forceindex);
- if (changes) {
- camel_folder_change_info_add_uid(changes, destname);
- camel_folder_change_info_recent_uid(changes, destname);
- }
- } else {
- /* else? we should probably care about failures, but wont */
- g_warning("Failed to move new maildir message %s to cur %s", src, dest);
- }
-
- /* c strings are painful to work with ... */
- g_free(destfilename);
- g_free(newname);
- g_free(src);
- g_free(dest);
- }
- camel_operation_end(NULL);
- }
- closedir(dir);
-
- g_free(new);
- g_free(cur);
-
- /* sort the summary based on receive time, since the directory order is not useful */
- CAMEL_SUMMARY_LOCK(s, summary_lock);
- qsort(s->messages->pdata, s->messages->len, sizeof(CamelMessageInfo *), sort_receive_cmp);
- CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-
- return 0;
-}
-
-/* sync the summary with the ondisk files. */
-static int
-maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- int count, i;
- CamelMessageInfo *info;
- CamelMaildirMessageInfo *mdi;
-#ifdef DOESTRV
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
-#endif
- char *name;
- struct stat st;
-
- d(printf("summary_sync(expunge=%s)\n", expunge?"true":"false"));
-
- if (camel_local_summary_check(cls, changes, ex) == -1)
- return -1;
-
- camel_operation_start(NULL, _("Storing folder"));
-
- count = camel_folder_summary_count((CamelFolderSummary *)cls);
- for (i=count-1;i>=0;i--) {
- camel_operation_progress(NULL, (count-i)*100/count);
-
- info = camel_folder_summary_index((CamelFolderSummary *)cls, i);
- mdi = (CamelMaildirMessageInfo *)info;
- if (info && (info->flags & CAMEL_MESSAGE_DELETED) && expunge) {
- name = g_strdup_printf("%s/cur/%s", cls->folder_path, camel_maildir_info_filename(mdi));
- d(printf("deleting %s\n", name));
- if (unlink(name) == 0 || errno==ENOENT) {
-
- /* FIXME: put this in folder_summary::remove()? */
- if (cls->index)
- camel_index_delete_name(cls->index, camel_message_info_uid(info));
-
- camel_folder_change_info_remove_uid(changes, camel_message_info_uid(info));
- camel_folder_summary_remove((CamelFolderSummary *)cls, info);
- }
- g_free(name);
- } else if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- char *newname = camel_maildir_summary_info_to_name(info);
- char *dest;
-
- /* do we care about additional metainfo stored inside the message? */
- /* probably should all go in the filename? */
-
- /* have our flags/ i.e. name changed? */
- if (strcmp(newname, camel_maildir_info_filename(mdi))) {
- name = g_strdup_printf("%s/cur/%s", cls->folder_path, camel_maildir_info_filename(mdi));
- dest = g_strdup_printf("%s/cur/%s", cls->folder_path, newname);
- rename(name, dest);
- if (stat(dest, &st) == -1) {
- /* we'll assume it didn't work, but dont change anything else */
- g_free(newname);
- } else {
- /* TODO: If this is made mt-safe, then this code could be a problem, since
- the estrv is being modified.
- Sigh, this may mean the maildir name has to be cached another way */
-#ifdef DOESTRV
-#warning "cannot modify the estrv after its been setup, for mt-safe code"
- CAMEL_SUMMARY_LOCK(s, summary_lock);
- /* need to update the summary hash ref */
- g_hash_table_remove(s->messages_uid, camel_message_info_uid(info));
- info->strings = e_strv_set_ref_free(info->strings, CAMEL_MAILDIR_INFO_FILENAME, newname);
- info->strings = e_strv_pack(info->strings);
- g_hash_table_insert(s->messages_uid, (char *)camel_message_info_uid(info), info);
- CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-#else
-# ifdef DOEPOOLV
- info->strings = e_poolv_set(info->strings, CAMEL_MAILDIR_INFO_FILENAME, newname, TRUE);
-# else
- g_free(mdi->filename);
- mdi->filename = newname;
-# endif
-#endif
- }
- g_free(name);
- g_free(dest);
- } else {
- g_free(newname);
- }
-
- /* strip FOLDER_MESSAGE_FLAGED, etc */
- info->flags &= 0xffff;
- }
- camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
- }
-
- camel_operation_end(NULL);
-
- return ((CamelLocalSummaryClass *)parent_class)->sync(cls, expunge, changes, ex);
-}
-
diff --git a/camel/providers/local/camel-maildir-summary.h b/camel/providers/local/camel-maildir-summary.h
deleted file mode 100644
index 0cae785c6c..0000000000
--- a/camel/providers/local/camel-maildir-summary.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Not Zed <notzed@lostzed.mmc.com.au>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_MAILDIR_SUMMARY_H
-#define _CAMEL_MAILDIR_SUMMARY_H
-
-#include "camel-local-summary.h"
-#include <camel/camel-folder.h>
-#include <camel/camel-exception.h>
-#include <camel/camel-index.h>
-
-#define CAMEL_MAILDIR_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_maildir_summary_get_type (), CamelMaildirSummary)
-#define CAMEL_MAILDIR_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_maildir_summary_get_type (), CamelMaildirSummaryClass)
-#define CAMEL_IS_MAILDIR_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_maildir_summary_get_type ())
-
-typedef struct _CamelMaildirSummary CamelMaildirSummary;
-typedef struct _CamelMaildirSummaryClass CamelMaildirSummaryClass;
-
-typedef struct _CamelMaildirMessageContentInfo {
- CamelMessageContentInfo info;
-} CamelMaildirMessageContentInfo;
-
-#if defined (DOEPOOLV) || defined (DOESTRV)
-enum {
- CAMEL_MAILDIR_INFO_FILENAME = CAMEL_MESSAGE_INFO_LAST,
- CAMEL_MAILDIR_INFO_LAST,
-};
-#endif
-
-typedef struct _CamelMaildirMessageInfo {
- CamelMessageInfo info;
-
-#if !defined (DOEPOOLV) && !defined (DOESTRV)
- char *filename; /* maildir has this annoying status shit on the end of the filename, use this to get the real message id */
-#endif
-} CamelMaildirMessageInfo;
-
-struct _CamelMaildirSummary {
- CamelLocalSummary parent;
- struct _CamelMaildirSummaryPrivate *priv;
-};
-
-struct _CamelMaildirSummaryClass {
- CamelLocalSummaryClass parent_class;
-
- /* virtual methods */
-
- /* signals */
-};
-
-CamelType camel_maildir_summary_get_type (void);
-CamelMaildirSummary *camel_maildir_summary_new (const char *filename, const char *maildirdir, CamelIndex *index);
-
-/* convert some info->flags to/from the messageinfo */
-char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info);
-int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name);
-
-#if defined (DOEPOOLV) || defined (DOESTRV)
-#define camel_maildir_info_filename(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MAILDIR_INFO_FILENAME)
-#define camel_maildir_info_set_filename(x, s) camel_message_info_set_string((CamelMessageInfo *)(x), CAMEL_MAILDIR_INFO_FILENAME, s)
-#else
-#define camel_maildir_info_filename(x) (((CamelMaildirMessageInfo *)x)->filename)
-#define camel_maildir_info_set_filename(x, s) (g_free(((CamelMaildirMessageInfo *)x)->filename),((CamelMaildirMessageInfo *)x)->filename = s)
-#endif
-
-#endif /* ! _CAMEL_MAILDIR_SUMMARY_H */
-
diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c
deleted file mode 100644
index 9c3a7036f2..0000000000
--- a/camel/providers/local/camel-mbox-folder.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999, 2003 Ximian Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include "camel-mbox-folder.h"
-#include "camel-mbox-store.h"
-#include "camel-stream-fs.h"
-#include "camel-mbox-summary.h"
-#include "camel-data-wrapper.h"
-#include "camel-mime-message.h"
-#include "camel-stream-filter.h"
-#include "camel-mime-filter-from.h"
-#include "camel-exception.h"
-
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-static CamelLocalFolderClass *parent_class = NULL;
-
-/* Returns the class for a CamelMboxFolder */
-#define CMBOXF_CLASS(so) CAMEL_MBOX_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CMBOXS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-char *camel_mbox_folder_get_full_path (const char *toplevel_dir, const char *full_name);
-char *camel_mbox_folder_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext);
-
-static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex);
-static void mbox_unlock(CamelLocalFolder *lf);
-
-#ifdef STATUS_PINE
-static void mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
-#endif
-
-static void mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value);
-static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
-
-static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, char **appended_uid, CamelException *ex);
-static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex);
-static CamelLocalSummary *mbox_create_summary(const char *path, const char *folder, CamelIndex *index);
-
-static void mbox_finalise(CamelObject * object);
-
-static void
-camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_mbox_folder_class);
- CamelLocalFolderClass *lclass = (CamelLocalFolderClass *)camel_mbox_folder_class;
-
- parent_class = (CamelLocalFolderClass *)camel_type_get_global_classfuncs(camel_local_folder_get_type());
-
- /* virtual method definition */
-
- /* virtual method overload */
- camel_folder_class->append_message = mbox_append_message;
- camel_folder_class->get_message = mbox_get_message;
-
-#ifdef STATUS_PINE
- camel_folder_class->set_message_flags = mbox_set_message_flags;
-#endif
- camel_folder_class->set_message_user_flag = mbox_set_message_user_flag;
- camel_folder_class->set_message_user_tag = mbox_set_message_user_tag;
-
- lclass->get_full_path = camel_mbox_folder_get_full_path;
- lclass->get_meta_path = camel_mbox_folder_get_meta_path;
- lclass->create_summary = mbox_create_summary;
- lclass->lock = mbox_lock;
- lclass->unlock = mbox_unlock;
-}
-
-static void
-mbox_init(gpointer object, gpointer klass)
-{
- /*CamelFolder *folder = object;*/
- CamelMboxFolder *mbox_folder = object;
-
- mbox_folder->lockfd = -1;
-}
-
-static void
-mbox_finalise(CamelObject * object)
-{
- CamelMboxFolder *mbox_folder = (CamelMboxFolder *)object;
-
- g_assert(mbox_folder->lockfd == -1);
-}
-
-CamelType camel_mbox_folder_get_type(void)
-{
- static CamelType camel_mbox_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_mbox_folder_type == CAMEL_INVALID_TYPE) {
- camel_mbox_folder_type = camel_type_register(CAMEL_LOCAL_FOLDER_TYPE, "CamelMboxFolder",
- sizeof(CamelMboxFolder),
- sizeof(CamelMboxFolderClass),
- (CamelObjectClassInitFunc) camel_mbox_folder_class_init,
- NULL,
- (CamelObjectInitFunc) mbox_init,
- (CamelObjectFinalizeFunc) mbox_finalise);
- }
-
- return camel_mbox_folder_type;
-}
-
-CamelFolder *
-camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex)
-{
- CamelFolder *folder;
-
- d(printf("Creating mbox folder: %s in %s\n", full_name, camel_local_store_get_toplevel_dir((CamelLocalStore *)parent_store)));
-
- folder = (CamelFolder *)camel_object_new(CAMEL_MBOX_FOLDER_TYPE);
- folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder,
- parent_store, full_name, flags, ex);
-
- return folder;
-}
-
-char *
-camel_mbox_folder_get_full_path (const char *toplevel_dir, const char *full_name)
-{
- const char *inptr = full_name;
- int subdirs = 0;
- char *path, *p;
-
- while (*inptr != '\0') {
- if (*inptr == '/')
- subdirs++;
- inptr++;
- }
-
- path = g_malloc (strlen (toplevel_dir) + (inptr - full_name) + (4 * subdirs) + 1);
- p = g_stpcpy (path, toplevel_dir);
-
- inptr = full_name;
- while (*inptr != '\0') {
- while (*inptr != '/' && *inptr != '\0')
- *p++ = *inptr++;
-
- if (*inptr == '/') {
- p = g_stpcpy (p, ".sbd/");
- inptr++;
-
- /* strip extranaeous '/'s */
- while (*inptr == '/')
- inptr++;
- }
- }
-
- *p = '\0';
-
- return path;
-}
-
-char *
-camel_mbox_folder_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext)
-{
-/*#define USE_HIDDEN_META_FILES*/
-#ifdef USE_HIDDEN_META_FILES
- char *name, *slash;
-
- name = g_alloca (strlen (full_name) + strlen (ext) + 2);
- if ((slash = strrchr (full_name, '/')))
- sprintf (name, "%.*s.%s%s", slash - full_name + 1, full_name, slash + 1, ext);
- else
- sprintf (name, ".%s%s", full_name, ext);
-
- return camel_mbox_folder_get_full_path (toplevel_dir, name);
-#else
- char *full_path, *path;
-
- full_path = camel_mbox_folder_get_full_path (toplevel_dir, full_name);
- path = g_strdup_printf ("%s%s", full_path, ext);
- g_free (full_path);
-
- return path;
-#endif
-}
-
-static CamelLocalSummary *mbox_create_summary(const char *path, const char *folder, CamelIndex *index)
-{
- return (CamelLocalSummary *)camel_mbox_summary_new(path, folder, index);
-}
-
-static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex)
-{
- CamelMboxFolder *mf = (CamelMboxFolder *)lf;
-
- /* make sure we have matching unlocks for locks, camel-local-folder class should enforce this */
- g_assert(mf->lockfd == -1);
-
- mf->lockfd = open(lf->folder_path, O_RDWR, 0);
- if (mf->lockfd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder lock on %s: %s"),
- lf->folder_path, g_strerror (errno));
- return -1;
- }
-
- if (camel_lock_folder(lf->folder_path, mf->lockfd, type, ex) == -1) {
- close(mf->lockfd);
- mf->lockfd = -1;
- return -1;
- }
-
- return 0;
-}
-
-static void mbox_unlock(CamelLocalFolder *lf)
-{
- CamelMboxFolder *mf = (CamelMboxFolder *)lf;
-
- g_assert(mf->lockfd != -1);
- camel_unlock_folder(lf->folder_path, mf->lockfd);
- close(mf->lockfd);
- mf->lockfd = -1;
-}
-
-static void
-mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, char **appended_uid, CamelException *ex)
-{
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- CamelStream *output_stream = NULL, *filter_stream = NULL;
- CamelMimeFilter *filter_from = NULL;
- CamelMboxSummary *mbs = (CamelMboxSummary *)folder->summary;
- CamelMessageInfo *mi;
- char *fromline = NULL;
- int fd, retval;
- struct stat st;
-#if 0
- char *xev;
-#endif
- /* If we can't lock, dont do anything */
- if (camel_local_folder_lock(lf, CAMEL_LOCK_WRITE, ex) == -1)
- return;
-
- d(printf("Appending message\n"));
-
- /* first, check the summary is correct (updates folder_size too) */
- retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, ex);
- if (retval == -1)
- goto fail;
-
- /* add it to the summary/assign the uid, etc */
- mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex);
- if (mi == NULL)
- goto fail;
-
- d(printf("Appending message: uid is %s\n", camel_message_info_uid(mi)));
-
- output_stream = camel_stream_fs_new_with_name(lf->folder_path, O_WRONLY|O_APPEND, 0600);
- if (output_stream == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot open mailbox: %s: %s\n"),
- lf->folder_path, g_strerror (errno));
- goto fail;
- }
-
- /* and we need to set the frompos/XEV explicitly */
- ((CamelMboxMessageInfo *)mi)->frompos = mbs->folder_size;
-#if 0
- xev = camel_local_summary_encode_x_evolution((CamelLocalSummary *)folder->summary, mi);
- if (xev) {
- /* the x-ev header should match the 'current' flags, no problem, so store as much */
- camel_medium_set_header((CamelMedium *)message, "X-Evolution", xev);
- mi->flags &= ~ CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED;
- g_free(xev);
- }
-#endif
-
- /* we must write this to the non-filtered stream ... */
- fromline = camel_mime_message_build_mbox_from(message);
- if (camel_stream_write(output_stream, fromline, strlen(fromline)) == -1)
- goto fail_write;
-
- /* and write the content to the filtering stream, that translates '\nFrom' into '\n>From' */
- filter_stream = (CamelStream *) camel_stream_filter_new_with_stream(output_stream);
- filter_from = (CamelMimeFilter *) camel_mime_filter_from_new();
- camel_stream_filter_add((CamelStreamFilter *) filter_stream, filter_from);
- if (camel_data_wrapper_write_to_stream((CamelDataWrapper *)message, filter_stream) == -1
- || camel_stream_write(filter_stream, "\n", 1) == -1
- || camel_stream_close(filter_stream) == -1)
- goto fail_write;
-
- /* filter stream ref's the output stream itself, so we need to unref it too */
- camel_object_unref((CamelObject *)filter_from);
- camel_object_unref((CamelObject *)filter_stream);
- camel_object_unref((CamelObject *)output_stream);
- g_free(fromline);
-
- /* now we 'fudge' the summary to tell it its uptodate, because its idea of uptodate has just changed */
- /* the stat really shouldn't fail, we just wrote to it */
- if (stat(lf->folder_path, &st) == 0) {
- mbs->folder_size = st.st_size;
- ((CamelFolderSummary *)mbs)->time = st.st_mtime;
- }
-
- /* unlock as soon as we can */
- camel_local_folder_unlock(lf);
-
- if (camel_folder_change_info_changed(lf->changes)) {
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes);
- camel_folder_change_info_clear(lf->changes);
- }
-
- if (appended_uid)
- *appended_uid = g_strdup(camel_message_info_uid(mi));
-
- return;
-
-fail_write:
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Mail append cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to mbox file: %s: %s"),
- lf->folder_path, g_strerror (errno));
-
- if (filter_stream)
- camel_object_unref(CAMEL_OBJECT(filter_stream));
-
- if (output_stream)
- camel_object_unref(CAMEL_OBJECT(output_stream));
-
- if (filter_from)
- camel_object_unref(CAMEL_OBJECT(filter_from));
-
- g_free(fromline);
-
- /* reset the file to original size */
- fd = open(lf->folder_path, O_WRONLY, 0600);
- if (fd != -1) {
- ftruncate(fd, mbs->folder_size);
- close(fd);
- }
-
- /* remove the summary info so we are not out-of-sync with the mbox */
- camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (mbs), camel_message_info_uid (mi));
-
- /* and tell the summary its uptodate */
- if (stat(lf->folder_path, &st) == 0) {
- mbs->folder_size = st.st_size;
- ((CamelFolderSummary *)mbs)->time = st.st_mtime;
- }
-
-fail:
- /* make sure we unlock the folder - before we start triggering events into appland */
- camel_local_folder_unlock(lf);
-
- /* cascade the changes through, anyway, if there are any outstanding */
- if (camel_folder_change_info_changed(lf->changes)) {
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes);
- camel_folder_change_info_clear(lf->changes);
- }
-}
-
-static CamelMimeMessage *
-mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex)
-{
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- CamelMimeMessage *message = NULL;
- CamelMboxMessageInfo *info;
- CamelMimeParser *parser = NULL;
- int fd, retval;
- int retried = FALSE;
- off_t frompos;
-
- d(printf("Getting message %s\n", uid));
-
- /* lock the folder first, burn if we can't, need write lock for summary check */
- if (camel_local_folder_lock(lf, CAMEL_LOCK_WRITE, ex) == -1)
- return NULL;
-
- /* check for new messages always */
- if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) {
- camel_local_folder_unlock(lf);
- return NULL;
- }
-
-retry:
- /* get the message summary info */
- info = (CamelMboxMessageInfo *) camel_folder_summary_uid(folder->summary, uid);
-
- if (info == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s\n %s"), uid, _("No such message"));
- goto fail;
- }
-
- /* no frompos, its an error in the library (and we can't do anything with it) */
- g_assert(info->frompos != -1);
-
- frompos = info->frompos;
- camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info);
-
- /* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache
- the whole message in memory if the stream is non-seekable (which it is when built from a parser
- with no stream). This means we dont have to lock the mbox for the life of the message, but only
- while it is being created. */
-
- fd = open(lf->folder_path, O_RDONLY);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s from folder %s\n %s"),
- uid, lf->folder_path, g_strerror (errno));
- goto fail;
- }
-
- /* we use a parser to verify the message is correct, and in the correct position */
- parser = camel_mime_parser_new();
- camel_mime_parser_init_with_fd(parser, fd);
- camel_mime_parser_scan_from(parser, TRUE);
-
- camel_mime_parser_seek(parser, frompos, SEEK_SET);
- if (camel_mime_parser_step(parser, NULL, NULL) != CAMEL_MIME_PARSER_STATE_FROM
- || camel_mime_parser_tell_start_from(parser) != frompos) {
-
- g_warning("Summary doesn't match the folder contents! eek!\n"
- " expecting offset %ld got %ld, state = %d", (long int)frompos,
- (long int)camel_mime_parser_tell_start_from(parser),
- camel_mime_parser_state(parser));
-
- camel_object_unref((CamelObject *)parser);
- parser = NULL;
-
- if (!retried) {
- retried = TRUE;
- camel_local_summary_check_force((CamelLocalSummary *)folder->summary);
- retval = camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex);
- if (retval != -1)
- goto retry;
- }
-
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s from folder %s\n %s"), uid, lf->folder_path,
- _("The folder appears to be irrecoverably corrupted."));
- goto fail;
- }
-
- message = camel_mime_message_new();
- if (camel_mime_part_construct_from_parser((CamelMimePart *)message, parser) == -1) {
- camel_exception_setv(ex, errno==EINTR?CAMEL_EXCEPTION_USER_CANCEL:CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s from folder %s\n %s"), uid, lf->folder_path,
- _("Message construction failed: Corrupt mailbox?"));
- camel_object_unref((CamelObject *)message);
- message = NULL;
- goto fail;
- }
-
- camel_medium_remove_header((CamelMedium *)message, "X-Evolution");
-fail:
- /* and unlock now we're finished with it */
- camel_local_folder_unlock(lf);
-
- if (parser)
- camel_object_unref((CamelObject *)parser);
-
- /* use the opportunity to notify of changes (particularly if we had a rebuild) */
- if (camel_folder_change_info_changed(lf->changes)) {
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes);
- camel_folder_change_info_clear(lf->changes);
- }
-
- return message;
-}
-
-#ifdef STATUS_PINE
-static void
-mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
-{
- /* Basically, if anything could change the Status line, presume it does */
- if (((CamelMboxSummary *)folder->summary)->xstatus
- && (flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED))) {
- flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
- set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
- }
-
- ((CamelFolderClass *)parent_class)->set_message_flags(folder, uid, flags, set);
-}
-#endif
-
-static void
-mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value)
-{
- CamelMessageInfo *info;
-
- g_return_if_fail(folder->summary != NULL);
-
- info = camel_folder_summary_uid(folder->summary, uid);
- if (info == NULL)
- return;
-
- if (camel_flag_set(&info->user_flags, name, value)) {
- info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
- camel_folder_summary_touch(folder->summary);
- camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid);
- }
- camel_folder_summary_info_free(folder->summary, info);
-}
-
-static void
-mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value)
-{
- CamelMessageInfo *info;
-
- g_return_if_fail(folder->summary != NULL);
-
- info = camel_folder_summary_uid(folder->summary, uid);
- if (info == NULL)
- return;
-
- if (camel_tag_set(&info->user_tags, name, value)) {
- info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
- camel_folder_summary_touch(folder->summary);
- camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid);
- }
- camel_folder_summary_info_free(folder->summary, info);
-}
diff --git a/camel/providers/local/camel-mbox-folder.h b/camel/providers/local/camel-mbox-folder.h
deleted file mode 100644
index aa0b67201f..0000000000
--- a/camel/providers/local/camel-mbox-folder.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999 Ximian .
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_MBOX_FOLDER_H
-#define CAMEL_MBOX_FOLDER_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-local-folder.h"
-#include "camel-mbox-summary.h"
-
-#define CAMEL_MBOX_FOLDER_TYPE (camel_mbox_folder_get_type ())
-#define CAMEL_MBOX_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MBOX_FOLDER_TYPE, CamelMboxFolder))
-#define CAMEL_MBOX_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MBOX_FOLDER_TYPE, CamelMboxFolderClass))
-#define CAMEL_IS_MBOX_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_MBOX_FOLDER_TYPE))
-
-typedef struct {
- CamelLocalFolder parent_object;
-
- int lockfd; /* for when we have a lock on the folder */
-} CamelMboxFolder;
-
-typedef struct {
- CamelLocalFolderClass parent_class;
-
- /* Virtual methods */
-
-} CamelMboxFolderClass;
-
-/* public methods */
-/* flags are taken from CAMEL_STORE_FOLDER_* flags */
-CamelFolder *camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex);
-
-/* Standard Camel function */
-CamelType camel_mbox_folder_get_type(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_MBOX_FOLDER_H */
diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c
deleted file mode 100644
index ffce19171f..0000000000
--- a/camel/providers/local/camel-mbox-store.c
+++ /dev/null
@@ -1,753 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "camel-mbox-store.h"
-#include "camel-mbox-folder.h"
-#include "camel-file-utils.h"
-#include "camel-text-index.h"
-#include "camel-exception.h"
-#include "camel-url.h"
-
-#define d(x)
-
-static CamelLocalStoreClass *parent_class = NULL;
-
-/* Returns the class for a CamelMboxStore */
-#define CMBOXS_CLASS(so) CAMEL_MBOX_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CMBOXF_CLASS(so) CAMEL_MBOX_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-extern char *camel_mbox_folder_get_full_path (const char *toplevel_dir, const char *full_name);
-extern char *camel_mbox_folder_get_meta_path (const char *toplevel_dir, const char *full_name, const char *ext);
-
-static CamelFolder *get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
-static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex);
-static void rename_folder (CamelStore *store, const char *old, const char *new, CamelException *ex);
-static CamelFolderInfo *create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex);
-static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
-
-static void
-camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class)
-{
- CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_mbox_store_class);
-
- parent_class = (CamelLocalStoreClass *)camel_type_get_global_classfuncs(camel_local_store_get_type());
-
- /* virtual method overload */
- camel_store_class->get_folder = get_folder;
- camel_store_class->delete_folder = delete_folder;
- camel_store_class->rename_folder = rename_folder;
- camel_store_class->create_folder = create_folder;
-
- camel_store_class->get_folder_info = get_folder_info;
- camel_store_class->free_folder_info = camel_store_free_folder_info_full;
-}
-
-CamelType
-camel_mbox_store_get_type (void)
-{
- static CamelType camel_mbox_store_type = CAMEL_INVALID_TYPE;
-
- if (camel_mbox_store_type == CAMEL_INVALID_TYPE) {
- camel_mbox_store_type = camel_type_register (CAMEL_LOCAL_STORE_TYPE, "CamelMboxStore",
- sizeof (CamelMboxStore),
- sizeof (CamelMboxStoreClass),
- (CamelObjectClassInitFunc) camel_mbox_store_class_init,
- NULL,
- NULL,
- NULL);
- }
-
- return camel_mbox_store_type;
-}
-
-static char *
-mbox_folder_name_to_path (CamelStore *store, const char *folder_name)
-{
- const char *toplevel_dir = CAMEL_LOCAL_STORE (store)->toplevel_dir;
-
- return camel_mbox_folder_get_full_path (toplevel_dir, folder_name);
-}
-
-static char *
-mbox_folder_name_to_meta_path (CamelStore *store, const char *folder_name, const char *ext)
-{
- const char *toplevel_dir = CAMEL_LOCAL_STORE (store)->toplevel_dir;
-
- return camel_mbox_folder_get_meta_path (toplevel_dir, folder_name, ext);
-}
-
-static char *extensions[] = {
- ".msf", ".ev-summary", ".ibex.index", ".ibex.index.data", ".cmeta"
-};
-
-static gboolean
-ignore_file (const char *filename, gboolean sbd)
-{
- int flen, len, i;
-
- flen = strlen (filename);
- for (i = 0; i < (sizeof (extensions) / sizeof (extensions[0])); i++) {
- len = strlen (extensions[i]);
- if (len < flen && !strcmp (filename + flen - len, extensions[i]))
- return TRUE;
- }
-
- if (sbd && flen > 4 && !strcmp (filename + flen - 4, ".sbd"))
- return TRUE;
-
- return FALSE;
-}
-
-static CamelFolder *
-get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
-{
- struct stat st;
- char *name;
-
- if (!((CamelStoreClass *) parent_class)->get_folder (store, folder_name, flags, ex))
- return NULL;
-
- name = mbox_folder_name_to_path (store, folder_name);
-
- if (stat (name, &st) == -1) {
- char *dirname;
- int fd;
-
- if (errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open file `%s':\n%s"),
- name, g_strerror (errno));
- g_free (name);
- return NULL;
- }
-
- if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Folder `%s' does not exist."),
- folder_name);
- g_free (name);
- return NULL;
- }
-
- dirname = g_path_get_dirname (name);
- if (camel_mkdir (dirname, 0777) == -1 && errno != EEXIST) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Could not create directory `%s':\n%s"),
- dirname, g_strerror (errno));
- g_free (dirname);
- g_free (name);
- return NULL;
- }
-
- g_free (dirname);
-
- fd = open (name, O_WRONLY | O_CREAT | O_APPEND, 0666);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create file `%s':\n%s"),
- name, g_strerror (errno));
- g_free (name);
- return NULL;
- }
-
- g_free (name);
- close (fd);
- } else if (!S_ISREG (st.st_mode)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("`%s' is not a regular file."),
- name);
- g_free (name);
- return NULL;
- } else
- g_free (name);
-
- return camel_mbox_folder_new (store, folder_name, flags, ex);
-}
-
-static void
-delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelFolderInfo *fi;
- CamelException lex;
- CamelFolder *lf;
- char *name, *path;
- struct stat st;
-
- name = mbox_folder_name_to_path (store, folder_name);
- path = g_strdup_printf ("%s.sbd", name);
-
- if (rmdir (path) == -1 && errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder `%s':\n%s"),
- folder_name, g_strerror (errno));
- g_free (path);
- g_free (name);
- return;
- }
-
- g_free (path);
-
- if (stat (name, &st) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder `%s':\n%s"),
- folder_name, g_strerror (errno));
- g_free (name);
- return;
- }
-
- if (!S_ISREG (st.st_mode)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("`%s' is not a regular file."), name);
- g_free (name);
- return;
- }
-
- if (st.st_size != 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_NON_EMPTY,
- _("Folder `%s' is not empty. Not deleted."),
- folder_name);
- g_free (name);
- return;
- }
-
- if (unlink (name) == -1 && errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder `%s':\n%s"),
- name, g_strerror (errno));
- g_free (name);
- return;
- }
-
- /* FIXME: we have to do our own meta cleanup here rather than
- * calling our parent class' delete_folder() method since our
- * naming convention is different. Need to find a way for
- * CamelLocalStore to be able to construct the folder & meta
- * paths itself */
- path = mbox_folder_name_to_meta_path (store, folder_name, ".ev-summary");
- if (unlink (path) == -1 && errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder summary file `%s': %s"),
- path, g_strerror (errno));
- g_free (path);
- g_free (name);
- return;
- }
-
- g_free (path);
-
- path = mbox_folder_name_to_meta_path (store, folder_name, ".ibex");
- if (camel_text_index_remove (path) == -1 && errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder index file `%s': %s"),
- path, g_strerror (errno));
- g_free (path);
- g_free (name);
- return;
- }
-
- g_free (path);
-
- camel_exception_init (&lex);
- if ((lf = camel_store_get_folder (store, folder_name, 0, &lex))) {
- camel_object_get (lf, NULL, CAMEL_OBJECT_STATE_FILE, &path, NULL);
- camel_object_set (lf, NULL, CAMEL_OBJECT_STATE_FILE, NULL, NULL);
- camel_object_unref (lf);
- } else {
- camel_exception_clear (&lex);
- }
-
- if (path == NULL)
- path = mbox_folder_name_to_meta_path (store, folder_name, ".cmeta");
-
- if (unlink (path) == -1 && errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder meta file `%s': %s"),
- path, g_strerror (errno));
-
- g_free (path);
- g_free (name);
- return;
- }
-
- g_free (path);
- g_free (name);
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = g_strdup (folder_name);
- fi->name = g_path_get_basename (folder_name);
- fi->url = g_strdup_printf ("mbox:%s#%s", ((CamelService *) store)->url->path, folder_name);
- fi->unread_message_count = -1;
- camel_folder_info_build_path (fi, '/');
-
- camel_object_trigger_event (store, "folder_deleted", fi);
-
- camel_folder_info_free (fi);
-}
-
-static CamelFolderInfo *
-create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex)
-{
- /* FIXME: this is almost an exact copy of CamelLocalStore::create_folder() except that we use
- * different path schemes... need to find a way to share parent's code? */
- const char *toplevel_dir = ((CamelLocalStore *) store)->toplevel_dir;
- CamelFolderInfo *info = NULL;
- char *path, *name, *dir;
- CamelFolder *folder;
- struct stat st;
-
- if (toplevel_dir[0] != '/') {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Store root %s is not an absolute path"), toplevel_dir);
- return NULL;
- }
-
- if (folder_name[0] == '.' || ignore_file (folder_name, TRUE)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create a folder by this name."));
- return NULL;
- }
-
- if (parent_name && *parent_name)
- name = g_strdup_printf ("%s/%s", parent_name, folder_name);
- else
- name = g_strdup (folder_name);
-
- path = mbox_folder_name_to_path (store, name);
-
- dir = g_path_get_dirname (path);
- if (camel_mkdir (dir, 0777) == -1 && errno != EEXIST) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create directory `%s': %s."),
- dir, g_strerror (errno));
-
- g_free (path);
- g_free (name);
- g_free (dir);
-
- return NULL;
- }
-
- g_free (dir);
-
- if (stat (path, &st) == 0 || errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Cannot create folder: %s: %s"),
- path, errno ? g_strerror (errno) :
- _("Folder already exists"));
-
- g_free (path);
- g_free (name);
-
- return NULL;
- }
-
- g_free (path);
-
- folder = ((CamelStoreClass *) ((CamelObject *) store)->klass)->get_folder (store, name, CAMEL_STORE_FOLDER_CREATE, ex);
- if (folder) {
- camel_object_unref (folder);
- info = ((CamelStoreClass *) ((CamelObject *) store)->klass)->get_folder_info (store, name, 0, ex);
- }
-
- g_free (name);
-
- return info;
-}
-
-static int
-xrename (CamelStore *store, const char *old_name, const char *new_name, const char *ext, gboolean missingok, CamelException *ex)
-{
- const char *toplevel_dir = ((CamelLocalStore *) store)->toplevel_dir;
- char *oldpath, *newpath;
- struct stat st;
- int ret = -1;
- int err = 0;
-
- if (ext != NULL) {
- oldpath = camel_mbox_folder_get_meta_path (toplevel_dir, old_name, ext);
- newpath = camel_mbox_folder_get_meta_path (toplevel_dir, new_name, ext);
- } else {
- oldpath = camel_mbox_folder_get_full_path (toplevel_dir, old_name);
- newpath = camel_mbox_folder_get_full_path (toplevel_dir, new_name);
- }
-
- if (stat (oldpath, &st) == -1) {
- if (missingok && errno == ENOENT) {
- ret = 0;
- } else {
- err = errno;
- ret = -1;
- }
- } else if (S_ISDIR (st.st_mode)) {
- /* use rename for dirs */
- if (rename (oldpath, newpath) == 0 || stat (newpath, &st) == 0) {
- ret = 0;
- } else {
- err = errno;
- ret = -1;
- }
- } else if (link (oldpath, newpath) == 0 /* and link for files */
- || (stat (newpath, &st) == 0 && st.st_nlink == 2)) {
- if (unlink (oldpath) == 0) {
- ret = 0;
- } else {
- err = errno;
- unlink (newpath);
- ret = -1;
- }
- } else {
- err = errno;
- ret = -1;
- }
-
- if (ret == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not rename %s to %s: %s"),
- oldpath, newpath, g_strerror (err));
- }
-
- g_free (oldpath);
- g_free (newpath);
-
- return ret;
-}
-
-static void
-rename_folder (CamelStore *store, const char *old, const char *new, CamelException *ex)
-{
- CamelLocalFolder *folder = NULL;
- char *oldibex, *newibex;
-
- if (new[0] == '.' || ignore_file (new, TRUE)) {
- printf ("exception: The new folder name is illegal.\n");
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("The new folder name is illegal."));
- return;
- }
-
- /* try to rollback failures, has obvious races */
-
- oldibex = mbox_folder_name_to_meta_path (store, old, ".ibex");
- newibex = mbox_folder_name_to_meta_path (store, new, ".ibex");
-
- folder = camel_object_bag_get (store->folders, old);
- if (folder && folder->index) {
- if (camel_index_rename (folder->index, newibex) == -1)
- goto ibex_failed;
- } else {
- /* TODO: camel_text_index_rename should find out if we have an active index itself? */
- if (camel_text_index_rename (oldibex, newibex) == -1)
- goto ibex_failed;
- }
-
- if (xrename (store, old, new, ".ev-summary", TRUE, ex))
- goto summary_failed;
-
- if (xrename (store, old, new, NULL, FALSE, ex))
- goto base_failed;
-
- g_free (oldibex);
- g_free (newibex);
-
- if (folder)
- camel_object_unref (folder);
-
- return;
-
- base_failed:
-
- xrename (store, new, old, ".ev-summary", TRUE, ex);
-
- summary_failed:
-
- if (folder) {
- if (folder->index)
- camel_index_rename (folder->index, oldibex);
- } else
- camel_text_index_rename (newibex, oldibex);
- ibex_failed:
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not rename '%s': %s"),
- old, g_strerror (errno));
-
- g_free (newibex);
- g_free (oldibex);
-
- if (folder)
- camel_object_unref (folder);
-}
-
-
-/* used to find out where we've visited already */
-struct _inode {
- dev_t dnode;
- ino_t inode;
-};
-
-static guint
-inode_hash (const void *d)
-{
- const struct _inode *v = d;
-
- return v->inode ^ v->dnode;
-}
-
-static gboolean
-inode_equal (const void *a, const void *b)
-{
- const struct _inode *v1 = a, *v2 = b;
-
- return v1->inode == v2->inode && v1->dnode == v2->dnode;
-}
-
-static void
-inode_free (void *k, void *v, void *d)
-{
- g_free (k);
-}
-
-static CamelFolderInfo *
-scan_dir (CamelStore *store, GHashTable *visited, CamelFolderInfo *parent, const char *root,
- const char *name, guint32 flags, CamelException *ex)
-{
- CamelFolderInfo *folders, *tail, *fi;
- GHashTable *folder_hash;
- struct dirent *dent;
- DIR *dir;
-
- tail = folders = NULL;
-
- if (!(dir = opendir (root)))
- return NULL;
-
- folder_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* FIXME: it would be better if we queue'd up the recursive
- * scans till the end so that we can limit the number of
- * directory descriptors open at any given time... */
-
- while ((dent = readdir (dir))) {
- char *short_name, *full_name, *path, *ext;
- CamelFolder *folder;
- struct stat st;
- int unread = -1;
-
- if (dent->d_name[0] == '.')
- continue;
-
- if (ignore_file (dent->d_name, FALSE))
- continue;
-
- path = g_strdup_printf ("%s/%s", root, dent->d_name);
- if (stat (path, &st) == -1) {
- g_free (path);
- continue;
- }
-
- if (S_ISDIR (st.st_mode)) {
- struct _inode in = { st.st_dev, st.st_ino };
-
- if (g_hash_table_lookup (visited, &in)) {
- g_free (path);
- continue;
- }
- }
-
- short_name = g_strdup (dent->d_name);
- if ((ext = strrchr (short_name, '.')) && !strcmp (ext, ".sbd"))
- *ext = '\0';
-
- if (name != NULL)
- full_name = g_strdup_printf ("%s/%s", name, short_name);
- else
- full_name = g_strdup (short_name);
-
- if (!S_ISDIR (st.st_mode)) {
- folder = camel_object_bag_get (store->folders, full_name);
- if (folder) {
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- camel_folder_refresh_info (folder, NULL);
- unread = camel_folder_get_unread_message_count (folder);
- camel_object_unref (folder);
- }
- }
-
- if ((fi = g_hash_table_lookup (folder_hash, short_name)) != NULL) {
- g_free (short_name);
- g_free (full_name);
-
- if (S_ISDIR (st.st_mode)) {
- fi->flags = (fi->flags & ~CAMEL_FOLDER_NOINFERIORS) | CAMEL_FOLDER_CHILDREN;
- } else {
- fi->unread_message_count = unread;
- fi->flags &= ~CAMEL_FOLDER_NOSELECT;
- if ((ext = strchr (fi->url, ';')) && !strncmp (ext, ";noselect=yes", 13))
- memmove (ext, ext + 13, strlen (ext + 13) + 1);
- }
- } else {
- fi = g_new0 (CamelFolderInfo, 1);
- fi->parent = parent;
-
- /* add ";noselect=yes" if we haven't found the mbox file yet. when we find it, remove the noselect */
- fi->url = g_strdup_printf ("mbox:%s%s#%s", ((CamelService *) store)->url->path,
- S_ISDIR (st.st_mode) ? ";noselect=yes" : "", full_name);
- fi->name = short_name;
- fi->full_name = full_name;
- fi->path = g_strdup_printf ("/%s", full_name);
- fi->unread_message_count = unread;
-
- if (S_ISDIR (st.st_mode))
- fi->flags = CAMEL_FOLDER_NOSELECT;
- else
- fi->flags = CAMEL_FOLDER_NOINFERIORS;
-
- if (tail == NULL)
- folders = fi;
- else
- tail->sibling = fi;
-
- tail = fi;
-
- g_hash_table_insert (folder_hash, fi->name, fi);
- }
-
- if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) && S_ISDIR (st.st_mode)) {
- struct _inode in = { st.st_dev, st.st_ino };
-
- if (g_hash_table_lookup (visited, &in) == NULL) {
- struct _inode *inew = g_new (struct _inode, 1);
-
- *inew = in;
-
- g_hash_table_insert (visited, inew, inew);
-
- if ((fi->child = scan_dir (store, visited, fi, path, fi->full_name, flags, ex)))
- fi->flags |= CAMEL_FOLDER_CHILDREN;
- }
- }
-
- g_free (path);
- }
-
- closedir (dir);
-
- g_hash_table_destroy (folder_hash);
-
- return folders;
-}
-
-static CamelFolderInfo *
-get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- GHashTable *visited;
- struct _inode *inode;
- char *path, *subdir;
- CamelFolderInfo *fi;
- CamelFolder *folder;
- const char *base;
- struct stat st;
- int unread = -1;
-
- top = top ? top : "";
- path = mbox_folder_name_to_path (store, top);
-
- if (*top == '\0') {
- /* requesting root dir scan */
- if (stat (path, &st) == -1 || !S_ISDIR (st.st_mode)) {
- g_free (path);
- return NULL;
- }
-
- visited = g_hash_table_new (inode_hash, inode_equal);
-
- inode = g_new (struct _inode, 1);
- inode->dnode = st.st_dev;
- inode->inode = st.st_ino;
-
- g_hash_table_insert (visited, inode, inode);
-
- fi = scan_dir (store, visited, NULL, path, NULL, flags, ex);
- g_hash_table_foreach (visited, inode_free, NULL);
- g_hash_table_destroy (visited);
- g_free (path);
-
- return fi;
- }
-
- /* requesting scan of specific folder */
- if (stat (path, &st) == -1 || !S_ISREG (st.st_mode)) {
- g_free (path);
- return NULL;
- }
-
- visited = g_hash_table_new (inode_hash, inode_equal);
-
- if (!(base = strrchr (top, '/')))
- base = top;
- else
- base++;
-
- folder = camel_object_bag_get (store->folders, top);
- if (folder) {
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- camel_folder_refresh_info (folder, NULL);
- unread = camel_folder_get_unread_message_count (folder);
- camel_object_unref (folder);
- }
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->parent = NULL;
- fi->url = g_strdup_printf ("mbox:%s#%s", ((CamelService *) store)->url->path, top);
- fi->name = g_strdup (base);
- fi->full_name = g_strdup (top);
- fi->unread_message_count = unread;
- fi->path = g_strdup_printf ("/%s", top);
-
- subdir = g_strdup_printf ("%s.sbd", path);
- if (stat (subdir, &st) == 0 && S_ISDIR (st.st_mode))
- fi->child = scan_dir (store, visited, fi, subdir, top, flags, ex);
-
- if (fi->child)
- fi->flags |= CAMEL_FOLDER_CHILDREN;
- else
- fi->flags |= CAMEL_FOLDER_NOINFERIORS;
-
- g_free (subdir);
-
- g_hash_table_foreach (visited, inode_free, NULL);
- g_hash_table_destroy (visited);
- g_free (path);
-
- return fi;
-}
diff --git a/camel/providers/local/camel-mbox-store.h b/camel/providers/local/camel-mbox-store.h
deleted file mode 100644
index 5b6fbdd926..0000000000
--- a/camel/providers/local/camel-mbox-store.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_MBOX_STORE_H
-#define CAMEL_MBOX_STORE_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-local-store.h"
-
-#define CAMEL_MBOX_STORE_TYPE (camel_mbox_store_get_type ())
-#define CAMEL_MBOX_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MBOX_STORE_TYPE, CamelMboxStore))
-#define CAMEL_MBOX_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MBOX_STORE_TYPE, CamelMboxStoreClass))
-#define CAMEL_IS_MBOX_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_MBOX_STORE_TYPE))
-
-typedef struct {
- CamelLocalStore parent_object;
-
-} CamelMboxStore;
-
-typedef struct {
- CamelLocalStoreClass parent_class;
-
-} CamelMboxStoreClass;
-
-/* public methods */
-
-/* Standard Camel function */
-CamelType camel_mbox_store_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_MBOX_STORE_H */
-
-
diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c
deleted file mode 100644
index 4018fc93c9..0000000000
--- a/camel/providers/local/camel-mbox-summary.c
+++ /dev/null
@@ -1,1029 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "camel-mbox-summary.h"
-#include "camel/camel-mime-message.h"
-#include "camel/camel-operation.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "camel-mbox-summary.h"
-#include "camel/camel-file-utils.h"
-#include "camel/camel-mime-message.h"
-#include "camel/camel-operation.h"
-
-#define io(x)
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-#define CAMEL_MBOX_SUMMARY_VERSION (0x1000)
-
-static int summary_header_load (CamelFolderSummary *, FILE *);
-static int summary_header_save (CamelFolderSummary *, FILE *);
-
-static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *);
-static CamelMessageInfo * message_info_new_from_parser (CamelFolderSummary *, CamelMimeParser *);
-static CamelMessageInfo * message_info_load (CamelFolderSummary *, FILE *);
-static int message_info_save (CamelFolderSummary *, FILE *, CamelMessageInfo *);
-/*static void message_info_free (CamelFolderSummary *, CamelMessageInfo *);*/
-
-static int mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-static int mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-#ifdef STATUS_PINE
-static CamelMessageInfo *mbox_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex);
-#endif
-
-static int mbox_summary_sync_quick(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-static int mbox_summary_sync_full(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-
-static void camel_mbox_summary_class_init (CamelMboxSummaryClass *klass);
-static void camel_mbox_summary_init (CamelMboxSummary *obj);
-static void camel_mbox_summary_finalise (CamelObject *obj);
-
-#ifdef STATUS_PINE
-/* Which status flags are stored in each separate header */
-#define STATUS_XSTATUS (CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED)
-#define STATUS_STATUS (CAMEL_MESSAGE_SEEN)
-
-static void encode_status(guint32 flags, char status[8]);
-static guint32 decode_status(const char *status);
-#endif
-
-static CamelLocalSummaryClass *camel_mbox_summary_parent;
-
-CamelType
-camel_mbox_summary_get_type(void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(camel_local_summary_get_type(), "CamelMboxSummary",
- sizeof (CamelMboxSummary),
- sizeof (CamelMboxSummaryClass),
- (CamelObjectClassInitFunc) camel_mbox_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_mbox_summary_init,
- (CamelObjectFinalizeFunc) camel_mbox_summary_finalise);
- }
-
- return type;
-}
-
-static void
-camel_mbox_summary_class_init(CamelMboxSummaryClass *klass)
-{
- CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *)klass;
- CamelLocalSummaryClass *lklass = (CamelLocalSummaryClass *)klass;
-
- camel_mbox_summary_parent = (CamelLocalSummaryClass *)camel_type_get_global_classfuncs(camel_local_summary_get_type());
-
- sklass->summary_header_load = summary_header_load;
- sklass->summary_header_save = summary_header_save;
-
- sklass->message_info_new = message_info_new;
- sklass->message_info_new_from_parser = message_info_new_from_parser;
- sklass->message_info_load = message_info_load;
- sklass->message_info_save = message_info_save;
- /*sklass->message_info_free = message_info_free;*/
-
- lklass->check = mbox_summary_check;
- lklass->sync = mbox_summary_sync;
-#ifdef STATUS_PINE
- lklass->add = mbox_summary_add;
-#endif
-
- klass->sync_quick = mbox_summary_sync_quick;
- klass->sync_full = mbox_summary_sync_full;
-}
-
-static void
-camel_mbox_summary_init(CamelMboxSummary *obj)
-{
- struct _CamelFolderSummary *s = (CamelFolderSummary *)obj;
-
- /* subclasses need to set the right instance data sizes */
- s->message_info_size = sizeof(CamelMboxMessageInfo);
- s->content_info_size = sizeof(CamelMboxMessageContentInfo);
-
- /* and a unique file version */
- s->version += CAMEL_MBOX_SUMMARY_VERSION;
-}
-
-static void
-camel_mbox_summary_finalise(CamelObject *obj)
-{
- /*CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(obj);*/
-}
-
-/**
- * camel_mbox_summary_new:
- *
- * Create a new CamelMboxSummary object.
- *
- * Return value: A new CamelMboxSummary widget.
- **/
-CamelMboxSummary *
-camel_mbox_summary_new(const char *filename, const char *mbox_name, CamelIndex *index)
-{
- CamelMboxSummary *new = (CamelMboxSummary *)camel_object_new(camel_mbox_summary_get_type());
-
- camel_local_summary_construct((CamelLocalSummary *)new, filename, mbox_name, index);
- return new;
-}
-
-void camel_mbox_summary_xstatus(CamelMboxSummary *mbs, int state)
-{
- mbs->xstatus = state;
-}
-
-static int
-summary_header_load(CamelFolderSummary *s, FILE *in)
-{
- CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s);
-
- if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_load(s, in) == -1)
- return -1;
-
- return camel_file_util_decode_uint32(in, (guint32 *) &mbs->folder_size);
-}
-
-static int
-summary_header_save(CamelFolderSummary *s, FILE *out)
-{
- CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s);
-
- if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_save(s, out) == -1)
- return -1;
-
- return camel_file_util_encode_uint32(out, mbs->folder_size);
-}
-
-static CamelMessageInfo *
-message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
-{
- CamelMessageInfo *mi;
- CamelMboxSummary *mbs = (CamelMboxSummary *)s;
-
- mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new(s, h);
- if (mi) {
- CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
- const char *xev, *uid;
- CamelMessageInfo *info = NULL;
- int add = 0; /* bitmask of things to add, 1 assign uid, 2, just add as new, 4 = recent */
-#ifdef STATUS_PINE
- const char *status = NULL, *xstatus = NULL;
- guint32 flags = 0;
-
- if (mbs->xstatus) {
- /* check for existance of status & x-status headers */
- status = camel_header_raw_find(&h, "Status", NULL);
- if (status)
- flags = decode_status(status);
- xstatus = camel_header_raw_find(&h, "X-Status", NULL);
- if (xstatus)
- flags |= decode_status(xstatus);
- }
-#endif
- /* if we have an xev header, use it, else assign a new one */
- xev = camel_header_raw_find(&h, "X-Evolution", NULL);
- if (xev != NULL
- && camel_local_summary_decode_x_evolution((CamelLocalSummary *)s, xev, mi) == 0) {
- uid = camel_message_info_uid(mi);
- d(printf("found valid x-evolution: %s\n", uid));
- info = camel_folder_summary_uid(s, uid);
- if (info) {
- if ((info->flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
- info->flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
- camel_folder_summary_info_free(s, mi);
- mbi = (CamelMboxMessageInfo *)mi = info;
- } else {
- add = 7;
- d(printf("seen '%s' before, adding anew\n", uid));
- camel_folder_summary_info_free(s, info);
- }
- } else {
- add = 2;
- d(printf("but isn't present in summary\n"));
- }
- } else {
- d(printf("didn't find x-evolution\n"));
- add = 7;
- }
-
- if (add&1) {
- mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
- camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s));
- } else {
- camel_folder_summary_set_uid(s, strtoul(camel_message_info_uid(mi), NULL, 10));
- }
-#ifdef STATUS_PINE
- if (mbs->xstatus && add&2) {
- /* use the status as the flags when we read it the first time */
- if (status)
- mi->flags = (mi->flags & ~(STATUS_STATUS)) | (flags & STATUS_STATUS);
- if (xstatus)
- mi->flags = (mi->flags & ~(STATUS_XSTATUS)) | (flags & STATUS_XSTATUS);
- }
-#endif
- if (mbs->changes) {
- if (add&2)
- camel_folder_change_info_add_uid(mbs->changes, camel_message_info_uid(mi));
- if ((add&4) && status == NULL)
- camel_folder_change_info_recent_uid(mbs->changes, camel_message_info_uid(mi));
- }
-
- mbi->frompos = -1;
- }
-
- return mi;
-}
-
-static CamelMessageInfo *
-message_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
-{
- CamelMessageInfo *mi;
-
- mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new_from_parser(s, mp);
- if (mi) {
- CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
-
- mbi->frompos = camel_mime_parser_tell_start_from(mp);
- }
-
- return mi;
-}
-
-static CamelMessageInfo *
-message_info_load(CamelFolderSummary *s, FILE *in)
-{
- CamelMessageInfo *mi;
-
- io(printf("loading mbox message info\n"));
-
- mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_load(s, in);
- if (mi) {
- CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
-
- if (camel_file_util_decode_off_t(in, &mbi->frompos) == -1)
- goto error;
- }
-
- return mi;
-error:
- camel_folder_summary_info_free(s, mi);
- return NULL;
-}
-
-static int
-message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
-{
- CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
-
- io(printf("saving mbox message info\n"));
-
- if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_save(s, out, mi) == -1
- || camel_file_util_encode_off_t(out, mbi->frompos) == -1)
- return -1;
-
- return 0;
-}
-
-/* like summary_rebuild, but also do changeinfo stuff (if supplied) */
-static int
-summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- int i, count;
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
- CamelMboxSummary *mbs = (CamelMboxSummary *)cls;
- CamelMimeParser *mp;
- CamelMessageInfo *mi;
- int fd;
- int ok = 0;
- struct stat st;
- off_t size = 0;
-
- d(printf("Calling summary update, from pos %d\n", (int)offset));
-
- cls->index_force = FALSE;
-
- camel_operation_start(NULL, _("Storing folder"));
-
- fd = open(cls->folder_path, O_RDONLY);
- if (fd == -1) {
- d(printf("%s failed to open: %s\n", cls->folder_path, strerror (errno)));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open folder: %s: %s"),
- cls->folder_path, g_strerror (errno));
- camel_operation_end(NULL);
- return -1;
- }
-
- if (fstat(fd, &st) == 0)
- size = st.st_size;
-
- mp = camel_mime_parser_new();
- camel_mime_parser_init_with_fd(mp, fd);
- camel_mime_parser_scan_from(mp, TRUE);
- camel_mime_parser_seek(mp, offset, SEEK_SET);
-
- if (offset > 0) {
- if (camel_mime_parser_step(mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM
- && camel_mime_parser_tell_start_from(mp) == offset) {
- camel_mime_parser_unstep(mp);
- } else {
- g_warning("The next message didn't start where I expected, building summary from start");
- camel_mime_parser_drop_step(mp);
- offset = 0;
- camel_mime_parser_seek(mp, offset, SEEK_SET);
- }
- }
-
- /* we mark messages as to whether we've seen them or not.
- If we're not starting from the start, we must be starting
- from the old end, so everything must be treated as new */
- count = camel_folder_summary_count(s);
- for (i=0;i<count;i++) {
- mi = camel_folder_summary_index(s, i);
- if (offset == 0)
- mi->flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN;
- else
- mi->flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
- camel_folder_summary_info_free(s, mi);
- }
- mbs->changes = changeinfo;
-
- while (camel_mime_parser_step(mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
- CamelMessageInfo *info;
- off_t pc = camel_mime_parser_tell_start_from (mp) + 1;
-
- camel_operation_progress (NULL, (int) (((float) pc / size) * 100));
-
- info = camel_folder_summary_add_from_parser(s, mp);
- if (info == NULL) {
- camel_exception_setv(ex, 1, _("Fatal mail parser error near position %ld in folder %s"),
- camel_mime_parser_tell(mp), cls->folder_path);
- ok = -1;
- break;
- }
-
- g_assert(camel_mime_parser_step(mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM_END);
- }
-
- camel_object_unref(CAMEL_OBJECT (mp));
-
- count = camel_folder_summary_count(s);
- for (i=0;i<count;i++) {
- mi = camel_folder_summary_index(s, i);
- /* must've dissapeared from the file? */
- if (mi->flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) {
- d(printf("uid '%s' vanished, removing", camel_message_info_uid(mi)));
- if (changeinfo)
- camel_folder_change_info_remove_uid(changeinfo, camel_message_info_uid(mi));
- camel_folder_summary_remove(s, mi);
- count--;
- i--;
- }
- camel_folder_summary_info_free(s, mi);
- }
- mbs->changes = NULL;
-
- /* update the file size/mtime in the summary */
- if (ok != -1) {
- if (stat(cls->folder_path, &st) == 0) {
- camel_folder_summary_touch(s);
- mbs->folder_size = st.st_size;
- s->time = st.st_mtime;
- }
- }
-
- camel_operation_end(NULL);
-
- return ok;
-}
-
-static int
-mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelMboxSummary *mbs = (CamelMboxSummary *)cls;
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
- struct stat st;
- int ret = 0;
- int i, count;
-
- d(printf("Checking summary\n"));
-
- /* check if the summary is up-to-date */
- if (stat(cls->folder_path, &st) == -1) {
- camel_folder_summary_clear(s);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot check folder: %s: %s"),
- cls->folder_path, g_strerror (errno));
- return -1;
- }
-
- if (cls->check_force)
- mbs->folder_size = 0;
- cls->check_force = 0;
-
- if (st.st_size == 0) {
- /* empty? No need to scan at all */
- d(printf("Empty mbox, clearing summary\n"));
- count= camel_folder_summary_count(s);
- for (i=0;i<count;i++) {
- CamelMessageInfo *info = camel_folder_summary_index(s, i);
-
- if (info) {
- camel_folder_change_info_remove_uid(changes, camel_message_info_uid(info));
- camel_folder_summary_info_free(s, info);
- }
- }
- camel_folder_summary_clear(s);
- ret = 0;
- } else {
- /* is the summary uptodate? */
- if (st.st_size != mbs->folder_size || st.st_mtime != s->time) {
- if (mbs->folder_size < st.st_size) {
- /* this will automatically rescan from 0 if there is a problem */
- d(printf("folder grew, attempting to rebuild from %d\n", mbs->folder_size));
- ret = summary_update(cls, mbs->folder_size, changes, ex);
- } else {
- d(printf("folder shrank! rebuilding from start\n"));
- ret = summary_update(cls, 0, changes, ex);
- }
- } else {
- d(printf("Folder unchanged, do nothing\n"));
- }
- }
-
- /* FIXME: move upstream? */
-
- if (ret != -1) {
- if (mbs->folder_size != st.st_size || s->time != st.st_mtime) {
- mbs->folder_size = st.st_size;
- s->time = st.st_mtime;
- camel_folder_summary_touch(s);
- }
- }
-
- return ret;
-}
-
-/* perform a full sync */
-static int
-mbox_summary_sync_full(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- CamelLocalSummary *cls = (CamelLocalSummary *)mbs;
- int fd = -1, fdout = -1;
- char *tmpname = NULL;
- guint32 flags = (expunge?1:0);
-
- d(printf("performing full summary/sync\n"));
-
- camel_operation_start(NULL, _("Storing folder"));
-
- fd = open(cls->folder_path, O_RDONLY);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open file: %s: %s"),
- cls->folder_path, g_strerror (errno));
- camel_operation_end(NULL);
- return -1;
- }
-
- tmpname = g_alloca (strlen (cls->folder_path) + 5);
- sprintf (tmpname, "%s.tmp", cls->folder_path);
- d(printf("Writing tmp file to %s\n", tmpname));
- fdout = open(tmpname, O_WRONLY|O_CREAT|O_TRUNC, 0600);
- if (fdout == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot open temporary mailbox: %s"),
- g_strerror (errno));
- goto error;
- }
-
- if (camel_mbox_summary_sync_mbox((CamelMboxSummary *)cls, flags, changeinfo, fd, fdout, ex) == -1)
- goto error;
-
- d(printf("Closing folders\n"));
-
- if (close(fd) == -1) {
- g_warning("Cannot close source folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not close source folder %s: %s"),
- cls->folder_path, g_strerror (errno));
- fd = -1;
- goto error;
- }
-
- if (close(fdout) == -1) {
- g_warning("Cannot close tmp folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not close temp folder: %s"),
- g_strerror (errno));
- fdout = -1;
- goto error;
- }
-
- /* this should probably either use unlink/link/unlink, or recopy over
- the original mailbox, for various locking reasons/etc */
- if (rename(tmpname, cls->folder_path) == -1) {
- g_warning("Cannot rename folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not rename folder: %s"),
- g_strerror (errno));
- goto error;
- }
- tmpname = NULL;
-
- camel_operation_end(NULL);
-
- return 0;
- error:
- if (fd != -1)
- close(fd);
-
- if (fdout != -1)
- close(fdout);
-
- if (tmpname)
- unlink(tmpname);
-
- camel_operation_end(NULL);
-
- return -1;
-}
-
-/* perform a quick sync - only system flags have changed */
-static int
-mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- CamelLocalSummary *cls = (CamelLocalSummary *)mbs;
- CamelFolderSummary *s = (CamelFolderSummary *)mbs;
- CamelMimeParser *mp = NULL;
- int i, count;
- CamelMboxMessageInfo *info = NULL;
- int fd = -1;
- char *xevnew, *xevtmp;
- const char *xev;
- int len;
- off_t lastpos;
-
- d(printf("Performing quick summary sync\n"));
-
- camel_operation_start(NULL, _("Storing folder"));
-
- fd = open(cls->folder_path, O_RDWR);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open file: %s: %s"),
- cls->folder_path, g_strerror (errno));
-
- camel_operation_end(NULL);
- return -1;
- }
-
- mp = camel_mime_parser_new();
- camel_mime_parser_scan_from(mp, TRUE);
- camel_mime_parser_scan_pre_from(mp, TRUE);
- camel_mime_parser_init_with_fd(mp, fd);
-
- count = camel_folder_summary_count(s);
- for (i = 0; i < count; i++) {
- int xevoffset;
- int pc = (i+1)*100/count;
-
- camel_operation_progress(NULL, pc);
-
- info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
-
- g_assert(info);
-
- d(printf("Checking message %s %08x\n", camel_message_info_uid(info), info->info.flags));
-
- if ((info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
- camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
- info = NULL;
- continue;
- }
-
- d(printf("Updating message %s\n", camel_message_info_uid(info)));
-
- camel_mime_parser_seek(mp, info->frompos, SEEK_SET);
-
- if (camel_mime_parser_step(mp, 0, 0) != CAMEL_MIME_PARSER_STATE_FROM) {
- g_warning("Expected a From line here, didn't get it");
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Summary and folder mismatch, even after a sync"));
- goto error;
- }
-
- if (camel_mime_parser_tell_start_from(mp) != info->frompos) {
- g_warning("Didn't get the next message where I expected (%d) got %d instead",
- (int)info->frompos, (int)camel_mime_parser_tell_start_from(mp));
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Summary and folder mismatch, even after a sync"));
- goto error;
- }
-
- if (camel_mime_parser_step(mp, 0, 0) == CAMEL_MIME_PARSER_STATE_FROM_END) {
- g_warning("camel_mime_parser_step failed (2)");
- goto error;
- }
-
- xev = camel_mime_parser_header(mp, "X-Evolution", &xevoffset);
- if (xev == NULL || camel_local_summary_decode_x_evolution(cls, xev, NULL) == -1) {
- g_warning("We're supposed to have a valid x-ev header, but we dont");
- goto error;
- }
- xevnew = camel_local_summary_encode_x_evolution(cls, (CamelMessageInfo *)info);
- /* SIGH: encode_param_list is about the only function which folds headers by itself.
- This should be fixed somehow differently (either parser doesn't fold headers,
- or param_list doesn't, or something */
- xevtmp = camel_header_unfold(xevnew);
- /* the raw header contains a leading ' ', so (dis)count that too */
- if (strlen(xev)-1 != strlen(xevtmp)) {
- printf ("strlen(xev)-1 = %d; strlen(xevtmp) = %d\n", strlen(xev)-1, strlen(xevtmp));
- printf ("xev='%s'; xevtmp='%s'\n", xev, xevtmp);
- g_free(xevnew);
- g_free(xevtmp);
- g_warning("Hmm, the xev headers shouldn't have changed size, but they did");
- goto error;
- }
- g_free(xevtmp);
-
- /* we write out the xevnew string, assuming its been folded identically to the original too! */
-
- lastpos = lseek(fd, 0, SEEK_CUR);
- lseek(fd, xevoffset+strlen("X-Evolution: "), SEEK_SET);
- do {
- len = write(fd, xevnew, strlen(xevnew));
- } while (len == -1 && errno == EINTR);
- lseek(fd, lastpos, SEEK_SET);
- g_free(xevnew);
-
- camel_mime_parser_drop_step(mp);
- camel_mime_parser_drop_step(mp);
-
- info->info.flags &= 0xffff;
- camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
- }
-
- d(printf("Closing folders\n"));
-
- if (close(fd) == -1) {
- g_warning ("Cannot close source folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not close source folder %s: %s"),
- cls->folder_path, g_strerror (errno));
- fd = -1;
- goto error;
- }
-
- camel_object_unref((CamelObject *)mp);
-
- camel_operation_end(NULL);
-
- return 0;
- error:
- if (fd != -1)
- close(fd);
- if (mp)
- camel_object_unref((CamelObject *)mp);
- if (info)
- camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
-
- camel_operation_end(NULL);
-
- return -1;
-}
-
-static int
-mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- struct stat st;
- CamelMboxSummary *mbs = (CamelMboxSummary *)cls;
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
- int i, count;
- int quick = TRUE, work=FALSE;
- int ret;
-
- /* first, sync ourselves up, just to make sure */
- if (camel_local_summary_check(cls, changeinfo, ex) == -1)
- return -1;
-
- count = camel_folder_summary_count(s);
- if (count == 0)
- return 0;
-
- /* check what work we have to do, if any */
- for (i=0;quick && i<count; i++) {
- CamelMessageInfo *info = camel_folder_summary_index(s, i);
- g_assert(info);
- if ((expunge && (info->flags & CAMEL_MESSAGE_DELETED)) ||
- (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_XEVCHANGE)))
- quick = FALSE;
- else
- work |= (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0;
- camel_folder_summary_info_free(s, info);
- }
-
- /* yuck i hate this logic, but its to simplify the 'all ok, update summary' and failover cases */
- ret = -1;
- if (quick) {
- if (work) {
- ret = ((CamelMboxSummaryClass *)((CamelObject *)cls)->klass)->sync_quick(mbs, expunge, changeinfo, ex);
- if (ret == -1) {
- g_warning("failed a quick-sync, trying a full sync");
- camel_exception_clear(ex);
- }
- } else {
- ret = 0;
- }
- }
-
- if (ret == -1)
- ret = ((CamelMboxSummaryClass *)((CamelObject *)cls)->klass)->sync_full(mbs, expunge, changeinfo, ex);
- if (ret == -1)
- return -1;
-
- if (stat(cls->folder_path, &st) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unknown error: %s"), g_strerror (errno));
- return -1;
- }
-
- if (mbs->folder_size != st.st_size || s->time != st.st_mtime) {
- s->time = st.st_mtime;
- mbs->folder_size = st.st_size;
- camel_folder_summary_touch(s);
- }
-
- return ((CamelLocalSummaryClass *)camel_mbox_summary_parent)->sync(cls, expunge, changeinfo, ex);
-}
-
-int
-camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderChangeInfo *changeinfo, int fd, int fdout, CamelException *ex)
-{
- CamelMboxSummary *mbs = (CamelMboxSummary *)cls;
- CamelFolderSummary *s = (CamelFolderSummary *)mbs;
- CamelMimeParser *mp = NULL;
- int i, count;
- CamelMboxMessageInfo *info = NULL;
- char *buffer, *xevnew = NULL;
- size_t len;
- const char *fromline;
- int lastdel = FALSE;
-#ifdef STATUS_PINE
- char statnew[8], xstatnew[8];
-#endif
-
- d(printf("performing full summary/sync\n"));
-
- /* need to dup this because the mime-parser owns the fd after we give it to it */
- fd = dup(fd);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not store folder: %s"),
- g_strerror (errno));
- return -1;
- }
-
- mp = camel_mime_parser_new();
- camel_mime_parser_scan_from(mp, TRUE);
- camel_mime_parser_scan_pre_from(mp, TRUE);
- camel_mime_parser_init_with_fd(mp, fd);
-
- count = camel_folder_summary_count(s);
- for (i = 0; i < count; i++) {
- int pc = (i + 1) * 100 / count;
-
- camel_operation_progress(NULL, pc);
-
- info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
-
- g_assert(info);
-
- d(printf("Looking at message %s\n", camel_message_info_uid(info)));
-
- /* only need to seek past deleted messages, otherwise we should be at the right spot/state already */
- if (lastdel) {
- d(printf("seeking to %d\n", (int)info->frompos));
- camel_mime_parser_seek(mp, info->frompos, SEEK_SET);
- }
-
- if (camel_mime_parser_step(mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_FROM) {
- g_warning("Expected a From line here, didn't get it");
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Summary and folder mismatch, even after a sync"));
- goto error;
- }
-
- if (camel_mime_parser_tell_start_from(mp) != info->frompos) {
- g_warning("Didn't get the next message where I expected (%d) got %d instead",
- (int)info->frompos, (int)camel_mime_parser_tell_start_from(mp));
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Summary and folder mismatch, even after a sync"));
- goto error;
- }
-
- lastdel = FALSE;
- if ((flags&1) && info->info.flags & CAMEL_MESSAGE_DELETED) {
- const char *uid = camel_message_info_uid(info);
-
- d(printf("Deleting %s\n", uid));
-
- if (((CamelLocalSummary *)cls)->index)
- camel_index_delete_name(((CamelLocalSummary *)cls)->index, uid);
-
- /* remove it from the change list */
- camel_folder_change_info_remove_uid(changeinfo, uid);
- camel_folder_summary_remove(s, (CamelMessageInfo *)info);
- camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
- count--;
- i--;
- info = NULL;
- lastdel = TRUE;
- } else {
- /* otherwise, the message is staying, copy its From_ line across */
-#if 0
- if (i>0)
- write(fdout, "\n", 1);
-#endif
- info->frompos = lseek(fdout, 0, SEEK_CUR);
- fromline = camel_mime_parser_from_line(mp);
- write(fdout, fromline, strlen(fromline));
- }
-
- if (info && info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- d(printf("Updating header for %s flags = %08x\n", camel_message_info_uid(info), info->info.flags));
-
- if (camel_mime_parser_step(mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_FROM_END) {
- g_warning("camel_mime_parser_step failed (2)");
- goto error;
- }
-
- xevnew = camel_local_summary_encode_x_evolution((CamelLocalSummary *)cls, (CamelMessageInfo *)info);
-#ifdef STATUS_PINE
- if (mbs->xstatus) {
- encode_status(((CamelMessageInfo *)info)->flags & STATUS_STATUS, statnew);
- encode_status(((CamelMessageInfo *)info)->flags & STATUS_XSTATUS, xstatnew);
- len = camel_local_summary_write_headers(fdout, camel_mime_parser_headers_raw(mp), xevnew, statnew, xstatnew);
- } else {
-#endif
- len = camel_local_summary_write_headers(fdout, camel_mime_parser_headers_raw(mp), xevnew, NULL, NULL);
-#ifdef STATUS_PINE
- }
-#endif
- if (len == -1) {
- d(printf("Error writing to tmp mailbox\n"));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Error writing to temp mailbox: %s"),
- g_strerror (errno));
- goto error;
- }
- info->info.flags &= 0xffff;
- g_free(xevnew);
- xevnew = NULL;
- camel_mime_parser_drop_step(mp);
- }
-
- camel_mime_parser_drop_step(mp);
- if (info) {
- d(printf("looking for message content to copy across from %d\n", (int)camel_mime_parser_tell(mp)));
- while (camel_mime_parser_step(mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_PRE_FROM) {
- /*d(printf("copying mbox contents to tmp: '%.*s'\n", len, buffer));*/
- if (write(fdout, buffer, len) != len) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Writing to tmp mailbox failed: %s: %s"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno));
- goto error;
- }
- }
-
- if (write(fdout, "\n", 1) != 1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Error writing to temp mailbox: %s"),
- g_strerror (errno));
- goto error;
- }
-
- d(printf("we are now at %d, from = %d\n", (int)camel_mime_parser_tell(mp),
- (int)camel_mime_parser_tell_start_from(mp)));
- camel_mime_parser_unstep(mp);
- camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
- info = NULL;
- }
- }
-
-#if 0
- /* if last was deleted, append the \n we removed */
- if (lastdel && count > 0)
- write(fdout, "\n", 1);
-#endif
-
- camel_object_unref((CamelObject *)mp);
-
- return 0;
- error:
- g_free(xevnew);
-
- if (mp)
- camel_object_unref((CamelObject *)mp);
- if (info)
- camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
-
- return -1;
-}
-
-#ifdef STATUS_PINE
-static CamelMessageInfo *
-mbox_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex)
-{
- CamelMessageInfo *mi;
-
- mi = ((CamelLocalSummaryClass *)camel_mbox_summary_parent)->add(cls, msg, info, ci, ex);
- if (mi && ((CamelMboxSummary *)cls)->xstatus) {
- char status[8];
-
- /* we snoop and add status/x-status headers to suit */
- encode_status(mi->flags & STATUS_STATUS, status);
- camel_medium_set_header((CamelMedium *)msg, "Status", status);
- encode_status(mi->flags & STATUS_XSTATUS, status);
- camel_medium_set_header((CamelMedium *)msg, "X-Status", status);
- }
-
- return mi;
-}
-
-static struct {
- char tag;
- guint32 flag;
-} status_flags[] = {
- { 'F', CAMEL_MESSAGE_FLAGGED },
- { 'A', CAMEL_MESSAGE_ANSWERED },
- { 'D', CAMEL_MESSAGE_DELETED },
- { 'R', CAMEL_MESSAGE_SEEN },
-};
-
-static void
-encode_status(guint32 flags, char status[8])
-{
- char *p;
- int i;
-
- p = status;
- for (i=0;i<sizeof(status_flags)/sizeof(status_flags[0]);i++)
- if (status_flags[i].flag & flags)
- *p++ = status_flags[i].tag;
- *p++ = 'O';
- *p=0;
-}
-
-static guint32
-decode_status(const char *status)
-{
- const char *p;
- char c;
- guint32 flags = 0;
- int i;
-
- p = status;
- while ((c = *p++)) {
- for (i=0;i<sizeof(status_flags)/sizeof(status_flags[0]);i++)
- if (status_flags[i].tag == *p)
- flags |= status_flags[i].flag;
- }
-
- return flags;
-}
-
-#endif /* STATUS_PINE */
diff --git a/camel/providers/local/camel-mbox-summary.h b/camel/providers/local/camel-mbox-summary.h
deleted file mode 100644
index dc64aa23fa..0000000000
--- a/camel/providers/local/camel-mbox-summary.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_MBOX_SUMMARY_H
-#define _CAMEL_MBOX_SUMMARY_H
-
-#include "camel-local-summary.h"
-
-/* Enable the use of elm/pine style "Status" & "X-Status" headers */
-#define STATUS_PINE
-
-#define CAMEL_MBOX_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_mbox_summary_get_type (), CamelMboxSummary)
-#define CAMEL_MBOX_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_mbox_summary_get_type (), CamelMboxSummaryClass)
-#define CAMEL_IS_MBOX_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_mbox_summary_get_type ())
-
-typedef struct _CamelMboxSummary CamelMboxSummary;
-typedef struct _CamelMboxSummaryClass CamelMboxSummaryClass;
-
-typedef struct _CamelMboxMessageContentInfo {
- CamelMessageContentInfo info;
-} CamelMboxMessageContentInfo;
-
-typedef struct _CamelMboxMessageInfo {
- CamelMessageInfo info;
-
- off_t frompos;
-} CamelMboxMessageInfo;
-
-struct _CamelMboxSummary {
- CamelLocalSummary parent;
-
- CamelFolderChangeInfo *changes; /* used to build change sets */
-
- size_t folder_size; /* size of the mbox file, last sync */
-
- unsigned int xstatus:1; /* do we store/honour xstatus/status headers */
-};
-
-struct _CamelMboxSummaryClass {
- CamelLocalSummaryClass parent_class;
-
- /* sync in-place */
- int (*sync_quick)(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
- /* sync requires copy */
- int (*sync_full)(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-};
-
-CamelType camel_mbox_summary_get_type (void);
-CamelMboxSummary *camel_mbox_summary_new (const char *filename, const char *mbox_name, CamelIndex *index);
-
-/* do we honour/use xstatus headers, etc */
-void camel_mbox_summary_xstatus(CamelMboxSummary *mbs, int state);
-
-/* build a new mbox from an existing mbox storing summary information */
-int camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderChangeInfo *changeinfo, int fd, int fdout, CamelException *ex);
-
-#endif /* ! _CAMEL_MBOX_SUMMARY_H */
-
diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c
deleted file mode 100644
index 25dbacc49a..0000000000
--- a/camel/providers/local/camel-mh-folder.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999, 2003 Ximian Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include "camel-mh-folder.h"
-#include "camel-mh-store.h"
-#include "camel-stream-fs.h"
-#include "camel-mh-summary.h"
-#include "camel-data-wrapper.h"
-#include "camel-mime-message.h"
-#include "camel-exception.h"
-
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-static CamelLocalFolderClass *parent_class = NULL;
-
-/* Returns the class for a CamelMhFolder */
-#define CMHF_CLASS(so) CAMEL_MH_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CMHS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static CamelLocalSummary *mh_create_summary(const char *path, const char *folder, CamelIndex *index);
-
-static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex);
-static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex);
-
-static void mh_finalize(CamelObject * object);
-
-static void camel_mh_folder_class_init(CamelObjectClass * camel_mh_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_mh_folder_class);
- CamelLocalFolderClass *lclass = (CamelLocalFolderClass *)camel_mh_folder_class;
-
- parent_class = CAMEL_LOCAL_FOLDER_CLASS (camel_type_get_global_classfuncs(camel_local_folder_get_type()));
-
- /* virtual method definition */
-
- /* virtual method overload */
- camel_folder_class->append_message = mh_append_message;
- camel_folder_class->get_message = mh_get_message;
-
- lclass->create_summary = mh_create_summary;
-}
-
-static void mh_init(gpointer object, gpointer klass)
-{
- /*CamelFolder *folder = object;
- CamelMhFolder *mh_folder = object;*/
-}
-
-static void mh_finalize(CamelObject * object)
-{
- /*CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(object);*/
-}
-
-CamelType camel_mh_folder_get_type(void)
-{
- static CamelType camel_mh_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_mh_folder_type == CAMEL_INVALID_TYPE) {
- camel_mh_folder_type = camel_type_register(CAMEL_LOCAL_FOLDER_TYPE, "CamelMhFolder",
- sizeof(CamelMhFolder),
- sizeof(CamelMhFolderClass),
- (CamelObjectClassInitFunc) camel_mh_folder_class_init,
- NULL,
- (CamelObjectInitFunc) mh_init,
- (CamelObjectFinalizeFunc) mh_finalize);
- }
-
- return camel_mh_folder_type;
-}
-
-CamelFolder *
-camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex)
-{
- CamelFolder *folder;
-
- d(printf("Creating mh folder: %s\n", full_name));
-
- folder = (CamelFolder *)camel_object_new(CAMEL_MH_FOLDER_TYPE);
- folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder,
- parent_store, full_name, flags, ex);
-
- return folder;
-}
-
-static CamelLocalSummary *mh_create_summary(const char *path, const char *folder, CamelIndex *index)
-{
- return (CamelLocalSummary *)camel_mh_summary_new(path, folder, index);
-}
-
-static void
-mh_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex)
-{
- CamelMhFolder *mh_folder = (CamelMhFolder *)folder;
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- CamelStream *output_stream;
- CamelMessageInfo *mi;
- char *name;
-
- /* FIXME: probably needs additional locking (although mh doesn't appear do do it) */
-
- d(printf("Appending message\n"));
-
- /* add it to the summary/assign the uid, etc */
- mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex);
- if (camel_exception_is_set (ex))
- return;
-
- d(printf("Appending message: uid is %s\n", camel_message_info_uid(mi)));
-
- /* write it out, use the uid we got from the summary */
- name = g_strdup_printf("%s/%s", lf->folder_path, camel_message_info_uid(mi));
- output_stream = camel_stream_fs_new_with_name(name, O_WRONLY|O_CREAT, 0600);
- if (output_stream == NULL)
- goto fail_write;
-
- if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *)message, output_stream) == -1
- || camel_stream_close (output_stream) == -1)
- goto fail_write;
-
- /* close this? */
- camel_object_unref (CAMEL_OBJECT (output_stream));
-
- g_free(name);
-
- camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed",
- ((CamelLocalFolder *)mh_folder)->changes);
- camel_folder_change_info_clear (((CamelLocalFolder *)mh_folder)->changes);
-
- if (appended_uid)
- *appended_uid = g_strdup(camel_message_info_uid(mi));
-
- return;
-
- fail_write:
-
- /* remove the summary info so we are not out-of-sync with the mh folder */
- camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary),
- camel_message_info_uid (mi));
-
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("MH append message cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to mh folder: %s: %s"),
- name, g_strerror (errno));
-
- if (output_stream) {
- camel_object_unref (CAMEL_OBJECT (output_stream));
- unlink (name);
- }
-
- g_free (name);
-}
-
-static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex)
-{
- CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- CamelStream *message_stream = NULL;
- CamelMimeMessage *message = NULL;
- CamelMessageInfo *info;
- char *name;
-
- d(printf("getting message: %s\n", uid));
-
- /* get the message summary info */
- if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), uid, _("No such message"));
- return NULL;
- }
-
- /* we only need it to check the message exists */
- camel_folder_summary_info_free(folder->summary, info);
-
- name = g_strdup_printf("%s/%s", lf->folder_path, uid);
- if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s\n %s"),
- name, g_strerror (errno));
- g_free(name);
- return NULL;
- }
-
- message = camel_mime_message_new();
- if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message: %s\n %s"),
- name, _("Invalid message contents"));
- g_free(name);
- camel_object_unref((CamelObject *)message_stream);
- camel_object_unref((CamelObject *)message);
- return NULL;
-
- }
- camel_object_unref((CamelObject *)message_stream);
- g_free(name);
-
- return message;
-}
diff --git a/camel/providers/local/camel-mh-folder.h b/camel/providers/local/camel-mh-folder.h
deleted file mode 100644
index 125f8c8ac5..0000000000
--- a/camel/providers/local/camel-mh-folder.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999 Ximian Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_MH_FOLDER_H
-#define CAMEL_MH_FOLDER_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus } */
-#include "camel-local-folder.h"
-
-#define CAMEL_MH_FOLDER_TYPE (camel_mh_folder_get_type ())
-#define CAMEL_MH_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MH_FOLDER_TYPE, CamelMhFolder))
-#define CAMEL_MH_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MH_FOLDER_TYPE, CamelMhFolderClass))
-#define CAMEL_IS_MH_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_MH_FOLDER_TYPE))
-
-typedef struct {
- CamelLocalFolder parent_object;
-
-} CamelMhFolder;
-
-typedef struct {
- CamelLocalFolderClass parent_class;
-
- /* Virtual methods */
-
-} CamelMhFolderClass;
-
-/* public methods */
-CamelFolder *camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex);
-
-/* Standard Camel function */
-CamelType camel_mh_folder_get_type(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* CAMEL_MH_FOLDER_H */
diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c
deleted file mode 100644
index 73a3d2046f..0000000000
--- a/camel/providers/local/camel-mh-store.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-
-#include "camel-mh-store.h"
-#include "camel-mh-folder.h"
-#include "camel-exception.h"
-#include "camel-url.h"
-#include "camel-private.h"
-
-#include <camel/camel-stream-fs.h>
-#include <camel/camel-stream-buffer.h>
-
-static CamelLocalStoreClass *parent_class = NULL;
-
-#define d(x)
-
-/* Returns the class for a CamelMhStore */
-#define CMHS_CLASS(so) CAMEL_MH_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CMHF_CLASS(so) CAMEL_MH_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static void construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex);
-static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex);
-static CamelFolder *get_inbox (CamelStore *store, CamelException *ex);
-static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex);
-static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex);
-static CamelFolderInfo * get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
-
-static void camel_mh_store_class_init(CamelObjectClass * camel_mh_store_class)
-{
- CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS(camel_mh_store_class);
- CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_mh_store_class);
-
- parent_class = (CamelLocalStoreClass *)camel_type_get_global_classfuncs(camel_local_store_get_type());
-
- /* virtual method overload, use defaults for most */
- camel_service_class->construct = construct;
-
- camel_store_class->get_folder = get_folder;
- camel_store_class->get_inbox = get_inbox;
- camel_store_class->delete_folder = delete_folder;
- camel_store_class->rename_folder = rename_folder;
- camel_store_class->get_folder_info = get_folder_info;
-}
-
-CamelType camel_mh_store_get_type(void)
-{
- static CamelType camel_mh_store_type = CAMEL_INVALID_TYPE;
-
- if (camel_mh_store_type == CAMEL_INVALID_TYPE) {
- camel_mh_store_type = camel_type_register(CAMEL_LOCAL_STORE_TYPE, "CamelMhStore",
- sizeof(CamelMhStore),
- sizeof(CamelMhStoreClass),
- (CamelObjectClassInitFunc) camel_mh_store_class_init,
- NULL,
- NULL,
- NULL);
- }
-
- return camel_mh_store_type;
-}
-
-static void
-construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
-{
- CamelMhStore *mh_store = (CamelMhStore *)service;
-
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
- if (camel_exception_is_set (ex))
- return;
-
- if (camel_url_get_param(url, "dotfolders"))
- mh_store->flags |= CAMEL_MH_DOTFOLDERS;
-}
-
-enum {
- UPDATE_NONE,
- UPDATE_ADD,
- UPDATE_REMOVE,
-};
-
-/* update the .folders file if it exists, or create it if it doesn't */
-static void
-folders_update(const char *root, const char *folder, int mode)
-{
- char *tmp, *tmpnew, *line = NULL;
- CamelStream *stream, *in = NULL, *out = NULL;
-
- tmpnew = g_alloca (strlen (root) + 16);
- sprintf (tmpnew, "%s.folders~", root);
-
- out = camel_stream_fs_new_with_name(tmpnew, O_WRONLY|O_CREAT|O_TRUNC, 0666);
- if (out == NULL)
- goto fail;
-
- tmp = g_alloca (strlen (root) + 16);
- sprintf (tmp, "%s.folders", root);
- stream = camel_stream_fs_new_with_name(tmp, O_RDONLY, 0);
- if (stream) {
- in = camel_stream_buffer_new(stream, CAMEL_STREAM_BUFFER_READ);
- camel_object_unref(stream);
- }
- if (in == NULL || stream == NULL) {
- if (mode == UPDATE_ADD && camel_stream_printf(out, "%s\n", folder) == -1)
- goto fail;
- goto done;
- }
-
- while ((line = camel_stream_buffer_read_line((CamelStreamBuffer *)in))) {
- int copy = TRUE;
-
- switch (mode) {
- case UPDATE_REMOVE:
- if (strcmp(line, folder) == 0)
- copy = FALSE;
- break;
- case UPDATE_ADD: {
- int cmp = strcmp(line, folder);
-
- if (cmp > 0) {
- /* found insertion point */
- if (camel_stream_printf(out, "%s\n", folder) == -1)
- goto fail;
- mode = UPDATE_NONE;
- } else if (tmp == 0) {
- /* already there */
- mode = UPDATE_NONE;
- }
- break; }
- case UPDATE_NONE:
- break;
- }
-
- if (copy && camel_stream_printf(out, "%s\n", line) == -1)
- goto fail;
-
- g_free(line);
- line = NULL;
- }
-
- /* add to end? */
- if (mode == UPDATE_ADD && camel_stream_printf(out, "%s\n", folder) == -1)
- goto fail;
-
- if (camel_stream_close(out) == -1)
- goto fail;
-
-done:
- /* should we care if this fails? I suppose so ... */
- rename(tmpnew, tmp);
-fail:
- unlink(tmpnew); /* remove it if its there */
- g_free(line);
- if (in)
- camel_object_unref(in);
- if (out)
- camel_object_unref(out);
-}
-
-static CamelFolder *
-get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex)
-{
- char *name;
- struct stat st;
-
- if (!((CamelStoreClass *)parent_class)->get_folder(store, folder_name, flags, ex))
- return NULL;
-
- name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
-
- if (stat(name, &st) == -1) {
- if (errno != ENOENT) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open folder `%s':\n%s"),
- folder_name, g_strerror (errno));
- g_free (name);
- return NULL;
- }
- if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Folder `%s' does not exist."), folder_name);
- g_free (name);
- return NULL;
- }
-
- if (mkdir(name, 0700) != 0) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create folder `%s':\n%s"),
- folder_name, g_strerror (errno));
- g_free (name);
- return NULL;
- }
-
- /* add to .folders if we are supposed to */
- /* FIXME: throw exception on error */
- if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS)
- folders_update(((CamelLocalStore *)store)->toplevel_dir, folder_name, UPDATE_ADD);
-
- } else if (!S_ISDIR(st.st_mode)) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("`%s' is not a directory."), name);
- g_free (name);
- return NULL;
- }
- g_free(name);
-
- return camel_mh_folder_new(store, folder_name, flags, ex);
-}
-
-static CamelFolder *
-get_inbox (CamelStore *store, CamelException *ex)
-{
- return get_folder (store, "inbox", 0, ex);
-}
-
-static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex)
-{
- char *name;
-
- /* remove folder directory - will fail if not empty */
- name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
- if (rmdir(name) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not delete folder `%s': %s"),
- folder_name, g_strerror (errno));
- g_free(name);
- return;
- }
- g_free(name);
-
- /* remove from .folders if we are supposed to */
- if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS)
- folders_update(((CamelLocalStore *)store)->toplevel_dir, folder_name, UPDATE_REMOVE);
-
- /* and remove metadata */
- ((CamelStoreClass *)parent_class)->delete_folder(store, folder_name, ex);
-}
-
-static void
-rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex)
-{
- CamelException e;
-
- camel_exception_init(&e);
- ((CamelStoreClass *)parent_class)->rename_folder(store, old, new, &e);
- if (camel_exception_is_set(&e)) {
- camel_exception_xfer(ex, &e);
- return;
- }
- camel_exception_clear(&e);
-
- if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) {
- /* yeah this is messy, but so is mh! */
- folders_update(((CamelLocalStore *)store)->toplevel_dir, new, UPDATE_ADD);
- folders_update(((CamelLocalStore *)store)->toplevel_dir, old, UPDATE_REMOVE);
- }
-}
-
-static CamelFolderInfo *folder_info_new(CamelStore *store, const char *root, const char *path)
-{
- CamelFolderInfo *fi;
- char *base;
- CamelFolder *folder;
-
- base = strrchr(path, '/');
-
- /* Build the folder info structure. */
- fi = g_malloc0(sizeof(*fi));
- fi->url = g_strdup_printf("mh:%s#%s", root, path);
- fi->full_name = g_strdup(path);
- fi->name = g_strdup(base?base+1:path);
- fi->unread_message_count = 0;
-
- /* check unread count if open */
- folder = camel_object_bag_get(store->folders, path);
- if (folder) {
- if ((((CamelMhStore *)store)->flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- camel_folder_refresh_info(folder, NULL);
- fi->unread_message_count = camel_folder_get_unread_message_count(folder);
- camel_object_unref(folder);
- }
-
- /* We could: if we have no folder, and FAST isn't specified, perform a full
- scan of all messages for their status flags. But its probably not worth
- it as we need to read the top of every file, i.e. very very slow */
-
- camel_folder_info_build_path(fi, '/');
-
- d(printf("New folderinfo:\n '%s'\n '%s'\n '%s'\n", fi->full_name, fi->url, fi->path));
-
- return fi;
-}
-
-/* used to find out where we've visited already */
-struct _inode {
- dev_t dnode;
- ino_t inode;
-};
-
-/* Scan path, under root, for directories to add folders for. Both
- * root and path should have a trailing "/" if they aren't empty. */
-static void recursive_scan(CamelStore *store, CamelFolderInfo **fip, CamelFolderInfo *parent, GHashTable *visited, const char *root, const char *path)
-{
- char *fullpath, *tmp;
- DIR *dp;
- struct dirent *d;
- struct stat st;
- CamelFolderInfo *fi;
- struct _inode in, *inew;
-
- /* Open the specified directory. */
- if (path[0]) {
- fullpath = alloca (strlen (root) + strlen (path) + 2);
- sprintf (fullpath, "%s/%s", root, path);
- } else
- fullpath = (char *)root;
-
- if (stat(fullpath, &st) == -1 || !S_ISDIR(st.st_mode))
- return;
-
- in.dnode = st.st_dev;
- in.inode = st.st_ino;
-
- /* see if we've visited already */
- if (g_hash_table_lookup(visited, &in) != NULL)
- return;
-
- inew = g_malloc(sizeof(*inew));
- *inew = in;
- g_hash_table_insert(visited, inew, inew);
-
- /* link in ... */
- fi = folder_info_new(store, root, path);
- fi->parent = parent;
- fi->sibling = *fip;
- *fip = fi;
-
- if ((( ((CamelMhStore *)store)->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || parent == NULL)) {
- /* now check content for possible other directories */
- dp = opendir(fullpath);
- if (dp == NULL)
- return;
-
- /* Look for subdirectories to add and scan. */
- while ((d = readdir(dp)) != NULL) {
- /* Skip current and parent directory. */
- if (strcmp(d->d_name, ".") == 0
- || strcmp(d->d_name, "..") == 0)
- continue;
-
- /* skip fully-numerical entries (i.e. mh messages) */
- strtoul(d->d_name, &tmp, 10);
- if (*tmp == 0)
- continue;
-
- /* otherwise, treat at potential node, and recurse, a bit more expensive than needed, but tough! */
- if (path[0]) {
- tmp = g_strdup_printf("%s/%s", path, d->d_name);
- recursive_scan(store, &fi->child, fi, visited, root, tmp);
- g_free(tmp);
- } else {
- recursive_scan(store, &fi->child, fi, visited, root, d->d_name);
- }
- }
-
- closedir(dp);
- }
-}
-
-/* scan a .folders file */
-static void
-folders_scan(CamelStore *store, const char *root, const char *top, CamelFolderInfo **fip)
-{
- CamelFolderInfo *fi;
- char line[512], *path, *tmp;
- CamelStream *stream, *in;
- struct stat st;
- GPtrArray *folders;
- GHashTable *visited;
- int len;
-
- tmp = g_alloca (strlen (root) + 16);
- sprintf (tmp, "%s/.folders", root);
- stream = camel_stream_fs_new_with_name(tmp, 0, O_RDONLY);
- if (stream == NULL)
- return;
-
- in = camel_stream_buffer_new(stream, CAMEL_STREAM_BUFFER_READ);
- camel_object_unref(stream);
- if (in == NULL)
- return;
-
- visited = g_hash_table_new(g_str_hash, g_str_equal);
- folders = g_ptr_array_new();
-
- while ( (len = camel_stream_buffer_gets((CamelStreamBuffer *)in, line, sizeof(line))) > 0) {
- /* ignore blank lines */
- if (len <= 1)
- continue;
- /* check for invalidly long lines, we abort evreything and fallback */
- if (line[len-1] != '\n') {
- int i;
-
- for (i=0;i<folders->len;i++)
- camel_folder_info_free(folders->pdata[i]);
- g_ptr_array_set_size(folders, 0);
- break;
- }
- line[len-1] = 0;
-
- /* check for \r ? */
-
- if (top && top[0]) {
- int toplen = strlen(top);
-
- /* check is subdir */
- if (strncmp(top, line, len) != 0)
- continue;
-
- /* check is not sub-subdir if not recursive */
- if (( ((CamelMhStore *)store)->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0
- && (tmp = strrchr(line, '/'))
- && tmp > line+toplen)
- continue;
- }
-
- if (g_hash_table_lookup(visited, line) != NULL)
- continue;
-
- tmp = g_strdup(line);
- g_hash_table_insert(visited, tmp, tmp);
-
- path = g_strdup_printf("%s/%s", root, line);
- if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
- fi = folder_info_new(store, root, line);
- g_ptr_array_add(folders, fi);
- }
- g_free(path);
- }
-
- if (folders->len)
- *fip = camel_folder_info_build(folders, NULL, '/', TRUE);
- g_ptr_array_free(folders, TRUE);
-
- g_hash_table_foreach(visited, (GHFunc)g_free, NULL);
- g_hash_table_destroy(visited);
-
- camel_object_unref(in);
-}
-
-/* FIXME: move to camel-local, this is shared with maildir code */
-static guint inode_hash(const void *d)
-{
- const struct _inode *v = d;
-
- return v->inode ^ v->dnode;
-}
-
-static gboolean inode_equal(const void *a, const void *b)
-{
- const struct _inode *v1 = a, *v2 = b;
-
- return v1->inode == v2->inode && v1->dnode == v2->dnode;
-}
-
-static void inode_free(void *k, void *v, void *d)
-{
- g_free(k);
-}
-
-static CamelFolderInfo *
-get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelFolderInfo *fi = NULL;
- char *root;
-
- root = ((CamelService *)store)->url->path;
-
- /* use .folders if we are supposed to */
- if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) {
- folders_scan(store, root, top, &fi);
- } else {
- GHashTable *visited = g_hash_table_new(inode_hash, inode_equal);
-
- if (top == NULL)
- top = "";
-
- recursive_scan(store, &fi, NULL, visited, root, top);
-
- /* if we actually scanned from root, we have a "" root node we dont want */
- if (fi != NULL && top[0] == 0) {
- CamelFolderInfo *rfi;
-
- rfi = fi;
- fi = rfi->child;
- rfi->child = NULL;
- camel_folder_info_free(rfi);
- }
-
- g_hash_table_foreach(visited, inode_free, NULL);
- g_hash_table_destroy(visited);
- }
-
- return fi;
-}
diff --git a/camel/providers/local/camel-mh-store.h b/camel/providers/local/camel-mh-store.h
deleted file mode 100644
index 96522cb01f..0000000000
--- a/camel/providers/local/camel-mh-store.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_MH_STORE_H
-#define CAMEL_MH_STORE_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus } */
-
-#include "camel-local-store.h"
-
-#define CAMEL_MH_STORE_TYPE (camel_mh_store_get_type ())
-#define CAMEL_MH_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_MH_STORE_TYPE, CamelMhStore))
-#define CAMEL_MH_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MH_STORE_TYPE, CamelMhStoreClass))
-#define CAMEL_IS_MH_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_MH_STORE_TYPE))
-
-enum {
- CAMEL_MH_DOTFOLDERS = (1<<0), /* update/use .folders file */
-};
-
-typedef struct {
- CamelLocalStore parent_object;
-
- guint32 flags;
-} CamelMhStore;
-
-typedef struct {
- CamelLocalStoreClass parent_class;
-
-} CamelMhStoreClass;
-
-/* public methods */
-
-/* Standard Camel function */
-CamelType camel_mh_store_get_type(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* CAMEL_MH_STORE_H */
diff --git a/camel/providers/local/camel-mh-summary.c b/camel/providers/local/camel-mh-summary.c
deleted file mode 100644
index 5dd26ac9ba..0000000000
--- a/camel/providers/local/camel-mh-summary.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Not Zed <notzed@lostzed.mmc.com.au>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <dirent.h>
-
-#include <ctype.h>
-
-#include "camel-mh-summary.h"
-#include <camel/camel-mime-message.h>
-
-#include "camel-private.h"
-
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-#define CAMEL_MH_SUMMARY_VERSION (0x2000)
-
-static int mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-static int mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-/*static int mh_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);*/
-
-static char *mh_summary_next_uid_string(CamelFolderSummary *s);
-
-static void camel_mh_summary_class_init (CamelMhSummaryClass *class);
-static void camel_mh_summary_init (CamelMhSummary *gspaper);
-static void camel_mh_summary_finalise (CamelObject *obj);
-
-#define _PRIVATE(x) (((CamelMhSummary *)(x))->priv)
-
-struct _CamelMhSummaryPrivate {
- char *current_uid;
-};
-
-static CamelLocalSummaryClass *parent_class;
-
-CamelType
-camel_mh_summary_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(camel_local_summary_get_type (), "CamelMhSummary",
- sizeof(CamelMhSummary),
- sizeof(CamelMhSummaryClass),
- (CamelObjectClassInitFunc)camel_mh_summary_class_init,
- NULL,
- (CamelObjectInitFunc)camel_mh_summary_init,
- (CamelObjectFinalizeFunc)camel_mh_summary_finalise);
- }
-
- return type;
-}
-
-static void
-camel_mh_summary_class_init (CamelMhSummaryClass *class)
-{
- CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *) class;
- CamelLocalSummaryClass *lklass = (CamelLocalSummaryClass *)class;
-
- parent_class = (CamelLocalSummaryClass *)camel_type_get_global_classfuncs(camel_local_summary_get_type ());
-
- /* override methods */
- sklass->next_uid_string = mh_summary_next_uid_string;
-
- lklass->check = mh_summary_check;
- lklass->sync = mh_summary_sync;
- /*lklass->add = mh_summary_add;*/
-}
-
-static void
-camel_mh_summary_init (CamelMhSummary *o)
-{
- struct _CamelFolderSummary *s = (CamelFolderSummary *) o;
-
- o->priv = g_malloc0(sizeof(*o->priv));
- /* set unique file version */
- s->version += CAMEL_MH_SUMMARY_VERSION;
-}
-
-static void
-camel_mh_summary_finalise(CamelObject *obj)
-{
- CamelMhSummary *o = (CamelMhSummary *)obj;
-
- g_free(o->priv);
-}
-
-/**
- * camel_mh_summary_new:
- *
- * Create a new CamelMhSummary object.
- *
- * Return value: A new #CamelMhSummary object.
- **/
-CamelMhSummary *camel_mh_summary_new (const char *filename, const char *mhdir, CamelIndex *index)
-{
- CamelMhSummary *o = (CamelMhSummary *)camel_object_new(camel_mh_summary_get_type ());
-
- camel_local_summary_construct((CamelLocalSummary *)o, filename, mhdir, index);
- return o;
-}
-
-static char *mh_summary_next_uid_string(CamelFolderSummary *s)
-{
- CamelMhSummary *mhs = (CamelMhSummary *)s;
- CamelLocalSummary *cls = (CamelLocalSummary *)s;
- int fd = -1;
- guint32 uid;
- char *name;
- char *uidstr;
-
- /* if we are working to add an existing file, then use current_uid */
- if (mhs->priv->current_uid) {
- uidstr = g_strdup(mhs->priv->current_uid);
- /* tell the summary of this, so we always append numbers to the end */
- camel_folder_summary_set_uid(s, strtoul(uidstr, NULL, 10)+1);
- } else {
- /* else scan for one - and create it too, to make sure */
- do {
- close(fd);
- uid = camel_folder_summary_next_uid(s);
- name = g_strdup_printf("%s/%u", cls->folder_path, uid);
- /* O_EXCL isn't guaranteed, sigh. Oh well, bad luck, mh has problems anyway */
- fd = open(name, O_WRONLY|O_CREAT|O_EXCL, 0600);
- g_free(name);
- } while (fd == -1 && errno == EEXIST);
-
- close(fd);
-
- uidstr = g_strdup_printf("%u", uid);
- }
-
- return uidstr;
-}
-
-static int camel_mh_summary_add(CamelLocalSummary *cls, const char *name, int forceindex)
-{
- CamelMhSummary *mhs = (CamelMhSummary *)cls;
- char *filename = g_strdup_printf("%s/%s", cls->folder_path, name);
- int fd;
- CamelMimeParser *mp;
-
- d(printf("summarising: %s\n", name));
-
- fd = open(filename, O_RDONLY);
- if (fd == -1) {
- g_warning ("Cannot summarise/index: %s: %s", filename, strerror (errno));
- g_free(filename);
- return -1;
- }
- mp = camel_mime_parser_new();
- camel_mime_parser_scan_from(mp, FALSE);
- camel_mime_parser_init_with_fd(mp, fd);
- if (cls->index && (forceindex || !camel_index_has_name(cls->index, name))) {
- d(printf("forcing indexing of message content\n"));
- camel_folder_summary_set_index((CamelFolderSummary *)mhs, cls->index);
- } else {
- camel_folder_summary_set_index((CamelFolderSummary *)mhs, NULL);
- }
- mhs->priv->current_uid = (char *)name;
- camel_folder_summary_add_from_parser((CamelFolderSummary *)mhs, mp);
- camel_object_unref((CamelObject *)mp);
- mhs->priv->current_uid = NULL;
- camel_folder_summary_set_index((CamelFolderSummary *)mhs, NULL);
- g_free(filename);
- return 0;
-}
-
-static void
-remove_summary(char *key, CamelMessageInfo *info, CamelLocalSummary *cls)
-{
- d(printf("removing message %s from summary\n", key));
- if (cls->index)
- camel_index_delete_name(cls->index, camel_message_info_uid(info));
- camel_folder_summary_remove((CamelFolderSummary *)cls, info);
- camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
-}
-
-static int
-sort_uid_cmp(const void *ap, const void *bp)
-{
- const CamelMessageInfo
- *a = *((CamelMessageInfo **)ap),
- *b = *((CamelMessageInfo **)bp);
- const char
- *auid = camel_message_info_uid(a),
- *buid = camel_message_info_uid(b);
- int aval = atoi(auid), bval = atoi(buid);
-
- return (aval < bval) ? -1 : (aval > bval) ? 1 : 0;
-}
-
-static int
-mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- DIR *dir;
- struct dirent *d;
- char *p, c;
- CamelMessageInfo *info;
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
- GHashTable *left;
- int i, count;
- int forceindex;
-
- /* FIXME: Handle changeinfo */
-
- d(printf("checking summary ...\n"));
-
- /* scan the directory, check for mail files not in the index, or index entries that
- no longer exist */
- dir = opendir(cls->folder_path);
- if (dir == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot open MH directory path: %s: %s"),
- cls->folder_path, g_strerror (errno));
- return -1;
- }
-
- /* keeps track of all uid's that have not been processed */
- left = g_hash_table_new(g_str_hash, g_str_equal);
- count = camel_folder_summary_count((CamelFolderSummary *)cls);
- forceindex = count == 0;
- for (i=0;i<count;i++) {
- info = camel_folder_summary_index((CamelFolderSummary *)cls, i);
- if (info) {
- g_hash_table_insert(left, (char *)camel_message_info_uid(info), info);
- }
- }
-
- while ( (d = readdir(dir)) ) {
- /* FIXME: also run stat to check for regular file */
- p = d->d_name;
- while ( (c = *p++) ) {
- if (!isdigit(c))
- break;
- }
- if (c==0) {
- info = camel_folder_summary_uid((CamelFolderSummary *)cls, d->d_name);
- if (info == NULL || (cls->index && (!camel_index_has_name(cls->index, d->d_name)))) {
- /* need to add this file to the summary */
- if (info != NULL) {
- g_hash_table_remove(left, camel_message_info_uid(info));
- camel_folder_summary_remove((CamelFolderSummary *)cls, info);
- camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
- }
- camel_mh_summary_add(cls, d->d_name, forceindex);
- } else {
- const char *uid = camel_message_info_uid(info);
- CamelMessageInfo *old = g_hash_table_lookup(left, uid);
-
- if (old) {
- camel_folder_summary_info_free((CamelFolderSummary *)cls, old);
- g_hash_table_remove(left, uid);
- }
- camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
- }
- }
- }
- closedir(dir);
- g_hash_table_foreach(left, (GHFunc)remove_summary, cls);
- g_hash_table_destroy(left);
-
- /* sort the summary based on message number (uid), since the directory order is not useful */
- CAMEL_SUMMARY_LOCK(s, summary_lock);
- qsort(s->messages->pdata, s->messages->len, sizeof(CamelMessageInfo *), sort_uid_cmp);
- CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-
- return 0;
-}
-
-static int
-mh_summary_sync_message(CamelLocalSummary *cls, CamelMessageInfo *info, CamelException *ex)
-{
- CamelMimeParser *mp;
- const char *xev, *buffer;
- int xevoffset;
- int fd, outfd, len, outlen, ret=0;
- char *name, *tmpname, *xevnew;
-
- name = g_strdup_printf("%s/%s", cls->folder_path, camel_message_info_uid(info));
- fd = open(name, O_RDWR);
- if (fd == -1)
- return -1;
-
- mp = camel_mime_parser_new();
- camel_mime_parser_init_with_fd(mp, fd);
- if (camel_mime_parser_step(mp, 0, 0) != CAMEL_MIME_PARSER_STATE_EOF) {
- xev = camel_mime_parser_header(mp, "X-Evolution", &xevoffset);
- d(printf("xev = '%s'\n", xev));
- xevnew = camel_local_summary_encode_x_evolution(cls, info);
- if (xev == NULL
- || camel_local_summary_decode_x_evolution(cls, xev, NULL) == -1
- || strlen(xev)-1 != strlen(xevnew)) {
-
- d(printf("camel local summary_decode_xev = %d\n", camel_local_summary_decode_x_evolution(cls, xev, NULL)));
-
- /* need to write a new copy/unlink old */
- tmpname = g_strdup_printf("%s/.tmp.%d.%s", cls->folder_path, getpid(), camel_message_info_uid(info));
- d(printf("old xev was %d %s new xev is %d %s\n", strlen(xev), xev, strlen(xevnew), xevnew));
- d(printf("creating new message %s\n", tmpname));
- outfd = open(tmpname, O_CREAT|O_WRONLY|O_TRUNC, 0600);
- if (outfd != -1) {
- outlen = 0;
- len = camel_local_summary_write_headers(outfd, camel_mime_parser_headers_raw(mp), xevnew, NULL, NULL);
- if (len != -1) {
- while (outlen != -1 && (len = camel_mime_parser_read(mp, &buffer, 10240)) > 0) {
- d(printf("camel mime parser read, read %d bytes: %.*s\n", len, len, buffer));
- do {
- outlen = write(outfd, buffer, len);
- } while (outlen == -1 && errno == EINTR);
- }
- }
-
- d(printf("len = %d outlen = %d, renaming/finishing\n", len, outlen));
- if (close(outfd) == -1
- || len == -1
- || outlen == -1
- || rename(tmpname, name) == -1) {
- unlink(tmpname);
- ret = -1;
- }
- } else {
- g_warning("sync can't create tmp file: %s", strerror (errno));
- }
- g_free(tmpname);
- } else {
- d(printf("stamping in updated X-EV at %d\n", (int)xevoffset));
- /* else, we can just update the flags field */
- lseek(fd, xevoffset+strlen("X-Evolution: "), SEEK_SET);
- do {
- len = write(fd, xevnew, strlen(xevnew));
- } while (len == -1 && errno == EINTR);
- if (len == -1)
- ret = -1;
- }
-
- g_free(xevnew);
- }
-
- camel_object_unref((CamelObject *)mp);
- g_free(name);
- return ret;
-}
-
-/* sync the summary file with the ondisk files */
-static int
-mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- int count, i;
- CamelMessageInfo *info;
- char *name;
- const char *uid;
-
- d(printf("summary_sync(expunge=%s)\n", expunge?"true":"false"));
-
- /* we could probably get away without this ... but why not use it, esp if we're going to
- be doing any significant io already */
- if (camel_local_summary_check(cls, changes, ex) == -1)
- return -1;
-
- count = camel_folder_summary_count((CamelFolderSummary *)cls);
- for (i=count-1;i>=0;i--) {
- info = camel_folder_summary_index((CamelFolderSummary *)cls, i);
- g_assert(info);
- if (expunge && (info->flags & CAMEL_MESSAGE_DELETED)) {
- uid = camel_message_info_uid(info);
- name = g_strdup_printf("%s/%s", cls->folder_path, uid);
- d(printf("deleting %s\n", name));
- if (unlink(name) == 0 || errno==ENOENT) {
-
- /* FIXME: put this in folder_summary::remove()? */
- if (cls->index)
- camel_index_delete_name(cls->index, (char *)uid);
-
- camel_folder_change_info_remove_uid(changes, uid);
- camel_folder_summary_remove((CamelFolderSummary *)cls, info);
- }
- g_free(name);
- } else if (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- if (mh_summary_sync_message(cls, info, ex) != -1) {
- info->flags &= 0xffff;
- } else {
- g_warning("Problem occured when trying to expunge, ignored");
- }
- }
- camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
- }
-
- return ((CamelLocalSummaryClass *)parent_class)->sync(cls, expunge, changes, ex);
-}
diff --git a/camel/providers/local/camel-mh-summary.h b/camel/providers/local/camel-mh-summary.h
deleted file mode 100644
index 4ee30df63b..0000000000
--- a/camel/providers/local/camel-mh-summary.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Not Zed <notzed@lostzed.mmc.com.au>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_MH_SUMMARY_H
-#define _CAMEL_MH_SUMMARY_H
-
-#include "camel-local-summary.h"
-#include <camel/camel-folder.h>
-#include <camel/camel-exception.h>
-#include <camel/camel-index.h>
-
-#define CAMEL_MH_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_mh_summary_get_type (), CamelMhSummary)
-#define CAMEL_MH_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_mh_summary_get_type (), CamelMhSummaryClass)
-#define CAMEL_IS_MH_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_mh_summary_get_type ())
-
-typedef struct _CamelMhSummary CamelMhSummary;
-typedef struct _CamelMhSummaryClass CamelMhSummaryClass;
-
-struct _CamelMhSummary {
- CamelLocalSummary parent;
- struct _CamelMhSummaryPrivate *priv;
-};
-
-struct _CamelMhSummaryClass {
- CamelLocalSummaryClass parent_class;
-
- /* virtual methods */
-
- /* signals */
-};
-
-CamelType camel_mh_summary_get_type (void);
-CamelMhSummary *camel_mh_summary_new (const char *filename, const char *mhdir, CamelIndex *index);
-
-#endif /* ! _CAMEL_MH_SUMMARY_H */
-
diff --git a/camel/providers/local/camel-spool-folder.c b/camel/providers/local/camel-spool-folder.c
deleted file mode 100644
index 4c4a49fbf9..0000000000
--- a/camel/providers/local/camel-spool-folder.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2001-2003 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include "camel-spool-folder.h"
-#include "camel-spool-store.h"
-#include "camel-stream-fs.h"
-#include "camel-spool-summary.h"
-#include "camel-data-wrapper.h"
-#include "camel-mime-message.h"
-#include "camel-stream-filter.h"
-#include "camel-mime-filter-from.h"
-#include "camel-exception.h"
-
-#include "camel-lock-client.h"
-
-#include "camel-local-private.h"
-
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-static CamelFolderClass *parent_class = NULL;
-
-/* Returns the class for a CamelSpoolFolder */
-#define CSPOOLF_CLASS(so) CAMEL_SPOOL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CSPOOLS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static CamelLocalSummary *spool_create_summary(const char *path, const char *folder, CamelIndex *index);
-
-static int spool_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex);
-static void spool_unlock(CamelLocalFolder *lf);
-
-static void spool_finalize(CamelObject * object);
-
-static void
-camel_spool_folder_class_init(CamelSpoolFolderClass *klass)
-{
- CamelLocalFolderClass *lklass = (CamelLocalFolderClass *)klass;
-
- parent_class = (CamelFolderClass *)camel_mbox_folder_get_type();
-
- /* virtual method overload */
- lklass->create_summary = spool_create_summary;
- lklass->lock = spool_lock;
- lklass->unlock = spool_unlock;
-}
-
-static void
-spool_init(gpointer object, gpointer klass)
-{
- CamelSpoolFolder *spool_folder = object;
-
- spool_folder->lockid = -1;
-}
-
-static void
-spool_finalize(CamelObject * object)
-{
- /*CamelSpoolFolder *spool_folder = CAMEL_SPOOL_FOLDER(object);*/
-}
-
-CamelType camel_spool_folder_get_type(void)
-{
- static CamelType camel_spool_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_spool_folder_type == CAMEL_INVALID_TYPE) {
- camel_spool_folder_type = camel_type_register(camel_mbox_folder_get_type(), "CamelSpoolFolder",
- sizeof(CamelSpoolFolder),
- sizeof(CamelSpoolFolderClass),
- (CamelObjectClassInitFunc) camel_spool_folder_class_init,
- NULL,
- (CamelObjectInitFunc) spool_init,
- (CamelObjectFinalizeFunc) spool_finalize);
- }
-
- return camel_spool_folder_type;
-}
-
-CamelFolder *
-camel_spool_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex)
-{
- CamelFolder *folder;
-
- d(printf("Creating spool folder: %s in %s\n", full_name, camel_local_store_get_toplevel_dir((CamelLocalStore *)parent_store)));
-
- folder = (CamelFolder *)camel_object_new(CAMEL_SPOOL_FOLDER_TYPE);
-
- if (parent_store->flags & CAMEL_STORE_FILTER_INBOX
- && strcmp(full_name, "INBOX") == 0)
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
- flags &= CAMEL_STORE_FOLDER_BODY_INDEX;
-
- folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder, parent_store, full_name, flags, ex);
- if (folder) {
- if (camel_url_get_param(((CamelService *)parent_store)->url, "xstatus"))
- camel_mbox_summary_xstatus((CamelMboxSummary *)folder->summary, TRUE);
- }
-
- return folder;
-}
-
-static CamelLocalSummary *
-spool_create_summary(const char *path, const char *folder, CamelIndex *index)
-{
- return (CamelLocalSummary *)camel_spool_summary_new(folder);
-}
-
-static int
-spool_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex)
-{
- int retry = 0;
- CamelMboxFolder *mf = (CamelMboxFolder *)lf;
- CamelSpoolFolder *sf = (CamelSpoolFolder *)lf;
-
- mf->lockfd = open(lf->folder_path, O_RDWR, 0);
- if (mf->lockfd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder lock on %s: %s"),
- lf->folder_path, g_strerror (errno));
- return -1;
- }
-
- while (retry < CAMEL_LOCK_RETRY) {
- if (retry > 0)
- sleep(CAMEL_LOCK_DELAY);
-
- camel_exception_clear(ex);
-
- if (camel_lock_fcntl(mf->lockfd, type, ex) == 0) {
- if (camel_lock_flock(mf->lockfd, type, ex) == 0) {
- if ((sf->lockid = camel_lock_helper_lock(lf->folder_path, ex)) != -1)
- return 0;
- camel_unlock_flock(mf->lockfd);
- }
- camel_unlock_fcntl(mf->lockfd);
- }
- retry++;
- }
-
- return -1;
-}
-
-static void
-spool_unlock(CamelLocalFolder *lf)
-{
- CamelMboxFolder *mf = (CamelMboxFolder *)lf;
- CamelSpoolFolder *sf = (CamelSpoolFolder *)lf;
-
- camel_lock_helper_unlock(sf->lockid);
- sf->lockid = -1;
- camel_unlock_flock(mf->lockfd);
- camel_unlock_fcntl(mf->lockfd);
-
- close(mf->lockfd);
- mf->lockfd = -1;
-}
diff --git a/camel/providers/local/camel-spool-folder.h b/camel/providers/local/camel-spool-folder.h
deleted file mode 100644
index e778cdecf7..0000000000
--- a/camel/providers/local/camel-spool-folder.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Author: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2001 Ximian Inc (www.ximian.com/)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_SPOOL_FOLDER_H
-#define CAMEL_SPOOL_FOLDER_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-mbox-folder.h"
-#include <camel/camel-folder-search.h>
-#include <camel/camel-index.h>
-#include "camel-spool-summary.h"
-#include "camel-lock.h"
-
-/* #include "camel-store.h" */
-
-#define CAMEL_SPOOL_FOLDER_TYPE (camel_spool_folder_get_type ())
-#define CAMEL_SPOOL_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SPOOL_FOLDER_TYPE, CamelSpoolFolder))
-#define CAMEL_SPOOL_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SPOOL_FOLDER_TYPE, CamelSpoolFolderClass))
-#define CAMEL_IS_SPOOL_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_SPOOL_FOLDER_TYPE))
-
-typedef struct {
- CamelMboxFolder parent;
-
- struct _CamelSpoolFolderPrivate *priv;
-
- int lockid; /* lock id for dot locking */
-} CamelSpoolFolder;
-
-typedef struct {
- CamelMboxFolderClass parent_class;
-} CamelSpoolFolderClass;
-
-/* Standard Camel function */
-CamelType camel_spool_folder_get_type(void);
-
-CamelFolder *camel_spool_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_SPOOL_FOLDER_H */
diff --git a/camel/providers/local/camel-spool-store.c b/camel/providers/local/camel-spool-store.c
deleted file mode 100644
index 09720e4a01..0000000000
--- a/camel/providers/local/camel-spool-store.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2001 Ximian Inc (www.ximian.com/)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <dirent.h>
-
-#include "camel-spool-store.h"
-#include "camel-spool-folder.h"
-#include "camel-exception.h"
-#include "camel-url.h"
-#include "camel-private.h"
-
-#define d(x)
-
-/* Returns the class for a CamelSpoolStore */
-#define CSPOOLS_CLASS(so) CAMEL_SPOOL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static void construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex);
-static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex);
-static char *get_name(CamelService *service, gboolean brief);
-static CamelFolder *get_inbox (CamelStore *store, CamelException *ex);
-static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
-static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
-static void free_folder_info (CamelStore *store, CamelFolderInfo *fi);
-
-static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex);
-static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex);
-
-static CamelStoreClass *parent_class = NULL;
-
-static void
-camel_spool_store_class_init (CamelSpoolStoreClass *camel_spool_store_class)
-{
- CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_spool_store_class);
- CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_spool_store_class);
-
- parent_class = CAMEL_STORE_CLASS(camel_mbox_store_get_type());
-
- /* virtual method overload */
- camel_service_class->construct = construct;
- camel_service_class->get_name = get_name;
- camel_store_class->get_folder = get_folder;
- camel_store_class->get_inbox = get_inbox;
- camel_store_class->get_folder_info = get_folder_info;
- camel_store_class->free_folder_info = free_folder_info;
-
- camel_store_class->delete_folder = delete_folder;
- camel_store_class->rename_folder = rename_folder;
-}
-
-CamelType
-camel_spool_store_get_type (void)
-{
- static CamelType camel_spool_store_type = CAMEL_INVALID_TYPE;
-
- if (camel_spool_store_type == CAMEL_INVALID_TYPE) {
- camel_spool_store_type = camel_type_register (camel_mbox_store_get_type(), "CamelSpoolStore",
- sizeof (CamelSpoolStore),
- sizeof (CamelSpoolStoreClass),
- (CamelObjectClassInitFunc) camel_spool_store_class_init,
- NULL,
- NULL,
- NULL);
- }
-
- return camel_spool_store_type;
-}
-
-static void
-construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
-{
- struct stat st;
-
- d(printf("constructing store of type %s '%s:%s'\n",
- camel_type_to_name(((CamelObject *)service)->s.type), url->protocol, url->path));
-
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
- if (camel_exception_is_set (ex))
- return;
-
- if (service->url->path[0] != '/') {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Store root %s is not an absolute path"), service->url->path);
- return;
- }
-
- if (stat(service->url->path, &st) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Spool `%s' cannot be opened: %s"),
- service->url->path, g_strerror (errno));
- return;
- }
-
- if (S_ISREG(st.st_mode))
- ((CamelSpoolStore *)service)->type = CAMEL_SPOOL_STORE_MBOX;
- else if (S_ISDIR(st.st_mode))
- /* we could check here for slight variations */
- ((CamelSpoolStore *)service)->type = CAMEL_SPOOL_STORE_ELM;
- else {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Spool `%s' is not a regular file or directory"),
- service->url->path);
- return;
- }
-}
-
-static CamelFolder *
-get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex)
-{
- CamelFolder *folder = NULL;
- struct stat st;
- char *name;
-
- d(printf("opening folder %s on path %s\n", folder_name, path));
-
- /* we only support an 'INBOX' in mbox mode */
- if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX) {
- if (strcmp(folder_name, "INBOX") != 0) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Folder `%s/%s' does not exist."),
- ((CamelService *)store)->url->path, folder_name);
- } else {
- folder = camel_spool_folder_new(store, folder_name, flags, ex);
- }
- } else {
- name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
- if (stat(name, &st) == -1) {
- if (errno != ENOENT) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open folder `%s':\n%s"),
- folder_name, g_strerror (errno));
- } else if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Folder `%s' does not exist."),
- folder_name);
- } else {
- if (creat (name, 0600) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create folder `%s':\n%s"),
- folder_name, g_strerror (errno));
- } else {
- folder = camel_spool_folder_new(store, folder_name, flags, ex);
- }
- }
- } else if (!S_ISREG(st.st_mode)) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("`%s' is not a mailbox file."), name);
- } else {
- folder = camel_spool_folder_new(store, folder_name, flags, ex);
- }
- g_free(name);
- }
-
- return folder;
-}
-
-static CamelFolder *
-get_inbox(CamelStore *store, CamelException *ex)
-{
- if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX)
- return get_folder (store, "INBOX", CAMEL_STORE_FOLDER_CREATE, ex);
- else {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Store does not support an INBOX"));
- return NULL;
- }
-}
-
-static char *
-get_name (CamelService *service, gboolean brief)
-{
- if (brief)
- return g_strdup(service->url->path);
- else
- return g_strdup_printf(((CamelSpoolStore *)service)->type == CAMEL_SPOOL_STORE_MBOX?
- _("Spool mail file %s"):_("Spool folder tree %s"), service->url->path);
-}
-
-/* default implementation, rename all */
-static void
-rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex)
-{
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Spool folders cannot be renamed"));
-}
-
-/* default implementation, only delete metadata */
-static void
-delete_folder(CamelStore *store, const char *folder_name, CamelException *ex)
-{
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Spool folders cannot be deleted"));
-}
-
-static void free_folder_info (CamelStore *store, CamelFolderInfo *fi)
-{
- if (fi) {
- g_free(fi->url);
- g_free(fi->name);
- g_free(fi->full_name);
- g_free(fi->path);
- g_free(fi);
- }
-}
-
-static CamelFolderInfo *
-camel_folder_info_new(const char *url, const char *full, const char *name, int unread)
-{
- CamelFolderInfo *fi;
-
- fi = g_malloc0(sizeof(*fi));
- fi->url = g_strdup(url);
- fi->full_name = g_strdup(full);
- fi->name = g_strdup(name);
- fi->unread_message_count = unread;
- camel_folder_info_build_path(fi, '/');
-
- d(printf("Adding spoold info: '%s' '%s' '%s' '%s'\n", fi->path, fi->name, fi->full_name, fi->url));
-
- return fi;
-}
-
-/* used to find out where we've visited already */
-struct _inode {
- dev_t dnode;
- ino_t inode;
-};
-
-/* returns number of records found at or below this level */
-static int scan_dir(CamelStore *store, GHashTable *visited, char *root, const char *path, guint32 flags, CamelFolderInfo *parent, CamelFolderInfo **fip, CamelException *ex)
-{
- DIR *dir;
- struct dirent *d;
- char *name, *uri, *tmp, *fname;
- CamelFolderInfo *fi = NULL;
- struct stat st;
- CamelFolder *folder;
- int unread;
- char from[80];
- FILE *fp;
-
- d(printf("checking dir '%s' part '%s' for mbox content\n", root, path));
-
- /* look for folders matching the right structure, recursively */
- if (path) {
- name = alloca(strlen(root) + strlen(path) + 2);
- sprintf(name, "%s/%s", root, path);
- } else
- name = root;
-
- if (stat(name, &st) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not scan folder `%s': %s"),
- name, g_strerror (errno));
- } else if (S_ISREG(st.st_mode)) {
- /* incase we start scanning from a file. messy duplication :-/ */
- if (path) {
- folder = camel_object_bag_get(store->folders, path);
- if (folder) {
- /* should this refresh if ! FAST? */
- unread = camel_folder_get_unread_message_count(folder);
- camel_object_unref(folder);
- } else
- unread = -1;
- tmp = strrchr(path, '/');
- if (tmp)
- tmp++;
- else
- tmp = (char *)path;
- uri = g_strdup_printf("%s:%s#%s", ((CamelService *)store)->url->protocol, root, path);
- fi = camel_folder_info_new(uri, path, tmp, unread);
- fi->parent = parent;
- fi->sibling = *fip;
- *fip = fi;
- g_free(uri);
- }
- return 0;
- }
-
- dir = opendir(name);
- if (dir == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not scan folder `%s': %s"),
- name, g_strerror (errno));
- return -1;
- }
-
- if (path != NULL) {
- uri = g_strdup_printf("%s:%s;noselect=yes#%s", ((CamelService *)store)->url->protocol, root, path);
- tmp = strrchr(path, '/');
- if (tmp == NULL)
- tmp = (char *)path;
- else
- tmp++;
- fi = camel_folder_info_new(uri, path, tmp, -1);
- fi->parent = parent;
- fi->sibling = *fip;
- *fip = fi;
- g_free(uri);
-
- fip = &fi->child;
- parent = fi;
- }
-
- while ( (d = readdir(dir)) ) {
- if (strcmp(d->d_name, ".") == 0
- || strcmp(d->d_name, "..") == 0)
- continue;
-
- tmp = g_strdup_printf("%s/%s", name, d->d_name);
- if (stat(tmp, &st) == 0) {
- if (path)
- fname = g_strdup_printf("%s/%s", path, d->d_name);
- else
- fname = g_strdup(d->d_name);
-
- if (S_ISREG(st.st_mode)) {
- /* first, see if we already have it open */
- folder = camel_object_bag_get(store->folders, fname);
- if (folder) {
- /* should this refresh if ! FAST? */
- unread = camel_folder_get_unread_message_count(folder);
- camel_object_unref(folder);
- } else
- unread = -1;
-
- /* no? check its content to see if its a folder or not */
- if (folder == NULL) {
- fp = fopen(tmp, "r");
- if (fp != NULL) {
- if (st.st_size == 0
- || (fgets(from, sizeof(from), fp) != NULL
- && strncmp(from, "From ", 5) == 0)) {
- folder = (CamelFolder *)1;
- /* TODO: if slow mode selected, we could look up unread counts here -
- but its pretty expensive */
- }
- fclose(fp);
- }
- }
-
- if (folder != NULL) {
- uri = g_strdup_printf("%s:%s#%s", ((CamelService *)store)->url->protocol, root, fname);
- fi = camel_folder_info_new(uri, fname, d->d_name, unread);
- fi->parent = parent;
- fi->sibling = *fip;
- *fip = fi;
- g_free(uri);
- }
-
- } else if (S_ISDIR(st.st_mode)) {
- struct _inode in = { st.st_dev, st.st_ino };
-
- /* see if we've visited already */
- if (g_hash_table_lookup(visited, &in) == NULL) {
- struct _inode *inew = g_malloc(sizeof(*inew));
-
- *inew = in;
- g_hash_table_insert(visited, inew, inew);
-
- if (scan_dir(store, visited, root, fname, flags, parent, fip, ex) == -1) {
- g_free(tmp);
- g_free(fname);
- closedir(dir);
- return -1;
- }
- }
- }
- g_free(fname);
-
- }
- g_free(tmp);
- }
- closedir(dir);
-
- return 0;
-}
-
-static guint inode_hash(const void *d)
-{
- const struct _inode *v = d;
-
- return v->inode ^ v->dnode;
-}
-
-static gboolean inode_equal(const void *a, const void *b)
-{
- const struct _inode *v1 = a, *v2 = b;
-
- return v1->inode == v2->inode && v1->dnode == v2->dnode;
-}
-
-static void inode_free(void *k, void *v, void *d)
-{
- g_free(k);
-}
-
-static CamelFolderInfo *
-get_folder_info_elm(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelFolderInfo *fi = NULL;
- GHashTable *visited;
-
- visited = g_hash_table_new(inode_hash, inode_equal);
-
- if (scan_dir(store, visited, ((CamelService *)store)->url->path, top, flags, NULL, &fi, ex) == -1 && fi != NULL) {
- camel_store_free_folder_info_full(store, fi);
- fi = NULL;
- }
-
- g_hash_table_foreach(visited, inode_free, NULL);
- g_hash_table_destroy(visited);
-
- return fi;
-}
-
-static CamelFolderInfo *
-get_folder_info_mbox(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelFolderInfo *fi = NULL;
- CamelService *service = (CamelService *)store;
- CamelFolder *folder;
-
- if (top == NULL || strcmp(top, "INBOX") == 0) {
- fi = g_malloc0(sizeof(*fi));
- fi->full_name = g_strdup("INBOX");
- fi->name = g_strdup("INBOX");
- fi->url = g_strdup_printf("%s:%s#%s", service->url->protocol, service->url->path, fi->name);
-
- folder = camel_object_bag_get(store->folders, fi->full_name);
- if (folder) {
- fi->unread_message_count = camel_folder_get_unread_message_count(folder);
- camel_object_unref(folder);
- } else
- fi->unread_message_count = -1;
-
- camel_folder_info_build_path(fi, '/');
- }
-
- return fi;
-}
-
-static CamelFolderInfo *
-get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX)
- return get_folder_info_mbox(store, top, flags, ex);
- else
- return get_folder_info_elm(store, top, flags, ex);
-}
diff --git a/camel/providers/local/camel-spool-store.h b/camel/providers/local/camel-spool-store.h
deleted file mode 100644
index 1e1753481b..0000000000
--- a/camel/providers/local/camel-spool-store.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2001 Ximian Inc (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_SPOOL_STORE_H
-#define CAMEL_SPOOL_STORE_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-mbox-store.h"
-
-#define CAMEL_SPOOL_STORE_TYPE (camel_spool_store_get_type ())
-#define CAMEL_SPOOL_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SPOOL_STORE_TYPE, CamelSpoolStore))
-#define CAMEL_SPOOL_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SPOOL_STORE_TYPE, CamelSpoolStoreClass))
-#define CAMEL_IS_SPOOL_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_SPOOL_STORE_TYPE))
-
-typedef enum _camel_spool_store_t {
- CAMEL_SPOOL_STORE_MBOX, /* a single mbox */
- CAMEL_SPOOL_STORE_ELM, /* elm/pine/etc tree of mbox files in folders */
-} camel_spool_store_t;
-
-typedef struct {
- CamelMboxStore parent_object;
-
- camel_spool_store_t type;
-} CamelSpoolStore;
-
-
-
-typedef struct {
- CamelMboxStoreClass parent_class;
-
-} CamelSpoolStoreClass;
-
-
-/* public methods */
-
-/* Standard Camel function */
-CamelType camel_spool_store_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_SPOOL_STORE_H */
-
-
diff --git a/camel/providers/local/camel-spool-summary.c b/camel/providers/local/camel-spool-summary.c
deleted file mode 100644
index 7991a881cc..0000000000
--- a/camel/providers/local/camel-spool-summary.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Copyright (C) 2001 Ximian Inc. (www.ximian.com)
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <ctype.h>
-
-#include "camel-spool-summary.h"
-#include "camel-mime-message.h"
-#include "camel-file-utils.h"
-#include "camel-operation.h"
-
-#define io(x)
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-#define CAMEL_SPOOL_SUMMARY_VERSION (0x400)
-
-static int spool_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex);
-static int spool_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-
-static int spool_summary_sync_full(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
-
-static void camel_spool_summary_class_init (CamelSpoolSummaryClass *klass);
-static void camel_spool_summary_init (CamelSpoolSummary *obj);
-static void camel_spool_summary_finalise (CamelObject *obj);
-
-static CamelFolderSummaryClass *camel_spool_summary_parent;
-
-CamelType
-camel_spool_summary_get_type(void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(camel_mbox_summary_get_type(), "CamelSpoolSummary",
- sizeof (CamelSpoolSummary),
- sizeof (CamelSpoolSummaryClass),
- (CamelObjectClassInitFunc) camel_spool_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_spool_summary_init,
- (CamelObjectFinalizeFunc) camel_spool_summary_finalise);
- }
-
- return type;
-}
-
-static void
-camel_spool_summary_class_init(CamelSpoolSummaryClass *klass)
-{
- CamelLocalSummaryClass *lklass = (CamelLocalSummaryClass *)klass;
- CamelMboxSummaryClass *mklass = (CamelMboxSummaryClass *)klass;
-
- camel_spool_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_mbox_summary_get_type());
-
- lklass->load = spool_summary_load;
- lklass->check = spool_summary_check;
-
- mklass->sync_full = spool_summary_sync_full;
-}
-
-static void
-camel_spool_summary_init(CamelSpoolSummary *obj)
-{
- struct _CamelFolderSummary *s = (CamelFolderSummary *)obj;
-
- /* message info size is from mbox parent */
-
- /* and a unique file version */
- s->version += CAMEL_SPOOL_SUMMARY_VERSION;
-}
-
-static void
-camel_spool_summary_finalise(CamelObject *obj)
-{
- /*CamelSpoolSummary *mbs = CAMEL_SPOOL_SUMMARY(obj);*/
-}
-
-CamelSpoolSummary *
-camel_spool_summary_new(const char *mbox_name)
-{
- CamelSpoolSummary *new = (CamelSpoolSummary *)camel_object_new(camel_spool_summary_get_type());
-
- camel_local_summary_construct((CamelLocalSummary *)new, NULL, mbox_name, NULL);
- return new;
-}
-
-static int
-spool_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex)
-{
- g_warning("spool summary - not loading anything\n");
- return 0;
-}
-
-/* perform a full sync */
-static int
-spool_summary_sync_full(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- int fd = -1, fdout = -1;
- char *tmpname = NULL;
- char *buffer, *p;
- off_t spoollen, outlen;
- int size, sizeout;
- struct stat st;
- guint32 flags = (expunge?1:0);
-
- d(printf("performing full summary/sync\n"));
-
- camel_operation_start(NULL, _("Storing folder"));
-
- fd = open(((CamelLocalSummary *)cls)->folder_path, O_RDWR);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not open file: %s: %s"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno));
- camel_operation_end(NULL);
- return -1;
- }
-
-#ifdef HAVE_MKSTEMP
- tmpname = alloca (64);
- sprintf (tmpname, "/tmp/spool.camel.XXXXXX");
- fdout = mkstemp (tmpname);
-#else
-#warning "Your system has no mkstemp(3), spool updating may be insecure"
- tmpname = alloca (L_tmpnam);
- tmpnam (tmpname);
- fdout = open (tmpname, O_RDWR|O_CREAT|O_EXCL, 0600);
-#endif
- d(printf("Writing tmp file to %s\n", tmpname));
- if (fdout == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot open temporary mailbox: %s"),
- g_strerror (errno));
- goto error;
- }
-
- if (camel_mbox_summary_sync_mbox((CamelMboxSummary *)cls, flags, changeinfo, fd, fdout, ex) == -1)
- goto error;
-
-
- /* sync out content */
- if (fsync(fdout) == -1) {
- g_warning("Cannot sync temporary folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not sync temporary folder %s: %s"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno));
- goto error;
- }
-
- /* see if we can write this much to the spool file */
- if (fstat(fd, &st) == -1) {
- g_warning("Cannot sync temporary folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not sync temporary folder %s: %s"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno));
- goto error;
- }
- spoollen = st.st_size;
-
- if (fstat(fdout, &st) == -1) {
- g_warning("Cannot sync temporary folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not sync temporary folder %s: %s"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno));
- goto error;
- }
- outlen = st.st_size;
-
- /* I think this is the right way to do this - checking that the file will fit the new data */
- if (outlen>0
- && (lseek(fd, outlen-1, SEEK_SET) == -1
- || write(fd, "", 1) != 1
- || fsync(fd) == -1
- || lseek(fd, 0, SEEK_SET) == -1
- || lseek(fdout, 0, SEEK_SET) == -1)) {
- g_warning("Cannot sync spool folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not sync spool folder %s: %s"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno));
- /* incase we ran out of room, remove any trailing space first */
- ftruncate(fd, spoollen);
- goto error;
- }
-
-
- /* now copy content back */
- buffer = g_malloc(8192);
- size = 1;
- while (size>0) {
- do {
- size = read(fdout, buffer, 8192);
- } while (size == -1 && errno == EINTR);
-
- if (size > 0) {
- p = buffer;
- do {
- sizeout = write(fd, p, size);
- if (sizeout > 0) {
- p+= sizeout;
- size -= sizeout;
- }
- } while ((sizeout == -1 && errno == EINTR) && size > 0);
- size = sizeout;
- }
-
- if (size == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not sync spool folder %s: %s\n"
- "Folder may be corrupt, copy saved in `%s'"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno), tmpnam);
- /* so we dont delete it */
- close(fdout);
- tmpname = NULL;
- fdout = -1;
- g_free(buffer);
- goto error;
- }
- }
-
- g_free(buffer);
-
- d(printf("Closing folders\n"));
-
- if (ftruncate(fd, outlen) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not sync spool folder %s: %s\n"
- "Folder may be corrupt, copy saved in `%s'"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno), tmpnam);
- close(fdout);
- tmpname = NULL;
- fdout = -1;
- goto error;
- }
-
- if (close(fd) == -1) {
- g_warning("Cannot close source folder: %s", strerror (errno));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not sync spool folder %s: %s\n"
- "Folder may be corrupt, copy saved in `%s'"),
- ((CamelLocalSummary *)cls)->folder_path,
- g_strerror (errno), tmpnam);
- close(fdout);
- tmpname = NULL;
- fdout = -1;
- fd = -1;
- goto error;
- }
-
- close(fdout);
- unlink(tmpname);
-
- camel_operation_end(NULL);
-
- return 0;
- error:
- if (fd != -1)
- close(fd);
-
- if (fdout != -1)
- close(fdout);
-
- if (tmpname)
- unlink(tmpname);
-
- camel_operation_end(NULL);
-
- return -1;
-}
-
-static int
-spool_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex)
-{
- int i, work, count;
- struct stat st;
- CamelFolderSummary *s = (CamelFolderSummary *)cls;
-
- if (((CamelLocalSummaryClass *)camel_spool_summary_parent)->check(cls, changeinfo, ex) == -1)
- return -1;
-
- /* check to see if we need to copy/update the file; missing xev headers prompt this */
- work = FALSE;
- count = camel_folder_summary_count(s);
- for (i=0;!work && i<count; i++) {
- CamelMessageInfo *info = camel_folder_summary_index(s, i);
- g_assert(info);
- work = (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0;
- camel_folder_summary_info_free(s, info);
- }
-
- /* if we do, then write out the headers using sync_full, etc */
- if (work) {
- d(printf("Have to add new headers, re-syncing from the start to accomplish this\n"));
- if (((CamelMboxSummaryClass *)((CamelObject *)cls)->klass)->sync_full((CamelMboxSummary *)cls, FALSE, changeinfo, ex) == -1)
- return -1;
-
- if (stat(cls->folder_path, &st) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unknown error: %s"),
- g_strerror (errno));
- return -1;
- }
-
- ((CamelMboxSummary *)cls)->folder_size = st.st_size;
- ((CamelFolderSummary *)cls)->time = st.st_mtime;
- }
-
- return 0;
-}
diff --git a/camel/providers/local/camel-spool-summary.h b/camel/providers/local/camel-spool-summary.h
deleted file mode 100644
index b72aeda527..0000000000
--- a/camel/providers/local/camel-spool-summary.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2001 Ximian Inc. (www.ximian.com)
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_SPOOL_SUMMARY_H
-#define _CAMEL_SPOOL_SUMMARY_H
-
-#include <camel/camel-folder-summary.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-exception.h>
-#include <camel/camel-index.h>
-#include "camel-mbox-summary.h"
-
-#define CAMEL_SPOOL_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_spool_summary_get_type (), CamelSpoolSummary)
-#define CAMEL_SPOOL_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_spool_summary_get_type (), CamelSpoolSummaryClass)
-#define CAMEL_IS_SPOOL_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_spool_summary_get_type ())
-
-typedef struct _CamelSpoolSummary CamelSpoolSummary;
-typedef struct _CamelSpoolSummaryClass CamelSpoolSummaryClass;
-
-struct _CamelSpoolSummary {
- CamelMboxSummary parent;
-
-};
-
-struct _CamelSpoolSummaryClass {
- CamelMboxSummaryClass parent_class;
-};
-
-CamelType camel_spool_summary_get_type (void);
-void camel_spool_summary_construct (CamelSpoolSummary *new, const char *filename, const char *spool_name, CamelIndex *index);
-
-/* create the summary, in-memory only */
-CamelSpoolSummary *camel_spool_summary_new(const char *filename);
-
-/* load/check the summary */
-int camel_spool_summary_load(CamelSpoolSummary *cls, int forceindex, CamelException *ex);
-/* check for new/removed messages */
-int camel_spool_summary_check(CamelSpoolSummary *cls, CamelFolderChangeInfo *, CamelException *ex);
-/* perform a folder sync or expunge, if needed */
-int camel_spool_summary_sync(CamelSpoolSummary *cls, gboolean expunge, CamelFolderChangeInfo *, CamelException *ex);
-/* add a new message to the summary */
-CamelMessageInfo *camel_spool_summary_add(CamelSpoolSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
-
-/* generate an X-Evolution header line */
-char *camel_spool_summary_encode_x_evolution(CamelSpoolSummary *cls, const CamelMessageInfo *info);
-int camel_spool_summary_decode_x_evolution(CamelSpoolSummary *cls, const char *xev, CamelMessageInfo *info);
-
-/* utility functions - write headers to a file with optional X-Evolution header */
-int camel_spool_summary_write_headers(int fd, struct _camel_header_raw *header, char *xevline);
-
-#endif /* ! _CAMEL_SPOOL_SUMMARY_H */
-
diff --git a/camel/providers/local/libcamellocal.urls b/camel/providers/local/libcamellocal.urls
deleted file mode 100644
index e2279ed72a..0000000000
--- a/camel/providers/local/libcamellocal.urls
+++ /dev/null
@@ -1,5 +0,0 @@
-mh
-mbox
-maildir
-spool
-spoold
diff --git a/camel/providers/nntp/.cvsignore b/camel/providers/nntp/.cvsignore
deleted file mode 100644
index 2fbeab8712..0000000000
--- a/camel/providers/nntp/.cvsignore
+++ /dev/null
@@ -1,12 +0,0 @@
-.deps
-Makefile
-Makefile.in
-.libs
-.deps
-*.lo
-*.la
-test-newsrc
-*.bb
-*.bbg
-*.da
-*.gcov
diff --git a/camel/providers/nntp/Makefile.am b/camel/providers/nntp/Makefile.am
deleted file mode 100644
index 464624b82d..0000000000
--- a/camel/providers/nntp/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelnntpincludedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamelnntp.la
-camel_provider_DATA = libcamelnntp.urls
-
-INCLUDES = -I../.. \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/e-util \
- -I$(top_srcdir) \
- $(CAMEL_CFLAGS) \
- $(GNOME_INCLUDEDIR) \
- $(GTK_INCLUDEDIR) \
- -DG_LOG_DOMAIN=\"camel-nntp-provider\"
-
-libcamelnntp_la_SOURCES = \
- camel-nntp-provider.c \
- camel-nntp-store.c \
- camel-nntp-folder.c \
- camel-nntp-stream.c \
- camel-nntp-summary.c
-
-libcamelnntpinclude_HEADERS = \
- camel-nntp-store.h \
- camel-nntp-folder.h \
- camel-nntp-stream.h \
- camel-nntp-summary.h
-
-noinst_HEADERS = \
- camel-nntp-private.h
-
-libcamelnntp_la_LDFLAGS = -avoid-version -module
-
-EXTRA_DIST = libcamelnntp.urls
diff --git a/camel/providers/nntp/camel-nntp-auth.c b/camel/providers/nntp/camel-nntp-auth.c
deleted file mode 100644
index f8d3a62e27..0000000000
--- a/camel/providers/nntp/camel-nntp-auth.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-auth.c : authentication for nntp */
-
-/*
- *
- * Copyright (C) 2000 Ximian, Inc. <toshok@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <camel-nntp-auth.h>
-#include <camel-nntp-store.h>
-#include <camel-nntp-resp-codes.h>
-#include <camel-exception.h>
-#include <camel-session.h>
-
-int
-camel_nntp_auth_authenticate (CamelNNTPStore *store, CamelException *ex)
-{
- CamelService *service = CAMEL_SERVICE (store);
- CamelSession *session = camel_service_get_session (service);
- int resp;
-
- if (!service->url->authmech && !service->url->passwd) {
- gchar *prompt;
-
- prompt = g_strdup_printf (_("Please enter the NNTP password for %s@%s"),
- service->url->user, service->url->host);
- service->url->passwd =
- camel_session_get_password (session, prompt,
- TRUE, service, "password", ex);
- g_free (prompt);
-
- if (!service->url->passwd) {
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- "You didn\'t enter a password.");
- resp = 666;
- goto done;
- }
- }
-
- /* first send username */
- resp = camel_nntp_command (store, ex, NULL, "AUTHINFO USER %s", service->url->user);
-
- if (resp == NNTP_AUTH_REJECTED) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Server rejected username"));
- goto done;
-
- }
- else if (resp != NNTP_AUTH_CONTINUE) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Failed to send username to server"));
- goto done;
- }
-
- /* then send the username if the server asks for it */
- resp = camel_nntp_command (store, ex, NULL, "AUTHINFO PASS %s", service->url->passwd);
-
- if (resp == NNTP_AUTH_REJECTED) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Server rejected username/password"));
- goto done;
- }
-
- done:
-
- if (service->url->passwd) {
- /* let's be paranoid */
- memset (service->url->passwd, 0, strlen (service->url->passwd));
- g_free (service->url->passwd);
- service->url->passwd = NULL;
- }
- return resp;
-}
diff --git a/camel/providers/nntp/camel-nntp-auth.h b/camel/providers/nntp/camel-nntp-auth.h
deleted file mode 100644
index fc96cf6a4e..0000000000
--- a/camel/providers/nntp/camel-nntp-auth.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-auth.h : authentication for nntp */
-
-/*
- *
- * Author : Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 1999 Ximian .
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_NNTP_AUTH_H
-#define CAMEL_NNTP_AUTH_H 1
-
-#include <camel-nntp-store.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-int camel_nntp_auth_authenticate (CamelNNTPStore *store, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_NNTP_AUTH_H */
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
deleted file mode 100644
index 9f0832bc33..0000000000
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-folder.c : Class for a news folder
- *
- * Authors : Chris Toshok <toshok@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2001-2003 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "camel/camel-file-utils.h"
-#include "camel/camel-stream-mem.h"
-#include "camel/camel-data-wrapper.h"
-#include "camel/camel-mime-message.h"
-#include "camel/camel-folder-search.h"
-#include "camel/camel-exception.h"
-#include "camel/camel-session.h"
-#include "camel/camel-data-cache.h"
-
-#include "camel-nntp-summary.h"
-#include "camel-nntp-store.h"
-#include "camel-nntp-folder.h"
-#include "camel-nntp-store.h"
-#include "camel-nntp-private.h"
-
-static CamelFolderClass *parent_class = NULL;
-
-/* Returns the class for a CamelNNTPFolder */
-#define CNNTPF_CLASS(so) CAMEL_NNTP_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CNNTPS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static void
-nntp_folder_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
- CamelNNTPStore *nntp_store;
- CamelFolderChangeInfo *changes = NULL;
- CamelNNTPFolder *nntp_folder;
-
- nntp_store = (CamelNNTPStore *)folder->parent_store;
- nntp_folder = (CamelNNTPFolder *)folder;
-
- CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
-
- if (camel_nntp_summary_check((CamelNNTPSummary *)folder->summary, nntp_folder->changes, ex) != -1)
- camel_folder_summary_save (folder->summary);
-
- if (camel_folder_change_info_changed(nntp_folder->changes)) {
- changes = nntp_folder->changes;
- nntp_folder->changes = camel_folder_change_info_new();
- }
-
- CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
-
- if (changes) {
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", changes);
- camel_folder_change_info_free(changes);
- }
-}
-
-static void
-nntp_folder_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
-{
- ((CamelFolderClass *)parent_class)->set_message_flags(folder, uid, flags, set);
-}
-
-static CamelMimeMessage *
-nntp_folder_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
-{
- CamelMimeMessage *message = NULL;
- CamelNNTPStore *nntp_store;
- CamelFolderChangeInfo *changes;
- CamelNNTPFolder *nntp_folder;
- CamelStream *stream = NULL;
- int ret;
- char *line;
- const char *msgid;
-
- nntp_store = (CamelNNTPStore *)folder->parent_store;
- nntp_folder = (CamelNNTPFolder *)folder;
-
- CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
-
- msgid = strchr(uid, ',');
- if (msgid == 0) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Internal error: uid in invalid format: %s"), uid);
- goto fail;
- }
- msgid++;
-
- /* Lookup in cache, NEWS is global messageid's so use a global cache path */
- stream = camel_data_cache_get(nntp_store->cache, "cache", msgid, NULL);
- if (stream == NULL) {
- /* Not in cache, retrieve and put in cache */
- if (camel_nntp_store_set_folder(nntp_store, folder, nntp_folder->changes, ex) == -1)
- goto fail;
-
- ret = camel_nntp_command(nntp_store, &line, "article %s", msgid);
- if (ret == -1)
- goto error;
-
- if (ret == 220) {
- stream = camel_data_cache_add(nntp_store->cache, "cache", msgid, NULL);
- if (stream) {
- if (camel_stream_write_to_stream((CamelStream *)nntp_store->stream, stream) == -1)
- goto error;
- if (camel_stream_reset(stream) == -1)
- goto error;
- } else {
- stream = (CamelStream *)nntp_store->stream;
- camel_object_ref((CamelObject *)stream);
- }
- }
- }
-
- if (stream) {
- message = camel_mime_message_new();
- if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, stream) == -1)
- goto error;
-
- CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
-
- camel_object_unref((CamelObject *)stream);
- return message;
- }
-
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get message %s: %s"), uid, line);
-
-error:
- if (errno == EINTR)
- camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("User cancelled"));
- else
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get message %s: %s"), uid, strerror(errno));
-
-fail:
- if (message)
- camel_object_unref((CamelObject *)message);
-
- if (stream)
- camel_object_unref((CamelObject *)stream);
-
- if (camel_folder_change_info_changed(nntp_folder->changes)) {
- changes = nntp_folder->changes;
- nntp_folder->changes = camel_folder_change_info_new();
- } else {
- changes = NULL;
- }
-
- CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
-
- if (changes) {
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", changes);
- camel_folder_change_info_free(changes);
- }
-
- return NULL;
-}
-
-static GPtrArray*
-nntp_folder_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
-{
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
- GPtrArray *matches, *summary;
-
- CAMEL_NNTP_FOLDER_LOCK(nntp_folder, search_lock);
-
- if(nntp_folder->search == NULL)
- nntp_folder->search = camel_folder_search_new();
-
- camel_folder_search_set_folder(nntp_folder->search, folder);
- summary = camel_folder_get_summary(folder);
- camel_folder_search_set_summary(nntp_folder->search, summary);
-
- matches = camel_folder_search_execute_expression(nntp_folder->search, expression, ex);
-
- CAMEL_NNTP_FOLDER_UNLOCK(nntp_folder, search_lock);
-
- camel_folder_free_summary(folder, summary);
-
- return matches;
-}
-
-static GPtrArray *
-nntp_folder_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
-{
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER(folder);
- GPtrArray *summary, *matches;
- int i;
-
- /* NOTE: could get away without the search lock by creating a new
- search object each time */
-
- summary = g_ptr_array_new();
- for (i=0;i<uids->len;i++) {
- CamelMessageInfo *info;
-
- info = camel_folder_get_message_info(folder, uids->pdata[i]);
- if (info)
- g_ptr_array_add(summary, info);
- }
-
- if (summary->len == 0)
- return summary;
-
- CAMEL_NNTP_FOLDER_LOCK(folder, search_lock);
-
- if (nntp_folder->search == NULL)
- nntp_folder->search = camel_folder_search_new();
-
- camel_folder_search_set_folder(nntp_folder->search, folder);
- camel_folder_search_set_summary(nntp_folder->search, summary);
-
- matches = camel_folder_search_execute_expression(nntp_folder->search, expression, ex);
-
- CAMEL_NNTP_FOLDER_UNLOCK(folder, search_lock);
-
- for (i=0;i<summary->len;i++)
- camel_folder_free_message_info(folder, summary->pdata[i]);
- g_ptr_array_free(summary, TRUE);
-
- return matches;
-}
-
-static void
-nntp_folder_search_free(CamelFolder *folder, GPtrArray *result)
-{
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
-
- camel_folder_search_free_result(nntp_folder->search, result);
-
-}
-
-static void
-nntp_folder_init(CamelNNTPFolder *nntp_folder, CamelNNTPFolderClass *klass)
-{
- struct _CamelNNTPFolderPrivate *p;
-
- nntp_folder->changes = camel_folder_change_info_new();
- p = nntp_folder->priv = g_malloc0(sizeof(*nntp_folder->priv));
- p->search_lock = g_mutex_new();
- p->cache_lock = g_mutex_new();
-}
-
-static void
-nntp_folder_finalise (CamelNNTPFolder *nntp_folder)
-{
- struct _CamelNNTPFolderPrivate *p;
-
- g_free(nntp_folder->storage_path);
-
- p = nntp_folder->priv;
- g_mutex_free(p->search_lock);
- g_mutex_free(p->cache_lock);
- g_free(p);
-}
-
-static void
-nntp_folder_class_init (CamelNNTPFolderClass *camel_nntp_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_nntp_folder_class);
-
- parent_class = CAMEL_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_folder_get_type ()));
-
- /* virtual method definition */
-
- /* virtual method overload */
- camel_folder_class->sync = nntp_folder_sync;
- camel_folder_class->set_message_flags = nntp_folder_set_message_flags;
- camel_folder_class->get_message = nntp_folder_get_message;
- camel_folder_class->search_by_expression = nntp_folder_search_by_expression;
- camel_folder_class->search_by_uids = nntp_folder_search_by_uids;
- camel_folder_class->search_free = nntp_folder_search_free;
-}
-
-CamelType
-camel_nntp_folder_get_type (void)
-{
- static CamelType camel_nntp_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_nntp_folder_type == CAMEL_INVALID_TYPE) {
- camel_nntp_folder_type = camel_type_register (CAMEL_FOLDER_TYPE, "CamelNNTPFolder",
- sizeof (CamelNNTPFolder),
- sizeof (CamelNNTPFolderClass),
- (CamelObjectClassInitFunc) nntp_folder_class_init,
- NULL,
- (CamelObjectInitFunc) nntp_folder_init,
- (CamelObjectFinalizeFunc) nntp_folder_finalise);
- }
-
- return camel_nntp_folder_type;
-}
-
-
-/* not yet */
-/* Idea is we update in stages, but this requires a different xover command, etc */
-#ifdef ASYNC_SUMMARY
-struct _folder_check_msg {
- CamelSessionThreadMsg msg;
- CamelNNTPFolder *folder;
-};
-
-static void
-folder_check(CamelSession *session, CamelSessionThreadMsg *msg)
-{
- struct _folder_check_msg *m = (struct _folder_check_msg *)msg;
- CamelException *ex;
- CamelNNTPStore *nntp_store;
-
- nntp_store = (CamelNNTPStore *)m->folder->parent.parent_store;
-
- CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
-
- ex = camel_exception_new();
- camel_nntp_summary_check((CamelNNTPSummary *)m->folder->parent.summary, m->folder->changes, ex);
- camel_exception_free(ex);
-
- CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
-}
-
-static void
-folder_check_free(CamelSession *session, CamelSessionThreadMsg *msg)
-{
- struct _folder_check_msg *m = (struct _folder_check_msg *)msg;
-
- camel_object_unref((CamelObject *)m->folder);
-}
-
-static CamelSessionThreadOps folder_check_ops = {
- folder_check,
- folder_check_free,
-};
-#endif
-
-CamelFolder *
-camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelException *ex)
-{
- CamelFolder *folder;
- CamelNNTPFolder *nntp_folder;
- char *root;
- CamelService *service;
-#ifdef ASYNC_SUMMARY
- struct _folder_check_msg *m;
-#endif
-
- service = (CamelService *)parent;
- root = camel_session_get_storage_path(service->session, service, ex);
- if (root == NULL)
- return NULL;
-
- /* If this doesn't work, stuff wont save, but let it continue anyway */
- camel_mkdir (root, 0777);
-
- folder = (CamelFolder *) camel_object_new (CAMEL_NNTP_FOLDER_TYPE);
- nntp_folder = (CamelNNTPFolder *)folder;
-
- camel_folder_construct (folder, parent, folder_name, folder_name);
- folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY|CAMEL_FOLDER_HAS_SEARCH_CAPABILITY;
-
- nntp_folder->storage_path = g_strdup_printf("%s/%s", root, folder->full_name);
- g_free(root);
-
- folder->summary = (CamelFolderSummary *)camel_nntp_summary_new(nntp_folder);
- camel_folder_summary_load (folder->summary);
-#ifdef ASYNC_SUMMARY
- m = camel_session_thread_msg_new(service->session, &folder_check_ops, sizeof(*m));
- m->folder = nntp_folder;
- camel_object_ref((CamelObject *)folder);
- camel_session_thread_queue(service->session, &m->msg, 0);
-#else
- if (camel_nntp_summary_check((CamelNNTPSummary *)folder->summary, nntp_folder->changes, ex) == -1) {
- camel_object_unref((CamelObject *)folder);
- folder = NULL;
- }
-#endif
-
- return folder;
-}
diff --git a/camel/providers/nntp/camel-nntp-folder.h b/camel/providers/nntp/camel-nntp-folder.h
deleted file mode 100644
index 300d61762d..0000000000
--- a/camel/providers/nntp/camel-nntp-folder.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-folder.h : NNTP group (folder) support. */
-
-/*
- *
- * Author : Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 2000 Ximian .
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_NNTP_FOLDER_H
-#define CAMEL_NNTP_FOLDER_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel/camel-folder.h"
-
-/* #include "camel-store.h" */
-
-#define CAMEL_NNTP_FOLDER_TYPE (camel_nntp_folder_get_type ())
-#define CAMEL_NNTP_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_NNTP_FOLDER_TYPE, CamelNNTPFolder))
-#define CAMEL_NNTP_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_NNTP_FOLDER_TYPE, CamelNNTPFolderClass))
-#define CAMEL_IS_NNTP_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_NNTP_FOLDER_TYPE))
-
-typedef struct _CamelNNTPFolder {
- CamelFolder parent;
-
- struct _CamelNNTPFolderPrivate *priv;
-
- struct _CamelFolderChangeInfo *changes;
- char *storage_path;
- CamelFolderSearch *search;
-} CamelNNTPFolder;
-
-typedef struct _CamelNNTPFolderClass {
- CamelFolderClass parent;
-
- /* Virtual methods */
-
-} CamelNNTPFolderClass;
-
-/* public methods */
-
-/* Standard Camel function */
-CamelType camel_nntp_folder_get_type (void);
-
-CamelFolder *camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_NNTP_FOLDER_H */
diff --git a/camel/providers/nntp/camel-nntp-grouplist.c b/camel/providers/nntp/camel-nntp-grouplist.c
deleted file mode 100644
index 7f3850f9c1..0000000000
--- a/camel/providers/nntp/camel-nntp-grouplist.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-grouplist.c : getting/updating the list of newsgroups on the server. */
-
-/*
- * Author : Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 2000 Ximian .
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include <config.h>
-#include <errno.h>
-#include <string.h>
-
-#include "camel-exception.h"
-#include "camel-nntp-grouplist.h"
-#include "camel-nntp-resp-codes.h"
-
-static CamelNNTPGroupList *
-camel_nntp_get_grouplist_from_server (CamelNNTPStore *store, CamelException *ex)
-{
- int status;
- gboolean done = FALSE;
- CamelNNTPGroupList *list;
-
- CAMEL_NNTP_STORE_LOCK(store);
- status = camel_nntp_command (store, ex, NULL,
- "LIST");
-
- if (status != NNTP_LIST_FOLLOWS) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not get group list from server."));
- return NULL;
- }
-
- list = g_new0 (CamelNNTPGroupList, 1);
- list->time = time (NULL);
-
- while (!done) {
- char *line;
-
- if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, ex) < 0) {
- list->group_list = g_list_reverse(list->group_list);
- return list;
- }
-
- if (*line == '.') {
- done = TRUE;
- }
- else {
- CamelNNTPGroupListEntry *entry = g_new (CamelNNTPGroupListEntry, 1);
- char **split_line = g_strsplit (line, " ", 4);
-
- entry->group_name = g_strdup (split_line[0]);
- entry->high = atoi (split_line[1]);
- entry->low = atoi (split_line[2]);
-
- g_strfreev (split_line);
-
- list->group_list = g_list_prepend (list->group_list, entry);
- }
- }
- CAMEL_NNTP_STORE_UNLOCK(store);
-
- list->group_list = g_list_reverse(list->group_list);
- return list;
-}
-
-static CamelNNTPGroupList*
-camel_nntp_get_grouplist_from_file (CamelNNTPStore *store, CamelException *ex)
-{
- gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(store));
- gchar *grouplist_file = g_strdup_printf ("%s/grouplist", root_dir);
- CamelNNTPGroupList *list;
- FILE *fp;
- char buf[300];
- unsigned long time;
-
- g_free (root_dir);
- fp = fopen (grouplist_file, "r");
- g_free (grouplist_file);
-
- if (fp == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Unable to load grouplist file for %s: %s"),
- CAMEL_SERVICE(store)->url->host,
- strerror(errno));
- return NULL;
- }
-
- /* read the time */
- if (!fgets (buf, sizeof (buf), fp)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Unable to load grouplist file for %s: %s"),
- CAMEL_SERVICE(store)->url->host,
- strerror(errno));
- fclose (fp);
- return NULL;
- }
-
-
- list = g_new0 (CamelNNTPGroupList, 1);
- list->store = store;
- sscanf (buf, "%lu", &time);
- list->time = time;
-
- while (fgets (buf, sizeof (buf), fp)) {
- CamelNNTPGroupListEntry *entry = g_new (CamelNNTPGroupListEntry, 1);
- char **split_line = g_strsplit (buf, " ", 4);
-
- entry->group_name = g_strdup (split_line[0]);
- entry->high = atoi (split_line[1]);
- entry->low = atoi (split_line[2]);
-
- g_strfreev (split_line);
-
- list->group_list = g_list_prepend (list->group_list, entry);
- }
-
- fclose (fp);
-
- list->group_list = g_list_reverse(list->group_list);
- return list;
-}
-
-static void
-save_entry (CamelNNTPGroupListEntry *entry, FILE *fp)
-{
- fprintf (fp, "%s %d %d\n", entry->group_name, entry->low, entry->high);
-}
-
-void
-camel_nntp_grouplist_save (CamelNNTPGroupList *group_list, CamelException *ex)
-{
- FILE *fp;
- gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(group_list->store));
- gchar *grouplist_file = g_strdup_printf ("%s/grouplist", root_dir);
-
- g_free (root_dir);
- fp = fopen (grouplist_file, "w");
- g_free (grouplist_file);
-
- if (fp == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Unable to save grouplist file for %s: %s"),
- CAMEL_SERVICE(group_list->store)->url->host,
- strerror(errno));
- return;
- }
-
- fprintf (fp, "%lu\n", (long)group_list->time);
-
- g_list_foreach (group_list->group_list, (GFunc)save_entry, fp);
-
- fclose (fp);
-}
-
-static void
-free_entry (CamelNNTPGroupListEntry *entry, void *data)
-{
- g_free (entry->group_name);
- g_free (entry);
-}
-
-void
-camel_nntp_grouplist_free (CamelNNTPGroupList *group_list)
-{
- g_return_if_fail (group_list);
-
- g_list_foreach (group_list->group_list, (GFunc)free_entry, NULL);
-
- g_free (group_list);
-}
-
-CamelNNTPGroupList*
-camel_nntp_grouplist_fetch (CamelNNTPStore *store, CamelException *ex)
-{
- CamelNNTPGroupList *list;
-
- list = camel_nntp_get_grouplist_from_file (store, ex);
-
- printf ("camel_nntp_get_grouplist_from_file returned %p\n", list);
-
- if (!list) {
- camel_exception_clear (ex);
-
- list = camel_nntp_get_grouplist_from_server (store, ex);
-
- if (!list) {
- camel_nntp_grouplist_free (list);
- }
- else {
- list->store = store;
- camel_nntp_grouplist_save (list, ex);
- return list;
- }
- }
-
- return list;
-}
-
-gint
-camel_nntp_grouplist_update (CamelNNTPGroupList *group_list, CamelException *ex)
-{
- return 0;
-}
diff --git a/camel/providers/nntp/camel-nntp-grouplist.h b/camel/providers/nntp/camel-nntp-grouplist.h
deleted file mode 100644
index edd1e64cb9..0000000000
--- a/camel/providers/nntp/camel-nntp-grouplist.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-grouplist.h : getting/updating the list of newsgroups on the server. */
-
-/*
- * Author : Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 2000 Ximian .
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_NNTP_GROUPLIST_H
-#define CAMEL_NNTP_GROUPLIST_H 1
-
-#include <time.h>
-#include "camel-nntp-store.h"
-
-struct CamelNNTPGroupListEntry {
- char *group_name;
- guint32 low;
- guint32 high;
- guint32 flags;
-};
-
-struct CamelNNTPGroupList {
- CamelNNTPStore *store;
- time_t time;
- GList *group_list;
-};
-
-CamelNNTPGroupList* camel_nntp_grouplist_fetch (CamelNNTPStore *store, CamelException *ex);
-gint camel_nntp_grouplist_update (CamelNNTPGroupList *group_list, CamelException *ex);
-void camel_nntp_grouplist_save (CamelNNTPGroupList *group_list, CamelException *ex);
-void camel_nntp_grouplist_free (CamelNNTPGroupList *group_list);
-
-#endif /* CAMEL_NNTP_GROUPLIST_H */
diff --git a/camel/providers/nntp/camel-nntp-newsrc.c b/camel/providers/nntp/camel-nntp-newsrc.c
deleted file mode 100644
index 309e1f45c8..0000000000
--- a/camel/providers/nntp/camel-nntp-newsrc.c
+++ /dev/null
@@ -1,651 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Chris Toshok <toshok@ximian.com>
- *
- * Copyright 2000-2003 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "camel-nntp-newsrc.h"
-#include <camel/camel-folder-summary.h>
-
-#define NEWSRC_LOCK(f, l) (g_mutex_lock(((CamelNNTPNewsrc *)f)->l))
-#define NEWSRC_UNLOCK(f, l) (g_mutex_unlock(((CamelNNTPNewsrc *)f)->l))
-
-typedef struct {
- guint low;
- guint high;
-} ArticleRange;
-
-typedef struct {
- char *name;
- GArray *ranges;
- gboolean subscribed;
-} NewsrcGroup;
-
-struct CamelNNTPNewsrc {
- gchar *filename;
- GHashTable *groups;
- gboolean dirty;
- GMutex *lock;
-};
-
-
-static NewsrcGroup *
-camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, const char *group_name, gboolean subscribed)
-{
- NewsrcGroup *new_group = g_malloc(sizeof(NewsrcGroup));
-
- new_group->name = g_strdup(group_name);
- new_group->subscribed = subscribed;
- new_group->ranges = g_array_new (FALSE, FALSE, sizeof (ArticleRange));
-
- g_hash_table_insert (newsrc->groups, new_group->name, new_group);
-
- newsrc->dirty = TRUE;
-
- return new_group;
-}
-
-static int
-camel_nntp_newsrc_group_get_highest_article_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *group)
-{
- if (!group || group->ranges->len == 0)
- return 0;
-
- return g_array_index(group->ranges, ArticleRange, group->ranges->len - 1).high;
-}
-
-static int
-camel_nntp_newsrc_group_get_num_articles_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *group)
-{
- int i;
- int count = 0;
-
- if (group == NULL)
- return 0;
-
- for (i = 0; i < group->ranges->len; i ++)
- count += (g_array_index(group->ranges, ArticleRange, i).high -
- g_array_index(group->ranges, ArticleRange, i).low) + 1;
-
- return count;
-}
-
-
-static void
-camel_nntp_newsrc_group_mark_range_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *group, long low, long high)
-{
- int i;
-
- if (group->ranges->len == 1
- && g_array_index (group->ranges, ArticleRange, 0).low == 0
- && g_array_index (group->ranges, ArticleRange, 0).high == 0) {
- g_array_index (group->ranges, ArticleRange, 0).low = low;
- g_array_index (group->ranges, ArticleRange, 0).high = high;
-
- newsrc->dirty = TRUE;
- }
- else {
- ArticleRange tmp_range;
-
- for (i = 0; i < group->ranges->len; i ++) {
- guint range_low = g_array_index (group->ranges, ArticleRange, i).low;
- guint range_high = g_array_index (group->ranges, ArticleRange, i).high;
-
- /* if it's already part of a range, return immediately. */
- if (low >= range_low &&
- low <= range_high &&
- high >= range_low &&
- high <= range_high) {
- return;
- }
- /* if we have a new lower bound for this range, set it. */
- else if (low <= range_low
- && high >= range_low
- && high <= range_high) {
- g_array_index (group->ranges, ArticleRange, i).low = low;
- newsrc->dirty = TRUE;
- return;
- }
- /* if we have a new upper bound for this range, set it. */
- else if (high >= range_high
- && low >= range_low
- && low <= range_high) {
- g_array_index (group->ranges, ArticleRange, i).high = high;
- newsrc->dirty = TRUE;
- return;
- }
- /* if we would be inserting another range that
- starts one index higher than an existing
- one, make the upper value of the existing
- range the upper value of the new one. */
- else if (low == range_high + 1) {
- g_array_index (group->ranges, ArticleRange, i).high = high;
- newsrc->dirty = TRUE;
- return;
- }
- /* if we would be inserting another range that
- ends one index lower than an existing one,
- group the existing range by setting its low
- to the new low */
- else if (high == range_low - 1) {
- g_array_index (group->ranges, ArticleRange, i).low = low;
- newsrc->dirty = TRUE;
- return;
- }
- /* if the range lies entirely outside another
- range, doesn't coincide with it's
- endpoints, and has lower values, insert it
- into the middle of the list. */
- else if (low < range_low
- && high < range_low) {
- tmp_range.low = low;
- tmp_range.high = high;
-
- group->ranges = g_array_insert_val (group->ranges, i, tmp_range);
- newsrc->dirty = TRUE;
-
- return;
- }
- }
-
- /* if we made it here, the range needs to go at the end */
- tmp_range.low = low;
- tmp_range.high = high;
- group->ranges = g_array_append_val (group->ranges, tmp_range);
- newsrc->dirty = TRUE;
- }
-}
-
-int
-camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, const char *group_name)
-{
- NewsrcGroup *group;
- int ret;
-
- NEWSRC_LOCK(newsrc, lock);
-
- group = g_hash_table_lookup (newsrc->groups, group_name);
-
- if (group)
- ret = camel_nntp_newsrc_group_get_highest_article_read (newsrc, group);
- else
- ret = 0;
-
- NEWSRC_UNLOCK(newsrc, lock);
-
- return ret;
-}
-
-int
-camel_nntp_newsrc_get_num_articles_read (CamelNNTPNewsrc *newsrc, const char *group_name)
-{
- NewsrcGroup *group;
- int ret;
-
- NEWSRC_LOCK(newsrc, lock);
-
- group = g_hash_table_lookup (newsrc->groups, group_name);
-
- if (group)
- ret = camel_nntp_newsrc_group_get_num_articles_read (newsrc, group);
- else
- ret = 0;
-
- NEWSRC_UNLOCK(newsrc, lock);
-
- return ret;
-}
-
-void
-camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, const char *group_name, int num)
-{
- camel_nntp_newsrc_mark_range_read (newsrc, group_name, num, num);
-}
-
-void
-camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, const char *group_name, long low, long high)
-{
- NewsrcGroup *group;
-
- /* swap them if they're in the wrong order. */
- if (low > high) {
- long tmp;
-
- tmp = high;
- high = low;
- low = tmp;
- }
-
- NEWSRC_LOCK(newsrc, lock);
- group = g_hash_table_lookup (newsrc->groups, group_name);
-
- if (group)
- camel_nntp_newsrc_group_mark_range_read (newsrc, group, low, high);
- NEWSRC_UNLOCK(newsrc, lock);
-}
-
-gboolean
-camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, const char *group_name, long num)
-{
- int i;
- NewsrcGroup *group;
- int ret = FALSE;
-
- NEWSRC_LOCK(newsrc, lock);
- group = g_hash_table_lookup (newsrc->groups, group_name);
-
- if (group) {
- for (i = 0; i < group->ranges->len; i++) {
- if (num >= g_array_index (group->ranges, ArticleRange, i).low &&
- num <= g_array_index (group->ranges, ArticleRange, i).high) {
- ret = TRUE;
- break;
- }
- }
- }
-
- NEWSRC_UNLOCK(newsrc, lock);
-
- return FALSE;
-}
-
-gboolean
-camel_nntp_newsrc_group_is_subscribed (CamelNNTPNewsrc *newsrc, const char *group_name)
-{
- NewsrcGroup *group;
- int ret = FALSE;
-
- NEWSRC_LOCK(newsrc, lock);
-
- group = g_hash_table_lookup (newsrc->groups, group_name);
-
- if (group) {
- ret = group->subscribed;
- }
-
- NEWSRC_UNLOCK(newsrc, lock);
-
- return ret;
-}
-
-void
-camel_nntp_newsrc_subscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name)
-{
- NewsrcGroup *group;
-
- NEWSRC_LOCK(newsrc, lock);
-
- group = g_hash_table_lookup (newsrc->groups, group_name);
-
- if (group) {
- if (!group->subscribed)
- newsrc->dirty = TRUE;
- group->subscribed = TRUE;
- }
- else {
- camel_nntp_newsrc_group_add (newsrc, group_name, TRUE);
- }
-
- NEWSRC_UNLOCK(newsrc, lock);
-}
-
-void
-camel_nntp_newsrc_unsubscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name)
-{
- NewsrcGroup *group;
-
- NEWSRC_LOCK(newsrc, lock);
-
- group = g_hash_table_lookup (newsrc->groups, group_name);
- if (group) {
- if (group->subscribed)
- newsrc->dirty = TRUE;
- group->subscribed = FALSE;
- }
- else {
- camel_nntp_newsrc_group_add (newsrc, group_name, FALSE);
- }
-
- NEWSRC_UNLOCK(newsrc, lock);
-}
-
-struct newsrc_ptr_array {
- GPtrArray *ptr_array;
- gboolean subscribed_only;
-};
-
-/* this needs to strdup the grup_name, if the group array is likely to change */
-static void
-get_group_foreach (char *group_name, NewsrcGroup *group, struct newsrc_ptr_array *npa)
-{
- if (group->subscribed || !npa->subscribed_only) {
- g_ptr_array_add (npa->ptr_array, group_name);
- }
-}
-
-GPtrArray *
-camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc)
-{
- struct newsrc_ptr_array npa;
-
- g_return_val_if_fail (newsrc, NULL);
-
- NEWSRC_LOCK(newsrc, lock);
-
- npa.ptr_array = g_ptr_array_new();
- npa.subscribed_only = TRUE;
-
- g_hash_table_foreach (newsrc->groups,
- (GHFunc)get_group_foreach, &npa);
-
- NEWSRC_UNLOCK(newsrc, lock);
-
- return npa.ptr_array;
-}
-
-GPtrArray *
-camel_nntp_newsrc_get_all_group_names (CamelNNTPNewsrc *newsrc)
-{
- struct newsrc_ptr_array npa;
-
- g_return_val_if_fail (newsrc, NULL);
-
- NEWSRC_LOCK(newsrc, lock);
-
- npa.ptr_array = g_ptr_array_new();
- npa.subscribed_only = FALSE;
-
- g_hash_table_foreach (newsrc->groups,
- (GHFunc)get_group_foreach, &npa);
-
- NEWSRC_UNLOCK(newsrc, lock);
-
- return npa.ptr_array;
-}
-
-void
-camel_nntp_newsrc_free_group_names (CamelNNTPNewsrc *newsrc, GPtrArray *group_names)
-{
- g_ptr_array_free (group_names, TRUE);
-}
-
-struct newsrc_fp {
- CamelNNTPNewsrc *newsrc;
- FILE *fp;
-};
-
-static void
-camel_nntp_newsrc_write_group_line(gpointer key, NewsrcGroup *group, struct newsrc_fp *newsrc_fp)
-{
- CamelNNTPNewsrc *newsrc;
- FILE *fp;
- int i;
-
- fp = newsrc_fp->fp;
- newsrc = newsrc_fp->newsrc;
-
- fprintf (fp, "%s%c", group->name, group->subscribed ? ':' : '!');
-
- if (group->ranges->len == 1
- && g_array_index (group->ranges, ArticleRange, 0).low == 0
- && g_array_index (group->ranges, ArticleRange, 0).high == 0) {
- fprintf (fp, "\n");
-
- return; /* special case since our parsing code will insert this
- bogus range if there were no read articles. The code
- to add a range is smart enough to remove this one if we
- ever mark an article read, but we still need to deal with
- it if that code doesn't get hit. */
- }
-
- fprintf (fp, " ");
-
- for (i = 0; i < group->ranges->len; i ++) {
- char range_buffer[100];
- guint low = g_array_index (group->ranges, ArticleRange, i).low;
- guint high = g_array_index (group->ranges, ArticleRange, i).high;
-
- if (low == high)
- sprintf(range_buffer, "%d", low);
- else if (low == high - 1)
- sprintf(range_buffer, "%d,%d", low, high);
- else
- sprintf(range_buffer, "%d-%d", low, high);
-
- if (i != group->ranges->len - 1)
- strcat(range_buffer, ",");
-
- fprintf (fp, range_buffer);
- }
-
- fprintf (fp, "\n");
-}
-
-void
-camel_nntp_newsrc_write_to_file(CamelNNTPNewsrc *newsrc, FILE *fp)
-{
- struct newsrc_fp newsrc_fp;
-
- g_return_if_fail (newsrc);
-
- newsrc_fp.newsrc = newsrc;
- newsrc_fp.fp = fp;
-
- NEWSRC_LOCK(newsrc, lock);
-
- g_hash_table_foreach (newsrc->groups,
- (GHFunc)camel_nntp_newsrc_write_group_line,
- &newsrc_fp);
-
- NEWSRC_UNLOCK(newsrc, lock);
-}
-
-void
-camel_nntp_newsrc_write(CamelNNTPNewsrc *newsrc)
-{
- FILE *fp;
-
- g_return_if_fail (newsrc);
-
- NEWSRC_LOCK(newsrc, lock);
-
- if (!newsrc->dirty) {
- NEWSRC_UNLOCK(newsrc, lock);
- return;
- }
-
- if ((fp = fopen(newsrc->filename, "w")) == NULL) {
- g_warning ("Couldn't open newsrc file '%s'.\n", newsrc->filename);
- NEWSRC_UNLOCK(newsrc, lock);
- return;
- }
-
- newsrc->dirty = FALSE;
- NEWSRC_UNLOCK(newsrc, lock);
-
- camel_nntp_newsrc_write_to_file(newsrc, fp);
-
- fclose(fp);
-}
-
-static void
-camel_nntp_newsrc_parse_line(CamelNNTPNewsrc *newsrc, char *line)
-{
- char *p, *comma, *dash;
- gboolean is_subscribed;
- NewsrcGroup *group;
-
- p = strchr(line, ':');
-
- if (p) {
- is_subscribed = TRUE;
- }
- else {
- p = strchr(line, '!');
- if (p)
- is_subscribed = FALSE;
- else
- return; /* bogus line. */
- }
-
- *p++ = '\0';
-
- group = camel_nntp_newsrc_group_add (newsrc, line, is_subscribed);
-
- do {
- guint high, low;
-
- comma = strchr(p, ',');
-
- if (comma)
- *comma = '\0';
-
- dash = strchr(p, '-');
-
- if (!dash) { /* there wasn't a dash. must be just one number */
- high = low = atol(p);
- }
- else { /* there was a dash. */
- *dash = '\0';
- low = atol(p);
- *dash = '-';
- p = dash + 1;
- high = atol(p);
- }
-
- camel_nntp_newsrc_group_mark_range_read (newsrc, group, low, high);
-
- if (comma) {
- *comma = ',';
- p = comma + 1;
- }
-
- } while(comma);
-}
-
-static char*
-get_line (char *buf, char **p)
-{
- char *l;
- char *line;
-
- g_assert (*p == NULL || **p == '\n' || **p == '\0');
-
- if (*p == NULL) {
- *p = buf;
-
- if (**p == '\0')
- return NULL;
- }
- else {
- if (**p == '\0')
- return NULL;
-
- (*p) ++;
-
- /* if we just incremented to the end of the buffer, return NULL */
- if (**p == '\0')
- return NULL;
- }
-
- l = strchr (*p, '\n');
- if (l) {
- *l = '\0';
- line = g_strdup (*p);
- *l = '\n';
- *p = l;
- }
- else {
- /* we're at the last line (which isn't terminated by a \n, btw) */
- line = g_strdup (*p);
- (*p) += strlen (*p);
- }
-
- return line;
-}
-
-CamelNNTPNewsrc *
-camel_nntp_newsrc_read_for_server (const char *server)
-{
- int fd;
- char buf[1024];
- char *file_contents, *line, *p;
- char *filename;
- CamelNNTPNewsrc *newsrc;
- int newsrc_len;
- int len_read = 0;
- struct stat sb;
-
- filename = g_strdup_printf ("%s/.newsrc-%s", g_get_home_dir(), server);
-
- newsrc = g_new0(CamelNNTPNewsrc, 1);
- newsrc->filename = filename;
- newsrc->groups = g_hash_table_new (g_str_hash, g_str_equal);
- newsrc->lock = g_mutex_new();
-
- if ((fd = open(filename, O_RDONLY)) == -1) {
- g_warning ("~/.newsrc-%s not present.\n", server);
- return newsrc;
- }
-
- if (fstat (fd, &sb) == -1) {
- g_warning ("failed fstat on ~/.newsrc-%s: %s\n", server, strerror(errno));
- return newsrc;
- }
- newsrc_len = sb.st_size;
-
- file_contents = g_malloc (newsrc_len + 1);
-
- while (len_read < newsrc_len) {
- int c = read (fd, buf, sizeof (buf));
-
- if (c == -1)
- break;
-
- memcpy (&file_contents[len_read], buf, c);
- len_read += c;
- }
- file_contents [len_read] = 0;
-
- p = NULL;
- while ((line = get_line (file_contents, &p))) {
- camel_nntp_newsrc_parse_line(newsrc, line);
- g_free (line);
- }
-
- close (fd);
- g_free (file_contents);
-
- return newsrc;
-}
diff --git a/camel/providers/nntp/camel-nntp-newsrc.h b/camel/providers/nntp/camel-nntp-newsrc.h
deleted file mode 100644
index 652e3edbce..0000000000
--- a/camel/providers/nntp/camel-nntp-newsrc.h
+++ /dev/null
@@ -1,34 +0,0 @@
-
-#ifndef _CAMEL_NNTP_NEWSRC_H_
-#define _CAMEL_NNTP_NEWSRC_H_
-
-#include <stdio.h>
-#include "glib.h"
-
-typedef struct CamelNNTPNewsrc CamelNNTPNewsrc;
-
-int camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, const char *group_name);
-int camel_nntp_newsrc_get_num_articles_read (CamelNNTPNewsrc *newsrc, const char *group_name);
-void camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc,
- const char *group_name, int num);
-void camel_nntp_newsrc_mark_range_read (CamelNNTPNewsrc *newsrc,
- const char *group_name, long low, long high);
-
-gboolean camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc,
- const char *group_name, long num);
-
-gboolean camel_nntp_newsrc_group_is_subscribed (CamelNNTPNewsrc *newsrc, const char *group_name);
-void camel_nntp_newsrc_subscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name);
-void camel_nntp_newsrc_unsubscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name);
-
-GPtrArray* camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc);
-GPtrArray* camel_nntp_newsrc_get_all_group_names (CamelNNTPNewsrc *newsrc);
-void camel_nntp_newsrc_free_group_names (CamelNNTPNewsrc *newsrc, GPtrArray *group_names);
-
-void camel_nntp_newsrc_write_to_file (CamelNNTPNewsrc *newsrc, FILE *fp);
-void camel_nntp_newsrc_write (CamelNNTPNewsrc *newsrc);
-CamelNNTPNewsrc *camel_nntp_newsrc_read_for_server (const char *server);
-
-#endif /* _CAMEL_NNTP_NEWSRC_H_ */
-
-
diff --git a/camel/providers/nntp/camel-nntp-private.h b/camel/providers/nntp/camel-nntp-private.h
deleted file mode 100644
index f2cca4e187..0000000000
--- a/camel/providers/nntp/camel-nntp-private.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- * camel-nntp-private.h: Private info for nntp.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_NNTP_PRIVATE_H
-#define CAMEL_NNTP_PRIVATE_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* need a way to configure and save this data, if this header is to
- be installed. For now, dont install it */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-util/e-msgport.h"
-
-struct _CamelNNTPStorePrivate {
- EMutex *command_lock; /* for locking the command stream for a complete operation */
-};
-
-#define CAMEL_NNTP_STORE_LOCK(f, l) (e_mutex_lock(((CamelNNTPStore *)f)->priv->l))
-#define CAMEL_NNTP_STORE_UNLOCK(f, l) (e_mutex_unlock(((CamelNNTPStore *)f)->priv->l))
-
-
-struct _CamelNNTPFolderPrivate {
- GMutex *search_lock; /* for locking the search object */
- GMutex *cache_lock; /* for locking the cache object */
-};
-
-#define CAMEL_NNTP_FOLDER_LOCK(f, l) (g_mutex_lock(((CamelNNTPFolder *)f)->priv->l))
-#define CAMEL_NNTP_FOLDER_UNLOCK(f, l) (g_mutex_unlock(((CamelNNTPFolder *)f)->priv->l))
-#else
-#define CAMEL_NNTP_FOLDER_LOCK(f, l)
-#define CAMEL_NNTP_FOLDER_UNLOCK(f, l)
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_NNTP_PRIVATE_H */
-
diff --git a/camel/providers/nntp/camel-nntp-provider.c b/camel/providers/nntp/camel-nntp-provider.c
deleted file mode 100644
index 8f54b3ee98..0000000000
--- a/camel/providers/nntp/camel-nntp-provider.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-provider.c: nntp provider registration code */
-
-/*
- * Authors :
- * Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include "camel-nntp-store.h"
-#include "camel-provider.h"
-#include "camel-session.h"
-
-static void add_hash (guint *hash, char *s);
-static guint nntp_url_hash (gconstpointer key);
-static gint check_equal (char *s1, char *s2);
-static gint nntp_url_equal (gconstpointer a, gconstpointer b);
-
-static CamelProvider news_provider = {
- "nntp",
- N_("USENET news"),
-
- N_("This is a provider for reading from and posting to"
- "USENET newsgroups."),
-
- "news",
-
- CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
- CAMEL_PROVIDER_IS_STORAGE,
-
- CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_USER |
- CAMEL_URL_ALLOW_PASSWORD | CAMEL_URL_ALLOW_AUTH,
-
- /* ... */
-};
-
-void
-camel_provider_module_init (CamelSession *session)
-{
- news_provider.object_types[CAMEL_PROVIDER_STORE] =
- camel_nntp_store_get_type();
-
- news_provider.url_hash = nntp_url_hash;
- news_provider.url_equal = nntp_url_equal;
-
- camel_session_register_provider (session, &news_provider);
-}
-
-static void
-add_hash (guint *hash, char *s)
-{
- if (s)
- *hash ^= g_str_hash(s);
-}
-
-static guint
-nntp_url_hash (gconstpointer key)
-{
- const CamelURL *u = (CamelURL *)key;
- guint hash = 0;
-
- add_hash (&hash, u->user);
- add_hash (&hash, u->host);
- hash ^= u->port;
-
- return hash;
-}
-
-static gint
-check_equal (char *s1, char *s2)
-{
- if (s1 == NULL) {
- if (s2 == NULL)
- return TRUE;
- else
- return FALSE;
- }
-
- if (s2 == NULL)
- return FALSE;
-
- return strcmp (s1, s2) == 0;
-}
-
-static gint
-nntp_url_equal (gconstpointer a, gconstpointer b)
-{
- const CamelURL *u1 = a, *u2 = b;
-
- return check_equal (u1->user, u2->user)
- && check_equal (u1->host, u2->host)
- && u1->port == u2->port;
-}
diff --git a/camel/providers/nntp/camel-nntp-resp-codes.h b/camel/providers/nntp/camel-nntp-resp-codes.h
deleted file mode 100644
index d9aace81ef..0000000000
--- a/camel/providers/nntp/camel-nntp-resp-codes.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-resp-codes.h : #defines for all the response codes we care about */
-
-/*
- *
- * Copyright (C) 2000 Ximian, Inc. <toshok@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_NNTP_RESP_CODES_H
-#define CAMEL_NNTP_RESP_CODES_H 1
-
-#define CAMEL_NNTP_OK(x) ((x) < 400)
-#define CAMEL_NNTP_ERR(x) (!CAMEL_NNTP_OK(x) && (x) < 500)
-#define CAMEL_NNTP_FAIL(x) (!CAMEL_NNTP_OK(x) && !CAMEL_NNTP_ERR(x))
-
-#define NNTP_GREETING_POSTING_OK 200
-#define NNTP_GREETING_NO_POSTING 201
-
-#define NNTP_EXTENSIONS_SUPPORTED 202
-#define NNTP_GROUP_SELECTED 211
-#define NNTP_LIST_FOLLOWS 215
-#define NNTP_ARTICLE_FOLLOWS 220
-#define NNTP_HEAD_FOLLOWS 221
-#define NNTP_DATA_FOLLOWS 224
-#define NNTP_NEW_ARTICLE_LIST_FOLLOWS 230
-#define NNTP_NEW_GROUP_LIST_FOLLOWS 231
-
-#define NNTP_NO_SUCH_GROUP 411
-#define NNTP_NO_SUCH_ARTICLE 430
-
-#define NNTP_NO_PERMISSION 502
-
-/* authentication */
-#define NNTP_AUTH_ACCEPTED 281
-#define NNTP_AUTH_CONTINUE 381
-#define NNTP_AUTH_REQUIRED 480
-#define NNTP_AUTH_REJECTED 482
-
-#define NNTP_PROTOCOL_ERROR 666
-
-#endif /* CAMEL_NNTP_RESP_CODES_H */
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
deleted file mode 100644
index 531d4aefdf..0000000000
--- a/camel/providers/nntp/camel-nntp-store.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- *
- * Copyright (C) 2001-2003 Ximian, Inc. <www.ximain.com>
- *
- * Authors: Christopher Toshok <toshok@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <errno.h>
-
-#include <camel/camel-url.h>
-#include <camel/camel-string-utils.h>
-#include <camel/camel-session.h>
-#include <camel/camel-tcp-stream-raw.h>
-#include <camel/camel-tcp-stream-ssl.h>
-
-#include "camel-nntp-summary.h"
-#include "camel-nntp-store.h"
-#include "camel-nntp-folder.h"
-#include "camel-nntp-private.h"
-
-#define w(x)
-extern int camel_verbose_debug;
-#define dd(x) (camel_verbose_debug?(x):0)
-
-#define NNTP_PORT 119
-#define NNTPS_PORT 563
-
-#define DUMP_EXTENSIONS
-
-/* define if you want the subscribe ui to show folders in tree form */
-/* #define INFO_AS_TREE */
-
-static CamelStoreClass *parent_class = NULL;
-static CamelServiceClass *service_class = NULL;
-
-/* Returns the class for a CamelNNTPStore */
-#define CNNTPS_CLASS(so) CAMEL_NNTP_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-#define CNNTPF_CLASS(so) CAMEL_NNTP_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-
-enum {
- USE_SSL_NEVER,
- USE_SSL_ALWAYS,
- USE_SSL_WHEN_POSSIBLE
-};
-
-static gboolean
-connect_to_server (CamelService *service, int ssl_mode, CamelException *ex)
-{
- CamelNNTPStore *store = (CamelNNTPStore *) service;
- CamelStream *tcp_stream;
- gboolean retval = FALSE;
- unsigned char *buf;
- unsigned int len;
- struct hostent *h;
- int port, ret;
-
- CAMEL_NNTP_STORE_LOCK(store, command_lock);
-
- /* setup store-wide cache */
- if (store->cache == NULL) {
- char *root;
-
- root = camel_session_get_storage_path (service->session, service, ex);
- if (root == NULL)
- goto fail;
-
- store->cache = camel_data_cache_new (root, 0, ex);
- g_free (root);
- if (store->cache == NULL)
- goto fail;
-
- /* Default cache expiry - 2 weeks old, or not visited in 5 days */
- camel_data_cache_set_expire_age (store->cache, 60*60*24*14);
- camel_data_cache_set_expire_access (store->cache, 60*60*24*5);
- }
-
- h = camel_service_gethost (service, ex);
- if (!h)
- goto fail;
-
- port = service->url->port ? service->url->port : NNTP_PORT;
-
-#ifdef HAVE_SSL
- if (ssl_mode != USE_SSL_NEVER) {
- port = service->url->port ? service->url->port : NNTPS_PORT;
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3);
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-#else
- tcp_stream = camel_tcp_stream_raw_new ();
-#endif /* HAVE_SSL */
-
- ret = camel_tcp_stream_connect (CAMEL_TCP_STREAM (tcp_stream), h, port);
- camel_free_host (h);
- if (ret == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Connection cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port, g_strerror (errno));
-
- camel_object_unref (CAMEL_OBJECT (tcp_stream));
-
- goto fail;
- }
-
- store->stream = (CamelNNTPStream *) camel_nntp_stream_new (tcp_stream);
- camel_object_unref (CAMEL_OBJECT (tcp_stream));
-
- /* Read the greeting, if any. */
- if (camel_nntp_stream_line (store->stream, &buf, &len) == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Connection cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not read greeting from %s: %s"),
- service->url->host, g_strerror (errno));
-
- camel_object_unref (CAMEL_OBJECT (store->stream));
- store->stream = NULL;
-
- goto fail;
- }
-
- len = strtoul (buf, (char **) &buf, 10);
- if (len != 200 && len != 201) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("NNTP server %s returned error code %d: %s"),
- service->url->host, len, buf);
-
- camel_object_unref (CAMEL_OBJECT (store->stream));
- store->stream = NULL;
-
- goto fail;
- }
-
- /* set 'reader' mode & ignore return code */
- camel_nntp_command (store, (char **) &buf, "mode reader");
- retval = TRUE;
-
- fail:
- CAMEL_NNTP_STORE_UNLOCK(store, command_lock);
-
- return retval;
-}
-
-static struct {
- char *value;
- int mode;
-} ssl_options[] = {
- { "", USE_SSL_ALWAYS },
- { "always", USE_SSL_ALWAYS },
- { "when-possible", USE_SSL_WHEN_POSSIBLE },
- { "never", USE_SSL_NEVER },
- { NULL, USE_SSL_NEVER },
-};
-
-static gboolean
-nntp_connect (CamelService *service, CamelException *ex)
-{
-#ifdef HAVE_SSL
- const char *use_ssl;
- int i, ssl_mode;
-
- use_ssl = camel_url_get_param (service->url, "use_ssl");
- if (use_ssl) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, use_ssl))
- break;
- ssl_mode = ssl_options[i].mode;
- } else
- ssl_mode = USE_SSL_NEVER;
-
- if (ssl_mode == USE_SSL_ALWAYS) {
- /* Connect via SSL */
- return connect_to_server (service, ssl_mode, ex);
- } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
- /* If the server supports SSL, use it */
- if (!connect_to_server (service, ssl_mode, ex)) {
- if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
- /* The ssl port seems to be unavailable, fall back to plain NNTP */
- camel_exception_clear (ex);
- return connect_to_server (service, USE_SSL_NEVER, ex);
- } else {
- return FALSE;
- }
- }
-
- return TRUE;
- } else {
- /* User doesn't care about SSL */
- return connect_to_server (service, ssl_mode, ex);
- }
-#else
- return connect_to_server (service, USE_SSL_NEVER, ex);
-#endif
-}
-
-static gboolean
-nntp_disconnect (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
- char *line;
-
- CAMEL_NNTP_STORE_LOCK(store, command_lock);
-
- if (clean)
- camel_nntp_command (store, &line, "quit");
-
- if (!service_class->disconnect (service, clean, ex))
- return FALSE;
-
- camel_object_unref((CamelObject *)store->stream);
- store->stream = NULL;
-
- CAMEL_NNTP_STORE_UNLOCK(store, command_lock);
-
- return TRUE;
-}
-
-static char *
-nntp_store_get_name (CamelService *service, gboolean brief)
-{
- if (brief)
- return g_strdup_printf ("%s", service->url->host);
- else
- return g_strdup_printf (_("USENET News via %s"), service->url->host);
-
-}
-
-static CamelServiceAuthType password_authtype = {
- N_("Password"),
-
- N_("This option will authenticate with the NNTP server using a "
- "plaintext password."),
-
- "",
- TRUE
-};
-
-static GList *
-nntp_store_query_auth_types (CamelService *service, CamelException *ex)
-{
- g_warning ("nntp::query_auth_types: not implemented. Defaulting.");
-
- return g_list_append (NULL, &password_authtype);
-}
-
-static CamelFolder *
-nntp_store_get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
- CamelFolder *folder;
-
- CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
-
- folder = camel_nntp_folder_new(store, folder_name, ex);
-
- CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
-
- return folder;
-}
-
-static CamelFolderInfo *
-nntp_store_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelURL *url = CAMEL_SERVICE (store)->url;
- CamelNNTPStore *nntp_store = (CamelNNTPStore *)store;
- CamelFolderInfo *groups = NULL, *last = NULL, *fi;
- unsigned int len;
- unsigned char *line, *space;
- int ret = -1;
-
- CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
-
- ret = camel_nntp_command(nntp_store, (char **)&line, "list");
- if (ret != 215) {
- ret = -1;
- goto error;
- }
-
- while ( (ret = camel_nntp_stream_line(nntp_store->stream, &line, &len)) > 0) {
- space = strchr(line, ' ');
- if (space)
- *space = 0;
-
- if (top == NULL || top[0] == 0 || strcmp(top, line) == 0) {
- fi = g_malloc0(sizeof(*fi));
- fi->name = g_strdup(line);
- fi->full_name = g_strdup(line);
- if (url->user)
- fi->url = g_strdup_printf ("nntp://%s@%s/%s", url->user, url->host, line);
- else
- fi->url = g_strdup_printf ("nntp://%s/%s", url->host, line);
- fi->unread_message_count = -1;
- camel_folder_info_build_path(fi, '/');
-
- if (last)
- last->sibling = fi;
- else
- groups = fi;
- last = fi;
- }
- }
-
- if (ret < 0)
- goto error;
-
- CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
-
- return groups;
-
-error:
- CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
-
- if (groups)
- camel_store_free_folder_info(store, groups);
-
- return NULL;
-}
-
-static gboolean
-nntp_store_folder_subscribed (CamelStore *store, const char *folder_name)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
-
- nntp_store = nntp_store;
-
- /* FIXME: implement */
-
- return TRUE;
-}
-
-static void
-nntp_store_subscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
-
- nntp_store = nntp_store;
-
- /* FIXME: implement */
-}
-
-static void
-nntp_store_unsubscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
-
- nntp_store = nntp_store;
-
- /* FIXME: implement */
-}
-
-static void
-nntp_store_finalise (CamelObject *object)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (object);
- struct _CamelNNTPStorePrivate *p = nntp_store->priv;
-
- camel_service_disconnect((CamelService *)object, TRUE, NULL);
-
- camel_object_unref((CamelObject *)nntp_store->mem);
- nntp_store->mem = NULL;
- if (nntp_store->stream)
- camel_object_unref((CamelObject *)nntp_store->stream);
-
- e_mutex_destroy(p->command_lock);
-
- g_free(p);
-}
-
-static void
-nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class)
-{
- CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_nntp_store_class);
- CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_nntp_store_class);
-
- parent_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ()));
-
- service_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ()));
-
- /* virtual method overload */
- camel_service_class->connect = nntp_connect;
- camel_service_class->disconnect = nntp_disconnect;
- camel_service_class->query_auth_types = nntp_store_query_auth_types;
- camel_service_class->get_name = nntp_store_get_name;
-
- camel_store_class->get_folder = nntp_store_get_folder;
- camel_store_class->get_folder_info = nntp_store_get_folder_info;
- camel_store_class->free_folder_info = camel_store_free_folder_info_full;
-
- camel_store_class->folder_subscribed = nntp_store_folder_subscribed;
- camel_store_class->subscribe_folder = nntp_store_subscribe_folder;
- camel_store_class->unsubscribe_folder = nntp_store_unsubscribe_folder;
-}
-
-static void
-nntp_store_init (gpointer object, gpointer klass)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE(object);
- CamelStore *store = CAMEL_STORE (object);
- struct _CamelNNTPStorePrivate *p;
-
- store->flags = CAMEL_STORE_SUBSCRIPTIONS;
-
- nntp_store->mem = (CamelStreamMem *)camel_stream_mem_new();
-
- p = nntp_store->priv = g_malloc0(sizeof(*p));
- p->command_lock = e_mutex_new(E_MUTEX_REC);
-}
-
-CamelType
-camel_nntp_store_get_type (void)
-{
- static CamelType camel_nntp_store_type = CAMEL_INVALID_TYPE;
-
- if (camel_nntp_store_type == CAMEL_INVALID_TYPE) {
- camel_nntp_store_type =
- camel_type_register (CAMEL_STORE_TYPE,
- "CamelNNTPStore",
- sizeof (CamelNNTPStore),
- sizeof (CamelNNTPStoreClass),
- (CamelObjectClassInitFunc) nntp_store_class_init,
- NULL,
- (CamelObjectInitFunc) nntp_store_init,
- (CamelObjectFinalizeFunc) nntp_store_finalise);
- }
-
- return camel_nntp_store_type;
-}
-
-/* enter owning lock */
-int
-camel_nntp_store_set_folder (CamelNNTPStore *store, CamelFolder *folder, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- int ret;
-
- if (store->current_folder && strcmp(folder->full_name, store->current_folder) == 0)
- return 0;
-
- /* FIXME: Do something with changeinfo */
- ret = camel_nntp_summary_check((CamelNNTPSummary *)folder->summary, changes, ex);
-
- g_free(store->current_folder);
- store->current_folder = g_strdup(folder->full_name);
-
- return ret;
-}
-
-static gboolean
-nntp_connected (CamelNNTPStore *store, CamelException *ex)
-{
- if (store->stream == NULL)
- return camel_service_connect (CAMEL_SERVICE (store), ex);
- return TRUE;
-}
-
-/* Enter owning lock */
-int
-camel_nntp_command(CamelNNTPStore *store, char **line, const char *fmt, ...)
-{
- const unsigned char *p, *ps;
- unsigned char c;
- va_list ap;
- char *s;
- int d;
- unsigned int u, u2;
-
- e_mutex_assert_locked(store->priv->command_lock);
-
- if (!nntp_connected (store, NULL))
- return -1;
-
- /* Check for unprocessed data, ! */
- if (store->stream->mode == CAMEL_NNTP_STREAM_DATA) {
- g_warning("Unprocessed data left in stream, flushing");
- while (camel_nntp_stream_getd(store->stream, (unsigned char **)&p, &u) > 0)
- ;
- }
- camel_nntp_stream_set_mode(store->stream, CAMEL_NNTP_STREAM_LINE);
-
- va_start(ap, fmt);
- ps = p = fmt;
- while ( (c = *p++) ) {
- switch (c) {
- case '%':
- c = *p++;
- camel_stream_write((CamelStream *)store->mem, ps, p-ps-(c=='%'?1:2));
- ps = p;
- switch (c) {
- case 's':
- s = va_arg(ap, char *);
- camel_stream_write((CamelStream *)store->mem, s, strlen(s));
- break;
- case 'd':
- d = va_arg(ap, int);
- camel_stream_printf((CamelStream *)store->mem, "%d", d);
- break;
- case 'u':
- u = va_arg(ap, unsigned int);
- camel_stream_printf((CamelStream *)store->mem, "%u", u);
- break;
- case 'm':
- s = va_arg(ap, char *);
- camel_stream_printf((CamelStream *)store->mem, "<%s>", s);
- break;
- case 'r':
- u = va_arg(ap, unsigned int);
- u2 = va_arg(ap, unsigned int);
- if (u == u2)
- camel_stream_printf((CamelStream *)store->mem, "%u", u);
- else
- camel_stream_printf((CamelStream *)store->mem, "%u-%u", u, u2);
- break;
- default:
- g_warning("Passing unknown format to nntp_command: %c\n", c);
- g_assert(0);
- }
- }
- }
-
- camel_stream_write((CamelStream *)store->mem, ps, p-ps-1);
- dd(printf("NNTP_COMMAND: '%.*s'\n", (int)store->mem->buffer->len, store->mem->buffer->data));
- camel_stream_write((CamelStream *)store->mem, "\r\n", 2);
- camel_stream_write((CamelStream *)store->stream, store->mem->buffer->data, store->mem->buffer->len);
- camel_stream_reset((CamelStream *)store->mem);
- /* FIXME: hack */
- g_byte_array_set_size(store->mem->buffer, 0);
-
- if (camel_nntp_stream_line(store->stream, (unsigned char **)line, &u) == -1)
- return -1;
-
- u = strtoul(*line, NULL, 10);
-
- /* Handle all switching to data mode here, to make callers job easier */
- if (u == 215 || (u >= 220 && u <=224) || (u >= 230 && u <= 231))
- camel_nntp_stream_set_mode(store->stream, CAMEL_NNTP_STREAM_DATA);
-
- return u;
-}
-
diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h
deleted file mode 100644
index a201c2cea2..0000000000
--- a/camel/providers/nntp/camel-nntp-store.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-store.h : class for an nntp store */
-
-/*
- *
- * Copyright (C) 2000 Ximian, Inc. <toshok@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_NNTP_STORE_H
-#define CAMEL_NNTP_STORE_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#include <camel/camel-store.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-data-cache.h>
-#include <camel/camel-exception.h>
-#include <camel/camel-folder.h>
-
-#include "camel-nntp-stream.h"
-
-#define CAMEL_NNTP_STORE_TYPE (camel_nntp_store_get_type ())
-#define CAMEL_NNTP_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_NNTP_STORE_TYPE, CamelNNTPStore))
-#define CAMEL_NNTP_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_NNTP_STORE_TYPE, CamelNNTPStoreClass))
-#define CAMEL_IS_NNTP_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_NNTP_STORE_TYPE))
-
-#define CAMEL_NNTP_EXT_SEARCH (1<<0)
-#define CAMEL_NNTP_EXT_SETGET (1<<1)
-#define CAMEL_NNTP_EXT_OVER (1<<2)
-#define CAMEL_NNTP_EXT_XPATTEXT (1<<3)
-#define CAMEL_NNTP_EXT_XACTIVE (1<<4)
-#define CAMEL_NNTP_EXT_LISTMOTD (1<<5)
-#define CAMEL_NNTP_EXT_LISTSUBSCR (1<<6)
-#define CAMEL_NNTP_EXT_LISTPNAMES (1<<7)
-
-typedef struct _CamelNNTPStore CamelNNTPStore;
-typedef struct _CamelNNTPStoreClass CamelNNTPStoreClass;
-
-struct _CamelNNTPStore {
- CamelStore parent_object;
-
- struct _CamelNNTPStorePrivate *priv;
-
- guint32 extensions;
-
- gboolean posting_allowed;
-
- CamelNNTPStream *stream;
- CamelStreamMem *mem;
-
- CamelDataCache *cache;
-
- char *current_folder;
-};
-
-struct _CamelNNTPStoreClass {
- CamelStoreClass parent_class;
-
-};
-
-/* Standard Camel function */
-CamelType camel_nntp_store_get_type (void);
-
-int camel_nntp_command(CamelNNTPStore *store, char **line, const char *fmt, ...);
-int camel_nntp_store_set_folder(CamelNNTPStore *store, CamelFolder *folder, CamelFolderChangeInfo *changes, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_NNTP_STORE_H */
-
-
diff --git a/camel/providers/nntp/camel-nntp-stream.c b/camel/providers/nntp/camel-nntp-stream.c
deleted file mode 100644
index 1e2dcb23f9..0000000000
--- a/camel/providers/nntp/camel-nntp-stream.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Author:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-
-#include <string.h>
-#include <stdio.h>
-
-#include <glib.h>
-
-#include "camel-nntp-stream.h"
-
-extern int camel_verbose_debug;
-#define dd(x) (camel_verbose_debug?(x):0)
-
-static CamelObjectClass *parent_class = NULL;
-
-/* Returns the class for a CamelStream */
-#define CS_CLASS(so) CAMEL_NNTP_STREAM_CLASS(CAMEL_OBJECT_GET_CLASS(so))
-
-#define CAMEL_NNTP_STREAM_SIZE (4096)
-#define CAMEL_NNTP_STREAM_LINE (1024) /* maximum line size */
-
-static int
-stream_fill(CamelNNTPStream *is)
-{
- int left = 0;
-
- if (is->source) {
- left = is->end - is->ptr;
- memcpy(is->buf, is->ptr, left);
- is->end = is->buf + left;
- is->ptr = is->buf;
- left = camel_stream_read(is->source, is->end, CAMEL_NNTP_STREAM_SIZE - (is->end - is->buf));
- if (left > 0) {
- is->end += left;
- is->end[0] = '\n';
- return is->end - is->ptr;
- } else {
- dd(printf("NNTP_STREAM_FILL(ERROR): '%s'\n", strerror(errno)));
- return -1;
- }
- }
-
- return 0;
-}
-
-static ssize_t
-stream_read(CamelStream *stream, char *buffer, size_t n)
-{
- CamelNNTPStream *is = (CamelNNTPStream *)stream;
- char *o, *oe;
- unsigned char *p, *e, c;
- int state;
-
- if (is->mode != CAMEL_NNTP_STREAM_DATA || n == 0)
- return 0;
-
- o = buffer;
- oe = buffer + n;
- state = is->state;
-
- /* Need to copy/strip '.'s and whatnot */
- p = is->ptr;
- e = is->end;
-
- switch(state) {
- state_0:
- case 0: /* start of line, always read at least 3 chars */
- while (e - p < 3) {
- is->ptr = p;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- }
- if (p[0] == '.') {
- if (p[1] == '\r' && p[2] == '\n') {
- is->ptr = p+3;
- is->mode = CAMEL_NNTP_STREAM_EOD;
- is->state = 0;
- dd(printf("NNTP_STREAM_READ(%d):\n%.*s\n", o-buffer, o-buffer, buffer));
- return o-buffer;
- }
- p++;
- }
- state = 1;
- /* FALLS THROUGH */
- case 1: /* looking for next sol */
- while (o < oe) {
- c = *p++;
- if (c == '\n') {
- /* end of input sentinal check */
- if (p > e) {
- is->ptr = e;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- } else {
- *o++ = '\n';
- state = 0;
- goto state_0;
- }
- } else if (c != '\r') {
- *o++ = c;
- }
- }
- break;
- }
-
- is->ptr = p;
- is->state = state;
-
- dd(printf("NNTP_STREAM_READ(%d):\n%.*s\n", o-buffer, o-buffer, buffer));
-
- return o-buffer;
-}
-
-static ssize_t
-stream_write(CamelStream *stream, const char *buffer, size_t n)
-{
- CamelNNTPStream *is = (CamelNNTPStream *)stream;
-
- return camel_stream_write(is->source, buffer, n);
-}
-
-static int
-stream_close(CamelStream *stream)
-{
- /* nop? */
- return 0;
-}
-
-static int
-stream_flush(CamelStream *stream)
-{
- /* nop? */
- return 0;
-}
-
-static gboolean
-stream_eos(CamelStream *stream)
-{
- CamelNNTPStream *is = (CamelNNTPStream *)stream;
-
- return is->mode != CAMEL_NNTP_STREAM_DATA;
-}
-
-static int
-stream_reset(CamelStream *stream)
-{
- /* nop? reset literal mode? */
- return 0;
-}
-
-static void
-camel_nntp_stream_class_init (CamelStreamClass *camel_nntp_stream_class)
-{
- CamelStreamClass *camel_stream_class = (CamelStreamClass *)camel_nntp_stream_class;
-
- parent_class = camel_type_get_global_classfuncs( CAMEL_OBJECT_TYPE );
-
- /* virtual method definition */
- camel_stream_class->read = stream_read;
- camel_stream_class->write = stream_write;
- camel_stream_class->close = stream_close;
- camel_stream_class->flush = stream_flush;
- camel_stream_class->eos = stream_eos;
- camel_stream_class->reset = stream_reset;
-}
-
-static void
-camel_nntp_stream_init(CamelNNTPStream *is, CamelNNTPStreamClass *isclass)
-{
- /* +1 is room for appending a 0 if we need to for a line */
- is->ptr = is->end = is->buf = g_malloc(CAMEL_NNTP_STREAM_SIZE+1);
- is->lineptr = is->linebuf = g_malloc(CAMEL_NNTP_STREAM_LINE+1);
- is->lineend = is->linebuf + CAMEL_NNTP_STREAM_LINE;
-
- /* init sentinal */
- is->ptr[0] = '\n';
-
- is->state = 0;
- is->mode = CAMEL_NNTP_STREAM_LINE;
-}
-
-static void
-camel_nntp_stream_finalise(CamelNNTPStream *is)
-{
- g_free(is->buf);
- g_free(is->linebuf);
- if (is->source)
- camel_object_unref((CamelObject *)is->source);
-}
-
-CamelType
-camel_nntp_stream_get_type (void)
-{
- static CamelType camel_nntp_stream_type = CAMEL_INVALID_TYPE;
-
- if (camel_nntp_stream_type == CAMEL_INVALID_TYPE) {
- camel_nntp_stream_type = camel_type_register( camel_stream_get_type(),
- "CamelNNTPStream",
- sizeof( CamelNNTPStream ),
- sizeof( CamelNNTPStreamClass ),
- (CamelObjectClassInitFunc) camel_nntp_stream_class_init,
- NULL,
- (CamelObjectInitFunc) camel_nntp_stream_init,
- (CamelObjectFinalizeFunc) camel_nntp_stream_finalise );
- }
-
- return camel_nntp_stream_type;
-}
-
-/**
- * camel_nntp_stream_new:
- *
- * Returns a NULL stream. A null stream is always at eof, and
- * always returns success for all reads and writes.
- *
- * Return value: the stream
- **/
-CamelStream *
-camel_nntp_stream_new(CamelStream *source)
-{
- CamelNNTPStream *is;
-
- is = (CamelNNTPStream *)camel_object_new(camel_nntp_stream_get_type ());
- camel_object_ref((CamelObject *)source);
- is->source = source;
-
- return (CamelStream *)is;
-}
-
-/* Get one line from the nntp stream */
-int
-camel_nntp_stream_line(CamelNNTPStream *is, unsigned char **data, unsigned int *len)
-{
- register unsigned char c, *p, *o, *oe;
- int newlen, oldlen;
- unsigned char *e;
-
- if (is->mode == CAMEL_NNTP_STREAM_EOD) {
- *data = is->linebuf;
- *len = 0;
- return 0;
- }
-
- o = is->linebuf;
- oe = is->lineend - 1;
- p = is->ptr;
- e = is->end;
-
- /* Data mode, convert leading '..' to '.', and stop when we reach a solitary '.' */
- if (is->mode == CAMEL_NNTP_STREAM_DATA) {
- /* need at least 3 chars in buffer */
- while (e-p < 3) {
- is->ptr = p;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- }
-
- /* check for isolated '.\r\n' or begging of line '.' */
- if (p[0] == '.') {
- if (p[1] == '\r' && p[2] == '\n') {
- is->ptr = p+3;
- is->mode = CAMEL_NNTP_STREAM_EOD;
- *data = is->linebuf;
- *len = 0;
- is->linebuf[0] = 0;
-
- dd(printf("NNTP_STREAM_LINE(END)\n"));
-
- return 0;
- }
- p++;
- }
- }
-
- while (1) {
- while (o < oe) {
- c = *p++;
- if (c == '\n') {
- /* sentinal? */
- if (p> e) {
- is->ptr = e;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- } else {
- is->ptr = p;
- *data = is->linebuf;
- *len = o - is->linebuf;
- *o = 0;
-
- dd(printf("NNTP_STREAM_LINE(%d): '%s'\n", *len, *data));
-
- return 1;
- }
- } else if (c != '\r') {
- *o++ = c;
- }
- }
-
- /* limit this for bad server data? */
- oldlen = o - is->linebuf;
- newlen = (is->lineend - is->linebuf) * 3 / 2;
- is->lineptr = is->linebuf = g_realloc(is->linebuf, newlen);
- is->lineend = is->linebuf + newlen;
- oe = is->lineend - 1;
- o = is->linebuf + oldlen;
- }
-
- return -1;
-}
-
-/* returns -1 on error, 0 if last lot of data, >0 if more remaining */
-int camel_nntp_stream_gets(CamelNNTPStream *is, unsigned char **start, unsigned int *len)
-{
- int max;
- unsigned char *end;
-
- *len = 0;
-
- max = is->end - is->ptr;
- if (max == 0) {
- max = stream_fill(is);
- if (max <= 0)
- return max;
- }
-
- *start = is->ptr;
- end = memchr(is->ptr, '\n', max);
- if (end)
- max = (end - is->ptr) + 1;
- *start = is->ptr;
- *len = max;
- is->ptr += max;
-
- dd(printf("NNTP_STREAM_GETS(%s,%d): '%.*s'\n", end==NULL?"more":"last", *len, (int)*len, *start));
-
- return end == NULL?1:0;
-}
-
-void camel_nntp_stream_set_mode(CamelNNTPStream *is, camel_nntp_stream_mode_t mode)
-{
- is->mode = mode;
-}
-
-/* returns -1 on erorr, 0 if last data, >0 if more data left */
-int camel_nntp_stream_getd(CamelNNTPStream *is, unsigned char **start, unsigned int *len)
-{
- unsigned char *p, *e, *s;
- int state;
-
- *len = 0;
-
- if (is->mode == CAMEL_NNTP_STREAM_EOD)
- return 0;
-
- if (is->mode == CAMEL_NNTP_STREAM_LINE) {
- g_warning("nntp_stream reading data in line mode\n");
- return 0;
- }
-
- state = is->state;
- p = is->ptr;
- e = is->end;
-
- while (e - p < 3) {
- is->ptr = p;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- }
-
- s = p;
-
- do {
- switch(state) {
- case 0:
- /* check leading '.', ... */
- if (p[0] == '.') {
- if (p[1] == '\r' && p[2] == '\n') {
- is->ptr = p+3;
- *len = p-s;
- *start = s;
- is->mode = CAMEL_NNTP_STREAM_EOD;
- is->state = 0;
-
- dd(printf("NNTP_STREAM_GETD(%s,%d): '%.*s'\n", "last", *len, (int)*len, *start));
-
- return 0;
- }
-
- /* If at start, just skip '.', else return data upto '.' but skip it */
- if (p == s) {
- s++;
- p++;
- } else {
- is->ptr = p+1;
- *len = p-s;
- *start = s;
- is->state = 1;
-
- dd(printf("NNTP_STREAM_GETD(%s,%d): '%.*s'\n", "more", *len, (int)*len, *start));
-
- return 1;
- }
- }
- state = 1;
- case 1:
- /* Scan for sentinal */
- while ((*p++)!='\n')
- ;
-
- if (p > e) {
- p = e;
- } else {
- state = 0;
- }
- break;
- }
- } while ((e-p) >= 3);
-
- is->state = state;
- is->ptr = p;
- *len = p-s;
- *start = s;
-
- dd(printf("NNTP_STREAM_GETD(%s,%d): '%.*s'\n", "more", *len, (int)*len, *start));
- return 1;
-}
-
diff --git a/camel/providers/nntp/camel-nntp-stream.h b/camel/providers/nntp/camel-nntp-stream.h
deleted file mode 100644
index eef217cef2..0000000000
--- a/camel/providers/nntp/camel-nntp-stream.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2001 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_NNTP_STREAM_H
-#define _CAMEL_NNTP_STREAM_H
-
-#include <camel/camel-stream.h>
-
-#define CAMEL_NNTP_STREAM(obj) CAMEL_CHECK_CAST (obj, camel_nntp_stream_get_type (), CamelNNTPStream)
-#define CAMEL_NNTP_STREAM_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_nntp_stream_get_type (), CamelNNTPStreamClass)
-#define CAMEL_IS_NNTP_STREAM(obj) CAMEL_CHECK_TYPE (obj, camel_nntp_stream_get_type ())
-
-typedef struct _CamelNNTPStreamClass CamelNNTPStreamClass;
-typedef struct _CamelNNTPStream CamelNNTPStream;
-
-typedef enum {
- CAMEL_NNTP_STREAM_LINE,
- CAMEL_NNTP_STREAM_DATA,
- CAMEL_NNTP_STREAM_EOD, /* end of data, acts as if end of stream */
-} camel_nntp_stream_mode_t;
-
-struct _CamelNNTPStream {
- CamelStream parent;
-
- CamelStream *source;
-
- camel_nntp_stream_mode_t mode;
- int state;
-
- unsigned char *buf, *ptr, *end;
- unsigned char *linebuf, *lineptr, *lineend;
-};
-
-struct _CamelNNTPStreamClass {
- CamelStreamClass parent_class;
-};
-
-CamelType camel_nntp_stream_get_type (void);
-
-CamelStream *camel_nntp_stream_new (CamelStream *source);
-
-
-void camel_nntp_stream_set_mode (CamelNNTPStream *is, camel_nntp_stream_mode_t mode);
-
-int camel_nntp_stream_line (CamelNNTPStream *is, unsigned char **data, unsigned int *len);
-int camel_nntp_stream_gets (CamelNNTPStream *is, unsigned char **start, unsigned int *len);
-int camel_nntp_stream_getd (CamelNNTPStream *is, unsigned char **start, unsigned int *len);
-
-#endif /* ! _CAMEL_NNTP_STREAM_H */
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
deleted file mode 100644
index 2a9669d697..0000000000
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "camel/camel-file-utils.h"
-#include "camel/camel-mime-message.h"
-#include "camel/camel-stream-null.h"
-#include "camel/camel-operation.h"
-#include "camel/camel-data-cache.h"
-
-#include "camel-nntp-summary.h"
-#include "camel-nntp-folder.h"
-#include "camel-nntp-store.h"
-#include "camel-nntp-stream.h"
-
-#define w(x)
-#define io(x)
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-extern int camel_verbose_debug;
-#define dd(x) (camel_verbose_debug?(x):0)
-
-#define CAMEL_NNTP_SUMMARY_VERSION (0x200)
-
-static int xover_setup(CamelNNTPSummary *cns, CamelException *ex);
-static int add_range_xover(CamelNNTPSummary *cns, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex);
-static int add_range_head(CamelNNTPSummary *cns, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex);
-
-enum _xover_t {
- XOVER_STRING = 0,
- XOVER_MSGID,
- XOVER_SIZE,
-};
-
-struct _xover_header {
- struct _xover_header *next;
-
- const char *name;
- unsigned int skip:8;
- enum _xover_t type:8;
-};
-
-struct _CamelNNTPSummaryPrivate {
- char *uid;
-
- struct _xover_header *xover; /* xoverview format */
- int xover_setup;
-};
-
-#define _PRIVATE(o) (((CamelNNTPSummary *)(o))->priv)
-
-static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *);
-static int summary_header_load(CamelFolderSummary *, FILE *);
-static int summary_header_save(CamelFolderSummary *, FILE *);
-
-static void camel_nntp_summary_class_init (CamelNNTPSummaryClass *klass);
-static void camel_nntp_summary_init (CamelNNTPSummary *obj);
-static void camel_nntp_summary_finalise (CamelObject *obj);
-static CamelFolderSummaryClass *camel_nntp_summary_parent;
-
-CamelType
-camel_nntp_summary_get_type(void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(camel_folder_summary_get_type(), "CamelNNTPSummary",
- sizeof (CamelNNTPSummary),
- sizeof (CamelNNTPSummaryClass),
- (CamelObjectClassInitFunc) camel_nntp_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_nntp_summary_init,
- (CamelObjectFinalizeFunc) camel_nntp_summary_finalise);
- }
-
- return type;
-}
-
-static void
-camel_nntp_summary_class_init(CamelNNTPSummaryClass *klass)
-{
- CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *) klass;
-
- camel_nntp_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type()));
-
- sklass->message_info_new = message_info_new;
- sklass->summary_header_load = summary_header_load;
- sklass->summary_header_save = summary_header_save;
-}
-
-static void
-camel_nntp_summary_init(CamelNNTPSummary *obj)
-{
- struct _CamelNNTPSummaryPrivate *p;
- struct _CamelFolderSummary *s = (CamelFolderSummary *)obj;
-
- p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
-
- /* subclasses need to set the right instance data sizes */
- s->message_info_size = sizeof(CamelMessageInfo);
- s->content_info_size = sizeof(CamelMessageContentInfo);
-
- /* and a unique file version */
- s->version += CAMEL_NNTP_SUMMARY_VERSION;
-}
-
-static void
-camel_nntp_summary_finalise(CamelObject *obj)
-{
- CamelNNTPSummary *cns = CAMEL_NNTP_SUMMARY(obj);
- struct _xover_header *xover, *xn;
-
- xover = cns->priv->xover;
- while (xover) {
- xn = xover->next;
- g_free(xover);
- xover = xn;
- }
-
- g_free(cns->priv);
-}
-
-CamelNNTPSummary *
-camel_nntp_summary_new(CamelNNTPFolder *folder)
-{
- CamelNNTPSummary *cns = (CamelNNTPSummary *)camel_object_new(camel_nntp_summary_get_type());
- char *path;
-
- cns->folder = folder;
- path = g_strdup_printf("%s.ev-summary", folder->storage_path);
- camel_folder_summary_set_filename((CamelFolderSummary *)cns, path);
- g_free(path);
-
- camel_folder_summary_set_build_content((CamelFolderSummary *)cns, FALSE);
-
- return cns;
-}
-
-static CamelMessageInfo *
-message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
-{
- CamelMessageInfo *mi;
- CamelNNTPSummary *cns = (CamelNNTPSummary *)s;
-
- /* error to call without this setup */
- if (cns->priv->uid == NULL)
- return NULL;
-
- /* we shouldn't be here if we already have this uid */
- g_assert(camel_folder_summary_uid(s, cns->priv->uid) == NULL);
-
- mi = ((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new(s, h);
- if (mi) {
- camel_message_info_set_uid(mi, cns->priv->uid);
- cns->priv->uid = NULL;
- }
-
- return mi;
-}
-
-static int
-summary_header_load(CamelFolderSummary *s, FILE *in)
-{
- CamelNNTPSummary *cns = CAMEL_NNTP_SUMMARY(s);
-
- if (((CamelFolderSummaryClass *)camel_nntp_summary_parent)->summary_header_load(s, in) == -1
- || camel_file_util_decode_fixed_int32(in, &cns->high) == -1
- || camel_file_util_decode_fixed_int32(in, &cns->low) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-summary_header_save(CamelFolderSummary *s, FILE *out)
-{
- CamelNNTPSummary *cns = CAMEL_NNTP_SUMMARY(s);
-
- if (((CamelFolderSummaryClass *)camel_nntp_summary_parent)->summary_header_save(s, out) == -1
- || camel_file_util_encode_fixed_int32(out, cns->high) == -1
- || camel_file_util_encode_fixed_int32(out, cns->low) == -1)
- return -1;
-
- return 0;
-}
-
-/* Assumes we have the stream */
-int
-camel_nntp_summary_check(CamelNNTPSummary *cns, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelNNTPStore *store;
- CamelFolder *folder;
- CamelFolderSummary *s;
- int ret, i;
- char *line;
- unsigned int n, f, l;
- int count;
-
- if (xover_setup(cns, ex) == -1)
- return -1;
-
- folder = (CamelFolder *)cns->folder;
- store = (CamelNNTPStore *)folder->parent_store;
- s = (CamelFolderSummary *)cns;
-
- ret = camel_nntp_command(store, &line, "group %s", folder->full_name);
- if (ret == 411) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID,
- _("No such folder: %s"), line);
- return -1;
- } else if (ret != 211) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not get group: %s"), line);
- return -1;
- }
-
- line +=3;
- n = strtoul(line, &line, 10);
- f = strtoul(line, &line, 10);
- l = strtoul(line, &line, 10);
-
- dd(printf("nntp_summary: got last '%u' first '%u'\n"
- "nntp_summary: high '%u' low '%u'\n", l, f, cns->high, cns->low));
-
- if (cns->low == f && cns->high == l) {
- dd(printf("nntp_summary: no work to do!\n"));
- return 0;
- }
-
- /* Need to work out what to do with our messages */
-
- /* Check for messages no longer on the server */
- if (cns->low != f) {
- count = camel_folder_summary_count(s);
- for (i = 0; i < count; i++) {
- CamelMessageInfo *mi = camel_folder_summary_index(s, i);
-
- if (mi) {
- const char *uid = camel_message_info_uid(mi);
- const char *msgid;
-
- n = strtoul(uid, NULL, 10);
- if (n < f || n > l) {
- dd(printf("nntp_summary: %u is lower/higher than lowest/highest article, removed\n", n));
- /* Since we use a global cache this could prematurely remove
- a cached message that might be in another folder - not that important as
- it is a true cache */
- msgid = strchr(uid, ',');
- if (msgid)
- camel_data_cache_remove(store->cache, "cache", msgid+1, NULL);
- camel_folder_change_info_remove_uid(changes, uid);
- camel_folder_summary_remove(s, mi);
- count--;
- i--;
- }
-
- camel_folder_summary_info_free(s, mi);
- }
- }
- cns->low = f;
- }
-
- if (cns->high < l) {
- if (cns->high < f)
- cns->high = f-1;
-
- if (cns->priv->xover) {
- ret = add_range_xover(cns, l, cns->high+1, changes, ex);
- } else {
- ret = add_range_head(cns, l, cns->high+1, changes, ex);
- }
- }
-
- camel_folder_summary_touch(s);
-
- return ret;
-}
-
-static struct {
- const char *name;
- int type;
-} headers[] = {
- { "subject", 0 },
- { "from", 0 },
- { "date", 0 },
- { "message-id", 1 },
- { "references", 0 },
- { "bytes", 2 },
-};
-
-static int
-xover_setup(CamelNNTPSummary *cns, CamelException *ex)
-{
- CamelNNTPStore *store;
- CamelFolder *folder;
- CamelFolderSummary *s;
- int ret, i;
- char *line;
- unsigned int len;
- unsigned char c, *p;
- struct _xover_header *xover, *last;
-
- if (cns->priv->xover_setup)
- return 0;
-
- /* manual override */
- if (getenv("CAMEL_NNTP_DISABLE_XOVER") != NULL) {
- cns->priv->xover_setup = TRUE;
- return 0;
- }
-
- folder = (CamelFolder *)cns->folder;
- store = (CamelNNTPStore *)folder->parent_store;
- s = (CamelFolderSummary *)cns;
-
- ret = camel_nntp_command(store, &line, "list overview.fmt");
- if (ret == -1) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("NNTP Command failed: %s"), strerror(errno));
- return -1;
- }
-
- cns->priv->xover_setup = TRUE;
-
- /* unsupported command? */
- if (ret != 215)
- return 0;
-
- last = (struct _xover_header *)&cns->priv->xover;
-
- /* supported command */
- while ((ret = camel_nntp_stream_line(store->stream, (unsigned char **)&line, &len)) > 0) {
- p = line;
- xover = g_malloc0(sizeof(*xover));
- last->next = xover;
- last = xover;
- while ((c = *p++)) {
- if (c == ':') {
- p[-1] = 0;
- for (i=0;i<sizeof(headers)/sizeof(headers[0]);i++) {
- if (strcmp(line, headers[i].name) == 0) {
- xover->name = headers[i].name;
- if (strncmp(p, "full", 4) == 0)
- xover->skip = strlen(xover->name)+1;
- else
- xover->skip = 0;
- xover->type = headers[i].type;
- break;
- }
- }
- break;
- } else {
- p[-1] = tolower(c);
- }
- }
- }
-
- return ret;
-}
-
-static int
-add_range_xover(CamelNNTPSummary *cns, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelNNTPStore *store;
- CamelFolder *folder;
- CamelFolderSummary *s;
- CamelMessageInfo *mi;
- struct _camel_header_raw *headers = NULL;
- char *line, *tab;
- int len, ret;
- unsigned int n, count, total, size;
- struct _xover_header *xover;
- time_t last, now;
-
- folder = (CamelFolder *)cns->folder;
- store = (CamelNNTPStore *)folder->parent_store;
- s = (CamelFolderSummary *)cns;
-
- camel_operation_start(NULL, _("%s: Scanning new messages"), ((CamelService *)store)->url->host);
-
- ret = camel_nntp_command(store, &line, "xover %r", low, high);
- if (ret != 224) {
- camel_operation_end(NULL);
- return -1;
- }
-
- last = time(0);
- count = 0;
- total = high-low+1;
- while ((ret = camel_nntp_stream_line(store->stream, (unsigned char **)&line, &len)) > 0) {
- camel_operation_progress(NULL, (count * 100) / total);
- count++;
- n = strtoul(line, &tab, 10);
- if (*tab != '\t')
- continue;
- tab++;
- xover = cns->priv->xover;
- size = 0;
- for (;tab[0] && xover;xover = xover->next) {
- line = tab;
- tab = strchr(line, '\t');
- if (tab)
- *tab++ = 0;
- else
- tab = line+strlen(line);
-
- /* do we care about this column? */
- if (xover->name) {
- line += xover->skip;
- if (line < tab) {
- camel_header_raw_append(&headers, xover->name, line, -1);
- switch(xover->type) {
- case XOVER_STRING:
- break;
- case XOVER_MSGID:
- cns->priv->uid = g_strdup_printf("%u,%s", n, line);
- break;
- case XOVER_SIZE:
- size = strtoul(line, NULL, 10);
- break;
- }
- }
- }
- }
-
- /* truncated line? ignore? */
- if (xover == NULL) {
- mi = camel_folder_summary_uid(s, cns->priv->uid);
- if (mi == NULL) {
- mi = camel_folder_summary_add_from_header(s, headers);
- if (mi) {
- mi->size = size;
- cns->high = n;
- camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi));
- }
- } else {
- camel_folder_summary_info_free(s, mi);
- }
- }
-
- if (cns->priv->uid) {
- g_free(cns->priv->uid);
- cns->priv->uid = NULL;
- }
-
- camel_header_raw_clear(&headers);
-
- now = time(0);
- if (last + 2 < now) {
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", changes);
- camel_folder_change_info_clear(changes);
- last = now;
- }
- }
-
- camel_operation_end(NULL);
-
- return ret;
-}
-
-static int
-add_range_head(CamelNNTPSummary *cns, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelNNTPStore *store;
- CamelFolder *folder;
- CamelFolderSummary *s;
- int i, ret = -1;
- char *line, *msgid;
- unsigned int n, count, total;
- CamelMessageInfo *mi;
- CamelMimeParser *mp;
- time_t now, last;
-
- folder = (CamelFolder *)cns->folder;
- store = (CamelNNTPStore *)folder->parent_store;
- s = (CamelFolderSummary *)cns;
-
- mp = camel_mime_parser_new();
-
- camel_operation_start(NULL, _("%s: Scanning new messages"), ((CamelService *)store)->url->host);
-
- last = time(0);
- count = 0;
- total = high-low+1;
- for (i=low;i<high+1;i++) {
- camel_operation_progress(NULL, (count * 100) / total);
- count++;
- ret = camel_nntp_command(store, &line, "head %u", i);
- /* unknown article, ignore */
- if (ret == 423)
- continue;
- else if (ret == -1)
- goto error;
- else if (ret != 221) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Unknown server response: %s"), line);
- goto ioerror;
- }
- line += 3;
- n = strtoul(line, &line, 10);
- if (n != i)
- g_warning("retrieved message '%d' when i expected '%d'?\n", n, i);
-
- if ((msgid = strchr(line, '<')) && (line = strchr(msgid+1, '>'))){
- line[1] = 0;
- cns->priv->uid = g_strdup_printf("%u,%s\n", n, msgid);
- mi = camel_folder_summary_uid(s, cns->priv->uid);
- if (mi == NULL) {
- if (camel_mime_parser_init_with_stream(mp, (CamelStream *)store->stream) == -1)
- goto error;
- mi = camel_folder_summary_add_from_parser(s, mp);
- while (camel_mime_parser_step(mp, NULL, NULL) != CAMEL_MIME_PARSER_STATE_EOF)
- ;
- if (mi == NULL) {
- goto error;
- }
- cns->high = i;
- camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi));
- } else {
- /* already have, ignore */
- camel_folder_summary_info_free(s, mi);
- }
- if (cns->priv->uid) {
- g_free(cns->priv->uid);
- cns->priv->uid = NULL;
- }
- }
-
- now = time(0);
- if (last + 2 < now) {
- camel_object_trigger_event((CamelObject *)folder, "folder_changed", changes);
- camel_folder_change_info_clear(changes);
- last = now;
- }
- }
-
- ret = 0;
-error:
-
- if (ret == -1) {
- if (errno == EINTR)
- camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("Use cancel"));
- else
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Operation failed: %s"), strerror(errno));
- }
-ioerror:
-
- if (cns->priv->uid) {
- g_free(cns->priv->uid);
- cns->priv->uid = NULL;
- }
- camel_object_unref((CamelObject *)mp);
-
- camel_operation_end(NULL);
-
- return ret;
-}
diff --git a/camel/providers/nntp/camel-nntp-summary.h b/camel/providers/nntp/camel-nntp-summary.h
deleted file mode 100644
index 82070cdc31..0000000000
--- a/camel/providers/nntp/camel-nntp-summary.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2000 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_NNTP_SUMMARY_H
-#define _CAMEL_NNTP_SUMMARY_H
-
-#include <camel/camel-folder-summary.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-exception.h>
-#include <libibex/ibex.h>
-
-#define CAMEL_NNTP_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_nntp_summary_get_type (), CamelNNTPSummary)
-#define CAMEL_NNTP_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_nntp_summary_get_type (), CamelNNTPSummaryClass)
-#define CAMEL_IS_LOCAL_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_nntp_summary_get_type ())
-
-typedef struct _CamelNNTPSummary CamelNNTPSummary;
-typedef struct _CamelNNTPSummaryClass CamelNNTPSummaryClass;
-
-struct _CamelNNTPSummary {
- CamelFolderSummary parent;
-
- struct _CamelNNTPSummaryPrivate *priv;
-
- struct _CamelNNTPFolder *folder;
-
- guint32 high, low;
-};
-
-struct _CamelNNTPSummaryClass {
- CamelFolderSummaryClass parent_class;
-};
-
-CamelType camel_nntp_summary_get_type (void);
-CamelNNTPSummary *camel_nntp_summary_new(struct _CamelNNTPFolder *folder);
-
-int camel_nntp_summary_check(CamelNNTPSummary *cns, CamelFolderChangeInfo *, CamelException *ex);
-
-#if 0
-/* load/check the summary */
-int camel_nntp_summary_load(CamelNNTPSummary *cls, CamelException *ex);
-/* check for new/removed messages */
-int camel_nntp_summary_check(CamelNNTPSummary *cls, CamelFolderChangeInfo *, CamelException *ex);
-/* perform a folder sync or expunge, if needed */
-int camel_nntp_summary_sync(CamelNNTPSummary *cls, gboolean expunge, CamelFolderChangeInfo *, CamelException *ex);
-/* add a new message to the summary */
-CamelMessageInfo *camel_nntp_summary_add(CamelNNTPSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
-#endif
-
-#endif /* ! _CAMEL_NNTP_SUMMARY_H */
-
diff --git a/camel/providers/nntp/camel-nntp-types.h b/camel/providers/nntp/camel-nntp-types.h
deleted file mode 100644
index a37179c521..0000000000
--- a/camel/providers/nntp/camel-nntp-types.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-grouplist.h : getting/updating the list of newsgroups on the server. */
-
-/*
- * Author : Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 2000 Ximian .
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_NNTP_TYPES_H
-#define CAMEL_NNTP_TYPES_H 1
-
-typedef struct CamelNNTPGroupList CamelNNTPGroupList;
-typedef struct CamelNNTPGroupListEntry CamelNNTPGroupListEntry;
-typedef struct CamelNNTPOverField CamelNNTPOverField;
-typedef struct CamelNNTPStore CamelNNTPStore;
-typedef struct CamelNNTPStoreClass CamelNNTPStoreClass;
-
-#endif /* CAMEL_NNTP_TYPES_H */
diff --git a/camel/providers/nntp/camel-nntp-utils.c b/camel/providers/nntp/camel-nntp-utils.c
deleted file mode 100644
index d8000a85ee..0000000000
--- a/camel/providers/nntp/camel-nntp-utils.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-utils.c : utilities used by the nntp code. */
-
-/*
- * Author : Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 2000 Ximian .
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include "camel-folder-summary.h"
-#include "camel-nntp-resp-codes.h"
-#include "camel-nntp-folder.h"
-#include "camel-nntp-store.h"
-#include "camel-nntp-utils.h"
-#include "camel-stream-mem.h"
-#include "camel-exception.h"
-
-#include "e-util/md5-utils.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-static void
-get_XOVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
- int first_message, int last_message, CamelException *ex)
-{
- int status;
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
- char digest[16];
-
- status = camel_nntp_command (nntp_store, ex, NULL,
- "XOVER %d-%d",
- first_message,
- last_message);
-
- if (status == NNTP_DATA_FOLLOWS) {
- gboolean done = FALSE;
-
- while (!done) {
- char *line;
-
- if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (nntp_store), &line, ex) < 0) {
- g_warning ("failed to recv_line while building OVER header list\n");
- break;
- }
-
- if (*line == '.') {
- done = TRUE;
- g_print ("done\n");
- }
- else {
- CamelMessageInfo *new_info = camel_folder_summary_info_new(folder->summary);
- char **split_line = g_strsplit (line, "\t", 7);
- char *subject, *from, *date, *message_id, *bytes;
- char *uid;
-
- subject = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_SUBJECT].index];
- from = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_FROM].index];
- date = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_DATE].index];
- message_id = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_MESSAGE_ID].index];
- bytes = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_BYTES].index];
-
- /* if the overview format flagged this
- field as "full", skip over the
- preceding field name and colon */
- if (nntp_store->overview_field [ CAMEL_NNTP_OVER_SUBJECT ].full)
- subject += strlen ("Subject:");
- if (nntp_store->overview_field [ CAMEL_NNTP_OVER_FROM ].full)
- from += strlen ("From:");
- if (nntp_store->overview_field [ CAMEL_NNTP_OVER_DATE ].full)
- date += strlen ("Date:");
- if (nntp_store->overview_field [ CAMEL_NNTP_OVER_MESSAGE_ID ].full)
- message_id += strlen ("Message-ID:");
- if (nntp_store->overview_field [ CAMEL_NNTP_OVER_BYTES ].full)
- bytes += strlen ("Bytes:");
-
- uid = g_strdup_printf ("%s,%s", split_line[0], message_id);
- camel_message_info_set_subject(new_info, g_strdup(subject));
- camel_message_info_set_from(new_info, g_strdup(from));
- camel_message_info_set_to(new_info, g_strdup(folder->name));
- camel_message_info_set_uid(new_info, uid);
-
- new_info->date_sent = camel_header_decode_date(date, NULL);
-#if 0
- /* XXX do we need to fill in both dates? */
- new_info->headers.date_received = g_strdup(date);
-#endif
- new_info->size = atoi(bytes);
- md5_get_digest(message_id, strlen(message_id), digest);
- memcpy(new_info->message_id.id.hash, digest, sizeof(new_info->message_id.id.hash));
-
- if (camel_nntp_newsrc_article_is_read (nntp_store->newsrc,
- folder->name,
- atoi (split_line[0])))
- new_info->flags |= CAMEL_MESSAGE_SEEN;
-
- camel_folder_summary_add (folder->summary, new_info);
- g_strfreev (split_line);
- }
- g_free (line);
- }
- }
- else {
- /* XXX */
- g_warning ("weird nntp response for XOVER: %d\n", status);
- }
-}
-
-#if 0
-static GArray*
-get_HEAD_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
- int first_message, int last_message, CamelException *ex)
-{
- int i;
- int status;
-
- for (i = first_message; i < last_message; i ++) {
- status = camel_nntp_command (nntp_store, ex, NULL,
- "HEAD %d", i);
-
- if (status == NNTP_HEAD_FOLLOWS) {
- gboolean done = FALSE;
- char *buf;
- int buf_len;
- int buf_alloc;
- int h;
- CamelStream *header_stream;
- GArray *header_array;
- CamelStream *nntp_istream;
- CamelMessageInfo *new_info = g_new0(CamelMessageInfo, 1);
-
- buf_alloc = 2048;
- buf_len = 0;
- buf = g_malloc(buf_alloc);
- done = FALSE;
-
- buf[0] = 0;
-
- nntp_istream = nntp_store->istream;
-
- while (!done) {
- char *line;
- int line_length;
-
- line = camel_stream_buffer_read_line (
- CAMEL_STREAM_BUFFER ( nntp_istream ));
- line_length = strlen ( line );
-
- if (*line == '.') {
- done = TRUE;
- }
- else {
- if (buf_len + line_length > buf_alloc) {
- buf_alloc *= 2;
- buf = g_realloc (buf, buf_alloc);
- }
- strcat(buf, line);
- strcat(buf, "\n");
- buf_len += strlen(line);
- g_free (line);
- }
- }
-
- /* create a stream from which to parse the headers */
- header_stream = camel_stream_mem_new_with_buffer (buf, buf_len,
- CAMEL_STREAM_MEM_READ);
-
- header_array = get_header_array_from_stream (header_stream);
-
- memset (&info, 0, sizeof(info));
-
- for (h = 0; h < header_array->len; h ++) {
- Rfc822Header *header = &((Rfc822Header*)header_array->data)[h];
- if (!g_strcasecmp(header->name, "From"))
- new_info->from = g_strdup(header->value);
- else if (!g_strcasecmp(header->name, "To"))
- new_info->to = g_strdup(header->value);
- else if (!g_strcasecmp(header->name, "Subject"))
- new_info->subject = g_strdup(header->value);
- else if (!g_strcasecmp(header->name, "Message-ID")) {
- new_info->uid = g_strdup_printf("%d,%s", i, header->value);
- new_info->message_id = g_strdup(header->value);
- }
- else if (!g_strcasecmp(header->name, "Date")) {
- new_info->date_sent = camel_header_decode_date (header->value);
-#if 0
- new_info->date_sent = g_strdup(header->value);
- new_info->date_received = g_strdup(header->value);
-#endif
- }
- }
-
- camel_folder_summary_add (nntp_folder->summary, new_info);
- }
- else if (status == CAMEL_NNTP_FAIL) {
- /* nasty things are afoot */
- g_warning ("failure doing HEAD\n");
- break;
- }
- }
-}
-#endif
-
-static inline int
-uid_num (CamelFolderSummary *summary, int index)
-{
- char *tmp;
- char *brk;
- CamelMessageInfo *minfo;
- int ret;
-
- minfo = camel_folder_summary_index(summary, index);
- if(minfo == NULL)
- return 0;
-
- tmp = g_strdup(camel_message_info_uid(minfo));
- camel_message_info_free(minfo);
-
- if((brk = strchr(tmp, ',')) == NULL)
- ret = 0;
- else {
- *brk = 0;
- ret = atoi(tmp);
- }
-
- g_free(tmp);
-
- return ret;
-}
-
-void
-camel_nntp_get_headers (CamelStore *store,
- CamelNNTPFolder *nntp_folder,
- CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
- CamelFolder *folder = CAMEL_FOLDER (nntp_folder);
- char *ret;
- int first_message, nb_message, last_message, last_summary;
- int status;
- int i;
-
- status = camel_nntp_command (nntp_store, ex, &ret,
- "GROUP %s", folder->name);
- sscanf (ret, "%d %d %d", &nb_message, &first_message, &last_message);
- g_free (ret);
-
- i = camel_folder_summary_count(folder->summary);
- if(i != 0) {
- last_summary = uid_num(folder->summary, i-1);
-
- if(last_summary < first_message)
- camel_folder_summary_clear(folder->summary);
- else {
- while(uid_num(folder->summary, 0) < first_message)
- camel_folder_summary_remove_index(folder->summary, 0);
-
- if(last_summary >= last_message)
- return;
-
- first_message = last_summary;
- }
- }
-
- if (status == NNTP_NO_SUCH_GROUP) {
- /* XXX throw invalid group exception */
- camel_exception_setv (ex,
- CAMEL_EXCEPTION_FOLDER_INVALID,
- "group %s not found on server",
- folder->name);
- return;
- }
-
-
- if (nntp_store->extensions & CAMEL_NNTP_EXT_OVER) {
- get_XOVER_headers (nntp_store, folder, first_message, last_message, ex);
- }
- else {
- g_warning ("need to fix get_HEAD_headers\n");
-#if 0
- get_HEAD_headers (nntp_store, folder, first_message, last_message, ex);
-#endif
- }
-
-}
diff --git a/camel/providers/nntp/camel-nntp-utils.h b/camel/providers/nntp/camel-nntp-utils.h
deleted file mode 100644
index 48fd7490c9..0000000000
--- a/camel/providers/nntp/camel-nntp-utils.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-nntp-utils.h : Utilities for the NNTP provider */
-
-/*
- *
- * Author : Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 1999 Ximian .
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_NNTP_UTILS_H
-#define CAMEL_NNTP_UTILS_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-void camel_nntp_get_headers (CamelStore *store, CamelNNTPFolder *nntp_folder, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_NNTP_UTILS_H */
diff --git a/camel/providers/nntp/libcamelnntp.urls b/camel/providers/nntp/libcamelnntp.urls
deleted file mode 100644
index dee2e70f14..0000000000
--- a/camel/providers/nntp/libcamelnntp.urls
+++ /dev/null
@@ -1,2 +0,0 @@
-news
-nntp
diff --git a/camel/providers/nntp/test-newsrc.c b/camel/providers/nntp/test-newsrc.c
deleted file mode 100644
index c4b985e565..0000000000
--- a/camel/providers/nntp/test-newsrc.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <stdio.h>
-#include <glib.h>
-#include "camel-nntp-newsrc.h"
-
-int
-main(int argc, char *argv[])
-{
- CamelNNTPNewsrc *newsrc = camel_nntp_newsrc_read_for_server (argv[1]);
- camel_nntp_newsrc_write_to_file (newsrc, stdout);
-}
diff --git a/camel/providers/pop3/.cvsignore b/camel/providers/pop3/.cvsignore
deleted file mode 100644
index ddf4c8b28d..0000000000
--- a/camel/providers/pop3/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-Makefile
-Makefile.in
-.libs
-.deps
-*.lo
-*.la
-*.bb
-*.bbg
-*.da
-*.gcov
diff --git a/camel/providers/pop3/Makefile.am b/camel/providers/pop3/Makefile.am
deleted file mode 100644
index 84f5477f97..0000000000
--- a/camel/providers/pop3/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelpop3includedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamelpop3.la
-camel_provider_DATA = libcamelpop3.urls
-
-INCLUDES = \
- -I.. \
- -I$(srcdir)/.. \
- -I$(srcdir)/../../.. \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/e-util \
- $(CAMEL_CFLAGS) \
- $(GNOME_INCLUDEDIR) \
- $(GTK_INCLUDEDIR) \
- -DG_LOG_DOMAIN=\"camel-pop3-provider\"
-
-libcamelpop3_la_SOURCES = \
- camel-pop3-engine.c \
- camel-pop3-folder.c \
- camel-pop3-provider.c \
- camel-pop3-stream.c \
- camel-pop3-store.c
-
-libcamelpop3include_HEADERS = \
- camel-pop3-engine.h \
- camel-pop3-folder.h \
- camel-pop3-stream.h \
- camel-pop3-store.h
-
-
-libcamelpop3_la_LDFLAGS = -avoid-version -module
-
-libcamelpop3_la_LIBADD = $(top_builddir)/e-util/libeutil.la
-
-EXTRA_DIST = libcamelpop3.urls
diff --git a/camel/providers/pop3/camel-pop3-engine.c b/camel/providers/pop3/camel-pop3-engine.c
deleted file mode 100644
index 2186136f95..0000000000
--- a/camel/providers/pop3/camel-pop3-engine.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Author:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-
-#include <string.h>
-#include <stdio.h>
-
-#include <glib.h>
-
-#include "camel-pop3-engine.h"
-#include "camel-pop3-stream.h"
-#include <camel/camel-service.h>
-#include <camel/camel-sasl.h>
-
-/* max 'outstanding' bytes in output stream, so we can't deadlock waiting
- for the server to accept our data when pipelining */
-#define CAMEL_POP3_SEND_LIMIT (1024)
-
-
-extern int camel_verbose_debug;
-#define dd(x) (camel_verbose_debug?(x):0)
-
-static void get_capabilities(CamelPOP3Engine *pe, int read_greeting);
-
-static CamelObjectClass *parent_class = NULL;
-
-/* Returns the class for a CamelStream */
-#define CS_CLASS(so) CAMEL_POP3_ENGINE_CLASS(CAMEL_OBJECT_GET_CLASS(so))
-
-static void
-camel_pop3_engine_class_init (CamelPOP3EngineClass *camel_pop3_engine_class)
-{
- parent_class = camel_type_get_global_classfuncs( CAMEL_OBJECT_TYPE );
-}
-
-static void
-camel_pop3_engine_init(CamelPOP3Engine *pe, CamelPOP3EngineClass *peclass)
-{
- e_dlist_init(&pe->active);
- e_dlist_init(&pe->queue);
- e_dlist_init(&pe->done);
- pe->state = CAMEL_POP3_ENGINE_DISCONNECT;
-}
-
-static void
-camel_pop3_engine_finalise(CamelPOP3Engine *pe)
-{
- /* FIXME: Also flush/free any outstanding requests, etc */
-
- if (pe->stream)
- camel_object_unref((CamelObject *)pe->stream);
-}
-
-CamelType
-camel_pop3_engine_get_type (void)
-{
- static CamelType camel_pop3_engine_type = CAMEL_INVALID_TYPE;
-
- if (camel_pop3_engine_type == CAMEL_INVALID_TYPE) {
- camel_pop3_engine_type = camel_type_register(camel_object_get_type(),
- "CamelPOP3Engine",
- sizeof( CamelPOP3Engine ),
- sizeof( CamelPOP3EngineClass ),
- (CamelObjectClassInitFunc) camel_pop3_engine_class_init,
- NULL,
- (CamelObjectInitFunc) camel_pop3_engine_init,
- (CamelObjectFinalizeFunc) camel_pop3_engine_finalise );
- }
-
- return camel_pop3_engine_type;
-}
-
-/**
- * camel_pop3_engine_new:
- * @source: source stream
- * @flags: engine flags
- *
- * Returns a NULL stream. A null stream is always at eof, and
- * always returns success for all reads and writes.
- *
- * Return value: the stream
- **/
-CamelPOP3Engine *
-camel_pop3_engine_new(CamelStream *source, guint32 flags)
-{
- CamelPOP3Engine *pe;
-
- pe = (CamelPOP3Engine *)camel_object_new(camel_pop3_engine_get_type ());
-
- pe->stream = (CamelPOP3Stream *)camel_pop3_stream_new(source);
- pe->state = CAMEL_POP3_ENGINE_AUTH;
- pe->flags = flags;
-
- get_capabilities(pe, TRUE);
-
- return pe;
-}
-
-
-/**
- * camel_pop3_engine_reget_capabilities:
- * @engine: pop3 engine
- *
- * Regets server capabilities (needed after a STLS command is issued for example).
- **/
-void
-camel_pop3_engine_reget_capabilities (CamelPOP3Engine *engine)
-{
- g_return_if_fail (CAMEL_IS_POP3_ENGINE (engine));
-
- get_capabilities (engine, FALSE);
-}
-
-
-/* TODO: read implementation too?
- etc? */
-struct {
- char *cap;
- guint32 flag;
-} capa[] = {
- { "APOP" , CAMEL_POP3_CAP_APOP },
- { "TOP" , CAMEL_POP3_CAP_TOP },
- { "UIDL", CAMEL_POP3_CAP_UIDL },
- { "PIPELINING", CAMEL_POP3_CAP_PIPE },
- { "STLS", CAMEL_POP3_CAP_STLS }, /* STARTTLS */
-};
-
-static void
-cmd_capa(CamelPOP3Engine *pe, CamelPOP3Stream *stream, void *data)
-{
- unsigned char *line, *tok, *next;
- unsigned int len;
- int ret;
- int i;
- CamelServiceAuthType *auth;
-
- dd(printf("cmd_capa\n"));
-
- do {
- ret = camel_pop3_stream_line(stream, &line, &len);
- if (ret >= 0) {
- if (strncmp(line, "SASL ", 5) == 0) {
- tok = line+5;
- dd(printf("scanning tokens '%s'\n", tok));
- while (tok) {
- next = strchr(tok, ' ');
- if (next)
- *next++ = 0;
- auth = camel_sasl_authtype(tok);
- if (auth) {
- dd(printf("got auth type '%s'\n", tok));
- pe->auth = g_list_prepend(pe->auth, auth);
- } else {
- dd(printf("unsupported auth type '%s'\n", tok));
- }
- tok = next;
- }
- } else {
- for (i=0;i<sizeof(capa)/sizeof(capa[0]);i++) {
- if (strcmp(capa[i].cap, line) == 0)
- pe->capa |= capa[i].flag;
- }
- }
- }
- } while (ret>0);
-}
-
-static void
-get_capabilities(CamelPOP3Engine *pe, int read_greeting)
-{
- CamelPOP3Command *pc;
- unsigned char *line, *apop, *apopend;
- unsigned int len;
- extern CamelServiceAuthType camel_pop3_password_authtype;
- extern CamelServiceAuthType camel_pop3_apop_authtype;
-
- if (read_greeting) {
- /* first, read the greeting */
- if (camel_pop3_stream_line(pe->stream, &line, &len) == -1
- || strncmp(line, "+OK", 3) != 0)
- return;
-
- if ((apop = strchr(line+3, '<'))
- && (apopend = strchr(apop, '>'))) {
- apopend[1] = 0;
- pe->apop = g_strdup(apop);
- pe->capa = CAMEL_POP3_CAP_APOP;
- pe->auth = g_list_append(pe->auth, &camel_pop3_apop_authtype);
- }
-
- pe->auth = g_list_prepend(pe->auth, &camel_pop3_password_authtype);
- }
-
- if (!(pe->flags & CAMEL_POP3_ENGINE_DISABLE_EXTENSIONS)) {
- pc = camel_pop3_engine_command_new(pe, CAMEL_POP3_COMMAND_MULTI, cmd_capa, NULL, "CAPA\r\n");
- while (camel_pop3_engine_iterate(pe, pc) > 0)
- ;
- camel_pop3_engine_command_free(pe, pc);
-
- if (pe->state == CAMEL_POP3_ENGINE_TRANSACTION && !(pe->capa & CAMEL_POP3_CAP_UIDL)) {
- /* check for UIDL support manually */
- pc = camel_pop3_engine_command_new (pe, CAMEL_POP3_COMMAND_SIMPLE, NULL, NULL, "UIDL 1\r\n");
- while (camel_pop3_engine_iterate (pe, pc) > 0)
- ;
-
- if (pc->state == CAMEL_POP3_COMMAND_OK)
- pe->capa |= CAMEL_POP3_CAP_UIDL;
-
- camel_pop3_engine_command_free (pe, pc);
- }
- }
-}
-
-/* returns true if the command was sent, false if it was just queued */
-static int
-engine_command_queue(CamelPOP3Engine *pe, CamelPOP3Command *pc)
-{
- if (((pe->capa & CAMEL_POP3_CAP_PIPE) == 0 || (pe->sentlen + strlen(pc->data)) > CAMEL_POP3_SEND_LIMIT)
- && pe->current != NULL) {
- e_dlist_addtail(&pe->queue, (EDListNode *)pc);
- return FALSE;
- } else {
- /* ??? */
- if (camel_stream_write((CamelStream *)pe->stream, pc->data, strlen(pc->data)) == -1) {
- e_dlist_addtail(&pe->queue, (EDListNode *)pc);
- return FALSE;
- }
-
- pe->sentlen += strlen(pc->data);
-
- pc->state = CAMEL_POP3_COMMAND_DISPATCHED;
-
- if (pe->current == NULL)
- pe->current = pc;
- else
- e_dlist_addtail(&pe->active, (EDListNode *)pc);
-
- return TRUE;
- }
-}
-
-/* returns -1 on error (sets errno), 0 when no work to do, or >0 if work remaining */
-int
-camel_pop3_engine_iterate(CamelPOP3Engine *pe, CamelPOP3Command *pcwait)
-{
- unsigned char *p;
- unsigned int len;
- CamelPOP3Command *pc, *pw, *pn;
-
- if (pcwait && pcwait->state >= CAMEL_POP3_COMMAND_OK)
- return 0;
-
- pc = pe->current;
- if (pc == NULL)
- return 0;
-
- /* LOCK */
-
- if (camel_pop3_stream_line(pe->stream, &pe->line, &pe->linelen) == -1)
- return -1;
-
- p = pe->line;
- switch (p[0]) {
- case '+':
- dd(printf("Got + response\n"));
- if (pc->flags & CAMEL_POP3_COMMAND_MULTI) {
- pc->state = CAMEL_POP3_COMMAND_DATA;
- camel_pop3_stream_set_mode(pe->stream, CAMEL_POP3_STREAM_DATA);
-
- if (pc->func)
- pc->func(pe, pe->stream, pc->func_data);
-
- /* Make sure we get all data before going back to command mode */
- while (camel_pop3_stream_getd(pe->stream, &p, &len) > 0)
- ;
- camel_pop3_stream_set_mode(pe->stream, CAMEL_POP3_STREAM_LINE);
- } else {
- pc->state = CAMEL_POP3_COMMAND_OK;
- }
- break;
- case '-':
- pc->state = CAMEL_POP3_COMMAND_ERR;
- break;
- default:
- /* what do we do now? f'knows! */
- g_warning("Bad server response: %s\n", p);
- pc->state = CAMEL_POP3_COMMAND_ERR;
- break;
- }
-
- e_dlist_addtail(&pe->done, (EDListNode *)pc);
- pe->sentlen -= strlen(pc->data);
-
- /* Set next command */
- pe->current = (CamelPOP3Command *)e_dlist_remhead(&pe->active);
-
- /* check the queue for sending any we can now send also */
- pw = (CamelPOP3Command *)pe->queue.head;
- pn = pw->next;
- while (pn) {
- if (((pe->capa & CAMEL_POP3_CAP_PIPE) == 0 || (pe->sentlen + strlen(pw->data)) > CAMEL_POP3_SEND_LIMIT)
- && pe->current != NULL)
- break;
-
- if (camel_stream_write((CamelStream *)pe->stream, pw->data, strlen(pw->data)) == -1)
- return -1;
-
- e_dlist_remove((EDListNode *)pw);
-
- pe->sentlen += strlen(pw->data);
- pw->state = CAMEL_POP3_COMMAND_DISPATCHED;
-
- if (pe->current == NULL)
- pe->current = pw;
- else
- e_dlist_addtail(&pe->active, (EDListNode *)pw);
-
- pw = pn;
- pn = pn->next;
- }
-
- /* UNLOCK */
-
- if (pcwait && pcwait->state >= CAMEL_POP3_COMMAND_OK)
- return 0;
-
- return pe->current==NULL?0:1;
-}
-
-CamelPOP3Command *
-camel_pop3_engine_command_new(CamelPOP3Engine *pe, guint32 flags, CamelPOP3CommandFunc func, void *data, const char *fmt, ...)
-{
- CamelPOP3Command *pc;
- va_list ap;
-
- pc = g_malloc0(sizeof(*pc));
- pc->func = func;
- pc->func_data = data;
- pc->flags = flags;
-
- va_start(ap, fmt);
- pc->data = g_strdup_vprintf(fmt, ap);
- pc->state = CAMEL_POP3_COMMAND_IDLE;
-
- /* TODO: what about write errors? */
- engine_command_queue(pe, pc);
-
- return pc;
-}
-
-void
-camel_pop3_engine_command_free(CamelPOP3Engine *pe, CamelPOP3Command *pc)
-{
- if (pe->current != pc)
- e_dlist_remove((EDListNode *)pc);
- g_free(pc->data);
- g_free(pc);
-}
diff --git a/camel/providers/pop3/camel-pop3-engine.h b/camel/providers/pop3/camel-pop3-engine.h
deleted file mode 100644
index 3114980311..0000000000
--- a/camel/providers/pop3/camel-pop3-engine.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2001 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _CAMEL_POP3_ENGINE_H
-#define _CAMEL_POP3_ENGINE_H
-
-#include <camel/camel-object.h>
-#include "e-util/e-msgport.h"
-#include "camel-pop3-stream.h"
-
-#define CAMEL_POP3_ENGINE(obj) CAMEL_CHECK_CAST (obj, camel_pop3_engine_get_type (), CamelPOP3Engine)
-#define CAMEL_POP3_ENGINE_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_pop3_engine_get_type (), CamelPOP3EngineClass)
-#define CAMEL_IS_POP3_ENGINE(obj) CAMEL_CHECK_TYPE (obj, camel_pop3_engine_get_type ())
-
-typedef struct _CamelPOP3EngineClass CamelPOP3EngineClass;
-typedef struct _CamelPOP3Engine CamelPOP3Engine;
-typedef struct _CamelPOP3Command CamelPOP3Command;
-
-/* pop 3 connection states, actually since we're given a connected socket, we always start in auth state */
-typedef enum {
- CAMEL_POP3_ENGINE_DISCONNECT = 0,
- CAMEL_POP3_ENGINE_AUTH,
- CAMEL_POP3_ENGINE_TRANSACTION,
- CAMEL_POP3_ENGINE_UPDATE,
-} camel_pop3_engine_t;
-
-/* state of a command */
-typedef enum {
- CAMEL_POP3_COMMAND_IDLE = 0, /* command created or queued, not yet sent (e.g. non pipelined server) */
- CAMEL_POP3_COMMAND_DISPATCHED, /* command sent to server */
-
- /* completion codes */
- CAMEL_POP3_COMMAND_OK, /* plain ok response */
- CAMEL_POP3_COMMAND_DATA, /* processing command response */
- CAMEL_POP3_COMMAND_ERR, /* error response */
-} camel_pop3_command_t;
-
-/* flags for command types */
-enum {
- CAMEL_POP3_COMMAND_SIMPLE = 0, /* dont expect multiline response */
- CAMEL_POP3_COMMAND_MULTI = 1, /* expect multiline response */
-};
-
-/* flags for server options */
-enum {
- CAMEL_POP3_CAP_APOP = 1<<0,
- CAMEL_POP3_CAP_UIDL = 1<<1,
- CAMEL_POP3_CAP_SASL = 1<<2,
- CAMEL_POP3_CAP_TOP = 1<<3,
- CAMEL_POP3_CAP_PIPE = 1<<4,
- CAMEL_POP3_CAP_STLS = 1<<5
-};
-
-/* enable/disable flags for the engine itself */
-enum {
- CAMEL_POP3_ENGINE_DISABLE_EXTENSIONS = 1<<0,
-};
-
-typedef void (*CamelPOP3CommandFunc)(CamelPOP3Engine *pe, CamelPOP3Stream *stream, void *data);
-
-struct _CamelPOP3Command {
- struct _CamelPOP3Command *next;
- struct _CamelPOP3Command *prev;
-
- guint32 flags;
- camel_pop3_command_t state;
-
- CamelPOP3CommandFunc func;
- void *func_data;
-
- int data_size;
- char *data;
-};
-
-struct _CamelPOP3Engine {
- CamelObject parent;
-
- guint32 flags;
-
- camel_pop3_engine_t state;
-
- GList *auth; /* authtypes supported */
-
- guint32 capa; /* capabilities */
- char *apop; /* apop time string */
-
- unsigned char *line; /* current line buffer */
- unsigned int linelen;
-
- struct _CamelPOP3Stream *stream;
-
- unsigned int sentlen; /* data sent (so we dont overflow network buffer) */
-
- EDList active; /* active commands */
- EDList queue; /* queue of waiting commands */
- EDList done; /* list of done commands, awaiting free */
-
- CamelPOP3Command *current; /* currently busy (downloading) response */
-};
-
-struct _CamelPOP3EngineClass {
- CamelObjectClass parent_class;
-};
-
-CamelType camel_pop3_engine_get_type (void);
-
-CamelPOP3Engine *camel_pop3_engine_new (CamelStream *source, guint32 flags);
-
-void camel_pop3_engine_reget_capabilities (CamelPOP3Engine *engine);
-
-void camel_pop3_engine_command_free(CamelPOP3Engine *pe, CamelPOP3Command *pc);
-
-int camel_pop3_engine_iterate (CamelPOP3Engine *pe, CamelPOP3Command *pc);
-
-CamelPOP3Command *camel_pop3_engine_command_new (CamelPOP3Engine *pe, guint32 flags, CamelPOP3CommandFunc func, void *data, const char *fmt, ...);
-
-#endif /* ! _CAMEL_POP3_ENGINE_H */
diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c
deleted file mode 100644
index db77ad8191..0000000000
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-pop3-folder.c : class for a pop3 folder */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-
-#include "camel-pop3-folder.h"
-#include "camel-pop3-store.h"
-#include "camel-exception.h"
-#include "camel-stream-mem.h"
-#include "camel-stream-filter.h"
-#include "camel-mime-message.h"
-#include "camel-operation.h"
-#include "camel-data-cache.h"
-
-#include <e-util/md5-utils.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#define d(x)
-
-#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(o)))
-static CamelFolderClass *parent_class;
-
-static void pop3_finalize (CamelObject *object);
-static void pop3_refresh_info (CamelFolder *folder, CamelException *ex);
-static void pop3_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
-static gint pop3_get_message_count (CamelFolder *folder);
-static GPtrArray *pop3_get_uids (CamelFolder *folder);
-static CamelMimeMessage *pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex);
-static void pop3_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
-
-static void
-camel_pop3_folder_class_init (CamelPOP3FolderClass *camel_pop3_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_pop3_folder_class);
-
- parent_class = CAMEL_FOLDER_CLASS(camel_folder_get_type());
-
- /* virtual method overload */
- camel_folder_class->refresh_info = pop3_refresh_info;
- camel_folder_class->sync = pop3_sync;
-
- camel_folder_class->get_message_count = pop3_get_message_count;
- camel_folder_class->get_uids = pop3_get_uids;
- camel_folder_class->free_uids = camel_folder_free_shallow;
-
- camel_folder_class->get_message = pop3_get_message;
- camel_folder_class->set_message_flags = pop3_set_message_flags;
-}
-
-CamelType
-camel_pop3_folder_get_type (void)
-{
- static CamelType camel_pop3_folder_type = CAMEL_INVALID_TYPE;
-
- if (!camel_pop3_folder_type) {
- camel_pop3_folder_type = camel_type_register (CAMEL_FOLDER_TYPE, "CamelPOP3Folder",
- sizeof (CamelPOP3Folder),
- sizeof (CamelPOP3FolderClass),
- (CamelObjectClassInitFunc) camel_pop3_folder_class_init,
- NULL,
- NULL,
- (CamelObjectFinalizeFunc) pop3_finalize);
- }
-
- return camel_pop3_folder_type;
-}
-
-static void
-pop3_finalize (CamelObject *object)
-{
- CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (object);
- CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata;
- CamelPOP3Store *pop3_store = (CamelPOP3Store *)((CamelFolder *)pop3_folder)->parent_store;
- int i;
-
- if (pop3_folder->uids) {
- for (i=0;i<pop3_folder->uids->len;i++,fi++) {
- if (fi[0]->cmd) {
- while (camel_pop3_engine_iterate(pop3_store->engine, fi[0]->cmd) > 0)
- ;
- camel_pop3_engine_command_free(pop3_store->engine, fi[0]->cmd);
- }
-
- g_free(fi[0]->uid);
- g_free(fi[0]);
- }
-
- g_ptr_array_free(pop3_folder->uids, TRUE);
- g_hash_table_destroy(pop3_folder->uids_uid);
- }
-}
-
-CamelFolder *
-camel_pop3_folder_new (CamelStore *parent, CamelException *ex)
-{
- CamelFolder *folder;
-
- d(printf("opening pop3 INBOX folder\n"));
-
- folder = CAMEL_FOLDER (camel_object_new (CAMEL_POP3_FOLDER_TYPE));
- camel_folder_construct (folder, parent, "inbox", "inbox");
-
- /* mt-ok, since we dont have the folder-lock for new() */
- camel_folder_refresh_info (folder, ex);/* mt-ok */
- if (camel_exception_is_set (ex)) {
- camel_object_unref (CAMEL_OBJECT (folder));
- folder = NULL;
- }
-
- return folder;
-}
-
-/* create a uid from md5 of 'top' output */
-static void
-cmd_builduid(CamelPOP3Engine *pe, CamelPOP3Stream *stream, void *data)
-{
- CamelPOP3FolderInfo *fi = data;
- MD5Context md5;
- unsigned char digest[16];
- struct _camel_header_raw *h;
- CamelMimeParser *mp;
-
- /* TODO; somehow work out the limit and use that for proper progress reporting
- We need a pointer to the folder perhaps? */
- camel_operation_progress_count(NULL, fi->id);
-
- md5_init(&md5);
- mp = camel_mime_parser_new();
- camel_mime_parser_init_with_stream(mp, (CamelStream *)stream);
- switch (camel_mime_parser_step(mp, NULL, NULL)) {
- case CAMEL_MIME_PARSER_STATE_HEADER:
- case CAMEL_MIME_PARSER_STATE_MESSAGE:
- case CAMEL_MIME_PARSER_STATE_MULTIPART:
- h = camel_mime_parser_headers_raw(mp);
- while (h) {
- if (strcasecmp(h->name, "status") != 0
- && strcasecmp(h->name, "x-status") != 0) {
- md5_update(&md5, h->name, strlen(h->name));
- md5_update(&md5, h->value, strlen(h->value));
- }
- h = h->next;
- }
- default:
- break;
- }
- camel_object_unref(mp);
- md5_final(&md5, digest);
- fi->uid = camel_base64_encode_simple(digest, 16);
-
- d(printf("building uid for id '%d' = '%s'\n", fi->id, fi->uid));
-}
-
-static void
-cmd_list(CamelPOP3Engine *pe, CamelPOP3Stream *stream, void *data)
-{
- int ret;
- unsigned int len, id, size;
- unsigned char *line;
- CamelFolder *folder = data;
- CamelPOP3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store);
- CamelPOP3FolderInfo *fi;
-
- do {
- ret = camel_pop3_stream_line(stream, &line, &len);
- if (ret>=0) {
- if (sscanf(line, "%u %u", &id, &size) == 2) {
- fi = g_malloc0(sizeof(*fi));
- fi->size = size;
- fi->id = id;
- fi->index = ((CamelPOP3Folder *)folder)->uids->len;
- if ((pop3_store->engine->capa & CAMEL_POP3_CAP_UIDL) == 0)
- fi->cmd = camel_pop3_engine_command_new(pe, CAMEL_POP3_COMMAND_MULTI, cmd_builduid, fi, "TOP %u 0\r\n", id);
- g_ptr_array_add(((CamelPOP3Folder *)folder)->uids, fi);
- g_hash_table_insert(((CamelPOP3Folder *)folder)->uids_id, GINT_TO_POINTER(id), fi);
- }
- }
- } while (ret>0);
-}
-
-static void
-cmd_uidl(CamelPOP3Engine *pe, CamelPOP3Stream *stream, void *data)
-{
- int ret;
- unsigned int len;
- unsigned char *line;
- char uid[1025];
- unsigned int id;
- CamelPOP3FolderInfo *fi;
- CamelPOP3Folder *folder = data;
-
- do {
- ret = camel_pop3_stream_line(stream, &line, &len);
- if (ret>=0) {
- if (strlen(line) > 1024)
- line[1024] = 0;
- if (sscanf(line, "%u %s", &id, uid) == 2) {
- fi = g_hash_table_lookup(folder->uids_id, GINT_TO_POINTER(id));
- if (fi) {
- camel_operation_progress(NULL, (fi->index+1) * 100 / folder->uids->len);
- fi->uid = g_strdup(uid);
- g_hash_table_insert(folder->uids_uid, fi->uid, fi);
- } else {
- g_warning("ID %u (uid: %s) not in previous LIST output", id, uid);
- }
- }
- }
- } while (ret>0);
-}
-
-static void
-pop3_refresh_info (CamelFolder *folder, CamelException *ex)
-{
- CamelPOP3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store);
- CamelPOP3Folder *pop3_folder = (CamelPOP3Folder *) folder;
- CamelPOP3Command *pcl, *pcu = NULL;
- int i;
-
- camel_operation_start (NULL, _("Retrieving POP summary"));
-
- pop3_folder->uids = g_ptr_array_new ();
- pop3_folder->uids_uid = g_hash_table_new(g_str_hash, g_str_equal);
- /* only used during setup */
- pop3_folder->uids_id = g_hash_table_new(NULL, NULL);
-
- pcl = camel_pop3_engine_command_new(pop3_store->engine, CAMEL_POP3_COMMAND_MULTI, cmd_list, folder, "LIST\r\n");
- if (pop3_store->engine->capa & CAMEL_POP3_CAP_UIDL) {
- pcu = camel_pop3_engine_command_new(pop3_store->engine, CAMEL_POP3_COMMAND_MULTI, cmd_uidl, folder, "UIDL\r\n");
- }
- while ((i = camel_pop3_engine_iterate(pop3_store->engine, NULL)) > 0)
- ;
-
- if (i == -1) {
- if (errno == EINTR)
- camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("User cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get POP summary: %s"),
- g_strerror (errno));
- }
-
- /* TODO: check every id has a uid & commands returned OK too? */
-
- camel_pop3_engine_command_free(pop3_store->engine, pcl);
-
- if (pop3_store->engine->capa & CAMEL_POP3_CAP_UIDL) {
- camel_pop3_engine_command_free(pop3_store->engine, pcu);
- } else {
- for (i=0;i<pop3_folder->uids->len;i++) {
- CamelPOP3FolderInfo *fi = pop3_folder->uids->pdata[i];
- if (fi->cmd) {
- camel_pop3_engine_command_free(pop3_store->engine, fi->cmd);
- fi->cmd = NULL;
- }
- if (fi->uid)
- g_hash_table_insert(pop3_folder->uids_uid, fi->uid, fi);
- }
- }
-
- /* dont need this anymore */
- g_hash_table_destroy(pop3_folder->uids_id);
-
- camel_operation_end (NULL);
- return;
-}
-
-static void
-pop3_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
- CamelPOP3Folder *pop3_folder;
- CamelPOP3Store *pop3_store;
- int i;
- CamelPOP3FolderInfo *fi;
-
- if (!expunge)
- return;
-
- pop3_folder = CAMEL_POP3_FOLDER (folder);
- pop3_store = CAMEL_POP3_STORE (folder->parent_store);
-
- camel_operation_start(NULL, _("Expunging deleted messages"));
-
- for (i = 0; i < pop3_folder->uids->len; i++) {
- fi = pop3_folder->uids->pdata[i];
- /* busy already? wait for that to finish first */
- if (fi->cmd) {
- while (camel_pop3_engine_iterate(pop3_store->engine, fi->cmd) > 0)
- ;
- camel_pop3_engine_command_free(pop3_store->engine, fi->cmd);
- fi->cmd = NULL;
- }
-
- if (fi->flags & CAMEL_MESSAGE_DELETED) {
- fi->cmd = camel_pop3_engine_command_new(pop3_store->engine, 0, NULL, NULL, "DELE %u\r\n", fi->id);
-
- /* also remove from cache */
- if (pop3_store->cache && fi->uid)
- camel_data_cache_remove(pop3_store->cache, "cache", fi->uid, NULL);
- }
- }
-
- for (i = 0; i < pop3_folder->uids->len; i++) {
- fi = pop3_folder->uids->pdata[i];
- /* wait for delete commands to finish */
- if (fi->cmd) {
- while (camel_pop3_engine_iterate(pop3_store->engine, fi->cmd) > 0)
- ;
- camel_pop3_engine_command_free(pop3_store->engine, fi->cmd);
- fi->cmd = NULL;
- }
- camel_operation_progress(NULL, (i+1) * 100 / pop3_folder->uids->len);
- }
-
- camel_operation_end(NULL);
-
- camel_pop3_store_expunge (pop3_store, ex);
-}
-
-static void
-cmd_tocache(CamelPOP3Engine *pe, CamelPOP3Stream *stream, void *data)
-{
- CamelPOP3FolderInfo *fi = data;
- char buffer[2048];
- int w = 0, n;
-
- /* What if it fails? */
-
- /* We write an '*' to the start of the stream to say its not complete yet */
- /* This should probably be part of the cache code */
- if ((n = camel_stream_write(fi->stream, "*", 1)) == -1)
- goto done;
-
- while ((n = camel_stream_read((CamelStream *)stream, buffer, sizeof(buffer))) > 0) {
- n = camel_stream_write(fi->stream, buffer, n);
- if (n == -1)
- break;
-
- w += n;
- if (w > fi->size)
- w = fi->size;
- if (fi->size != 0)
- camel_operation_progress(NULL, (w * 100) / fi->size);
- }
-
- /* it all worked, output a '#' to say we're a-ok */
- if (n != -1) {
- camel_stream_reset(fi->stream);
- n = camel_stream_write(fi->stream, "#", 1);
- }
-done:
- if (n == -1) {
- fi->err = errno;
- g_warning("POP3 retrieval failed: %s", strerror(errno));
- } else {
- fi->err = 0;
- }
-
- camel_object_unref((CamelObject *)fi->stream);
- fi->stream = NULL;
-}
-
-static CamelMimeMessage *
-pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
-{
- CamelMimeMessage *message = NULL;
- CamelPOP3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store);
- CamelPOP3Folder *pop3_folder = (CamelPOP3Folder *)folder;
- CamelPOP3Command *pcr;
- CamelPOP3FolderInfo *fi;
- char buffer[1];
- int ok, i, last;
- CamelStream *stream = NULL;
-
- fi = g_hash_table_lookup(pop3_folder->uids_uid, uid);
- if (fi == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("No message with uid %s"), uid);
- return NULL;
- }
-
- /* Sigh, most of the crap in this function is so that the cancel button
- returns the proper exception code. Sigh. */
-
- camel_operation_start_transient(NULL, _("Retrieving POP message %d"), fi->id);
-
- /* If we have an oustanding retrieve message running, wait for that to complete
- & then retrieve from cache, otherwise, start a new one, and similar */
-
- if (fi->cmd != NULL) {
- while ((i = camel_pop3_engine_iterate(pop3_store->engine, fi->cmd)) > 0)
- ;
-
- if (i == -1)
- fi->err = errno;
-
- /* getting error code? */
- ok = fi->cmd->state == CAMEL_POP3_COMMAND_DATA;
- camel_pop3_engine_command_free(pop3_store->engine, fi->cmd);
- fi->cmd = NULL;
-
- if (fi->err != 0) {
- if (fi->err == EINTR)
- camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("User cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get message %s: %s"),
- uid, g_strerror (fi->err));
- goto fail;
- }
- }
-
- /* check to see if we have safely written flag set */
- if (pop3_store->cache == NULL
- || (stream = camel_data_cache_get(pop3_store->cache, "cache", fi->uid, NULL)) == NULL
- || camel_stream_read(stream, buffer, 1) != 1
- || buffer[0] != '#') {
-
- /* Initiate retrieval, if disk backing fails, use a memory backing */
- if (pop3_store->cache == NULL
- || (stream = camel_data_cache_add(pop3_store->cache, "cache", fi->uid, NULL)) == NULL)
- stream = camel_stream_mem_new();
-
- /* ref it, the cache storage routine unref's when done */
- camel_object_ref((CamelObject *)stream);
- fi->stream = stream;
- fi->err = EIO;
- pcr = camel_pop3_engine_command_new(pop3_store->engine, CAMEL_POP3_COMMAND_MULTI, cmd_tocache, fi, "RETR %u\r\n", fi->id);
-
- /* Also initiate retrieval of some of the following messages, assume we'll be receiving them */
- if (pop3_store->cache != NULL) {
- /* This should keep track of the last one retrieved, also how many are still
- oustanding incase of random access on large folders */
- i = fi->index+1;
- last = MIN(i+10, pop3_folder->uids->len);
- for (;i<last;i++) {
- CamelPOP3FolderInfo *pfi = pop3_folder->uids->pdata[i];
-
- if (pfi->uid && pfi->cmd == NULL) {
- pfi->stream = camel_data_cache_add(pop3_store->cache, "cache", pfi->uid, NULL);
- if (pfi->stream) {
- pfi->err = EIO;
- pfi->cmd = camel_pop3_engine_command_new(pop3_store->engine, CAMEL_POP3_COMMAND_MULTI,
- cmd_tocache, pfi, "RETR %u\r\n", pfi->id);
- }
- }
- }
- }
-
- /* now wait for the first one to finish */
- while ((i = camel_pop3_engine_iterate(pop3_store->engine, pcr)) > 0)
- ;
-
- if (i == -1)
- fi->err = errno;
-
- /* getting error code? */
- ok = pcr->state == CAMEL_POP3_COMMAND_DATA;
- camel_pop3_engine_command_free(pop3_store->engine, pcr);
- camel_stream_reset(stream);
-
- /* Check to see we have safely written flag set */
- if (fi->err != 0) {
- if (fi->err == EINTR)
- camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("User cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get message %s: %s"),
- uid, g_strerror (fi->err));
- goto done;
- }
-
- if (camel_stream_read(stream, buffer, 1) != 1 || buffer[0] != '#') {
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("Cannot get message %s: %s"), uid, _("Unknown reason"));
- goto done;
- }
- }
-
- message = camel_mime_message_new ();
- if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, stream) == -1) {
- if (errno == EINTR)
- camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("User cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get message %s: %s"),
- uid, g_strerror (errno));
- camel_object_unref((CamelObject *)message);
- message = NULL;
- }
-done:
- camel_object_unref((CamelObject *)stream);
-fail:
- camel_operation_end(NULL);
-
- return message;
-}
-
-static void
-pop3_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
-{
- CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
- CamelPOP3FolderInfo *fi;
-
- fi = g_hash_table_lookup(pop3_folder->uids_uid, uid);
- if (fi)
- fi->flags = (fi->flags & ~flags) | (set & flags);
-}
-
-static gint
-pop3_get_message_count (CamelFolder *folder)
-{
- CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
-
- return pop3_folder->uids->len;
-}
-
-static GPtrArray *
-pop3_get_uids (CamelFolder *folder)
-{
- CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
- GPtrArray *uids = g_ptr_array_new();
- CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata;
- int i;
-
- for (i=0;i<pop3_folder->uids->len;i++,fi++) {
- if (fi[0]->uid)
- g_ptr_array_add(uids, fi[0]->uid);
- }
-
- return uids;
-}
diff --git a/camel/providers/pop3/camel-pop3-folder.h b/camel/providers/pop3/camel-pop3-folder.h
deleted file mode 100644
index 7dab07124c..0000000000
--- a/camel/providers/pop3/camel-pop3-folder.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-pop3-folder.h : Class for a POP3 folder */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_POP3_FOLDER_H
-#define CAMEL_POP3_FOLDER_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-folder.h"
-
-#define CAMEL_POP3_FOLDER_TYPE (camel_pop3_folder_get_type ())
-#define CAMEL_POP3_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_POP3_FOLDER_TYPE, CamelPOP3Folder))
-#define CAMEL_POP3_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_POP3_FOLDER_TYPE, CamelPOP3FolderClass))
-#define CAMEL_IS_POP3_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_POP3_FOLDER_TYPE))
-
-typedef struct {
- guint32 id;
- guint32 size;
- guint32 flags;
- guint32 index; /* index of request */
- char *uid;
- int err;
- struct _CamelPOP3Command *cmd;
- struct _CamelStream *stream;
-} CamelPOP3FolderInfo;
-
-typedef struct {
- CamelFolder parent_object;
-
- GPtrArray *uids;
- GHashTable *uids_uid; /* messageinfo by uid */
- GHashTable *uids_id; /* messageinfo by id */
-} CamelPOP3Folder;
-
-typedef struct {
- CamelFolderClass parent_class;
-
- /* Virtual methods */
-
-} CamelPOP3FolderClass;
-
-/* public methods */
-CamelFolder *camel_pop3_folder_new (CamelStore *parent, CamelException *ex);
-
-/* Standard Camel function */
-CamelType camel_pop3_folder_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_POP3_FOLDER_H */
diff --git a/camel/providers/pop3/camel-pop3-provider.c b/camel/providers/pop3/camel-pop3-provider.c
deleted file mode 100644
index 1354470e69..0000000000
--- a/camel/providers/pop3/camel-pop3-provider.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-pop3-provider.c: pop3 provider registration code */
-
-/*
- * Authors :
- * Dan Winship <danw@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "camel-pop3-store.h"
-#include "camel-provider.h"
-#include "camel-session.h"
-#include "camel-url.h"
-#include "camel-sasl.h"
-
-CamelProviderConfEntry pop3_conf_entries[] = {
- { CAMEL_PROVIDER_CONF_SECTION_START, NULL, NULL,
- N_("Message storage") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "keep_on_server", NULL,
- N_("Leave messages on server"), "0" },
-#ifdef NOT_FOR_1_0
- { CAMEL_PROVIDER_CONF_CHECKSPIN, "delete_after", "UNIMPLEMENTED",
- N_("Delete after %s day(s)"), "0:1:7:365" },
-#endif
- { CAMEL_PROVIDER_CONF_CHECKBOX, "disable_extensions", NULL,
- N_("Disable support for all POP3 extensions"), "0" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider pop3_provider = {
- "pop",
-
- N_("POP"),
-
- N_("For connecting to and downloading mail from POP servers."),
-
- "mail",
-
- CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
- CAMEL_PROVIDER_SUPPORTS_SSL,
-
- CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH,
-
- pop3_conf_entries,
-
- /* ... */
-};
-
-CamelServiceAuthType camel_pop3_password_authtype = {
- N_("Password"),
-
- N_("This option will connect to the POP server using a plaintext "
- "password. This is the only option supported by many POP servers."),
-
- "",
- TRUE
-};
-
-CamelServiceAuthType camel_pop3_apop_authtype = {
- "APOP",
-
- N_("This option will connect to the POP server using an encrypted "
- "password via the APOP protocol. This may not work for all users "
- "even on servers that claim to support it."),
-
- "+APOP",
- TRUE
-};
-
-void
-camel_provider_module_init (CamelSession *session)
-{
- CamelServiceAuthType *auth;
-
- pop3_provider.object_types[CAMEL_PROVIDER_STORE] = camel_pop3_store_get_type();
- pop3_provider.url_hash = camel_url_hash;
- pop3_provider.url_equal = camel_url_equal;
-
- pop3_provider.authtypes = camel_sasl_authtype_list (FALSE);
- auth = camel_sasl_authtype("LOGIN");
- if (auth)
- pop3_provider.authtypes = g_list_prepend(pop3_provider.authtypes, auth);
- pop3_provider.authtypes = g_list_prepend(pop3_provider.authtypes, &camel_pop3_apop_authtype);
- pop3_provider.authtypes = g_list_prepend(pop3_provider.authtypes, &camel_pop3_password_authtype);
-
- camel_session_register_provider(session, &pop3_provider);
-}
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
deleted file mode 100644
index fbdae86833..0000000000
--- a/camel/providers/pop3/camel-pop3-store.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-pop3-store.c : class for a pop3 store */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2000-2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "camel-operation.h"
-
-#include "camel-pop3-store.h"
-#include "camel-pop3-folder.h"
-#include "camel-stream-buffer.h"
-#include "camel-session.h"
-#include "camel-exception.h"
-#include "camel-url.h"
-#include "e-util/md5-utils.h"
-#include "camel-pop3-engine.h"
-#include "camel-sasl.h"
-#include "camel-data-cache.h"
-#include "camel-tcp-stream.h"
-#include "camel-tcp-stream-raw.h"
-#ifdef HAVE_SSL
-#include "camel-tcp-stream-ssl.h"
-#endif
-
-/* Specified in RFC 1939 */
-#define POP3_PORT 110
-
-static CamelStoreClass *parent_class = NULL;
-
-static void finalize (CamelObject *object);
-
-static gboolean pop3_connect (CamelService *service, CamelException *ex);
-static gboolean pop3_disconnect (CamelService *service, gboolean clean, CamelException *ex);
-static GList *query_auth_types (CamelService *service, CamelException *ex);
-
-static CamelFolder *get_folder (CamelStore *store, const char *folder_name,
- guint32 flags, CamelException *ex);
-
-static void init_trash (CamelStore *store);
-static CamelFolder *get_trash (CamelStore *store, CamelException *ex);
-
-static void
-camel_pop3_store_class_init (CamelPOP3StoreClass *camel_pop3_store_class)
-{
- CamelServiceClass *camel_service_class =
- CAMEL_SERVICE_CLASS (camel_pop3_store_class);
- CamelStoreClass *camel_store_class =
- CAMEL_STORE_CLASS (camel_pop3_store_class);
-
- parent_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ()));
-
- /* virtual method overload */
- camel_service_class->query_auth_types = query_auth_types;
- camel_service_class->connect = pop3_connect;
- camel_service_class->disconnect = pop3_disconnect;
-
- camel_store_class->get_folder = get_folder;
- camel_store_class->init_trash = init_trash;
- camel_store_class->get_trash = get_trash;
-}
-
-
-
-static void
-camel_pop3_store_init (gpointer object, gpointer klass)
-{
- ;
-}
-
-CamelType
-camel_pop3_store_get_type (void)
-{
- static CamelType camel_pop3_store_type = CAMEL_INVALID_TYPE;
-
- if (!camel_pop3_store_type) {
- camel_pop3_store_type = camel_type_register (CAMEL_STORE_TYPE,
- "CamelPOP3Store",
- sizeof (CamelPOP3Store),
- sizeof (CamelPOP3StoreClass),
- (CamelObjectClassInitFunc) camel_pop3_store_class_init,
- NULL,
- (CamelObjectInitFunc) camel_pop3_store_init,
- finalize);
- }
-
- return camel_pop3_store_type;
-}
-
-static void
-finalize (CamelObject *object)
-{
- CamelPOP3Store *pop3_store = CAMEL_POP3_STORE (object);
-
- /* force disconnect so we dont have it run later, after we've cleaned up some stuff */
- /* SIGH */
-
- camel_service_disconnect((CamelService *)pop3_store, TRUE, NULL);
-
- if (pop3_store->engine)
- camel_object_unref((CamelObject *)pop3_store->engine);
- if (pop3_store->cache)
- camel_object_unref((CamelObject *)pop3_store->cache);
-}
-
-enum {
- USE_SSL_NEVER,
- USE_SSL_ALWAYS,
- USE_SSL_WHEN_POSSIBLE
-};
-
-#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
-
-static gboolean
-connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelException *ex)
-{
- CamelPOP3Store *store = CAMEL_POP3_STORE (service);
- CamelStream *tcp_stream;
- CamelPOP3Command *pc;
- struct hostent *h;
- guint32 flags = 0;
- int clean_quit;
- int ret, port;
-
- h = camel_service_gethost (service, ex);
- if (!h)
- return FALSE;
-
- port = service->url->port ? service->url->port : 110;
-
- if (ssl_mode != USE_SSL_NEVER) {
-#ifdef HAVE_SSL
- if (try_starttls) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- port = service->url->port ? service->url->port : 995;
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- if (!try_starttls)
- port = service->url->port ? service->url->port : 995;
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port,
- _("SSL unavailable"));
-
- camel_free_host (h);
-
- return FALSE;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- ret = camel_tcp_stream_connect (CAMEL_TCP_STREAM (tcp_stream), h, port);
- camel_free_host (h);
- if (ret == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Connection cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to POP server %s (port %d): %s"),
- service->url->host, port, g_strerror (errno));
-
- camel_object_unref (CAMEL_OBJECT (tcp_stream));
-
- return FALSE;
- }
-
- /* parent class connect initialization */
- if (CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex) == FALSE) {
- camel_object_unref (CAMEL_OBJECT (tcp_stream));
- return FALSE;
- }
-
- if (camel_url_get_param (service->url, "disable_extensions"))
- flags |= CAMEL_POP3_ENGINE_DISABLE_EXTENSIONS;
-
- store->engine = camel_pop3_engine_new (tcp_stream, flags);
-
-#ifdef HAVE_SSL
- if (store->engine) {
- if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
- if (store->engine->capa & CAMEL_POP3_CAP_STLS)
- goto starttls;
- } else if (ssl_mode == USE_SSL_ALWAYS) {
- if (try_starttls) {
- if (store->engine->capa & CAMEL_POP3_CAP_STLS) {
- /* attempt to toggle STARTTLS mode */
- goto starttls;
- } else {
- /* server doesn't support STARTTLS, abort */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to POP server %s in secure mode: %s"),
- service->url->host, _("SSL/TLS extension not supported."));
- /* we have the possibility of quitting cleanly here */
- clean_quit = TRUE;
- goto stls_exception;
- }
- }
- }
- }
-#endif /* HAVE_SSL */
-
- camel_object_unref (CAMEL_OBJECT (tcp_stream));
-
- return store->engine != NULL;
-
-#ifdef HAVE_SSL
- starttls:
- /* as soon as we send a STLS command, all hope is lost of a clean QUIT if problems arise */
- clean_quit = FALSE;
-
- pc = camel_pop3_engine_command_new (store->engine, 0, NULL, NULL, "STLS\r\n");
- while (camel_pop3_engine_iterate (store->engine, NULL) > 0)
- ;
-
- ret = pc->state == CAMEL_POP3_COMMAND_OK;
- camel_pop3_engine_command_free (store->engine, pc);
-
- if (ret == FALSE) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to POP server %s in secure mode: %s"),
- service->url->host, store->engine->line);
- goto stls_exception;
- }
-
- /* Okay, now toggle SSL/TLS mode */
- ret = camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream));
-
- camel_object_unref (CAMEL_OBJECT (tcp_stream));
-
- if (ret == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to POP server %s in secure mode: %s"),
- service->url->host, _("SSL negotiations failed"));
- goto stls_exception;
- }
-
- /* rfc2595, section 4 states that after a successful STLS
- command, the client MUST discard prior CAPA responses */
- camel_pop3_engine_reget_capabilities (store->engine);
-
- return TRUE;
-
- stls_exception:
- if (clean_quit) {
- /* try to disconnect cleanly */
- pc = camel_pop3_engine_command_new (store->engine, 0, NULL, NULL, "QUIT\r\n");
- while (camel_pop3_engine_iterate (store->engine, NULL) > 0)
- ;
- camel_pop3_engine_command_free (store->engine, pc);
- }
-
- camel_object_unref (CAMEL_OBJECT (store->engine));
- camel_object_unref (CAMEL_OBJECT (tcp_stream));
- store->engine = NULL;
-
- return FALSE;
-#endif /* HAVE_SSL */
-}
-
-static struct {
- char *value;
- int mode;
-} ssl_options[] = {
- { "", USE_SSL_ALWAYS },
- { "always", USE_SSL_ALWAYS },
- { "when-possible", USE_SSL_WHEN_POSSIBLE },
- { "never", USE_SSL_NEVER },
- { NULL, USE_SSL_NEVER },
-};
-
-static gboolean
-connect_to_server_wrapper (CamelService *service, CamelException *ex)
-{
-#ifdef HAVE_SSL
- const char *use_ssl;
- int i, ssl_mode;
-
- use_ssl = camel_url_get_param (service->url, "use_ssl");
- if (use_ssl) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, use_ssl))
- break;
- ssl_mode = ssl_options[i].mode;
- } else
- ssl_mode = USE_SSL_NEVER;
-
- if (ssl_mode == USE_SSL_ALWAYS) {
- /* First try the ssl port */
- if (!connect_to_server (service, ssl_mode, FALSE, ex)) {
- if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
- /* The ssl port seems to be unavailable, lets try STARTTLS */
- camel_exception_clear (ex);
- return connect_to_server (service, ssl_mode, TRUE, ex);
- } else {
- return FALSE;
- }
- }
-
- return TRUE;
- } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
- /* If the server supports STARTTLS, use it */
- return connect_to_server (service, ssl_mode, TRUE, ex);
- } else {
- /* User doesn't care about SSL */
- return connect_to_server (service, ssl_mode, FALSE, ex);
- }
-#else
- return connect_to_server (service, USE_SSL_NEVER, FALSE, ex);
-#endif
-}
-
-extern CamelServiceAuthType camel_pop3_password_authtype;
-extern CamelServiceAuthType camel_pop3_apop_authtype;
-
-static GList *
-query_auth_types (CamelService *service, CamelException *ex)
-{
- CamelPOP3Store *store = CAMEL_POP3_STORE (service);
- GList *types = NULL;
-
- types = CAMEL_SERVICE_CLASS (parent_class)->query_auth_types (service, ex);
- if (camel_exception_is_set (ex))
- return NULL;
-
- if (connect_to_server_wrapper (service, NULL)) {
- types = g_list_concat(types, g_list_copy(store->engine->auth));
- pop3_disconnect (service, TRUE, NULL);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to POP server %s"),
- service->url->host);
- }
-
- return types;
-}
-
-/**
- * camel_pop3_store_expunge:
- * @store: the store
- * @ex: a CamelException
- *
- * Expunge messages from the store. This will result in the connection
- * being closed, which may cause later commands to fail if they can't
- * reconnect.
- **/
-void
-camel_pop3_store_expunge (CamelPOP3Store *store, CamelException *ex)
-{
- CamelPOP3Command *pc;
-
- pc = camel_pop3_engine_command_new(store->engine, 0, NULL, NULL, "QUIT\r\n");
- while (camel_pop3_engine_iterate(store->engine, NULL) > 0)
- ;
- camel_pop3_engine_command_free(store->engine, pc);
-
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, ex);
-}
-
-static int
-try_sasl(CamelPOP3Store *store, const char *mech, CamelException *ex)
-{
- CamelPOP3Stream *stream = store->engine->stream;
- unsigned char *line, *resp;
- CamelSasl *sasl;
- unsigned int len;
- int ret;
-
- sasl = camel_sasl_new("pop3", mech, (CamelService *)store);
- if (sasl == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
- _("Unable to connect to POP server %s: "
- "No support for requested authentication mechanism."),
- CAMEL_SERVICE (store)->url->host);
- return -1;
- }
-
- if (camel_stream_printf((CamelStream *)stream, "AUTH %s\r\n", mech) == -1)
- goto ioerror;
-
- while (1) {
- if (camel_pop3_stream_line(stream, &line, &len) == -1)
- goto ioerror;
- if (strncmp(line, "+OK", 3) == 0)
- break;
- if (strncmp(line, "-ERR", 4) == 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("SASL `%s' Login failed for POP server %s: %s"),
- mech, CAMEL_SERVICE (store)->url->host, line);
- goto done;
- }
- /* If we dont get continuation, or the sasl object's run out of work, or we dont get a challenge,
- its a protocol error, so fail, and try reset the server */
- if (strncmp(line, "+ ", 2) != 0
- || camel_sasl_authenticated(sasl)
- || (resp = camel_sasl_challenge_base64(sasl, line+2, ex)) == NULL) {
- camel_stream_printf((CamelStream *)stream, "*\r\n");
- camel_pop3_stream_line(stream, &line, &len);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Cannot login to POP server %s: SASL Protocol error"),
- CAMEL_SERVICE (store)->url->host);
- goto done;
- }
-
- ret = camel_stream_printf((CamelStream *)stream, "%s\r\n", resp);
- g_free(resp);
- if (ret == -1)
- goto ioerror;
-
- }
- camel_object_unref((CamelObject *)sasl);
- return 0;
-
- ioerror:
- if (errno == EINTR) {
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled"));
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to authenticate on POP server %s: %s"),
- CAMEL_SERVICE (store)->url->host, g_strerror (errno));
- }
- done:
- camel_object_unref((CamelObject *)sasl);
- return -1;
-}
-
-static int
-pop3_try_authenticate (CamelService *service, gboolean reprompt, const char *errmsg, CamelException *ex)
-{
- CamelPOP3Store *store = (CamelPOP3Store *)service;
- CamelPOP3Command *pcu = NULL, *pcp = NULL;
- int status;
-
- /* override, testing only */
- /*printf("Forcing authmech to 'login'\n");
- service->url->authmech = g_strdup("LOGIN");*/
-
- if (!service->url->passwd) {
- char *prompt;
-
- prompt = g_strdup_printf (_("%sPlease enter the POP password for %s@%s"),
- errmsg ? errmsg : "",
- service->url->user,
- service->url->host);
- service->url->passwd = camel_session_get_password (camel_service_get_session (service),
- prompt, reprompt, TRUE, service, "password", ex);
- g_free (prompt);
- if (!service->url->passwd)
- return FALSE;
- }
-
- if (!service->url->authmech) {
- /* pop engine will take care of pipelining ability */
- pcu = camel_pop3_engine_command_new(store->engine, 0, NULL, NULL, "USER %s\r\n", service->url->user);
- pcp = camel_pop3_engine_command_new(store->engine, 0, NULL, NULL, "PASS %s\r\n", service->url->passwd);
- } else if (strcmp(service->url->authmech, "+APOP") == 0 && store->engine->apop) {
- char *secret, md5asc[33], *d;
- unsigned char md5sum[16], *s;
-
- secret = g_alloca(strlen(store->engine->apop)+strlen(service->url->passwd)+1);
- sprintf(secret, "%s%s", store->engine->apop, service->url->passwd);
- md5_get_digest(secret, strlen (secret), md5sum);
-
- for (s = md5sum, d = md5asc; d < md5asc + 32; s++, d += 2)
- sprintf (d, "%.2x", *s);
-
- pcp = camel_pop3_engine_command_new(store->engine, 0, NULL, NULL, "APOP %s %s\r\n",
- service->url->user, md5asc);
- } else {
- CamelServiceAuthType *auth;
- GList *l;
-
- l = store->engine->auth;
- while (l) {
- auth = l->data;
- if (strcmp(auth->authproto, service->url->authmech) == 0)
- return try_sasl(store, service->url->authmech, ex) == -1;
- l = l->next;
- }
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
- _("Unable to connect to POP server %s: "
- "No support for requested authentication mechanism."),
- CAMEL_SERVICE (store)->url->host);
- return FALSE;
- }
-
- while ((status = camel_pop3_engine_iterate(store->engine, pcp)) > 0)
- ;
-
- if (status == -1) {
- if (errno == EINTR) {
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled"));
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to connect to POP server %s.\n"
- "Error sending password: %s"),
- CAMEL_SERVICE (store)->url->host,
- errno ? g_strerror (errno) : _("Unknown error"));
- }
- } else if (pcp->state != CAMEL_POP3_COMMAND_OK)
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Unable to connect to POP server %s.\n"
- "Error sending password: %s"),
- CAMEL_SERVICE (store)->url->host,
- store->engine->line ? (char *)store->engine->line : _("Unknown error"));
-
- camel_pop3_engine_command_free(store->engine, pcp);
-
- if (pcu)
- camel_pop3_engine_command_free(store->engine, pcu);
-
- return status;
-}
-
-static gboolean
-pop3_connect (CamelService *service, CamelException *ex)
-{
- CamelPOP3Store *store = (CamelPOP3Store *)service;
- gboolean reprompt = FALSE;
- CamelSession *session;
- char *errbuf = NULL;
- int status;
-
- session = camel_service_get_session (service);
-
- if (store->cache == NULL) {
- char *root;
-
- root = camel_session_get_storage_path (session, service, ex);
- if (root) {
- store->cache = camel_data_cache_new(root, 0, ex);
- g_free(root);
- if (store->cache) {
- /* Default cache expiry - 1 week or not visited in a day */
- camel_data_cache_set_expire_age(store->cache, 60*60*24*7);
- camel_data_cache_set_expire_access(store->cache, 60*60*24);
- }
- }
- }
-
- if (!connect_to_server_wrapper (service, ex))
- return FALSE;
-
- do {
- camel_exception_clear (ex);
- status = pop3_try_authenticate (service, reprompt, errbuf, ex);
- g_free (errbuf);
- errbuf = NULL;
-
- /* we only re-prompt if we failed to authenticate, any other error and we just abort */
- if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE) {
- errbuf = g_strdup_printf ("%s\n\n", camel_exception_get_description (ex));
- g_free (service->url->passwd);
- service->url->passwd = NULL;
- reprompt = TRUE;
- }
- } while (status != -1 && ex->id == CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE);
-
- g_free (errbuf);
-
- if (status == -1 || camel_exception_is_set(ex)) {
- camel_service_disconnect(service, TRUE, ex);
- return FALSE;
- }
-
- /* Now that we are in the TRANSACTION state, try regetting the capabilities */
- store->engine->state = CAMEL_POP3_ENGINE_TRANSACTION;
- camel_pop3_engine_reget_capabilities (store->engine);
-
- return TRUE;
-}
-
-static gboolean
-pop3_disconnect (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelPOP3Store *store = CAMEL_POP3_STORE (service);
-
- if (clean) {
- CamelPOP3Command *pc;
-
- pc = camel_pop3_engine_command_new(store->engine, 0, NULL, NULL, "QUIT\r\n");
- while (camel_pop3_engine_iterate(store->engine, NULL) > 0)
- ;
- camel_pop3_engine_command_free(store->engine, pc);
- }
-
- if (!CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, clean, ex))
- return FALSE;
-
- camel_object_unref((CamelObject *)store->engine);
- store->engine = NULL;
-
- return TRUE;
-}
-
-static CamelFolder *
-get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
-{
- if (strcasecmp (folder_name, "inbox") != 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
- _("No such folder `%s'."), folder_name);
- return NULL;
- }
- return camel_pop3_folder_new (store, ex);
-}
-
-static void
-init_trash (CamelStore *store)
-{
- /* no-op */
- ;
-}
-
-static CamelFolder *
-get_trash (CamelStore *store, CamelException *ex)
-{
- /* no-op */
- return NULL;
-}
diff --git a/camel/providers/pop3/camel-pop3-store.h b/camel/providers/pop3/camel-pop3-store.h
deleted file mode 100644
index 3b9b1f7ae1..0000000000
--- a/camel/providers/pop3/camel-pop3-store.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-pop3-store.h : class for an pop3 store */
-
-/*
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 2000-2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_POP3_STORE_H
-#define CAMEL_POP3_STORE_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <camel/camel-types.h>
-#include <camel/camel-store.h>
-#include "camel-pop3-engine.h"
-
-#define CAMEL_POP3_STORE_TYPE (camel_pop3_store_get_type ())
-#define CAMEL_POP3_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_POP3_STORE_TYPE, CamelPOP3Store))
-#define CAMEL_POP3_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_POP3_STORE_TYPE, CamelPOP3StoreClass))
-#define CAMEL_IS_POP3_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_POP3_STORE_TYPE))
-
-
-typedef struct {
- CamelStore parent_object;
-
- CamelPOP3Engine *engine; /* pop processing engine */
-
- struct _CamelDataCache *cache;
-} CamelPOP3Store;
-
-
-
-typedef struct {
- CamelStoreClass parent_class;
-
-} CamelPOP3StoreClass;
-
-
-/* public methods */
-void camel_pop3_store_expunge (CamelPOP3Store *store, CamelException *ex);
-
-/* support functions */
-enum { CAMEL_POP3_OK, CAMEL_POP3_ERR, CAMEL_POP3_FAIL };
-int camel_pop3_command (CamelPOP3Store *store, char **ret, CamelException *ex, char *fmt, ...);
-char *camel_pop3_command_get_additional_data (CamelPOP3Store *store, int total, CamelException *ex);
-
-/* Standard Camel function */
-CamelType camel_pop3_store_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_POP3_STORE_H */
-
-
diff --git a/camel/providers/pop3/camel-pop3-stream.c b/camel/providers/pop3/camel-pop3-stream.c
deleted file mode 100644
index cb27bece26..0000000000
--- a/camel/providers/pop3/camel-pop3-stream.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
- *
- * Author:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-/* This is *identical* to the camel-nntp-stream, so should probably
- work out a way to merge them */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-
-#include <string.h>
-#include <stdio.h>
-
-#include <glib.h>
-
-#include "camel-pop3-stream.h"
-
-extern int camel_verbose_debug;
-#define dd(x) (camel_verbose_debug?(x):0)
-
-static CamelObjectClass *parent_class = NULL;
-
-/* Returns the class for a CamelStream */
-#define CS_CLASS(so) CAMEL_POP3_STREAM_CLASS(CAMEL_OBJECT_GET_CLASS(so))
-
-#define CAMEL_POP3_STREAM_SIZE (4096)
-#define CAMEL_POP3_STREAM_LINE (1024) /* maximum line size */
-
-static int
-stream_fill(CamelPOP3Stream *is)
-{
- int left = 0;
-
- if (is->source) {
- left = is->end - is->ptr;
- memcpy(is->buf, is->ptr, left);
- is->end = is->buf + left;
- is->ptr = is->buf;
- left = camel_stream_read(is->source, is->end, CAMEL_POP3_STREAM_SIZE - (is->end - is->buf));
- if (left > 0) {
- is->end += left;
- is->end[0] = '\n';
- return is->end - is->ptr;
- } else {
- dd(printf("POP3_STREAM_FILL(ERROR): '%s'\n", strerror (errno)));
- return -1;
- }
- }
-
- return 0;
-}
-
-static ssize_t
-stream_read(CamelStream *stream, char *buffer, size_t n)
-{
- CamelPOP3Stream *is = (CamelPOP3Stream *)stream;
- char *o, *oe;
- unsigned char *p, *e, c;
- int state;
-
- if (is->mode != CAMEL_POP3_STREAM_DATA || n == 0)
- return 0;
-
- o = buffer;
- oe = buffer + n;
- state = is->state;
-
- /* Need to copy/strip '.'s and whatnot */
- p = is->ptr;
- e = is->end;
-
- switch(state) {
- state_0:
- case 0: /* start of line, always read at least 3 chars */
- while (e - p < 3) {
- is->ptr = p;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- }
- if (p[0] == '.') {
- if (p[1] == '\r' && p[2] == '\n') {
- is->ptr = p+3;
- is->mode = CAMEL_POP3_STREAM_EOD;
- is->state = 0;
- dd(printf("POP3_STREAM_READ(%d):\n%.*s\n", o-buffer, o-buffer, buffer));
- return o-buffer;
- }
- p++;
- }
- state = 1;
- /* FALLS THROUGH */
- case 1: /* looking for next sol */
- while (o < oe) {
- c = *p++;
- if (c == '\n') {
- /* end of input sentinal check */
- if (p > e) {
- is->ptr = e;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- } else {
- *o++ = '\n';
- state = 0;
- goto state_0;
- }
- } else if (c != '\r') {
- *o++ = c;
- }
- }
- break;
- }
-
- is->ptr = p;
- is->state = state;
-
- dd(printf("POP3_STREAM_READ(%d):\n%.*s\n", o-buffer, o-buffer, buffer));
-
- return o-buffer;
-}
-
-static ssize_t
-stream_write(CamelStream *stream, const char *buffer, size_t n)
-{
- CamelPOP3Stream *is = (CamelPOP3Stream *)stream;
-
- if (strncmp (buffer, "PASS ", 5) != 0)
- dd(printf("POP3_STREAM_WRITE(%d):\n%.*s\n", n, (int)n, buffer));
- else
- dd(printf("POP3_STREAM_WRITE(%d):\nPASS xxxxxxxx\n", n));
-
- return camel_stream_write(is->source, buffer, n);
-}
-
-static int
-stream_close(CamelStream *stream)
-{
- /* nop? */
- return 0;
-}
-
-static int
-stream_flush(CamelStream *stream)
-{
- /* nop? */
- return 0;
-}
-
-static gboolean
-stream_eos(CamelStream *stream)
-{
- CamelPOP3Stream *is = (CamelPOP3Stream *)stream;
-
- return is->mode != CAMEL_POP3_STREAM_DATA;
-}
-
-static int
-stream_reset(CamelStream *stream)
-{
- /* nop? reset literal mode? */
- return 0;
-}
-
-static void
-camel_pop3_stream_class_init (CamelStreamClass *camel_pop3_stream_class)
-{
- CamelStreamClass *camel_stream_class = (CamelStreamClass *)camel_pop3_stream_class;
-
- parent_class = camel_type_get_global_classfuncs( CAMEL_OBJECT_TYPE );
-
- /* virtual method definition */
- camel_stream_class->read = stream_read;
- camel_stream_class->write = stream_write;
- camel_stream_class->close = stream_close;
- camel_stream_class->flush = stream_flush;
- camel_stream_class->eos = stream_eos;
- camel_stream_class->reset = stream_reset;
-}
-
-static void
-camel_pop3_stream_init(CamelPOP3Stream *is, CamelPOP3StreamClass *isclass)
-{
- /* +1 is room for appending a 0 if we need to for a line */
- is->ptr = is->end = is->buf = g_malloc(CAMEL_POP3_STREAM_SIZE+1);
- is->lineptr = is->linebuf = g_malloc(CAMEL_POP3_STREAM_LINE+1);
- is->lineend = is->linebuf + CAMEL_POP3_STREAM_LINE;
-
- /* init sentinal */
- is->ptr[0] = '\n';
-
- is->state = 0;
- is->mode = CAMEL_POP3_STREAM_LINE;
-}
-
-static void
-camel_pop3_stream_finalise(CamelPOP3Stream *is)
-{
- g_free(is->buf);
- g_free(is->linebuf);
- if (is->source)
- camel_object_unref((CamelObject *)is->source);
-}
-
-CamelType
-camel_pop3_stream_get_type (void)
-{
- static CamelType camel_pop3_stream_type = CAMEL_INVALID_TYPE;
-
- if (camel_pop3_stream_type == CAMEL_INVALID_TYPE) {
- camel_pop3_stream_type = camel_type_register( camel_stream_get_type(),
- "CamelPOP3Stream",
- sizeof( CamelPOP3Stream ),
- sizeof( CamelPOP3StreamClass ),
- (CamelObjectClassInitFunc) camel_pop3_stream_class_init,
- NULL,
- (CamelObjectInitFunc) camel_pop3_stream_init,
- (CamelObjectFinalizeFunc) camel_pop3_stream_finalise );
- }
-
- return camel_pop3_stream_type;
-}
-
-/**
- * camel_pop3_stream_new:
- *
- * Returns a NULL stream. A null stream is always at eof, and
- * always returns success for all reads and writes.
- *
- * Return value: the stream
- **/
-CamelStream *
-camel_pop3_stream_new(CamelStream *source)
-{
- CamelPOP3Stream *is;
-
- is = (CamelPOP3Stream *)camel_object_new(camel_pop3_stream_get_type ());
- camel_object_ref((CamelObject *)source);
- is->source = source;
-
- return (CamelStream *)is;
-}
-
-/* Get one line from the pop3 stream */
-int
-camel_pop3_stream_line(CamelPOP3Stream *is, unsigned char **data, unsigned int *len)
-{
- register unsigned char c, *p, *o, *oe;
- int newlen, oldlen;
- unsigned char *e;
-
- if (is->mode == CAMEL_POP3_STREAM_EOD) {
- *data = is->linebuf;
- *len = 0;
- return 0;
- }
-
- o = is->linebuf;
- oe = is->lineend - 1;
- p = is->ptr;
- e = is->end;
-
- /* Data mode, convert leading '..' to '.', and stop when we reach a solitary '.' */
- if (is->mode == CAMEL_POP3_STREAM_DATA) {
- /* need at least 3 chars in buffer */
- while (e-p < 3) {
- is->ptr = p;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- }
-
- /* check for isolated '.\r\n' or begging of line '.' */
- if (p[0] == '.') {
- if (p[1] == '\r' && p[2] == '\n') {
- is->ptr = p+3;
- is->mode = CAMEL_POP3_STREAM_EOD;
- *data = is->linebuf;
- *len = 0;
- is->linebuf[0] = 0;
-
- dd(printf("POP3_STREAM_LINE(END)\n"));
-
- return 0;
- }
- p++;
- }
- }
-
- while (1) {
- while (o < oe) {
- c = *p++;
- if (c == '\n') {
- /* sentinal? */
- if (p> e) {
- is->ptr = e;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- } else {
- is->ptr = p;
- *data = is->linebuf;
- *len = o - is->linebuf;
- *o = 0;
-
- dd(printf("POP3_STREAM_LINE(%d): '%s'\n", *len, *data));
-
- return 1;
- }
- } else if (c != '\r') {
- *o++ = c;
- }
- }
-
- /* limit this for bad server data? */
- oldlen = o - is->linebuf;
- newlen = (is->lineend - is->linebuf) * 3 / 2;
- is->lineptr = is->linebuf = g_realloc(is->linebuf, newlen);
- is->lineend = is->linebuf + newlen;
- oe = is->lineend - 1;
- o = is->linebuf + oldlen;
- }
-
- return -1;
-}
-
-/* returns -1 on error, 0 if last lot of data, >0 if more remaining */
-int camel_pop3_stream_gets(CamelPOP3Stream *is, unsigned char **start, unsigned int *len)
-{
- int max;
- unsigned char *end;
-
- *len = 0;
-
- max = is->end - is->ptr;
- if (max == 0) {
- max = stream_fill(is);
- if (max <= 0)
- return max;
- }
-
- *start = is->ptr;
- end = memchr(is->ptr, '\n', max);
- if (end)
- max = (end - is->ptr) + 1;
- *start = is->ptr;
- *len = max;
- is->ptr += max;
-
- dd(printf("POP3_STREAM_GETS(%s,%d): '%.*s'\n", end==NULL?"more":"last", *len, (int)*len, *start));
-
- return end == NULL?1:0;
-}
-
-void camel_pop3_stream_set_mode(CamelPOP3Stream *is, camel_pop3_stream_mode_t mode)
-{
- is->mode = mode;
-}
-
-/* returns -1 on erorr, 0 if last data, >0 if more data left */
-int camel_pop3_stream_getd(CamelPOP3Stream *is, unsigned char **start, unsigned int *len)
-{
- unsigned char *p, *e, *s;
- int state;
-
- *len = 0;
-
- if (is->mode == CAMEL_POP3_STREAM_EOD)
- return 0;
-
- if (is->mode == CAMEL_POP3_STREAM_LINE) {
- g_warning("pop3_stream reading data in line mode\n");
- return 0;
- }
-
- state = is->state;
- p = is->ptr;
- e = is->end;
-
- while (e - p < 3) {
- is->ptr = p;
- if (stream_fill(is) == -1)
- return -1;
- p = is->ptr;
- e = is->end;
- }
-
- s = p;
-
- do {
- switch(state) {
- case 0:
- /* check leading '.', ... */
- if (p[0] == '.') {
- if (p[1] == '\r' && p[2] == '\n') {
- is->ptr = p+3;
- *len = p-s;
- *start = s;
- is->mode = CAMEL_POP3_STREAM_EOD;
- is->state = 0;
-
- dd(printf("POP3_STREAM_GETD(%s,%d): '%.*s'\n", "last", *len, (int)*len, *start));
-
- return 0;
- }
-
- /* If at start, just skip '.', else return data upto '.' but skip it */
- if (p == s) {
- s++;
- p++;
- } else {
- is->ptr = p+1;
- *len = p-s;
- *start = s;
- is->state = 1;
-
- dd(printf("POP3_STREAM_GETD(%s,%d): '%.*s'\n", "more", *len, (int)*len, *start));
-
- return 1;
- }
- }
- state = 1;
- case 1:
- /* Scan for sentinal */
- while ((*p++)!='\n')
- ;
-
- if (p > e) {
- p = e;
- } else {
- state = 0;
- }
- break;
- }
- } while ((e-p) >= 3);
-
- is->state = state;
- is->ptr = p;
- *len = p-s;
- *start = s;
-
- dd(printf("POP3_STREAM_GETD(%s,%d): '%.*s'\n", "more", *len, (int)*len, *start));
-
- return 1;
-}
diff --git a/camel/providers/pop3/camel-pop3-stream.h b/camel/providers/pop3/camel-pop3-stream.h
deleted file mode 100644
index 2a4ebc01f2..0000000000
--- a/camel/providers/pop3/camel-pop3-stream.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2002 Ximian Inc.
- *
- * Authors: Michael Zucchi <notzed@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* This is *identical* to the camel-nntp-stream, so should probably
- work out a way to merge them */
-
-#ifndef _CAMEL_POP3_STREAM_H
-#define _CAMEL_POP3_STREAM_H
-
-#include <camel/camel-stream.h>
-
-#define CAMEL_POP3_STREAM(obj) CAMEL_CHECK_CAST (obj, camel_pop3_stream_get_type (), CamelPOP3Stream)
-#define CAMEL_POP3_STREAM_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_pop3_stream_get_type (), CamelPOP3StreamClass)
-#define CAMEL_IS_POP3_STREAM(obj) CAMEL_CHECK_TYPE (obj, camel_pop3_stream_get_type ())
-
-typedef struct _CamelPOP3StreamClass CamelPOP3StreamClass;
-typedef struct _CamelPOP3Stream CamelPOP3Stream;
-
-typedef enum {
- CAMEL_POP3_STREAM_LINE,
- CAMEL_POP3_STREAM_DATA,
- CAMEL_POP3_STREAM_EOD, /* end of data, acts as if end of stream */
-} camel_pop3_stream_mode_t;
-
-struct _CamelPOP3Stream {
- CamelStream parent;
-
- CamelStream *source;
-
- camel_pop3_stream_mode_t mode;
- int state;
-
- unsigned char *buf, *ptr, *end;
- unsigned char *linebuf, *lineptr, *lineend;
-};
-
-struct _CamelPOP3StreamClass {
- CamelStreamClass parent_class;
-};
-
-CamelType camel_pop3_stream_get_type (void);
-
-CamelStream *camel_pop3_stream_new (CamelStream *source);
-
-
-void camel_pop3_stream_set_mode (CamelPOP3Stream *is, camel_pop3_stream_mode_t mode);
-
-int camel_pop3_stream_line (CamelPOP3Stream *is, unsigned char **data, unsigned int *len);
-int camel_pop3_stream_gets (CamelPOP3Stream *is, unsigned char **start, unsigned int *len);
-int camel_pop3_stream_getd (CamelPOP3Stream *is, unsigned char **start, unsigned int *len);
-
-#endif /* ! _CAMEL_POP3_STREAM_H */
diff --git a/camel/providers/pop3/libcamelpop3.urls b/camel/providers/pop3/libcamelpop3.urls
deleted file mode 100644
index 7fffa4d861..0000000000
--- a/camel/providers/pop3/libcamelpop3.urls
+++ /dev/null
@@ -1 +0,0 @@
-pop
diff --git a/camel/providers/sendmail/.cvsignore b/camel/providers/sendmail/.cvsignore
deleted file mode 100644
index 097fdedafb..0000000000
--- a/camel/providers/sendmail/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-Makefile
-Makefile.in
-.deps
-.libs
-*.lo
-*.la
-*.o
-*.bb
-*.bbg
-*.da
-*.gcov
diff --git a/camel/providers/sendmail/Makefile.am b/camel/providers/sendmail/Makefile.am
deleted file mode 100644
index 8c75af2de8..0000000000
--- a/camel/providers/sendmail/Makefile.am
+++ /dev/null
@@ -1,28 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelsendmailincludedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamelsendmail.la
-camel_provider_DATA = libcamelsendmail.urls
-
-INCLUDES = \
- -I.. \
- -I$(srcdir)/.. \
- -I$(srcdir)/../../.. \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/camel \
- $(CAMEL_CFLAGS) \
- $(GNOME_INCLUDEDIR) \
- $(GTK_INCLUDEDIR) \
- -DG_LOG_DOMAIN=\"camel-sendmail-provider\"
-
-libcamelsendmail_la_SOURCES = \
- camel-sendmail-provider.c \
- camel-sendmail-transport.c
-
-libcamelsendmailinclude_HEADERS = \
- camel-sendmail-transport.h
-
-libcamelsendmail_la_LDFLAGS = -avoid-version -module
-
-EXTRA_DIST = libcamelsendmail.urls
diff --git a/camel/providers/sendmail/camel-sendmail-provider.c b/camel/providers/sendmail/camel-sendmail-provider.c
deleted file mode 100644
index 9615dff1b4..0000000000
--- a/camel/providers/sendmail/camel-sendmail-provider.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-sendmail-provider.c: sendmail provider registration code */
-
-/*
- * Authors :
- * Dan Winship <danw@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "camel-provider.h"
-#include "camel-sendmail-transport.h"
-#include "camel-session.h"
-#include "camel-url.h"
-
-static CamelProvider sendmail_provider = {
- "sendmail",
- N_("Sendmail"),
-
- N_("For delivering mail by passing it to the \"sendmail\" program "
- "on the local system."),
-
- "mail",
-
- 0, /* flags */
-
- 0, /* url_flags */
-
- /* ... */
-};
-
-void
-camel_provider_module_init (CamelSession *session)
-{
- sendmail_provider.object_types[CAMEL_PROVIDER_TRANSPORT] =
- camel_sendmail_transport_get_type();
-
- sendmail_provider.url_hash = camel_url_hash;
- sendmail_provider.url_equal = camel_url_equal;
-
- camel_session_register_provider (session, &sendmail_provider);
-}
-
-
-
diff --git a/camel/providers/sendmail/camel-sendmail-transport.c b/camel/providers/sendmail/camel-sendmail-transport.c
deleted file mode 100644
index fbf6f08a6b..0000000000
--- a/camel/providers/sendmail/camel-sendmail-transport.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-sendmail-transport.c: Sendmail-based transport class. */
-
-/*
- *
- * Authors: Dan Winship <danw@ximian.com>
- *
- * Copyright 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "camel-sendmail-transport.h"
-#include "camel-mime-filter-crlf.h"
-#include "camel-stream-filter.h"
-#include "camel-mime-message.h"
-#include "camel-data-wrapper.h"
-#include "camel-stream-fs.h"
-#include "camel-exception.h"
-
-static char *get_name (CamelService *service, gboolean brief);
-
-static gboolean sendmail_send_to (CamelTransport *transport,
- CamelMimeMessage *message,
- CamelAddress *from, CamelAddress *recipients,
- CamelException *ex);
-
-
-static void
-camel_sendmail_transport_class_init (CamelSendmailTransportClass *camel_sendmail_transport_class)
-{
- CamelTransportClass *camel_transport_class =
- CAMEL_TRANSPORT_CLASS (camel_sendmail_transport_class);
- CamelServiceClass *camel_service_class =
- CAMEL_SERVICE_CLASS (camel_sendmail_transport_class);
-
- /* virtual method overload */
- camel_service_class->get_name = get_name;
- camel_transport_class->send_to = sendmail_send_to;
-}
-
-CamelType
-camel_sendmail_transport_get_type (void)
-{
- static CamelType camel_sendmail_transport_type = CAMEL_INVALID_TYPE;
-
- if (camel_sendmail_transport_type == CAMEL_INVALID_TYPE) {
- camel_sendmail_transport_type =
- camel_type_register (CAMEL_TRANSPORT_TYPE, "CamelSendmailTransport",
- sizeof (CamelSendmailTransport),
- sizeof (CamelSendmailTransportClass),
- (CamelObjectClassInitFunc) camel_sendmail_transport_class_init,
- NULL,
- (CamelObjectInitFunc) NULL,
- NULL);
- }
-
- return camel_sendmail_transport_type;
-}
-
-
-static gboolean
-sendmail_send_to (CamelTransport *transport, CamelMimeMessage *message,
- CamelAddress *from, CamelAddress *recipients,
- CamelException *ex)
-{
- struct _camel_header_raw *header, *savedbcc, *n, *tail;
- const char *from_addr, *addr, **argv;
- int i, len, fd[2], nullfd, wstat;
- CamelStreamFilter *filter;
- CamelMimeFilter *crlf;
- sigset_t mask, omask;
- CamelStream *out;
- pid_t pid;
-
- if (!camel_internet_address_get (CAMEL_INTERNET_ADDRESS (from), 0, NULL, &from_addr))
- return FALSE;
-
- len = camel_address_length (recipients);
- argv = g_malloc ((len + 6) * sizeof (char *));
- argv[0] = "sendmail";
- argv[1] = "-i";
- argv[2] = "-f";
- argv[3] = from_addr;
- argv[4] = "--";
-
- for (i = 0; i < len; i++) {
- if (!camel_internet_address_get (CAMEL_INTERNET_ADDRESS (recipients), i, NULL, &addr)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not parse recipient list"));
- g_free (argv);
- return FALSE;
- }
-
- argv[i + 5] = addr;
- }
-
- argv[i + 5] = NULL;
-
- /* unlink the bcc headers */
- savedbcc = NULL;
- tail = (struct _camel_header_raw *) &savedbcc;
-
- header = (struct _camel_header_raw *) &CAMEL_MIME_PART (message)->headers;
- n = header->next;
- while (n != NULL) {
- if (!strcasecmp (n->name, "Bcc")) {
- header->next = n->next;
- tail->next = n;
- n->next = NULL;
- tail = n;
- } else {
- header = n;
- }
-
- n = header->next;
- }
-
- if (pipe (fd) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create pipe to sendmail: "
- "%s: mail not sent"),
- g_strerror (errno));
-
- /* restore the bcc headers */
- header->next = savedbcc;
-
- return FALSE;
- }
-
- /* Block SIGCHLD so the calling application doesn't notice
- * sendmail exiting before we do.
- */
- sigemptyset (&mask);
- sigaddset (&mask, SIGCHLD);
- sigprocmask (SIG_BLOCK, &mask, &omask);
-
- pid = fork ();
- switch (pid) {
- case -1:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not fork sendmail: "
- "%s: mail not sent"),
- g_strerror (errno));
- sigprocmask (SIG_SETMASK, &omask, NULL);
- g_free (argv);
-
- /* restore the bcc headers */
- header->next = savedbcc;
-
- return FALSE;
- case 0:
- /* Child process */
- nullfd = open ("/dev/null", O_RDWR);
- dup2 (fd[0], STDIN_FILENO);
- /*dup2 (nullfd, STDOUT_FILENO);
- dup2 (nullfd, STDERR_FILENO);*/
- close (nullfd);
- close (fd[1]);
-
- execv (SENDMAIL_PATH, (char **)argv);
- _exit (255);
- }
- g_free (argv);
-
- /* Parent process. Write the message out. */
- close (fd[0]);
- out = camel_stream_fs_new_with_fd (fd[1]);
-
- /* workaround for lame sendmail implementations that can't handle CRLF eoln sequences */
- filter = camel_stream_filter_new_with_stream (out);
- crlf = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- camel_stream_filter_add (filter, crlf);
- camel_object_unref (crlf);
- camel_object_unref (out);
-
- out = (CamelStream *) filter;
- if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), out) == -1
- || camel_stream_close (out) == -1) {
- camel_object_unref (CAMEL_OBJECT (out));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not send message: %s"),
- g_strerror (errno));
-
- /* Wait for sendmail to exit. */
- while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
- ;
-
- sigprocmask (SIG_SETMASK, &omask, NULL);
-
- /* restore the bcc headers */
- header->next = savedbcc;
-
- return FALSE;
- }
-
- camel_object_unref (CAMEL_OBJECT (out));
-
- /* Wait for sendmail to exit. */
- while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
- ;
-
- sigprocmask (SIG_SETMASK, &omask, NULL);
-
- /* restore the bcc headers */
- header->next = savedbcc;
-
- if (!WIFEXITED (wstat)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("sendmail exited with signal %s: "
- "mail not sent."),
- g_strsignal (WTERMSIG (wstat)));
- return FALSE;
- } else if (WEXITSTATUS (wstat) != 0) {
- if (WEXITSTATUS (wstat) == 255) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not execute %s: "
- "mail not sent."),
- SENDMAIL_PATH);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("sendmail exited with status "
- "%d: mail not sent."),
- WEXITSTATUS (wstat));
- }
- return FALSE;
- }
-
- return TRUE;
-}
-
-static char *
-get_name (CamelService *service, gboolean brief)
-{
- if (brief)
- return g_strdup (_("sendmail"));
- else
- return g_strdup (_("Mail delivery via the sendmail program"));
-}
diff --git a/camel/providers/sendmail/camel-sendmail-transport.h b/camel/providers/sendmail/camel-sendmail-transport.h
deleted file mode 100644
index 056be03bc8..0000000000
--- a/camel/providers/sendmail/camel-sendmail-transport.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-sendmail-transport.h: Sendmail-based transport class */
-
-/*
- *
- * Author :
- * Dan Winship <danw@ximian.com>
- *
- * Copyright 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_SENDMAIL_TRANSPORT_H
-#define CAMEL_SENDMAIL_TRANSPORT_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-transport.h"
-
-#define CAMEL_SENDMAIL_TRANSPORT_TYPE (camel_sendmail_transport_get_type ())
-#define CAMEL_SENDMAIL_TRANSPORT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SENDMAIL_TRANSPORT_TYPE, CamelSendmailTransport))
-#define CAMEL_SENDMAIL_TRANSPORT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SENDMAIL_TRANSPORT_TYPE, CamelSendmailTransportClass))
-#define CAMEL_IS_SENDMAIL_TRANSPORT(o) (CAMEL_CHECK_TYPE((o), CAMEL_SENDMAIL_TRANSPORT_TYPE))
-
-
-typedef struct {
- CamelTransport parent_object;
-
-} CamelSendmailTransport;
-
-
-typedef struct {
- CamelTransportClass parent_class;
-
-} CamelSendmailTransportClass;
-
-
-/* Standard Camel function */
-CamelType camel_sendmail_transport_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_SENDMAIL_TRANSPORT_H */
diff --git a/camel/providers/sendmail/libcamelsendmail.urls b/camel/providers/sendmail/libcamelsendmail.urls
deleted file mode 100644
index ccad52828e..0000000000
--- a/camel/providers/sendmail/libcamelsendmail.urls
+++ /dev/null
@@ -1 +0,0 @@
-sendmail
diff --git a/camel/providers/smtp/.cvsignore b/camel/providers/smtp/.cvsignore
deleted file mode 100644
index b948585108..0000000000
--- a/camel/providers/smtp/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-*.lo
-*.la
-*.bb
-*.bbg
-*.da
-*.gcov
diff --git a/camel/providers/smtp/Makefile.am b/camel/providers/smtp/Makefile.am
deleted file mode 100644
index b6bba766d6..0000000000
--- a/camel/providers/smtp/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelsmtpincludedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamelsmtp.la
-camel_provider_DATA = libcamelsmtp.urls
-
-INCLUDES = \
- -I.. \
- -I$(srcdir)/.. \
- -I$(srcdir)/../../.. \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/e-util \
- $(CAMEL_CFLAGS) \
- $(GNOME_INCLUDEDIR) \
- $(GTK_INCLUDEDIR) \
- $(NSPR_CFLAGS) \
- $(NSS_CFLAGS) \
- $(OPENSSL_CFLAGS) \
- -DG_LOG_DOMAIN=\"camel-smtp-provider\"
-
-libcamelsmtp_la_SOURCES = \
- camel-smtp-provider.c \
- camel-smtp-transport.c
-
-libcamelsmtpinclude_HEADERS = \
- camel-smtp-transport.h
-
-
-libcamelsmtp_la_LDFLAGS = -avoid-version -module
-
-libcamelsmtp_la_LIBADD = $(top_builddir)/e-util/libeutil.la
-
-EXTRA_DIST = libcamelsmtp.urls
diff --git a/camel/providers/smtp/camel-smtp-provider.c b/camel/providers/smtp/camel-smtp-provider.c
deleted file mode 100644
index 07991eb695..0000000000
--- a/camel/providers/smtp/camel-smtp-provider.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-smtp-provider.c: smtp provider registration code */
-/*
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2002 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "camel-smtp-transport.h"
-#include "camel-provider.h"
-#include "camel-session.h"
-#include "camel-url.h"
-#include "camel-sasl.h"
-
-static CamelProvider smtp_provider = {
- "smtp",
- N_("SMTP"),
-
- N_("For delivering mail by connecting to a remote mailhub "
- "using SMTP.\n"),
-
- "mail",
-
- CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_SUPPORTS_SSL,
-
- CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH | CAMEL_URL_ALLOW_USER,
-
- /* ... */
-};
-
-void
-camel_provider_module_init (CamelSession *session)
-{
- smtp_provider.object_types[CAMEL_PROVIDER_TRANSPORT] =
- camel_smtp_transport_get_type ();
- smtp_provider.authtypes = g_list_append (camel_sasl_authtype_list (TRUE), camel_sasl_authtype ("LOGIN"));
- smtp_provider.authtypes = g_list_append (smtp_provider.authtypes, camel_sasl_authtype ("POPB4SMTP"));
- smtp_provider.url_hash = camel_url_hash;
- smtp_provider.url_equal = camel_url_equal;
-
- camel_session_register_provider (session, &smtp_provider);
-}
-
-
-
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
deleted file mode 100644
index 5bf5add2ee..0000000000
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ /dev/null
@@ -1,1455 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-smtp-transport.c : class for a smtp transport */
-
-/*
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#undef MIN
-#undef MAX
-#include "camel-mime-filter-crlf.h"
-#include "camel-stream-filter.h"
-#include "camel-smtp-transport.h"
-#include "camel-mime-message.h"
-#include "camel-multipart.h"
-#include "camel-mime-part.h"
-#include "camel-operation.h"
-#include "camel-stream-buffer.h"
-#include "camel-tcp-stream.h"
-#include "camel-tcp-stream-raw.h"
-#ifdef HAVE_SSL
-#include "camel-tcp-stream-ssl.h"
-#endif
-#include "camel-session.h"
-#include "camel-exception.h"
-#include "camel-sasl.h"
-
-
-extern int camel_verbose_debug;
-#define d(x) (camel_verbose_debug ? (x) : 0)
-
-/* Specified in RFC 821 */
-#define SMTP_PORT 25
-
-/* camel smtp transport class prototypes */
-static gboolean smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
- CamelAddress *from, CamelAddress *recipients, CamelException *ex);
-
-/* support prototypes */
-static void smtp_construct (CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- CamelException *ex);
-static gboolean smtp_connect (CamelService *service, CamelException *ex);
-static gboolean smtp_disconnect (CamelService *service, gboolean clean, CamelException *ex);
-static GHashTable *esmtp_get_authtypes (const unsigned char *buffer);
-static GList *query_auth_types (CamelService *service, CamelException *ex);
-static char *get_name (CamelService *service, gboolean brief);
-
-static gboolean smtp_helo (CamelSmtpTransport *transport, CamelException *ex);
-static gboolean smtp_auth (CamelSmtpTransport *transport, const char *mech, CamelException *ex);
-static gboolean smtp_mail (CamelSmtpTransport *transport, const char *sender,
- gboolean has_8bit_parts, CamelException *ex);
-static gboolean smtp_rcpt (CamelSmtpTransport *transport, const char *recipient, CamelException *ex);
-static gboolean smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, CamelException *ex);
-static gboolean smtp_rset (CamelSmtpTransport *transport, CamelException *ex);
-static gboolean smtp_quit (CamelSmtpTransport *transport, CamelException *ex);
-
-static void smtp_set_exception (CamelSmtpTransport *transport, const char *respbuf,
- const char *message, CamelException *ex);
-
-/* private data members */
-static CamelTransportClass *parent_class = NULL;
-
-static void
-camel_smtp_transport_class_init (CamelSmtpTransportClass *camel_smtp_transport_class)
-{
- CamelTransportClass *camel_transport_class =
- CAMEL_TRANSPORT_CLASS (camel_smtp_transport_class);
- CamelServiceClass *camel_service_class =
- CAMEL_SERVICE_CLASS (camel_smtp_transport_class);
-
- parent_class = CAMEL_TRANSPORT_CLASS (camel_type_get_global_classfuncs (camel_transport_get_type ()));
-
- /* virtual method overload */
- camel_service_class->construct = smtp_construct;
- camel_service_class->connect = smtp_connect;
- camel_service_class->disconnect = smtp_disconnect;
- camel_service_class->query_auth_types = query_auth_types;
- camel_service_class->get_name = get_name;
-
- camel_transport_class->send_to = smtp_send_to;
-}
-
-static void
-camel_smtp_transport_init (gpointer object)
-{
- CamelSmtpTransport *smtp = CAMEL_SMTP_TRANSPORT (object);
-
- smtp->flags = 0;
- smtp->connected = FALSE;
-}
-
-CamelType
-camel_smtp_transport_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register (CAMEL_TRANSPORT_TYPE,
- "CamelSmtpTransport",
- sizeof (CamelSmtpTransport),
- sizeof (CamelSmtpTransportClass),
- (CamelObjectClassInitFunc) camel_smtp_transport_class_init,
- NULL,
- (CamelObjectInitFunc) camel_smtp_transport_init,
- NULL);
- }
-
- return type;
-}
-
-static void
-smtp_construct (CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- CamelException *ex)
-{
- CamelSmtpTransport *smtp_transport = CAMEL_SMTP_TRANSPORT (service);
- const char *use_ssl;
-
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
-
- if ((use_ssl = camel_url_get_param (url, "use_ssl"))) {
- /* Note: previous versions would use "" to toggle use_ssl to 'on' */
- if (!*use_ssl || !strcmp (use_ssl, "always"))
- smtp_transport->flags |= CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS;
- else if (!strcmp (use_ssl, "when-possible"))
- smtp_transport->flags |= CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE;
- }
-}
-
-static const char *
-smtp_error_string (int error)
-{
- /* SMTP error codes grabbed from rfc821 */
- switch (error) {
- case 0:
- /* looks like a read problem, check errno */
- if (errno)
- return g_strerror (errno);
- else
- return _("Unknown");
- case 500:
- return _("Syntax error, command unrecognized");
- case 501:
- return _("Syntax error in parameters or arguments");
- case 502:
- return _("Command not implemented");
- case 504:
- return _("Command parameter not implemented");
- case 211:
- return _("System status, or system help reply");
- case 214:
- return _("Help message");
- case 220:
- return _("Service ready");
- case 221:
- return _("Service closing transmission channel");
- case 421:
- return _("Service not available, closing transmission channel");
- case 250:
- return _("Requested mail action okay, completed");
- case 251:
- return _("User not local; will forward to <forward-path>");
- case 450:
- return _("Requested mail action not taken: mailbox unavailable");
- case 550:
- return _("Requested action not taken: mailbox unavailable");
- case 451:
- return _("Requested action aborted: error in processing");
- case 551:
- return _("User not local; please try <forward-path>");
- case 452:
- return _("Requested action not taken: insufficient system storage");
- case 552:
- return _("Requested mail action aborted: exceeded storage allocation");
- case 553:
- return _("Requested action not taken: mailbox name not allowed");
- case 354:
- return _("Start mail input; end with <CRLF>.<CRLF>");
- case 554:
- return _("Transaction failed");
-
- /* AUTH error codes: */
- case 432:
- return _("A password transition is needed");
- case 534:
- return _("Authentication mechanism is too weak");
- case 538:
- return _("Encryption required for requested authentication mechanism");
- case 454:
- return _("Temporary authentication failure");
- case 530:
- return _("Authentication required");
-
- default:
- return _("Unknown");
- }
-}
-
-#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
-
-static gboolean
-connect_to_server (CamelService *service, int try_starttls, CamelException *ex)
-{
- CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
- CamelStream *tcp_stream;
- char *respbuf = NULL;
- struct hostent *h;
- int port, ret;
-
- if (!CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex))
- return FALSE;
-
- h = camel_service_gethost (service, ex);
- if (!h)
- return FALSE;
-
- /* set some smtp transport defaults */
- transport->flags &= CAMEL_SMTP_TRANSPORT_USE_SSL; /* reset all but ssl flags */
- transport->authtypes = NULL;
-
- port = service->url->port ? service->url->port : SMTP_PORT;
-
- if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL) {
-#ifdef HAVE_SSL
- if (try_starttls) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- port = service->url->port ? service->url->port : 465;
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- if (!try_starttls)
- port = service->url->port ? service->url->port : 465;
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port,
- _("SSL unavailable"));
-
- camel_free_host (h);
-
- return FALSE;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- ret = camel_tcp_stream_connect (CAMEL_TCP_STREAM (tcp_stream), h, port);
- camel_free_host (h);
- if (ret == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port,
- g_strerror (errno));
-
- camel_object_unref (tcp_stream);
-
- return FALSE;
- }
-
- transport->connected = TRUE;
-
- /* get the localaddr - needed later by smtp_helo */
- transport->localaddr = camel_tcp_stream_get_local_address (CAMEL_TCP_STREAM (tcp_stream));
-
- transport->ostream = tcp_stream;
- transport->istream = camel_stream_buffer_new (tcp_stream, CAMEL_STREAM_BUFFER_READ);
-
- /* Read the greeting, note whether the server is ESMTP or not. */
- do {
- /* Check for "220" */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
- if (!respbuf || strncmp (respbuf, "220", 3)) {
- smtp_set_exception (transport, respbuf, _("Welcome response error"), ex);
- g_free (respbuf);
- return FALSE;
- }
- } while (*(respbuf+3) == '-'); /* if we got "220-" then loop again */
- g_free (respbuf);
-
- /* Try sending EHLO */
- transport->flags |= CAMEL_SMTP_TRANSPORT_IS_ESMTP;
- if (!smtp_helo (transport, ex)) {
- if (!transport->connected)
- return FALSE;
-
- /* Fall back to HELO */
- camel_exception_clear (ex);
- transport->flags &= ~CAMEL_SMTP_TRANSPORT_IS_ESMTP;
- if (!smtp_helo (transport, ex) && !transport->connected)
- return FALSE;
- }
-
- /* clear any EHLO/HELO exception and assume that any SMTP errors encountered were non-fatal */
- camel_exception_clear (ex);
-
-#ifdef HAVE_SSL
- if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE) {
- /* try_starttls is always TRUE here */
- if (transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS)
- goto starttls;
- } else if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS) {
- if (try_starttls) {
- if (transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS) {
- goto starttls;
- } else {
- /* server doesn't support STARTTLS, abort */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to SMTP server %s in secure mode: %s"),
- service->url->host, _("server does not appear to support SSL"));
- goto exception_cleanup;
- }
- }
- }
-#endif /* HAVE_SSL */
-
- return TRUE;
-
-#ifdef HAVE_SSL
- starttls:
- d(fprintf (stderr, "sending : STARTTLS\r\n"));
- if (camel_stream_write (tcp_stream, "STARTTLS\r\n", 10) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("STARTTLS request timed out: %s"),
- g_strerror (errno));
- goto exception_cleanup;
- }
-
- respbuf = NULL;
-
- do {
- /* Check for "220 Ready for TLS" */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "220", 3)) {
- smtp_set_exception (transport, respbuf, _("STARTTLS response error"), ex);
- g_free (respbuf);
- goto exception_cleanup;
- }
- } while (*(respbuf+3) == '-'); /* if we got "220-" then loop again */
-
- /* Okay, now toggle SSL/TLS mode */
- if (camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream)) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to SMTP server %s in secure mode: %s"),
- service->url->host, g_strerror (errno));
- goto exception_cleanup;
- }
-
- /* We are supposed to re-EHLO after a successful STARTTLS to
- re-fetch any supported extensions. */
- if (!smtp_helo (transport, ex) && !transport->connected)
- return FALSE;
-
- return TRUE;
-
- exception_cleanup:
-
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- transport->connected = FALSE;
-
- return FALSE;
-#endif /* HAVE_SSL */
-}
-
-static gboolean
-connect_to_server_wrapper (CamelService *service, CamelException *ex)
-{
-#ifdef HAVE_SSL
- CamelSmtpTransport *transport = (CamelSmtpTransport *) service;
-
- if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS) {
- /* First try connecting to the SSL port */
- if (!connect_to_server (service, FALSE, ex)) {
- if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
- /* Seems the SSL port is unavailable, lets try STARTTLS */
- camel_exception_clear (ex);
- return connect_to_server (service, TRUE, ex);
- } else {
- return FALSE;
- }
- }
-
- return TRUE;
- } else if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE) {
- /* If the server supports STARTTLS, use it */
- return connect_to_server (service, TRUE, ex);
- } else {
- /* User doesn't care about SSL */
- return connect_to_server (service, FALSE, ex);
- }
-#else
- return connect_to_server (service, FALSE, ex);
-#endif
-}
-
-static gboolean
-smtp_connect (CamelService *service, CamelException *ex)
-{
- CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
- gboolean has_authtypes;
-
- /* We (probably) need to check popb4smtp before we connect ... */
- if (service->url->authmech && !strcmp (service->url->authmech, "POPB4SMTP")) {
- int truth;
- GByteArray *chal;
- CamelSasl *sasl;
-
- sasl = camel_sasl_new ("smtp", "POPB4SMTP", service);
- chal = camel_sasl_challenge (sasl, NULL, ex);
- truth = camel_sasl_authenticated (sasl);
- if (chal)
- g_byte_array_free (chal, TRUE);
- camel_object_unref (sasl);
-
- if (!truth)
- return FALSE;
-
- return connect_to_server_wrapper (service, ex);
- }
-
- if (!connect_to_server_wrapper (service, ex))
- return FALSE;
-
- /* check to see if AUTH is required, if so...then AUTH ourselves */
- has_authtypes = transport->authtypes ? g_hash_table_size (transport->authtypes) > 0 : FALSE;
- if (service->url->authmech && (transport->flags & CAMEL_SMTP_TRANSPORT_IS_ESMTP) && has_authtypes) {
- CamelSession *session = camel_service_get_session (service);
- CamelServiceAuthType *authtype;
- gboolean authenticated = FALSE;
- char *errbuf = NULL;
-
- if (!g_hash_table_lookup (transport->authtypes, service->url->authmech)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("SMTP server %s does not support requested "
- "authentication type %s."),
- service->url->host, service->url->authmech);
- camel_service_disconnect (service, TRUE, NULL);
- return FALSE;
- }
-
- authtype = camel_sasl_authtype (service->url->authmech);
- if (!authtype) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("No support for authentication type %s"),
- service->url->authmech);
- camel_service_disconnect (service, TRUE, NULL);
- return FALSE;
- }
-
- if (!authtype->need_password) {
- /* authentication mechanism doesn't need a password,
- so if it fails there's nothing we can do */
- authenticated = smtp_auth (transport, authtype->authproto, ex);
- if (!authenticated) {
- camel_service_disconnect (service, TRUE, NULL);
- return FALSE;
- }
- }
-
- /* keep trying to login until either we succeed or the user cancels */
- while (!authenticated) {
- if (errbuf) {
- /* We need to un-cache the password before prompting again */
- camel_session_forget_password (session, service, "password", NULL);
- g_free (service->url->passwd);
- service->url->passwd = NULL;
- }
-
- if (!service->url->passwd) {
- char *prompt;
-
- prompt = g_strdup_printf (_("%sPlease enter the SMTP password for %s@%s"),
- errbuf ? errbuf : "", service->url->user,
- service->url->host);
-
- service->url->passwd = camel_session_get_password (session, prompt, FALSE, TRUE,
- service, "password", ex);
-
- g_free (prompt);
- g_free (errbuf);
- errbuf = NULL;
-
- if (!service->url->passwd) {
- camel_service_disconnect (service, TRUE, NULL);
- return FALSE;
- }
- }
-
- authenticated = smtp_auth (transport, authtype->authproto, ex);
- if (!authenticated) {
- errbuf = g_strdup_printf (_("Unable to authenticate "
- "to SMTP server.\n%s\n\n"),
- camel_exception_get_description (ex));
- camel_exception_clear (ex);
- }
- }
-
- /* The spec says we have to re-EHLO, but some servers
- * we won't bother to name don't want you to... so ignore
- * errors.
- */
- if (!smtp_helo (transport, ex) && !transport->connected)
- return FALSE;
-
- camel_exception_clear (ex);
- }
-
- return TRUE;
-}
-
-static void
-authtypes_free (gpointer key, gpointer value, gpointer data)
-{
- g_free (value);
-}
-
-static gboolean
-smtp_disconnect (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
-
- /*if (!service->connected)
- * return TRUE;
- */
-
- if (transport->connected && clean) {
- /* send the QUIT command to the SMTP server */
- smtp_quit (transport, ex);
- }
-
- if (!CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, clean, ex))
- return FALSE;
-
- if (transport->authtypes) {
- g_hash_table_foreach (transport->authtypes, authtypes_free, NULL);
- g_hash_table_destroy (transport->authtypes);
- transport->authtypes = NULL;
- }
-
- if (transport->istream) {
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- }
-
- if (transport->ostream) {
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
- }
-
- camel_tcp_address_free (transport->localaddr);
- transport->localaddr = NULL;
-
- transport->connected = FALSE;
-
- return TRUE;
-}
-
-static GHashTable *
-esmtp_get_authtypes (const unsigned char *buffer)
-{
- const unsigned char *start, *end;
- GHashTable *table = NULL;
-
- /* advance to the first token */
- start = buffer;
- while (isspace ((int) *start) || *start == '=')
- start++;
-
- if (!*start)
- return NULL;
-
- table = g_hash_table_new (g_str_hash, g_str_equal);
-
- for ( ; *start; ) {
- char *type;
-
- /* advance to the end of the token */
- end = start;
- while (*end && !isspace ((int) *end))
- end++;
-
- type = g_strndup (start, end - start);
- g_hash_table_insert (table, type, type);
-
- /* advance to the next token */
- start = end;
- while (isspace ((int) *start))
- start++;
- }
-
- return table;
-}
-
-static GList *
-query_auth_types (CamelService *service, CamelException *ex)
-{
- CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
- CamelServiceAuthType *authtype;
- GList *types, *t, *next;
-
- if (!connect_to_server_wrapper (service, ex))
- return NULL;
-
- types = g_list_copy (service->provider->authtypes);
- for (t = types; t; t = next) {
- authtype = t->data;
- next = t->next;
-
- if (!g_hash_table_lookup (transport->authtypes, authtype->authproto)) {
- types = g_list_remove_link (types, t);
- g_list_free_1 (t);
- }
- }
-
- smtp_disconnect (service, TRUE, NULL);
-
- return types;
-}
-
-static char *
-get_name (CamelService *service, gboolean brief)
-{
- if (brief)
- return g_strdup_printf (_("SMTP server %s"), service->url->host);
- else {
- return g_strdup_printf (_("SMTP mail delivery via %s"),
- service->url->host);
- }
-}
-
-static gboolean
-smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
- CamelAddress *from, CamelAddress *recipients,
- CamelException *ex)
-{
- CamelSmtpTransport *smtp_transport = CAMEL_SMTP_TRANSPORT (transport);
- const CamelInternetAddress *cia;
- gboolean has_8bit_parts;
- const char *addr;
- int i, len;
-
- if (!camel_internet_address_get (CAMEL_INTERNET_ADDRESS (from), 0, NULL, &addr)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot send message: "
- "sender address not valid."));
- return FALSE;
- }
-
- camel_operation_start (NULL, _("Sending message"));
-
- /* find out if the message has 8bit mime parts */
- has_8bit_parts = camel_mime_message_has_8bit_parts (message);
-
- /* rfc1652 (8BITMIME) requires that you notify the ESMTP daemon that
- you'll be sending an 8bit mime message at "MAIL FROM:" time. */
- if (!smtp_mail (smtp_transport, addr, has_8bit_parts, ex)) {
- camel_operation_end (NULL);
- return FALSE;
- }
-
- len = camel_address_length (recipients);
- if (len == 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot send message: no recipients defined."));
- camel_operation_end (NULL);
- return FALSE;
- }
-
- cia = CAMEL_INTERNET_ADDRESS (recipients);
- for (i = 0; i < len; i++) {
- char *enc;
-
- if (!camel_internet_address_get (cia, i, NULL, &addr)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot send message: one or more invalid recipients"));
- camel_operation_end (NULL);
- return FALSE;
- }
-
- enc = camel_internet_address_encode_address(NULL, NULL, addr);
- if (!smtp_rcpt (smtp_transport, enc, ex)) {
- g_free(enc);
- camel_operation_end (NULL);
- return FALSE;
- }
- g_free(enc);
- }
-
- if (!smtp_data (smtp_transport, message, ex)) {
- camel_operation_end (NULL);
- return FALSE;
- }
-
- /* reset the service for our next transfer session */
- smtp_rset (smtp_transport, ex);
-
- camel_operation_end (NULL);
-
- return TRUE;
-}
-
-static const char *
-smtp_next_token (const char *buf)
-{
- const unsigned char *token;
-
- token = (const unsigned char *) buf;
- while (*token && !isspace ((int) *token))
- token++;
-
- while (*token && isspace ((int) *token))
- token++;
-
- return (const char *) token;
-}
-
-#define HEXVAL(c) (isdigit (c) ? (c) - '0' : (c) - 'A' + 10)
-
-/**
- * example (rfc2034):
- * 5.1.1 Mailbox "nosuchuser" does not exist
- *
- * The human-readable status code is what we want. Since this text
- * could possibly be encoded, we must decode it.
- *
- * "xtext" is formally defined as follows:
- *
- * xtext = *( xchar / hexchar / linear-white-space / comment )
- *
- * xchar = any ASCII CHAR between "!" (33) and "~" (126) inclusive,
- * except for "+", "\" and "(".
- *
- * "hexchar"s are intended to encode octets that cannot be represented
- * as plain text, either because they are reserved, or because they are
- * non-printable. However, any octet value may be represented by a
- * "hexchar".
- *
- * hexchar = ASCII "+" immediately followed by two upper case
- * hexadecimal digits
- **/
-static char *
-smtp_decode_status_code (const char *in, size_t len)
-{
- unsigned char *inptr, *outptr;
- const unsigned char *inend;
- char *outbuf;
-
- outptr = outbuf = g_malloc (len + 1);
-
- inptr = (unsigned char *) in;
- inend = inptr + len;
- while (inptr < inend) {
- if (*inptr == '+') {
- if (isxdigit (inptr[1]) && isxdigit (inptr[2])) {
- *outptr++ = HEXVAL (inptr[1]) * 16 + HEXVAL (inptr[2]);
- inptr += 3;
- } else
- *outptr++ = *inptr++;
- } else
- *outptr++ = *inptr++;
- }
-
- *outptr = '\0';
-
- return outbuf;
-}
-
-static void
-smtp_set_exception (CamelSmtpTransport *transport, const char *respbuf, const char *message, CamelException *ex)
-{
- const char *token, *rbuf = respbuf;
- char *buffer = NULL;
- GString *string;
- int error;
-
- if (!respbuf || !(transport->flags & CAMEL_SMTP_TRANSPORT_ENHANCEDSTATUSCODES)) {
- fake_status_code:
- error = respbuf ? atoi (respbuf) : 0;
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "%s: %s", message,
- smtp_error_string (error));
- } else {
- string = g_string_new ("");
- do {
- token = smtp_next_token (rbuf + 4);
- if (*token == '\0') {
- g_free (buffer);
- g_string_free (string, TRUE);
- goto fake_status_code;
- }
-
- g_string_append (string, token);
- if (*(rbuf + 3) == '-') {
- g_free (buffer);
- buffer = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
- g_string_append_c (string, '\n');
- } else {
- g_free (buffer);
- buffer = NULL;
- }
-
- rbuf = buffer;
- } while (rbuf);
-
- buffer = smtp_decode_status_code (string->str, string->len);
- g_string_free (string, TRUE);
- if (!buffer)
- goto fake_status_code;
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- "%s: %s", message, buffer);
-
- g_free (buffer);
- }
-
- if (!respbuf) {
- /* we got disconnected */
- transport->connected = FALSE;
- }
-}
-
-static gboolean
-smtp_helo (CamelSmtpTransport *transport, CamelException *ex)
-{
- /* say hello to the server */
- char *name = NULL, *cmdbuf = NULL, *respbuf = NULL;
- struct hostent *host;
- CamelException err;
- const char *token;
- int af;
-
- /* these are flags that we set, so unset them in case we
- are being called a second time (ie, after a STARTTLS) */
- transport->flags &= ~(CAMEL_SMTP_TRANSPORT_8BITMIME |
- CAMEL_SMTP_TRANSPORT_ENHANCEDSTATUSCODES |
- CAMEL_SMTP_TRANSPORT_STARTTLS);
-
- if (transport->authtypes) {
- g_hash_table_foreach (transport->authtypes, authtypes_free, NULL);
- g_hash_table_destroy (transport->authtypes);
- transport->authtypes = NULL;
- }
-
- camel_operation_start_transient (NULL, _("SMTP Greeting"));
-
- /* get the local host name */
- camel_exception_init (&err);
-#ifdef ENABLE_IPv6
- af = transport->localaddr->family == CAMEL_TCP_ADDRESS_IPv6 ? AF_INET6 : AF_INET;
-#else
- af = AF_INET;
-#endif
- host = camel_gethostbyaddr ((char *) &transport->localaddr->address,
- transport->localaddr->length, af, &err);
-
- camel_exception_clear (&err);
-
- if (host && host->h_name && *host->h_name) {
- name = g_strdup (host->h_name);
- } else {
-#ifdef ENABLE_IPv6
- char ip[MAXHOSTNAMELEN + 1];
- const char *proto;
-
- proto = transport->localaddr->family == CAMEL_TCP_ADDRESS_IPv6 ? "IPv6:" : "";
- name = g_strdup_printf ("[%s%s]", proto, inet_ntop (af, transport->localaddr->address, ip, MAXHOSTNAMELEN));
-#else
- /* We *could* use inet_ntoa() here, but it's probably
- not worth it since we would have to worry about
- some systems not having inet_ntoa() */
- name = g_strdup_printf ("[%d.%d.%d.%d]",
- transport->localaddr->address[0],
- transport->localaddr->address[1],
- transport->localaddr->address[2],
- transport->localaddr->address[3]);
-#endif
- }
-
- if (host)
- camel_free_host (host);
-
- /* hiya server! how are you today? */
- if (transport->flags & CAMEL_SMTP_TRANSPORT_IS_ESMTP)
- cmdbuf = g_strdup_printf ("EHLO %s\r\n", name);
- else
- cmdbuf = g_strdup_printf ("HELO %s\r\n", name);
- g_free (name);
-
- d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
- g_free (cmdbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("HELO request timed out: %s"),
- g_strerror (errno));
- camel_operation_end (NULL);
-
- transport->connected = FALSE;
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- return FALSE;
- }
- g_free (cmdbuf);
-
- do {
- /* Check for "250" */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
- smtp_set_exception (transport, respbuf, _("HELO response error"), ex);
- camel_operation_end (NULL);
- g_free (respbuf);
-
- return FALSE;
- }
-
- token = respbuf + 4;
-
- if (transport->flags & CAMEL_SMTP_TRANSPORT_IS_ESMTP) {
- if (!strncmp (token, "8BITMIME", 8)) {
- d(fprintf (stderr, "This server supports 8bit MIME\n"));
- transport->flags |= CAMEL_SMTP_TRANSPORT_8BITMIME;
- } else if (!strncmp (token, "ENHANCEDSTATUSCODES", 19)) {
- d(fprintf (stderr, "This server supports enhanced status codes\n"));
- transport->flags |= CAMEL_SMTP_TRANSPORT_ENHANCEDSTATUSCODES;
- } else if (!strncmp (token, "STARTTLS", 8)) {
- d(fprintf (stderr, "This server supports STARTTLS\n"));
- transport->flags |= CAMEL_SMTP_TRANSPORT_STARTTLS;
- } else if (!strncmp (token, "AUTH", 4)) {
- if (!transport->authtypes || transport->flags & CAMEL_SMTP_TRANSPORT_AUTH_EQUAL) {
- /* Don't bother parsing any authtypes if we already have a list.
- * Some servers will list AUTH twice, once the standard way and
- * once the way Microsoft Outlook requires them to be:
- *
- * 250-AUTH LOGIN PLAIN DIGEST-MD5 CRAM-MD5
- * 250-AUTH=LOGIN PLAIN DIGEST-MD5 CRAM-MD5
- *
- * Since they can come in any order, parse each list that we get
- * until we parse an authtype list that does not use the AUTH=
- * format. We want to let the standard way have priority over the
- * broken way.
- **/
-
- if (token[4] == '=')
- transport->flags |= CAMEL_SMTP_TRANSPORT_AUTH_EQUAL;
- else
- transport->flags &= ~CAMEL_SMTP_TRANSPORT_AUTH_EQUAL;
-
- /* parse for supported AUTH types */
- token += 5;
-
- if (transport->authtypes) {
- g_hash_table_foreach (transport->authtypes, authtypes_free, NULL);
- g_hash_table_destroy (transport->authtypes);
- }
-
- transport->authtypes = esmtp_get_authtypes (token);
- }
- }
- }
- } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
- g_free (respbuf);
-
- camel_operation_end (NULL);
-
- return TRUE;
-}
-
-static gboolean
-smtp_auth (CamelSmtpTransport *transport, const char *mech, CamelException *ex)
-{
- char *cmdbuf, *respbuf = NULL, *challenge;
- gboolean auth_challenge = FALSE;
- CamelSasl *sasl = NULL;
-
- camel_operation_start_transient (NULL, _("SMTP Authentication"));
-
- sasl = camel_sasl_new ("smtp", mech, CAMEL_SERVICE (transport));
- if (!sasl) {
- camel_operation_end (NULL);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Error creating SASL authentication object."));
- return FALSE;
- }
-
- challenge = camel_sasl_challenge_base64 (sasl, NULL, ex);
- if (challenge) {
- auth_challenge = TRUE;
- cmdbuf = g_strdup_printf ("AUTH %s %s\r\n", mech, challenge);
- g_free (challenge);
- } else {
- cmdbuf = g_strdup_printf ("AUTH %s\r\n", mech);
- }
-
- d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
- g_free (cmdbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("AUTH request timed out: %s"),
- g_strerror (errno));
- goto lose;
- }
- g_free (cmdbuf);
-
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- while (!camel_sasl_authenticated (sasl)) {
- if (!respbuf) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("AUTH request timed out: %s"),
- g_strerror (errno));
- goto lose;
- }
-
- /* the server challenge/response should follow a 334 code */
- if (strncmp (respbuf, "334", 3)) {
- g_free (respbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("AUTH request failed."));
- goto lose;
- }
-
- if (FALSE) {
- broken_smtp_server:
- d(fprintf (stderr, "Your SMTP server's implementation of the %s SASL\n"
- "authentication mechanism is broken. Please report this to the\n"
- "appropriate vendor and suggest that they re-read rfc2554 again\n"
- "for the first time (specifically Section 4).\n",
- mech));
- }
-
- /* eat whtspc */
- for (challenge = respbuf + 4; isspace (*challenge); challenge++);
-
- challenge = camel_sasl_challenge_base64 (sasl, challenge, ex);
- g_free (respbuf);
- if (challenge == NULL)
- goto break_and_lose;
-
- /* send our challenge */
- cmdbuf = g_strdup_printf ("%s\r\n", challenge);
- g_free (challenge);
- d(fprintf (stderr, "sending : %s", cmdbuf));
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
- g_free (cmdbuf);
- goto lose;
- }
- g_free (cmdbuf);
-
- /* get the server's response */
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
- }
-
- /* check that the server says we are authenticated */
- if (!respbuf || strncmp (respbuf, "235", 3)) {
- if (respbuf && auth_challenge && !strncmp (respbuf, "334", 3)) {
- /* broken server, but lets try and work around it anyway... */
- goto broken_smtp_server;
- }
- g_free (respbuf);
- goto lose;
- }
-
- camel_object_unref (sasl);
- camel_operation_end (NULL);
-
- return TRUE;
-
- break_and_lose:
- /* Get the server out of "waiting for continuation data" mode. */
- d(fprintf (stderr, "sending : *\n"));
- camel_stream_write (transport->ostream, "*\r\n", 3);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- lose:
- if (!camel_exception_is_set (ex)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Bad authentication response from server.\n"));
- }
-
- camel_object_unref (sasl);
- camel_operation_end (NULL);
-
- return FALSE;
-}
-
-static gboolean
-smtp_mail (CamelSmtpTransport *transport, const char *sender, gboolean has_8bit_parts, CamelException *ex)
-{
- /* we gotta tell the smtp server who we are. (our email addy) */
- char *cmdbuf, *respbuf = NULL;
-
- if (transport->flags & CAMEL_SMTP_TRANSPORT_8BITMIME && has_8bit_parts)
- cmdbuf = g_strdup_printf ("MAIL FROM:<%s> BODY=8BITMIME\r\n", sender);
- else
- cmdbuf = g_strdup_printf ("MAIL FROM:<%s>\r\n", sender);
-
- d(fprintf (stderr, "sending : %s", cmdbuf));
-
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
- g_free (cmdbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("MAIL FROM request timed out: %s: mail not sent"),
- g_strerror (errno));
-
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- return FALSE;
- }
- g_free (cmdbuf);
-
- do {
- /* Check for "250 Sender OK..." */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
- smtp_set_exception (transport, respbuf, _("MAIL FROM response error"), ex);
- g_free (respbuf);
- return FALSE;
- }
- } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
- g_free (respbuf);
-
- return TRUE;
-}
-
-static gboolean
-smtp_rcpt (CamelSmtpTransport *transport, const char *recipient, CamelException *ex)
-{
- /* we gotta tell the smtp server who we are going to be sending
- * our email to */
- char *cmdbuf, *respbuf = NULL;
-
- cmdbuf = g_strdup_printf ("RCPT TO:<%s>\r\n", recipient);
-
- d(fprintf (stderr, "sending : %s", cmdbuf));
-
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
- g_free (cmdbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("RCPT TO request timed out: %s: mail not sent"),
- g_strerror (errno));
-
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- return FALSE;
- }
- g_free (cmdbuf);
-
- do {
- /* Check for "250 Recipient OK..." */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
- char *message;
-
- message = g_strdup_printf (_("RCPT TO <%s> failed"), recipient);
- smtp_set_exception (transport, respbuf, message, ex);
- g_free (message);
- g_free (respbuf);
- return FALSE;
- }
- } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
- g_free (respbuf);
-
- return TRUE;
-}
-
-static gboolean
-smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, CamelException *ex)
-{
- CamelBestencEncoding enctype = CAMEL_BESTENC_8BIT;
- struct _camel_header_raw *header, *savedbcc, *n, *tail;
- char *cmdbuf, *respbuf = NULL;
- CamelStreamFilter *filtered_stream;
- CamelMimeFilter *crlffilter;
- int ret;
-
- /* If the server doesn't support 8BITMIME, set our required encoding to be 7bit */
- if (!(transport->flags & CAMEL_SMTP_TRANSPORT_8BITMIME))
- enctype = CAMEL_BESTENC_7BIT;
-
- /* FIXME: should we get the best charset too?? */
- /* Changes the encoding of all mime parts to fit within our required
- encoding type and also force any text parts with long lines (longer
- than 998 octets) to wrap by QP or base64 encoding them. */
- camel_mime_message_set_best_encoding (message, CAMEL_BESTENC_GET_ENCODING, enctype);
-
- cmdbuf = g_strdup ("DATA\r\n");
-
- d(fprintf (stderr, "sending : %s", cmdbuf));
-
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
- g_free (cmdbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("DATA request timed out: %s: mail not sent"),
- g_strerror (errno));
-
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- return FALSE;
- }
- g_free (cmdbuf);
-
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "354", 3)) {
- /* we should have gotten instructions on how to use the DATA command:
- * 354 Enter mail, end with "." on a line by itself
- */
- smtp_set_exception (transport, respbuf, _("DATA response error"), ex);
- g_free (respbuf);
- return FALSE;
- }
-
- g_free (respbuf);
- respbuf = NULL;
-
- /* setup stream filtering */
- crlffilter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_DOTS);
- filtered_stream = camel_stream_filter_new_with_stream (transport->ostream);
- camel_stream_filter_add (filtered_stream, CAMEL_MIME_FILTER (crlffilter));
- camel_object_unref (crlffilter);
-
- /* unlink the bcc headers */
- savedbcc = NULL;
- tail = (struct _camel_header_raw *) &savedbcc;
-
- header = (struct _camel_header_raw *) &CAMEL_MIME_PART (message)->headers;
- n = header->next;
- while (n != NULL) {
- if (!strcasecmp (n->name, "Bcc")) {
- header->next = n->next;
- tail->next = n;
- n->next = NULL;
- tail = n;
- } else {
- header = n;
- }
-
- n = header->next;
- }
-
- /* write the message */
- ret = camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), CAMEL_STREAM (filtered_stream));
-
- /* restore the bcc headers */
- header->next = savedbcc;
-
- if (ret == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("DATA send timed out: message termination: "
- "%s: mail not sent"),
- g_strerror (errno));
-
- camel_object_unref (filtered_stream);
-
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- return FALSE;
- }
-
- camel_stream_flush (CAMEL_STREAM (filtered_stream));
- camel_object_unref (filtered_stream);
-
- /* terminate the message body */
-
- d(fprintf (stderr, "sending : \\r\\n.\\r\\n\n"));
-
- if (camel_stream_write (transport->ostream, "\r\n.\r\n", 5) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("DATA send timed out: message termination: "
- "%s: mail not sent"),
- g_strerror (errno));
-
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- return FALSE;
- }
-
- do {
- /* Check for "250 Sender OK..." */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
- smtp_set_exception (transport, respbuf, _("DATA termination response error"), ex);
- g_free (respbuf);
- return FALSE;
- }
- } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
- g_free (respbuf);
-
- return TRUE;
-}
-
-static gboolean
-smtp_rset (CamelSmtpTransport *transport, CamelException *ex)
-{
- /* we are going to reset the smtp server (just to be nice) */
- char *cmdbuf, *respbuf = NULL;
-
- cmdbuf = g_strdup ("RSET\r\n");
-
- d(fprintf (stderr, "sending : %s", cmdbuf));
-
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
- g_free (cmdbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("RSET request timed out: %s"),
- g_strerror (errno));
-
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- return FALSE;
- }
- g_free (cmdbuf);
-
- do {
- /* Check for "250" */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "250", 3)) {
- smtp_set_exception (transport, respbuf, _("RSET response error"), ex);
- g_free (respbuf);
- return FALSE;
- }
- } while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
- g_free (respbuf);
-
- return TRUE;
-}
-
-static gboolean
-smtp_quit (CamelSmtpTransport *transport, CamelException *ex)
-{
- /* we are going to reset the smtp server (just to be nice) */
- char *cmdbuf, *respbuf = NULL;
-
- cmdbuf = g_strdup ("QUIT\r\n");
-
- d(fprintf (stderr, "sending : %s", cmdbuf));
-
- if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
- g_free (cmdbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("QUIT request timed out: %s"),
- g_strerror (errno));
-
- camel_object_unref (transport->istream);
- transport->istream = NULL;
- camel_object_unref (transport->ostream);
- transport->ostream = NULL;
-
- return FALSE;
- }
- g_free (cmdbuf);
-
- do {
- /* Check for "221" */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "221", 3)) {
- smtp_set_exception (transport, respbuf, _("QUIT response error"), ex);
- g_free (respbuf);
- return FALSE;
- }
- } while (*(respbuf+3) == '-'); /* if we got "221-" then loop again */
- g_free (respbuf);
-
- return TRUE;
-}
diff --git a/camel/providers/smtp/camel-smtp-transport.h b/camel/providers/smtp/camel-smtp-transport.h
deleted file mode 100644
index ef15f2b07d..0000000000
--- a/camel/providers/smtp/camel-smtp-transport.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-smtp-transport.h : class for an smtp transfer */
-
-/*
- * Authors:
- * Jeffrey Stedfast <fejj@stampede.org>
- *
- * Copyright (C) 2000 Ximian, Inc. (www.ximian.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_SMTP_TRANSPORT_H
-#define CAMEL_SMTP_TRANSPORT_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-
-#include "camel-transport.h"
-#include "camel-tcp-stream.h"
-
-#define CAMEL_SMTP_TRANSPORT_TYPE (camel_smtp_transport_get_type ())
-#define CAMEL_SMTP_TRANSPORT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SMTP_TRANSPORT_TYPE, CamelSmtpTransport))
-#define CAMEL_SMTP_TRANSPORT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SMTP_TRANSPORT_TYPE, CamelSmtpTransportClass))
-#define CAMEL_IS_SMTP_TRANSPORT(o) (CAMEL_CHECK_TYPE((o), CAMEL_SMTP_TRANSPORT_TYPE))
-
-
-#define CAMEL_SMTP_TRANSPORT_IS_ESMTP (1 << 0)
-#define CAMEL_SMTP_TRANSPORT_8BITMIME (1 << 1)
-#define CAMEL_SMTP_TRANSPORT_ENHANCEDSTATUSCODES (1 << 2)
-#define CAMEL_SMTP_TRANSPORT_STARTTLS (1 << 3)
-
-#define CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS (1 << 4)
-#define CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE (1 << 5)
-
-#define CAMEL_SMTP_TRANSPORT_USE_SSL (CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS | \
- CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE)
-
-#define CAMEL_SMTP_TRANSPORT_AUTH_EQUAL (1 << 6) /* set if we are using authtypes from a broken AUTH= */
-
-typedef struct {
- CamelTransport parent_object;
-
- CamelStream *istream, *ostream;
-
- guint32 flags;
-
- gboolean connected;
- CamelTcpAddress *localaddr;
-
- GHashTable *authtypes;
-
-} CamelSmtpTransport;
-
-
-
-typedef struct {
- CamelTransportClass parent_class;
-
-} CamelSmtpTransportClass;
-
-
-/* Standard Camel function */
-CamelType camel_smtp_transport_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_SMTP_TRANSPORT_H */
-
-
diff --git a/camel/providers/smtp/libcamelsmtp.urls b/camel/providers/smtp/libcamelsmtp.urls
deleted file mode 100644
index ec2fc0fc16..0000000000
--- a/camel/providers/smtp/libcamelsmtp.urls
+++ /dev/null
@@ -1 +0,0 @@
-smtp