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.am18
-rw-r--r--camel/providers/groupwise/.cvsignore2
-rw-r--r--camel/providers/groupwise/Makefile.am28
-rw-r--r--camel/providers/groupwise/camel-groupwise-provider.c207
-rw-r--r--camel/providers/groupwise/camel-gw-listener.c921
-rw-r--r--camel/providers/groupwise/camel-gw-listener.h63
-rw-r--r--camel/providers/groupwise/libcamelgroupwise.urls1
-rw-r--r--camel/providers/imap/.cvsignore11
-rw-r--r--camel/providers/imap/Makefile.am44
-rw-r--r--camel/providers/imap/camel-imap-command.c819
-rw-r--r--camel/providers/imap/camel-imap-command.h80
-rw-r--r--camel/providers/imap/camel-imap-folder.c2812
-rw-r--r--camel/providers/imap/camel-imap-folder.h92
-rw-r--r--camel/providers/imap/camel-imap-message-cache.c528
-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.c164
-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.c3229
-rw-r--r--camel/providers/imap/camel-imap-store.h149
-rw-r--r--camel/providers/imap/camel-imap-summary.c276
-rw-r--r--camel/providers/imap/camel-imap-summary.h80
-rw-r--r--camel/providers/imap/camel-imap-types.h39
-rw-r--r--camel/providers/imap/camel-imap-utils.c1429
-rw-r--r--camel/providers/imap/camel-imap-utils.h100
-rw-r--r--camel/providers/imap/camel-imap-wrapper.c187
-rw-r--r--camel/providers/imap/camel-imap-wrapper.h71
-rw-r--r--camel/providers/imap/libcamelimap.urls1
-rw-r--r--camel/providers/imap4/.cvsignore7
-rw-r--r--camel/providers/imap4/Makefile.am42
-rw-r--r--camel/providers/imap4/camel-imap4-command.c706
-rw-r--r--camel/providers/imap4/camel-imap4-command.h144
-rw-r--r--camel/providers/imap4/camel-imap4-engine.c1698
-rw-r--r--camel/providers/imap4/camel-imap4-engine.h234
-rw-r--r--camel/providers/imap4/camel-imap4-folder.c1178
-rw-r--r--camel/providers/imap4/camel-imap4-folder.h81
-rw-r--r--camel/providers/imap4/camel-imap4-provider.c151
-rw-r--r--camel/providers/imap4/camel-imap4-search.c314
-rw-r--r--camel/providers/imap4/camel-imap4-search.h64
-rw-r--r--camel/providers/imap4/camel-imap4-specials.c100
-rw-r--r--camel/providers/imap4/camel-imap4-specials.h53
-rw-r--r--camel/providers/imap4/camel-imap4-store-summary.c402
-rw-r--r--camel/providers/imap4/camel-imap4-store-summary.h92
-rw-r--r--camel/providers/imap4/camel-imap4-store.c1448
-rw-r--r--camel/providers/imap4/camel-imap4-store.h63
-rw-r--r--camel/providers/imap4/camel-imap4-stream.c725
-rw-r--r--camel/providers/imap4/camel-imap4-stream.h125
-rw-r--r--camel/providers/imap4/camel-imap4-summary.c1319
-rw-r--r--camel/providers/imap4/camel-imap4-summary.h91
-rw-r--r--camel/providers/imap4/camel-imap4-utils.c749
-rw-r--r--camel/providers/imap4/camel-imap4-utils.h107
-rw-r--r--camel/providers/imap4/libcamelimap4.urls1
-rw-r--r--camel/providers/imapp/.cvsignore11
-rw-r--r--camel/providers/imapp/ChangeLog22
-rw-r--r--camel/providers/imapp/Makefile.am40
-rw-r--r--camel/providers/imapp/camel-imapp-driver.c953
-rw-r--r--camel/providers/imapp/camel-imapp-driver.h100
-rw-r--r--camel/providers/imapp/camel-imapp-engine.c1154
-rw-r--r--camel/providers/imapp/camel-imapp-engine.h156
-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.c271
-rw-r--r--camel/providers/imapp/camel-imapp-folder.h66
-rw-r--r--camel/providers/imapp/camel-imapp-provider.c100
-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.c1018
-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.c184
-rw-r--r--camel/providers/imapp/camel-imapp-summary.h66
-rw-r--r--camel/providers/imapp/camel-imapp-utils.c1342
-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.am54
-rw-r--r--camel/providers/local/camel-local-folder.c631
-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.c234
-rw-r--r--camel/providers/local/camel-local-store.c477
-rw-r--r--camel/providers/local/camel-local-store.h68
-rw-r--r--camel/providers/local/camel-local-summary.c652
-rw-r--r--camel/providers/local/camel-local-summary.h96
-rw-r--r--camel/providers/local/camel-maildir-folder.c279
-rw-r--r--camel/providers/local/camel-maildir-folder.h58
-rw-r--r--camel/providers/local/camel-maildir-store.c449
-rw-r--r--camel/providers/local/camel-maildir-store.h55
-rw-r--r--camel/providers/local/camel-maildir-summary.c815
-rw-r--r--camel/providers/local/camel-maildir-summary.h76
-rw-r--r--camel/providers/local/camel-mbox-folder.c482
-rw-r--r--camel/providers/local/camel-mbox-folder.h66
-rw-r--r--camel/providers/local/camel-mbox-store.c838
-rw-r--r--camel/providers/local/camel-mbox-store.h58
-rw-r--r--camel/providers/local/camel-mbox-summary.c1109
-rw-r--r--camel/providers/local/camel-mbox-summary.h76
-rw-r--r--camel/providers/local/camel-mh-folder.c234
-rw-r--r--camel/providers/local/camel-mh-folder.h58
-rw-r--r--camel/providers/local/camel-mh-store.c579
-rw-r--r--camel/providers/local/camel-mh-store.h60
-rw-r--r--camel/providers/local/camel-mh-summary.c423
-rw-r--r--camel/providers/local/camel-mh-summary.h53
-rw-r--r--camel/providers/local/camel-spool-folder.c217
-rw-r--r--camel/providers/local/camel-spool-folder.h64
-rw-r--r--camel/providers/local/camel-spool-store.c466
-rw-r--r--camel/providers/local/camel-spool-store.h69
-rw-r--r--camel/providers/local/camel-spool-summary.c347
-rw-r--r--camel/providers/local/camel-spool-summary.h69
-rw-r--r--camel/providers/local/libcamellocal.urls4
-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.c533
-rw-r--r--camel/providers/nntp/camel-nntp-folder.h75
-rw-r--r--camel/providers/nntp/camel-nntp-grouplist.c218
-rw-r--r--camel/providers/nntp/camel-nntp-grouplist.h51
-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.c138
-rw-r--r--camel/providers/nntp/camel-nntp-resp-codes.h55
-rw-r--r--camel/providers/nntp/camel-nntp-store-summary.c438
-rw-r--r--camel/providers/nntp/camel-nntp-store-summary.h102
-rw-r--r--camel/providers/nntp/camel-nntp-store.c1391
-rw-r--r--camel/providers/nntp/camel-nntp-store.h114
-rw-r--r--camel/providers/nntp/camel-nntp-stream.c464
-rw-r--r--camel/providers/nntp/camel-nntp-stream.h66
-rw-r--r--camel/providers/nntp/camel-nntp-summary.c507
-rw-r--r--camel/providers/nntp/camel-nntp-summary.h56
-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.am31
-rw-r--r--camel/providers/pop3/camel-pop3-engine.c412
-rw-r--r--camel/providers/pop3/camel-pop3-engine.h134
-rw-r--r--camel/providers/pop3/camel-pop3-folder.c568
-rw-r--r--camel/providers/pop3/camel-pop3-folder.h77
-rw-r--r--camel/providers/pop3/camel-pop3-provider.c109
-rw-r--r--camel/providers/pop3/camel-pop3-store.c646
-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.am26
-rw-r--r--camel/providers/sendmail/camel-sendmail-provider.c63
-rw-r--r--camel/providers/sendmail/camel-sendmail-transport.c263
-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.am25
-rw-r--r--camel/providers/smtp/camel-smtp-provider.c65
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c1397
-rw-r--r--camel/providers/smtp/camel-smtp-transport.h74
-rw-r--r--camel/providers/smtp/libcamelsmtp.urls1
165 files changed, 0 insertions, 49775 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 0444da4382..0000000000
--- a/camel/providers/Makefile.am
+++ /dev/null
@@ -1,18 +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
-
-if ENABLE_IMAP4
-IMAP4_DIR=imap4
-endif
-
-SUBDIRS = pop3 sendmail smtp imap $(NNTP_DIR) local $(IMAPP_DIR) $(IMAP4_DIR)
-# groupwise
-
-
diff --git a/camel/providers/groupwise/.cvsignore b/camel/providers/groupwise/.cvsignore
deleted file mode 100644
index 282522db03..0000000000
--- a/camel/providers/groupwise/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
diff --git a/camel/providers/groupwise/Makefile.am b/camel/providers/groupwise/Makefile.am
deleted file mode 100644
index b15259532c..0000000000
--- a/camel/providers/groupwise/Makefile.am
+++ /dev/null
@@ -1,28 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelimapincludedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamelgroupwise.la
-camel_provider_DATA = libcamelgroupwise.urls
-
-INCLUDES = \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/servers/groupwise \
- -I$(top_srcdir) \
- -I$(top_srcdir)/camel/providers/imap \
- -I$(top_srcdir)/camel/providers/smtp \
- $(CAMEL_GROUPWISE_CFLAGS) \
- -DCAMEL_PROVIDERDIR=\"$(camel_providerdir)\" \
- -DG_LOG_DOMAIN=\"camel-groupwise-provider\"
-
-libcamelgroupwise_la_SOURCES = \
- camel-groupwise-provider.c \
- camel-gw-listener.c \
- camel-gw-listener.h
-libcamelgroupwise_la_LIBADD = $(CAMEL_GROUPWISE_LIBS)
-
-libcamelgroupwise_la_LDFLAGS = -avoid-version -module
-
-EXTRA_DIST = libcamelgroupwise.urls
-
diff --git a/camel/providers/groupwise/camel-groupwise-provider.c b/camel/providers/groupwise/camel-groupwise-provider.c
deleted file mode 100644
index 1162347c42..0000000000
--- a/camel/providers/groupwise/camel-groupwise-provider.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-groupwise-provider.c: Groupwise provider registration code */
-
-/*
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- * Sivaiah Nallagatla <snallagatla@novell.com>
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright 2003 Novell, Inc. (www.novell.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 <gmodule.h>
-#include "camel-imap-store.h"
-#include "camel-provider.h"
-#include "camel-session.h"
-#include "camel-smtp-transport.h"
-#include "camel-url.h"
-#include "camel-sasl.h"
-#include "camel-gw-listener.h"
-#include "camel-i18n.h"
-
-static void add_hash (guint *hash, char *s);
-static guint groupwise_url_hash (gconstpointer key);
-static gint check_equal (char *s1, char *s2);
-static gint groupwise_url_equal (gconstpointer a, gconstpointer b);
-static void free_groupwise_listener ( void );
-
-static CamelGwListener *config_listener = NULL;
-
-CamelProviderConfEntry groupwise_conf_entries[] = {
- /* override the labels/defaults of the standard settings */
-
- { 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, "general", NULL, N_("Options") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL,
- N_("Apply filters to new messages in Inbox on this server"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter_junk", NULL,
- N_("Check new messages for Junk contents"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter_junk_inbox", "filter_junk",
- N_("Only check for Junk messages in the INBOX folder"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "offline_sync", NULL,
- N_("Automatically synchronize account locally"), "0" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
-
- /* extra Groupwise configuration settings */
- {CAMEL_PROVIDER_CONF_SECTION_START, "soapport", NULL,
- N_("Address Book and Calendar") },
-
- { CAMEL_PROVIDER_CONF_ENTRY , "poa", NULL,
- N_("Post Office Agent:"), NULL },
-
- { CAMEL_PROVIDER_CONF_ENTRY, "soap_port", NULL,
- N_("Post Office Agent SOAP Port:"), "7181" },
-
- { CAMEL_PROVIDER_CONF_CHECKBOX, "soap_ssl", NULL,
- N_("Use Secure Connection (SSL)"), "0"},
-
- { CAMEL_PROVIDER_CONF_HIDDEN, "auth-domain", NULL,
- NULL, "Groupwise" },
-
- { CAMEL_PROVIDER_CONF_SECTION_END },
-
- { CAMEL_PROVIDER_CONF_END }
-};
-
-
-static CamelProvider groupwise_provider = {
- "groupwise",
- N_("Novell GroupWise"),
-
- N_("For accessing Novell Groupwise 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,
-
- groupwise_conf_entries,
-
- /* ... */
-};
-
-CamelServiceAuthType camel_groupwise_password_authtype = {
- N_("Password"),
-
- N_("This option will connect to the IMAP server using a "
- "plaintext password."),
-
- "",
- TRUE
-};
-
-static int
-groupwise_auto_detect_cb (CamelURL *url, GHashTable **auto_detected,
- CamelException *ex)
-{
- *auto_detected = g_hash_table_new (g_str_hash, g_str_equal);
-
- g_hash_table_insert (*auto_detected, g_strdup ("poa"),
- g_strdup (url->host));
-
- return 0;
-}
-
-void
-camel_provider_module_init(void)
-{
- CamelProvider *imap_provider;
- CamelException ex = CAMEL_EXCEPTION_INITIALISER;
-
- imap_provider = camel_provider_get("imap://", &ex);
- groupwise_provider.url_hash = groupwise_url_hash;
- groupwise_provider.url_equal = groupwise_url_equal;
- groupwise_provider.auto_detect = groupwise_auto_detect_cb;
- groupwise_provider.authtypes = g_list_prepend (groupwise_provider.authtypes, &camel_groupwise_password_authtype);
- if (imap_provider != NULL) {
- groupwise_provider.object_types[CAMEL_PROVIDER_STORE] = imap_provider->object_types [CAMEL_PROVIDER_STORE];
- camel_provider_register(&groupwise_provider);
- } else {
- camel_exception_clear(&ex);
- }
-
- if (!config_listener) {
- config_listener = camel_gw_listener_new ();
- g_atexit ( free_groupwise_listener );
- }
-}
-
-void free_groupwise_listener ( void )
-{
- g_object_unref (config_listener);
-}
-
-static void
-add_hash (guint *hash, char *s)
-{
- if (s)
- *hash ^= g_str_hash(s);
-}
-
-static guint
-groupwise_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
-groupwise_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/groupwise/camel-gw-listener.c b/camel/providers/groupwise/camel-gw-listener.c
deleted file mode 100644
index 1f6eaf6267..0000000000
--- a/camel/providers/groupwise/camel-gw-listener.c
+++ /dev/null
@@ -1,921 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- *
- * Sivaiah Nallagatla <snallagatla@novell.com>
- *
- * Copyright 2003, Novell, 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 "camel-gw-listener.h"
-#include <string.h>
-#include "camel-i18n.h"
-#include <e-gw-connection.h>
-#include <e-passwords.h>
-#include "widgets/misc/e-error.h"
-
-/*stores some info about all currently existing groupwise accounts
- list of GwAccountInfo structures */
-
-static GList *groupwise_accounts = NULL;
-
-struct _CamelGwListenerPrivate {
- GConfClient *gconf_client;
- /* we get notification about mail account changes form this object */
- EAccountList *account_list;
-};
-
-struct _GwAccountInfo {
- char *uid;
- char *name;
- char *source_url;
-};
-
-typedef struct _GwAccountInfo GwAccountInfo;
-
-#define GROUPWISE_URI_PREFIX "groupwise://"
-#define GROUPWISE_PREFIX_LENGTH 12
-
-#define PARENT_TYPE G_TYPE_OBJECT
-
-static GObjectClass *parent_class = NULL;
-
-static void dispose (GObject *object);
-static void finalize (GObject *object);
-
-
-static void
-camel_gw_listener_class_init (CamelGwListenerClass *class)
-{
- GObjectClass *object_class;
-
- parent_class = g_type_class_ref (PARENT_TYPE);
- object_class = G_OBJECT_CLASS (class);
-
- /* virtual method override */
- object_class->dispose = dispose;
- object_class->finalize = finalize;
-}
-
-static void
-camel_gw_listener_init (CamelGwListener *config_listener, CamelGwListenerClass *class)
-{
- config_listener->priv = g_new0 (CamelGwListenerPrivate, 1);
-}
-
-static void
-dispose (GObject *object)
-{
- CamelGwListener *config_listener = CAMEL_GW_LISTENER (object);
-
- g_object_unref (config_listener->priv->gconf_client);
- g_object_unref (config_listener->priv->account_list);
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
- CamelGwListener *config_listener = CAMEL_GW_LISTENER (object);
- GList *list;
- GwAccountInfo *info;
-
- if (config_listener->priv) {
- g_free (config_listener->priv);
- }
-
- for ( list = g_list_first (groupwise_accounts); list ; list = g_list_next (list) ) {
-
- info = (GwAccountInfo *) (list->data);
-
- if (info) {
-
- g_free (info->uid);
- g_free (info->name);
- g_free (info->source_url);
- g_free (info);
- }
- }
-
- g_list_free (groupwise_accounts);
-}
-
-/*determines whehter the passed in account is groupwise or not by looking at source url */
-
-static gboolean
-is_groupwise_account (EAccount *account)
-{
- if (account->source->url != NULL) {
- return (strncmp (account->source->url, GROUPWISE_URI_PREFIX, GROUPWISE_PREFIX_LENGTH ) == 0);
- } else {
- return FALSE;
- }
-}
-
-/* looks up for an existing groupwise account info in the groupwise_accounts list based on uid */
-
-static GwAccountInfo*
-lookup_account_info (const char *key)
-{
- GList *list;
- GwAccountInfo *info ;
- int found = 0;
-
- if (!key)
- return NULL;
-
- info = NULL;
-
- for (list = g_list_first (groupwise_accounts); list; list = g_list_next (list)) {
- info = (GwAccountInfo *) (list->data);
- found = (strcmp (info->uid, key) == 0);
- if (found)
- break;
- }
- if (found)
- return info;
- return NULL;
-}
-
-#define CALENDAR_SOURCES "/apps/evolution/calendar/sources"
-#define TASKS_SOURCES "/apps/evolution/tasks/sources"
-#define SELECTED_CALENDARS "/apps/evolution/calendar/display/selected_calendars"
-#define SELECTED_TASKS "/apps/evolution/calendar/tasks/selected_tasks"
-
-static void
-add_esource (const char *conf_key, const char *group_name, const char *source_name, CamelURL *url)
-{
- ESourceList *source_list;
- ESourceGroup *group;
- ESource *source;
- GConfClient* client;
- GSList *ids, *temp ;
- char *source_selection_key;
- char *relative_uri;
- const char *soap_port;
- const char * use_ssl;
- const char *poa_address;
- const char *offline_sync;
-
-
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
- soap_port = camel_url_get_param (url, "soap_port");
-
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
-
- use_ssl = camel_url_get_param (url, "soap_ssl");
- if (use_ssl)
- use_ssl = "always";
- else
- use_ssl = NULL;
-
- offline_sync = camel_url_get_param (url, "offline_sync");
-
- client = gconf_client_get_default();
- source_list = e_source_list_new_for_gconf (client, conf_key);
-
- group = e_source_group_new (group_name, GROUPWISE_URI_PREFIX);
- if (!e_source_list_add_group (source_list, group, -1))
- return;
- relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
-
- source = e_source_new (source_name, relative_uri);
- e_source_set_property (source, "auth", "1");
- e_source_set_property (source, "username", url->user);
- e_source_set_property (source, "port", camel_url_get_param (url, "soap_port"));
- e_source_set_property (source, "auth-domain", "Groupwise");
- e_source_set_property (source, "use_ssl", camel_url_get_param (url, "use_ssl"));
- e_source_set_property (source, "offline_sync", offline_sync);
- // e_source_set_property (source, "offline_sync", );
- e_source_group_add_source (group, source, -1);
- e_source_list_sync (source_list, NULL);
-
- if (!strcmp (conf_key, CALENDAR_SOURCES))
- source_selection_key = SELECTED_CALENDARS;
- else if (!strcmp (conf_key, TASKS_SOURCES))
- source_selection_key = SELECTED_TASKS;
- else source_selection_key = NULL;
- if (source_selection_key) {
- ids = gconf_client_get_list (client, source_selection_key , GCONF_VALUE_STRING, NULL);
- ids = g_slist_append (ids, g_strdup (e_source_peek_uid (source)));
- gconf_client_set_list (client, source_selection_key, GCONF_VALUE_STRING, ids, NULL);
- temp = ids;
- for (; temp != NULL; temp = g_slist_next (temp))
- g_free (temp->data);
- g_slist_free (ids);
- }
-
- g_object_unref (source);
- g_object_unref (group);
- g_object_unref (source_list);
- g_object_unref (client);
- g_free (relative_uri);
-}
-
-
-static void
-remove_esource (const char *conf_key, const char *group_name, char* source_name, const char* relative_uri)
-{
- ESourceList *list;
- ESourceGroup *group;
- ESource *source;
- GSList *groups;
- GSList *sources;
- gboolean found_group;
- GConfClient* client;
- GSList *ids;
- GSList *node_tobe_deleted;
- char *source_selection_key;
-
- client = gconf_client_get_default();
- list = e_source_list_new_for_gconf (client, conf_key);
- groups = e_source_list_peek_groups (list);
-
- found_group = FALSE;
-
- for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) {
-
- group = E_SOURCE_GROUP (groups->data);
-
- if (strcmp (e_source_group_peek_name (group), group_name) == 0 &&
- strcmp (e_source_group_peek_base_uri (group), GROUPWISE_URI_PREFIX ) == 0) {
-
- sources = e_source_group_peek_sources (group);
-
- for( ; sources != NULL; sources = g_slist_next (sources)) {
-
- source = E_SOURCE (sources->data);
-
- if (strcmp (e_source_peek_relative_uri (source), relative_uri) == 0) {
-
- if (!strcmp (conf_key, CALENDAR_SOURCES))
- source_selection_key = SELECTED_CALENDARS;
- else if (!strcmp (conf_key, TASKS_SOURCES))
- source_selection_key = SELECTED_TASKS;
- else source_selection_key = NULL;
- if (source_selection_key) {
- ids = gconf_client_get_list (client, source_selection_key ,
- GCONF_VALUE_STRING, NULL);
- node_tobe_deleted = g_slist_find_custom (ids, e_source_peek_uid (source), (GCompareFunc) strcmp);
- if (node_tobe_deleted) {
- g_free (node_tobe_deleted->data);
- ids = g_slist_delete_link (ids, node_tobe_deleted);
- }
- gconf_client_set_list (client, source_selection_key,
- GCONF_VALUE_STRING, ids, NULL);
-
- }
- e_source_list_remove_group (list, group);
- e_source_list_sync (list, NULL);
- found_group = TRUE;
- break;
-
- }
- }
-
- }
-
-
- }
-
- g_object_unref (list);
- g_object_unref (client);
-
-}
-
-/* looks up for e-source with having same info as old_account_info and changes its values passed in new values */
-
-static void
-modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const char* new_group_name, CamelURL *new_url)
-{
- ESourceList *list;
- ESourceGroup *group;
- ESource *source;
- GSList *groups;
- GSList *sources;
- char *old_relative_uri;
- CamelURL *url;
- gboolean found_group;
- GConfClient* client;
- const char *poa_address;
- char *new_relative_uri;
- const char *new_poa_address;
-
- url = camel_url_new (old_account_info->source_url, NULL);
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
- new_poa_address = camel_url_get_param (new_url, "poa");
-
- old_relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
- client = gconf_client_get_default ();
- list = e_source_list_new_for_gconf (client, conf_key);
- groups = e_source_list_peek_groups (list);
-
- found_group = FALSE;
-
- for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) {
-
- group = E_SOURCE_GROUP (groups->data);
-
- if (strcmp (e_source_group_peek_name (group), old_account_info->name) == 0 &&
- strcmp (e_source_group_peek_base_uri (group), GROUPWISE_URI_PREFIX) == 0) {
-
- sources = e_source_group_peek_sources (group);
-
- for ( ; sources != NULL; sources = g_slist_next (sources)) {
-
- source = E_SOURCE (sources->data);
-
- if (strcmp (e_source_peek_relative_uri (source), old_relative_uri) == 0) {
-
- new_relative_uri = g_strdup_printf ("%s@%s/", new_url->user, new_poa_address);
- e_source_group_set_name (group, new_group_name);
- e_source_set_relative_uri (source, new_relative_uri);
- e_source_set_property (source, "username", new_url->user);
- e_source_set_property (source, "port", camel_url_get_param (new_url,"soap_port"));
- e_source_set_property (source, "use_ssl", camel_url_get_param (url, "soap_ssl"));
- e_source_set_property (source, "offline_sync", camel_url_get_param (url, "offline_sync"));
- e_source_list_sync (list, NULL);
- found_group = TRUE;
- g_free (new_relative_uri);
- break;
- }
- }
- }
- }
-
- g_object_unref (list);
- g_object_unref (client);
- camel_url_free (url);
- g_free (old_relative_uri);
-
-
-}
-/* add sources for calendar and tasks if the account added is groupwise account
- adds the new account info to groupwise_accounts list */
-
-static void
-add_calendar_tasks_sources (GwAccountInfo *info)
-{
- CamelURL *url;
- char *relative_uri;
- const char *soap_port;
- const char * use_ssl;
- const char *poa_address;
-
- url = camel_url_new (info->source_url, NULL);
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
- soap_port = camel_url_get_param (url, "soap_port");
-
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
-
- use_ssl = camel_url_get_param (url, "soap_ssl");
- if (use_ssl)
- use_ssl = "always";
- else
- use_ssl = NULL;
-
- relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
- add_esource ("/apps/evolution/calendar/sources", info->name, _("Calendar"), url);
- add_esource ("/apps/evolution/tasks/sources", info->name, _("Tasks"), url);
-
- camel_url_free (url);
- g_free (relative_uri);
-
-}
-
-/* removes calendar and tasks sources if the account removed is groupwise account
- removes the the account info from groupwise_account list */
-
-static void
-remove_calendar_tasks_sources (GwAccountInfo *info)
-{
- CamelURL *url;
- char *relative_uri;
- const char *soap_port;
- const char *poa_address;
-
- url = camel_url_new (info->source_url, NULL);
-
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
-
- soap_port = camel_url_get_param (url, "soap_port");
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
-
- relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
- remove_esource ("/apps/evolution/calendar/sources", info->name, _("Calendar"), relative_uri);
- remove_esource ("/apps/evolution/tasks/sources", info->name, _("Checklist"), relative_uri);
- camel_url_free (url);
- g_free (relative_uri);
-
-}
-
-static GList*
-get_addressbook_names_from_server (char *source_url)
-{
- char *key;
- EGwConnection *cnc;
- char *password;
- GList *book_list;
- int status;
- const char *soap_port;
- CamelURL *url;
- gboolean remember;
- char *failed_auth;
- char *prompt;
- char *uri;
- const char *use_ssl;
- const char *poa_address;
- guint32 flags = E_PASSWORDS_REMEMBER_FOREVER;
-
- url = camel_url_new (source_url, NULL);
- if (url == NULL) {
- return NULL;
- }
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return NULL;
-
- soap_port = camel_url_get_param (url, "soap_port");
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
- use_ssl = camel_url_get_param (url, "soap_ssl");
- if(use_ssl)
- use_ssl = "always";
- key = g_strdup_printf ("groupwise://%s@%s/", url->user, poa_address);
- if (use_ssl)
- uri = g_strdup_printf ("https://%s:%s/soap", poa_address, soap_port);
- else
- uri = g_strdup_printf ("http://%s:%s/soap", poa_address, soap_port);
-
- failed_auth = "";
- cnc = NULL;
- do {
- prompt = g_strdup_printf (_("%sEnter password for %s (user %s)"),
- failed_auth, poa_address, url->user);
-
- password = e_passwords_ask_password (prompt, "Groupwise", key, prompt,
- E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET, &remember,
- NULL);
- g_free (prompt);
-
- if (!password)
- break;
- cnc = e_gw_connection_new (uri, url->user, password);
- failed_auth = _("Failed to authenticate.\n");
- flags |= E_PASSWORDS_REPROMPT;
- } while (cnc == NULL);
-
- if (E_IS_GW_CONNECTION(cnc)) {
- book_list = NULL;
- status = e_gw_connection_get_address_book_list (cnc, &book_list);
- if (status == E_GW_CONNECTION_STATUS_OK)
- return book_list;
-
-
- }
- e_error_run (NULL, "mail:gw-accountsetup-error", poa_address, NULL);
- return NULL;
-}
-
-
-static gboolean
-add_addressbook_sources (EAccount *account)
-{
- CamelURL *url;
- ESourceList *list;
- ESourceGroup *group;
- ESource *source;
- char *base_uri;
- const char *soap_port;
- GList *books_list, *temp_list;
- GConfClient* client;
- const char* use_ssl;
- const char *poa_address;
-
-
- url = camel_url_new (account->source->url, NULL);
- if (url == NULL) {
- return FALSE;
- }
-
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return FALSE;
-
- soap_port = camel_url_get_param (url, "soap_port");
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
- use_ssl = camel_url_get_param (url, "soap_ssl");
- base_uri = g_strdup_printf ("groupwise://%s@%s", url->user, poa_address);
- client = gconf_client_get_default ();
- list = e_source_list_new_for_gconf (client, "/apps/evolution/addressbook/sources" );
- group = e_source_group_new (account->name, base_uri);
- books_list = get_addressbook_names_from_server (account->source->url);
- temp_list = books_list;
- if (!temp_list)
- return FALSE;
- for (; temp_list != NULL; temp_list = g_list_next (temp_list)) {
- const char *book_name = e_gw_container_get_name (E_GW_CONTAINER(temp_list->data));
- source = e_source_new (book_name, g_strconcat (";",book_name, NULL));
- e_source_set_property (source, "auth", "plain/password");
- e_source_set_property (source, "auth-domain", "Groupwise");
- e_source_set_property (source, "port", soap_port);
- e_source_set_property(source, "user", url->user);
- e_source_set_property (source, "offline_sync", camel_url_get_param (url, "offline_sync"));
- if (!e_gw_container_get_is_writable (E_GW_CONTAINER(temp_list->data)))
- e_source_set_property (source, "completion", "true");
- if (e_gw_container_get_is_frequent_contacts (E_GW_CONTAINER(temp_list->data)))
- e_source_set_property (source, "completion", "true");
- e_source_set_property (source, "use_ssl", use_ssl);
- e_source_group_add_source (group, source, -1);
- g_object_unref (source);
- g_object_unref (E_GW_CONTAINER(temp_list->data));
-
- }
-
- g_list_free (books_list);
-
-
- e_source_list_add_group (list, group, -1);
- e_source_list_sync (list, NULL);
- g_object_unref (group);
- g_object_unref (list);
- g_object_unref (client);
- g_free (base_uri);
-
- return TRUE;
-}
-
-static void
-modify_addressbook_sources ( EAccount *account, GwAccountInfo *existing_account_info )
-{
- CamelURL *url;
- ESourceList *list;
- ESourceGroup *group;
- GSList *groups;
- gboolean found_group;
- gboolean delete_group;
- char *old_base_uri;
- char *new_base_uri;
- const char *soap_port;
- const char *use_ssl;
- GSList *sources;
- ESource *source;
- GConfClient *client;
- const char *poa_address;
-
-
- url = camel_url_new (existing_account_info->source_url, NULL);
- if (url == NULL) {
- return;
- }
-
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
-
- old_base_uri = g_strdup_printf ("groupwise://%s@%s", url->user, poa_address);
- camel_url_free (url);
-
- url = camel_url_new (account->source->url, NULL);
- if (url == NULL)
- return ;
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
- new_base_uri = g_strdup_printf ("groupwise://%s@%s", url->user, poa_address);
- soap_port = camel_url_get_param (url, "soap_port");
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
- use_ssl = camel_url_get_param (url, "soap_ssl");
-
- client = gconf_client_get_default ();
- list = e_source_list_new_for_gconf (client, "/apps/evolution/addressbook/sources" );
- groups = e_source_list_peek_groups (list);
- delete_group = FALSE;
- if (strcmp (old_base_uri, new_base_uri) != 0)
- delete_group = TRUE;
- group = NULL;
- found_group = FALSE;
- for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) {
-
- group = E_SOURCE_GROUP (groups->data);
- if ( strcmp ( e_source_group_peek_base_uri(group), old_base_uri) == 0 && strcmp (e_source_group_peek_name (group), existing_account_info->name) == 0) {
- found_group = TRUE;
- if (!delete_group) {
- e_source_group_set_name (group, account->name);
- sources = e_source_group_peek_sources (group);
- for (; sources != NULL; sources = g_slist_next (sources)) {
- source = E_SOURCE (sources->data);
- e_source_set_property (source, "port", soap_port);
- e_source_set_property (source, "use_ssl", use_ssl);
- }
-
- e_source_list_sync (list, NULL);
- }
-
- }
- }
- if (found_group && delete_group) {
- e_source_list_remove_group (list, group);
- e_source_list_sync (list, NULL);
- g_object_unref (list);
- list = NULL;
- add_addressbook_sources (account);
- }
- g_free (old_base_uri);
- if (list)
- g_object_unref (list);
- camel_url_free (url);
- g_object_unref (client);
-
-
-}
-
-static void
-remove_addressbook_sources (GwAccountInfo *existing_account_info)
-{
- ESourceList *list;
- ESourceGroup *group;
- GSList *groups;
- gboolean found_group;
- CamelURL *url;
- char *base_uri;
- const char *soap_port;
- GConfClient *client;
- const char *poa_address;
-
- url = camel_url_new (existing_account_info->source_url, NULL);
- if (url == NULL) {
- return;
- }
-
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
-
- soap_port = camel_url_get_param (url, "soap_port");
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
- base_uri = g_strdup_printf ("groupwise://%s@%s", url->user, poa_address);
- client = gconf_client_get_default ();
- list = e_source_list_new_for_gconf (client, "/apps/evolution/addressbook/sources" );
- groups = e_source_list_peek_groups (list);
-
- found_group = FALSE;
-
- for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) {
-
- group = E_SOURCE_GROUP (groups->data);
- if ( strcmp ( e_source_group_peek_base_uri (group), base_uri) == 0 && strcmp (e_source_group_peek_name (group), existing_account_info->name) == 0) {
-
- e_source_list_remove_group (list, group);
- e_source_list_sync (list, NULL);
- found_group = TRUE;
-
- }
- }
- g_object_unref (list);
- g_object_unref (client);
- g_free (base_uri);
- camel_url_free (url);
-
-
-}
-
-
-
-static void
-account_added (EAccountList *account_listener, EAccount *account)
-{
-
- GwAccountInfo *info;
- gboolean status;
-
- if (!is_groupwise_account (account))
- return;
-
- info = g_new0 (GwAccountInfo, 1);
- info->uid = g_strdup (account->uid);
- info->name = g_strdup (account->name);
- info->source_url = g_strdup (account->source->url);
- status = add_addressbook_sources (account);
- if (status)
- add_calendar_tasks_sources (info);
- groupwise_accounts = g_list_append (groupwise_accounts, info);
-
-}
-
-static void
-account_removed (EAccountList *account_listener, EAccount *account)
-{
- GwAccountInfo *info;
-
- if (!is_groupwise_account (account))
- return;
-
- info = lookup_account_info (account->uid);
- if (info == NULL) {
- return;
- }
-
- remove_calendar_tasks_sources (info);
- remove_addressbook_sources (info);
- groupwise_accounts = g_list_remove (groupwise_accounts, info);
- g_free (info->uid);
- g_free (info->name);
- g_free (info->source_url);
- g_free (info);
-
-
-}
-
-
-static void
-account_changed (EAccountList *account_listener, EAccount *account)
-{
- gboolean is_gw_account;
- CamelURL *old_url, *new_url;
- const char *old_soap_port, *new_soap_port;
- GwAccountInfo *existing_account_info;
- const char *old_use_ssl, *new_use_ssl;
- gboolean old_ssl, new_ssl;
- const char *old_poa_address, *new_poa_address;
-
- is_gw_account = is_groupwise_account (account);
-
- existing_account_info = lookup_account_info (account->uid);
-
- if (existing_account_info == NULL && is_gw_account) {
-
- if (!account->enabled)
- return;
-
- /* some account of other type is changed to Groupwise */
- account_added (account_listener, account);
-
- } else if ( existing_account_info != NULL && !is_gw_account) {
-
- /*Groupwise account is changed to some other type */
- remove_calendar_tasks_sources (existing_account_info);
- remove_addressbook_sources (existing_account_info);
- groupwise_accounts = g_list_remove (groupwise_accounts, existing_account_info);
- g_free (existing_account_info->uid);
- g_free (existing_account_info->name);
- g_free (existing_account_info->source_url);
- g_free (existing_account_info);
-
- } else if ( existing_account_info != NULL && is_gw_account ) {
-
- if (!account->enabled) {
- account_removed (account_listener, account);
- return;
- }
- old_ssl = new_ssl = FALSE;
- /* some info of groupwise account is changed . update the sources with new info if required */
- old_url = camel_url_new (existing_account_info->source_url, NULL);
- old_poa_address = camel_url_get_param (old_url, "poa");
- old_soap_port = camel_url_get_param (old_url, "soap_port");
- old_use_ssl = camel_url_get_param (old_url, "soap_ssl");
- if (old_use_ssl)
- old_ssl = TRUE;
- new_url = camel_url_new (account->source->url, NULL);
-
- new_poa_address = camel_url_get_param (new_url, "poa");
- if (!new_poa_address || strlen (new_poa_address) ==0)
- return;
- new_soap_port = camel_url_get_param (new_url, "soap_port");
- if (!new_soap_port || strlen (new_soap_port) == 0)
- new_soap_port = "7181";
-
- new_use_ssl = camel_url_get_param (new_url, "soap_ssl");
- if (new_use_ssl){
- new_use_ssl = "always";
- new_ssl = TRUE;
- }
-
- if ((old_poa_address && strcmp (old_poa_address, new_poa_address))
- || (old_soap_port && strcmp (old_soap_port, new_soap_port))
- || strcmp (old_url->user, new_url->user)
- || ( old_ssl ^ new_ssl)) {
-
- account_removed (account_listener, account);
- account_added (account_listener, account);
- } else if (strcmp (existing_account_info->name, account->name)) {
-
- modify_esource ("/apps/evolution/calendar/sources", existing_account_info, account->name, new_url);
- modify_esource ("/apps/evolution/tasks/sources", existing_account_info, account->name, new_url);
- modify_addressbook_sources (account, existing_account_info);
-
- }
-
- g_free (existing_account_info->name);
- g_free (existing_account_info->source_url);
- existing_account_info->name = g_strdup (account->name);
- existing_account_info->source_url = g_strdup (account->source->url);
- camel_url_free (old_url);
- camel_url_free (new_url);
- }
-
-
-}
-
-
-
-static void
-camel_gw_listener_construct (CamelGwListener *config_listener)
-{
- EIterator *iter;
- EAccount *account;
- GwAccountInfo *info ;
-
- config_listener->priv->account_list = e_account_list_new (config_listener->priv->gconf_client);
-
- for ( iter = e_list_get_iterator (E_LIST ( config_listener->priv->account_list) ) ; e_iterator_is_valid (iter); e_iterator_next (iter) ) {
-
- account = E_ACCOUNT (e_iterator_get (iter));
- if ( is_groupwise_account (account) && account->enabled) {
-
- info = g_new0 (GwAccountInfo, 1);
- info->uid = g_strdup (account->uid);
- info->name = g_strdup (account->name);
- info->source_url = g_strdup (account->source->url);
- groupwise_accounts = g_list_append (groupwise_accounts, info);
-
- }
-
- }
- g_signal_connect (config_listener->priv->account_list, "account_added", G_CALLBACK (account_added), NULL);
- g_signal_connect (config_listener->priv->account_list, "account_changed", G_CALLBACK (account_changed), NULL);
- g_signal_connect (config_listener->priv->account_list, "account_removed", G_CALLBACK (account_removed), NULL);
-
-
-}
-
-GType
-camel_gw_listener_get_type (void)
-{
- static GType camel_gw_listener_type = 0;
-
- if (!camel_gw_listener_type) {
- static GTypeInfo info = {
- sizeof (CamelGwListenerClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) camel_gw_listener_class_init,
- NULL, NULL,
- sizeof (CamelGwListener),
- 0,
- (GInstanceInitFunc) camel_gw_listener_init
- };
- camel_gw_listener_type = g_type_register_static (PARENT_TYPE, "CamelGwListener", &info, 0);
- }
-
- return camel_gw_listener_type;
-}
-
-CamelGwListener*
-camel_gw_listener_new ()
-{
- CamelGwListener *config_listener;
-
- config_listener = g_object_new (CAMEL_TYPE_GW_LISTENER, NULL);
- config_listener->priv->gconf_client = gconf_client_get_default();
-
- camel_gw_listener_construct (config_listener);
-
- return config_listener;
-
-}
-
-
diff --git a/camel/providers/groupwise/camel-gw-listener.h b/camel/providers/groupwise/camel-gw-listener.h
deleted file mode 100644
index c4079723f4..0000000000
--- a/camel/providers/groupwise/camel-gw-listener.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- *
- * Sivaiah Nallagatla <snallagatla@novell.com>
- *
- * Copyright 2003, Novell, 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_GW_LISTENER_H
-#define CAMEL_GW_LISTENER_H
-
-
-#include <libedataserver/e-account-list.h>
-#include<libedataserver/e-source.h>
-#include<libedataserver/e-source-list.h>
-#include "camel-url.h"
-
-G_BEGIN_DECLS
-
-#define CAMEL_TYPE_GW_LISTENER (camel_gw_listener_get_type ())
-#define CAMEL_GW_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAMEL_TYPE_GW_LISTENER, CamelGwListener))
-#define CAMEL_GW_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_GW_LISTENER, CamelGWListenerClass))
-#define CAMEL_IS_GWLISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAMEL_TYPE_GW_LISTENER))
-#define CAMEL_IS_GW_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CAMEL_TYPE_GW_LISTENER))
-
-typedef struct _CamelGwListener CamelGwListener;
-typedef struct _CamelGwListenerClass CamelGwListenerClass;
-typedef struct _CamelGwListenerPrivate CamelGwListenerPrivate;
-struct _CamelGwListener {
- GObject parent;
-
- CamelGwListenerPrivate *priv;
-};
-
-struct _CamelGwListenerClass {
- GObjectClass parent_class;
-
-
-};
-
-GType camel_gw_listener_get_type (void);
-CamelGwListener *camel_gw_listener_new (void);
-
-G_END_DECLS
-
-#endif
-
diff --git a/camel/providers/groupwise/libcamelgroupwise.urls b/camel/providers/groupwise/libcamelgroupwise.urls
deleted file mode 100644
index fb6242262a..0000000000
--- a/camel/providers/groupwise/libcamelgroupwise.urls
+++ /dev/null
@@ -1 +0,0 @@
-groupwise
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 7c18acfa7f..0000000000
--- a/camel/providers/imap/Makefile.am
+++ /dev/null
@@ -1,44 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-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
-
-noinst_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 \
- camel-imap-private.h
-
-libcamelimap_la_LDFLAGS = -avoid-version -module
-
-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 eeb3ecd302..0000000000
--- a/camel/providers/imap/camel-imap-command.c
+++ /dev/null
@@ -1,819 +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>
-#include "camel-i18n.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 {
- camel_object_ref(folder);
- if (store->current_folder)
- camel_object_unref(store->current_folder);
- store->current_folder = 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 (!g_ascii_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 6cdd96bcf7..0000000000
--- a/camel/providers/imap/camel-imap-folder.c
+++ /dev/null
@@ -1,2812 +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 "libedataserver/e-path.h"*/
-#include "libedataserver/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"
-#include "camel-debug.h"
-#include "camel-i18n.h"
-
-#define d(x)
-
-/* set to -1 for infinite size (suggested max command-line length is
- * 1000 octets (see rfc2683), so we should keep the uid-set length to
- * something under that so that our command-lines don't exceed 1000
- * octets) */
-#define UID_SET_LIMIT (768)
-
-
-#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, *state_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, '/');
- 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 (folder, 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;
- }
-
- /* set/load persistent state */
- state_file = g_strdup_printf ("%s/cmeta", folder_dir);
- camel_object_set(folder, NULL, CAMEL_OBJECT_STATE_FILE, state_file, NULL);
- g_free(state_file);
- camel_object_state_read(folder);
-
- 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 (!g_ascii_strcasecmp (folder_name, "INBOX")) {
- if ((imap_store->parameters & IMAP_PARAM_FILTER_INBOX))
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
- if ((imap_store->parameters & IMAP_PARAM_FILTER_JUNK))
- folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
- } else {
- if ((imap_store->parameters & (IMAP_PARAM_FILTER_JUNK|IMAP_PARAM_FILTER_JUNK_INBOX)) == (IMAP_PARAM_FILTER_JUNK))
- folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
- }
-
- 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;
- guint32 perm_flags = 0;
- 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) && !perm_flags) {
- resp += 6;
- folder->permanent_flags = imap_parse_flag_list (&resp);
- } else if (!strncasecmp (resp, "OK [PERMANENTFLAGS ", 19)) {
- resp += 19;
-
- /* workaround for broken IMAP servers that send "* OK [PERMANENTFLAGS ()] Permanent flags"
- * even tho they do allow storing flags. *Sigh* So many fucking broken IMAP servers out there. */
- if ((perm_flags = imap_parse_flag_list (&resp)) != 0)
- folder->permanent_flags = perm_flags;
- } 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_strstrcase (response->status, "OK [READ-ONLY]"))
- imap_folder->read_only = TRUE;
-
- 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 (!g_ascii_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_message_info_free(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=0;
- 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, *state_file;
- char *folders;
-
- folders = g_strconcat (imap_store->storage_path, "/folders", NULL);
- folder_dir = imap_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);
-
- state_file = g_strdup_printf ("%s/cmeta", folder_dir);
- camel_object_set(folder, NULL, CAMEL_OBJECT_STATE_FILE, state_file, NULL);
- g_free(state_file);
-
- 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
- || g_ascii_strcasecmp(folder->full_name, "INBOX") == 0) {
- 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);
- }
- } else if (imap_folder->need_rescan) {
- /* 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.
- */
- 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 (g_ascii_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);
- }
-
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
-}
-
-/* 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_message_info_free(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_message_info_free(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;
-
- iinfo->info.flags = (iinfo->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_message_info_free(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;
- CamelImapMessageInfo *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 = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i);
- if (!info)
- continue;
- if ((info->info.flags & mask) != flags) {
- camel_message_info_free((CamelMessageInfo *)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;
- CamelImapMessageInfo *info;
- CamelException local_ex;
- GPtrArray *matches;
- char *set, *flaglist;
- gboolean unset;
- int i, j, max;
-
- if (((CamelImapFolder *)folder)->read_only) {
- imap_sync_offline (folder, ex);
- return;
- }
-
- 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++) {
- if (!(info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i)))
- continue;
-
- if (!(info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- camel_message_info_free((CamelMessageInfo *)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->info.flags & folder->permanent_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->info.flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
- folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED, &set);
- camel_message_info_free(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 ? folder->permanent_flags : info->info.flags & folder->permanent_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->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- ((CamelImapMessageInfo *) info)->server_flags = info->info.flags & CAMEL_IMAP_SERVER_FLAGS;
- }
- camel_folder_summary_touch (folder->summary);
- }
-
- for (j = 0; j < matches->len; j++) {
- info = matches->pdata[j];
- camel_message_info_free(&info->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)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- GPtrArray *keep_uids, *mark_uids;
- CamelImapResponse *response;
- char *result;
-
- if (imap_folder->read_only)
- return;
-
- 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;
- guint32 flags;
-
- flags = camel_message_info_flags(info);
- if (flags)
- flagstr = imap_create_flag_list (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_message_info_free(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 */
- if (store->current_folder != dest ||
- camel_folder_summary_count (dest->summary) == count)
- camel_folder_refresh_info (dest, ex);
-
- 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;
-
- /* 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);
- matches = camel_folder_search_search(imap_folder->search, expression, NULL, ex);
-
- CAMEL_IMAP_FOLDER_UNLOCK(folder, search_lock);
-
- 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 *matches;
-
- if (uids->len == 0)
- return g_ptr_array_new();
-
- CAMEL_IMAP_FOLDER_LOCK(folder, search_lock);
-
- camel_folder_search_set_folder(imap_folder->search, folder);
- matches = camel_folder_search_search(imap_folder->search, expression, uids, ex);
-
- CAMEL_IMAP_FOLDER_UNLOCK(folder, search_lock);
-
- 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,
- 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,
- int frommsg,
- CamelException *ex)
-{
- CamelDataWrapper *content = NULL;
- CamelStream *stream;
- char *part_spec;
-
- part_spec = content_info_get_part_spec (ci);
-
- d(printf("get content '%s' '%s' (frommsg = %d)\n", part_spec, camel_content_type_format(ci->type), frommsg));
-
- /* 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);
- if (frommsg)
- sprintf(spec, part_spec[0] ? "%s.TEXT" : "TEXT", part_spec);
- else
- strcpy(spec, 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, isdigest;
-
- 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);
- isdigest = camel_content_type_is(((CamelDataWrapper *)part)->mime_type, "multipart", "digest");
-
- 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, FALSE, ex);
- }
-
- if (!stream || !content) {
- camel_object_unref (CAMEL_OBJECT (body_mp));
- g_free (child_spec);
- return NULL;
- }
-
- if (camel_debug("imap:folder")) {
- char *ct = camel_content_type_format(camel_mime_part_get_content_type((CamelMimePart *)part));
- char *ct2 = camel_content_type_format(ci->type);
-
- printf("Setting part content type to '%s' contentinfo type is '%s'\n", ct, ct2);
- g_free(ct);
- g_free(ct2);
- }
-
- /* if we had no content-type header on a multipart/digest sub-part, then we need to
- treat it as message/rfc822 instead */
- if (isdigest && camel_medium_get_header((CamelMedium *)part, "content-type") == NULL) {
- CamelContentType *ct = camel_content_type_new("message", "rfc822");
-
- camel_data_wrapper_set_mime_type_field(content, ct);
- camel_content_type_unref(ct);
- } else {
- camel_data_wrapper_set_mime_type_field(content, camel_mime_part_get_content_type(part));
- }
-
- camel_medium_set_content_object (CAMEL_MEDIUM (part), content);
- camel_object_unref(content);
-
- camel_multipart_add_part (body_mp, part);
- camel_object_unref(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, ci->childs, ex);
- g_free (part_spec);
- return content;
- } else {
- CamelTransferEncoding enc;
- char *spec;
-
- spec = g_alloca(strlen(part_spec) + 6);
- if (frommsg)
- sprintf(spec, part_spec[0] ? "%s.TEXT" : "1.TEXT", part_spec);
- else
- strcpy(spec, part_spec[0]?part_spec:"1");
-
- enc = ci->encoding?camel_transfer_encoding_from_string(ci->encoding):CAMEL_TRANSFER_ENCODING_DEFAULT;
- content = camel_imap_wrapper_new (imap_folder, ci->type, enc, uid, spec, part);
- g_free (part_spec);
- return content;
- }
-}
-
-static CamelMimeMessage *
-get_message (CamelImapFolder *imap_folder, const char *uid,
- CamelMessageContentInfo *ci,
- CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (CAMEL_FOLDER (imap_folder)->parent_store);
- CamelDataWrapper *content;
- CamelMimeMessage *msg;
- CamelStream *stream;
- char *section_text, *part_spec;
- int ret;
-
- part_spec = content_info_get_part_spec(ci);
- d(printf("get message '%s'\n", part_spec));
- 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);
- g_free(part_spec);
- 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, TRUE, ex);
- if (!content) {
- camel_object_unref (CAMEL_OBJECT (msg));
- return NULL;
- }
-
- if (camel_debug("imap:folder")) {
- char *ct = camel_content_type_format(camel_mime_part_get_content_type((CamelMimePart *)msg));
- char *ct2 = camel_content_type_format(ci->type);
-
- printf("Setting message content type to '%s' contentinfo type is '%s'\n", ct, ct2);
- g_free(ct);
- g_free(ct2);
- }
-
- camel_data_wrapper_set_mime_type_field(content, camel_mime_part_get_content_type((CamelMimePart *)msg));
- camel_medium_set_content_object (CAMEL_MEDIUM (msg), content);
- camel_object_unref (CAMEL_OBJECT (content));
-
- return msg;
-}
-
-#define IMAP_SMALL_BODY_SIZE 5120
-
-static CamelMimeMessage *
-get_message_simple (CamelImapFolder *imap_folder, const char *uid,
- CamelStream *stream, CamelException *ex)
-{
- CamelMimeMessage *msg;
- 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;
- }
-
- return msg;
-}
-
-static gboolean
-content_info_incomplete (CamelMessageContentInfo *ci)
-{
- if (!ci->type)
- return TRUE;
-
- if (camel_content_type_is (ci->type, "multipart", "*")
- || camel_content_type_is (ci->type, "message", "rfc822")) {
- if (!ci->childs)
- return TRUE;
- for (ci = ci->childs;ci;ci=ci->next)
- if (content_info_incomplete(ci))
- return TRUE;
- }
-
- return FALSE;
-}
-
-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);
- CamelImapMessageInfo *mi;
- CamelMimeMessage *msg = NULL;
- CamelStream *stream = NULL;
- int retry;
-
- mi = (CamelImapMessageInfo *)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 its cached in full, just get it as is, this is only a shortcut,
- since we get stuff from the cache anyway. It affects a busted connection though. */
- if ( (stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, NULL))
- && (msg = get_message_simple(imap_folder, uid, stream, ex)))
- goto done;
-
- /* All this mess is so we silently retry a fetch if we fail with
- service_unavailable, without an (equivalent) mess of gotos */
- retry = 0;
- do {
- retry++;
- camel_exception_clear(ex);
-
- /* If we are online, make sure we're also connected */
- if (camel_disco_store_status((CamelDiscoStore *)store) == CAMEL_DISCO_STORE_ONLINE
- && !camel_imap_store_connected(store, ex))
- goto fail;
-
- /* If the message is small or only 1 part, or server doesn't do 4v1 (properly) fetch it in one piece. */
- if (store->server_level < IMAP_LEVEL_IMAP4REV1
- || store->braindamaged
- || mi->info.size < IMAP_SMALL_BODY_SIZE
- || (!content_info_incomplete(mi->info.content) && !mi->info.content->childs)) {
- msg = get_message_simple (imap_folder, uid, NULL, ex);
- } else {
- if (content_info_incomplete (mi->info.content)) {
- /* 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.)
- */
- 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"));
- goto fail;
- }
-
- response = camel_imap_command (store, folder, ex, "UID FETCH %s BODY", uid);
- if (response) {
- 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->info.content);
-
- if (fetch_data)
- g_datalist_clear (&fetch_data);
-
- camel_imap_response_free (store, response);
- }
- }
-
- if (camel_debug_start("imap:folder")) {
- printf("Folder get message '%s' folder info ->\n", uid);
- camel_message_info_dump((CamelMessageInfo *)mi);
- camel_debug_end();
- }
-
- /* 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.
- */
- if (content_info_incomplete (mi->info.content))
- msg = get_message_simple (imap_folder, uid, NULL, ex);
- else
- msg = get_message (imap_folder, uid, mi->info.content, ex);
- }
- } while (msg == NULL
- && retry < 2
- && camel_exception_get_id(ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE);
-
-done: /* FIXME, this shouldn't be done this way. */
- if (msg)
- camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source", store->base_url);
-fail:
- camel_message_info_free(&mi->info);
-
- 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;
- CamelImapMessageInfo *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 = (CamelImapMessageInfo *)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->info.date_received = decode_internaldate (idate);
-
- if (mi->info.date_received == -1)
- mi->info.date_received = mi->info.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;
- CamelImapMessageInfo *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 = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, seq - 1);
- uidval = strtoul(camel_message_info_uid (mi), NULL, 10);
- camel_message_info_free(&mi->info);
- } 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 = (CamelImapMessageInfo *)camel_message_info_clone(pmi);
- }
-
- uid = g_datalist_get_data (&data, "UID");
- if (uid)
- mi->info.uid = 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->info.flags |= flags;
- }
- size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE"));
- if (size)
- mi->info.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);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Incomplete server response: no information provided for message %d"),
- i + first);
- break;
- }
- uid = (char *)camel_message_info_uid(mi);
- if (uid[0] == 0) {
- g_warning("Server provided no uid: message %d", i + first);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Incomplete server response: no UID provided for message %d"),
- i + first);
- break;
- }
- info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
- if (info) {
- for (seq = 0; seq < camel_folder_summary_count (folder->summary); seq++) {
- if (folder->summary->messages->pdata[seq] == info)
- break;
- }
-
- g_warning("Message already present? %s", camel_message_info_uid(mi));
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unexpected server response: Identical UIDs provided for messages %d and %d"),
- seq + 1, i + first);
-
- camel_message_info_free(&info->info);
- break;
- }
-
- camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi);
- camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
-
- if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT))
- camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi));
- }
-
- for ( ; i < messages->len; i++) {
- if ((mi = messages->pdata[i]))
- camel_message_info_free(&mi->info);
- }
-
- g_ptr_array_free (messages, TRUE);
-
- 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_message_info_free(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_message_info_free(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 == NULL)
- stream = camel_stream_mem_new_with_buffer (body, body_len);
- }
-
- 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 a2ab1dfd2c..0000000000
--- a/camel/providers/imap/camel-imap-folder.h
+++ /dev/null
@@ -1,92 +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;
-
- CamelFolderSearch *search;
- CamelImapMessageCache *cache;
-
- unsigned int need_rescan:1;
- unsigned int need_refresh:1;
- unsigned int read_only:1;
-};
-
-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 3099602613..0000000000
--- a/camel/providers/imap/camel-imap-message-cache.c
+++ /dev/null
@@ -1,528 +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"
-#include "camel-i18n.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_message_info_free(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 d07358527a..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 "libedataserver/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 e574a5c1f7..0000000000
--- a/camel/providers/imap/camel-imap-provider.c
+++ /dev/null
@@ -1,164 +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"
-#include "camel-i18n.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, "mailcheck", NULL,
- N_("Checking for New Mail") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "check_all", NULL,
- N_("C_heck for new messages in all folders"), "1" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { 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, "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_("O_verride server-supplied folder namespace"), "0" },
- { CAMEL_PROVIDER_CONF_ENTRY, "namespace", "override_namespace",
- N_("Namespace") },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_SECTION_START, "general", NULL, N_("Options") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL,
- N_("_Apply filters to new messages in INBOX on this server"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter_junk", NULL,
- N_("Check new messages for _Junk contents"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter_junk_inbox", "filter_junk",
- N_("Only check for Junk messa_ges in the INBOX folder"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "offline_sync", NULL,
- N_("Automatically synchroni_ze remote mail locally"), "0" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { 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(void)
-{
- 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_provider_register(&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 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
-imap_url_equal (gconstpointer a, gconstpointer b)
-{
- const CamelURL *u1 = a, *u2 = b;
-
- return check_equal (u1->protocol, u2->protocol)
- && 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 2c0dcb02f6..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 "libedataserver/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 3ad7f8decc..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 <libedataserver/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 434f5b5da0..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 "libedataserver/md5-utils.h"
-#include "libedataserver/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 5811b0f691..0000000000
--- a/camel/providers/imap/camel-imap-store.c
+++ /dev/null
@@ -1,3229 +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 "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"
-#include "camel-debug.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
-
-#define d(x)
-
-/* Specified in RFC 2060 */
-#define IMAP_PORT "143"
-#define IMAPS_PORT "993"
-
-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 CamelFolder *imap_get_junk(CamelStore *store, CamelException *ex);
-static CamelFolder *imap_get_trash(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_store_class->get_trash = imap_get_trash;
- camel_store_class->get_junk = imap_get_junk;
-
- 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);
-}
-
-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';
-}
-
-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;
- }
- if (camel_url_get_param (url, "filter_junk"))
- imap_store->parameters |= IMAP_PARAM_FILTER_JUNK;
- if (camel_url_get_param (url, "filter_junk_inbox"))
- imap_store->parameters |= IMAP_PARAM_FILTER_JUNK_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;
- }
- }
-
- 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 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:
- 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;*/
- }
- break;
- case 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;*/
- }
- break;
- case 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... */
- break;
- case 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... */
- break;
- case CAMEL_IMAP_STORE_FILTER_JUNK:
- flags = args->argv[i].ca_int ? IMAP_PARAM_FILTER_JUNK : 0;
- store->parameters = flags | (store->parameters & ~IMAP_PARAM_FILTER_JUNK);
- break;
- case CAMEL_IMAP_STORE_FILTER_JUNK_INBOX:
- flags = args->argv[i].ca_int ? IMAP_PARAM_FILTER_JUNK_INBOX : 0;
- store->parameters = flags | (store->parameters & ~IMAP_PARAM_FILTER_JUNK_INBOX);
- break;
- default:
- /* 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:
- *args->argv[i].ca_str = store->namespace;
- break;
- case CAMEL_IMAP_STORE_OVERRIDE_NAMESPACE:
- *args->argv[i].ca_int = store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE ? TRUE : FALSE;
- break;
- case CAMEL_IMAP_STORE_CHECK_ALL:
- *args->argv[i].ca_int = store->parameters & IMAP_PARAM_CHECK_ALL ? TRUE : FALSE;
- break;
- case CAMEL_IMAP_STORE_FILTER_INBOX:
- *args->argv[i].ca_int = store->parameters & IMAP_PARAM_FILTER_INBOX ? TRUE : FALSE;
- break;
- case CAMEL_IMAP_STORE_FILTER_JUNK:
- *args->argv[i].ca_int = store->parameters & IMAP_PARAM_FILTER_JUNK ? TRUE : FALSE;
- break;
- case CAMEL_IMAP_STORE_FILTER_JUNK_INBOX:
- *args->argv[i].ca_int = store->parameters & IMAP_PARAM_FILTER_JUNK_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 (g_ascii_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 {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
-#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, struct addrinfo *ai, int ssl_mode, CamelException *ex)
-{
- CamelImapStore *store = (CamelImapStore *) service;
- CamelImapResponse *response;
- CamelStream *tcp_stream;
- CamelSockOptData sockopt;
- gboolean force_imap4 = FALSE;
- int clean_quit, ret;
- char *buf;
-
- if (ssl_mode != MODE_CLEAR) {
-#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
-
- return FALSE;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -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: %s"),
- service->url->host,
- g_strerror (errno));
-
- camel_object_unref (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;
-
- /* Disable Nagle - we send a lot of small requests which nagle slows down */
- sockopt.option = CAMEL_SOCKOPT_NODELAY;
- sockopt.value.no_delay = TRUE;
- camel_tcp_stream_setsockopt((CamelTcpStream *)tcp_stream, &sockopt);
-
- /* Set keepalive - needed for some hosts/router configurations, we're idle a lot */
- sockopt.option = CAMEL_SOCKOPT_KEEPALIVE;
- sockopt.value.keep_alive = TRUE;
- camel_tcp_stream_setsockopt((CamelTcpStream *)tcp_stream, &sockopt);
-
- /* Read the greeting, if any, and deal with PREAUTH */
- if (camel_imap_store_readline (store, &buf, ex) < 0) {
- if (store->istream) {
- camel_object_unref (store->istream);
- store->istream = NULL;
- }
-
- if (store->ostream) {
- camel_object_unref (store->ostream);
- store->ostream = NULL;
- }
-
- store->connected = FALSE;
-
- return FALSE;
- }
-
- if (!strncmp(buf, "* PREAUTH", 9))
- store->preauthed = TRUE;
-
- if (strstr (buf, "Courier-IMAP")) {
- /* Courier-IMAP is braindamaged. So far this flag only
- * works around the fact that Courier-IMAP is known to
- * give invalid BODY responses seemingly because its
- * MIME parser sucks. In any event, we can't rely on
- * them so we always have to request the full messages
- * rather than getting individual parts. */
- store->braindamaged = TRUE;
- } else if (strstr (buf, "WEB.DE") || strstr (buf, "Mail2World")) {
- /* This is a workaround for servers which advertise
- * IMAP4rev1 but which can sometimes subtly break in
- * various ways if we try to use IMAP4rev1 queries.
- *
- * WEB.DE: when querying for HEADER.FIELDS.NOT, it
- * returns an empty literal for the headers. Many
- * complaints about empty message-list fields on the
- * mailing lists and probably a few bugzilla bugs as
- * well.
- *
- * Mail2World (aka NamePlanet): When requesting
- * message info's, it ignores the fact that we
- * requested BODY.PEEK[HEADER.FIELDS.NOT (RECEIVED)]
- * and so the responses are incomplete. See bug #58766
- * for details.
- **/
- force_imap4 = TRUE;
- }
-
- g_free (buf);
-
- /* get the imap server capabilities */
- if (!imap_get_capability (service, ex)) {
- if (store->istream) {
- camel_object_unref (store->istream);
- store->istream = NULL;
- }
-
- if (store->ostream) {
- camel_object_unref (store->ostream);
- store->ostream = NULL;
- }
-
- store->connected = FALSE;
- return FALSE;
- }
-
- if (force_imap4) {
- store->capabilities &= ~IMAP_CAPABILITY_IMAP4REV1;
- store->server_level = IMAP_LEVEL_IMAP4;
- }
-
- if (ssl_mode != MODE_TLS) {
- /* we're done */
- return TRUE;
- }
-
- if (!(store->capabilities & IMAP_CAPABILITY_STARTTLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to IMAP server %s in secure mode: %s"),
- service->url->host, _("STARTTLS not supported"));
-
- goto exception;
- }
-
- /* 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 (store->istream);
- camel_object_unref (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 (store->istream);
- store->istream = NULL;
- }
-
- if (store->ostream) {
- camel_object_unref (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 (store->istream);
- store->istream = NULL;
- }
-
- if (store->ostream) {
- camel_object_unref (store->ostream);
- store->ostream = NULL;
- }
-
- store->connected = FALSE;
-
- return FALSE;
-}
-
-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 (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 (store->istream);
- store->istream = NULL;
- }
-
- if (store->ostream) {
- camel_object_unref (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 (store->istream);
- store->istream = NULL;
- }
-
- if (store->ostream) {
- camel_object_unref (store->ostream);
- store->ostream = NULL;
- }
-
- store->connected = FALSE;
- return FALSE;
- }
-
- return TRUE;
-
-}
-
-static struct {
- char *value;
- char *serv;
- char *port;
- int mode;
-} ssl_options[] = {
- { "", "imaps", IMAPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "imaps", IMAPS_PORT, MODE_SSL },
- { "when-possible", "imap", IMAP_PORT, MODE_TLS },
- { "never", "imap", IMAP_PORT, MODE_CLEAR },
- { NULL, "imap", IMAP_PORT, MODE_CLEAR },
-};
-
-static gboolean
-connect_to_server_wrapper (CamelService *service, CamelException *ex)
-{
- const char *command, *ssl_mode;
- struct addrinfo hints, *ai;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((command = camel_url_get_param (service->url, "command")))
- return connect_to_server_process (service, command, ex);
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
- break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
- } else {
- mode = MODE_CLEAR;
- serv = "imap";
- port = IMAP_PORT;
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
- }
-
- camel_freeaddrinfo (ai);
-
- return ret;
-}
-
-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 = 0;
- fi->total = 0;
-
- url = camel_url_new (imap_store->base_url, NULL);
- g_free (url->path);
- url->path = g_strdup_printf ("/%s", folder_name);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free(url);
- name = strrchr (fi->full_name, '/');
- if (name == NULL)
- name = fi->full_name;
- else
- name++;
- 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, *state_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 = imap_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 (NULL, 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/journal", folder_dir);
- unlink (journal_file);
- g_free (journal_file);
-
- state_file = g_strdup_printf ("%s/cmeta", folder_dir);
- unlink (state_file);
- g_free (state_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 \"\" %F",
- 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];
-
- /* NB: we can have vtrash folders also in our store ... bit hacky */
- if (!CAMEL_IS_IMAP_FOLDER(folder)) {
- camel_object_unref(folder);
- continue;
- }
-
- 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 (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 (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;
- const char *auth_domain;
-
- CAMEL_SERVICE_ASSERT_LOCKED (store, connect_lock);
- auth_domain = camel_url_get_param (service->url, "auth-domain");
-
- 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, auth_domain, "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, service, auth_domain,
- prompt, "password", CAMEL_SESSION_PASSWORD_SECRET, 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;
- 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 */
- }
- }
-
- /* 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 || !g_ascii_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 (!g_ascii_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 (!g_ascii_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 (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 (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 (store->istream);
- store->istream = NULL;
- }
-
- if (store->ostream) {
- camel_object_unref (store->ostream);
- store->ostream = NULL;
- }
-
- imap_disconnect_offline (service, clean, ex);
-
- return TRUE;
-}
-
-
-static gboolean
-imap_summary_is_dirty (CamelFolderSummary *summary)
-{
- CamelImapMessageInfo *info;
- int max, i;
- int found = FALSE;
-
- max = camel_folder_summary_count (summary);
- for (i = 0; i < max && !found; i++) {
- info = (CamelImapMessageInfo *)camel_folder_summary_index (summary, i);
- if (info) {
- found = info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED;
- camel_message_info_free(info);
- }
- }
-
- 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 CamelFolder *
-imap_get_trash(CamelStore *store, CamelException *ex)
-{
- CamelFolder *folder = CAMEL_STORE_CLASS(parent_class)->get_trash(store, ex);
-
- if (folder) {
- char *state = g_build_filename(((CamelImapStore *)store)->storage_path, "system", "Trash.cmeta", NULL);
-
- camel_object_set(folder, NULL, CAMEL_OBJECT_STATE_FILE, state, NULL);
- g_free(state);
- /* no defaults? */
- camel_object_state_read(folder);
- }
-
- return folder;
-}
-
-static CamelFolder *
-imap_get_junk(CamelStore *store, CamelException *ex)
-{
- CamelFolder *folder = CAMEL_STORE_CLASS(parent_class)->get_junk(store, ex);
-
- if (folder) {
- char *state = g_build_filename(((CamelImapStore *)store)->storage_path, "system", "Junk.cmeta", NULL);
-
- camel_object_set(folder, NULL, CAMEL_OBJECT_STATE_FILE, state, NULL);
- g_free(state);
- /* no defaults? */
- camel_object_state_read(folder);
- }
-
- return folder;
-}
-
-static guint
-hash_folder_name (gconstpointer key)
-{
- if (g_ascii_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 (g_ascii_strcasecmp (a, "INBOX") == 0)
- aname = "INBOX";
- if (g_ascii_strcasecmp (b, "INBOX") == 0)
- bname = "INBOX";
- return g_str_equal (aname, bname);
-}
-
-struct imap_status_item {
- struct imap_status_item *next;
- char *name;
- guint32 value;
-};
-
-static void
-imap_status_item_free (struct imap_status_item *items)
-{
- struct imap_status_item *next;
-
- while (items != NULL) {
- next = items->next;
- g_free (items->name);
- g_free (items);
- items = next;
- }
-}
-
-static struct imap_status_item *
-get_folder_status (CamelImapStore *imap_store, const char *folder_name, const char *type)
-{
- struct imap_status_item *items, *item, *tail;
- CamelImapResponse *response;
- char *status, *name, *p;
-
- /* 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 NULL;
- }
-
- if (!(status = camel_imap_response_extract (imap_store, response, "STATUS", NULL)))
- return NULL;
-
- p = status + strlen ("* STATUS ");
- while (*p == ' ')
- p++;
-
- /* skip past the mailbox string */
- if (*p == '"') {
- p++;
- while (*p != '\0') {
- if (*p == '"' && p[-1] != '\\') {
- p++;
- break;
- }
-
- p++;
- }
- } else {
- while (*p != ' ')
- p++;
- }
-
- while (*p == ' ')
- p++;
-
- if (*p++ != '(') {
- g_free (status);
- return NULL;
- }
-
- while (*p == ' ')
- p++;
-
- if (*p == ')') {
- g_free (status);
- return NULL;
- }
-
- items = NULL;
- tail = (struct imap_status_item *) &items;
-
- do {
- name = p;
- while (*p != ' ')
- p++;
-
- item = g_malloc (sizeof (struct imap_status_item));
- item->next = NULL;
- item->name = g_strndup (name, p - name);
- item->value = strtoul (p, &p, 10);
-
- tail->next = item;
- tail = item;
-
- while (*p == ' ')
- p++;
- } while (*p != ')');
-
- g_free (status);
-
- return items;
-}
-
-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 (!g_ascii_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 (imap_store->current_folder);
- imap_store->current_folder = NULL;
- }
- response = camel_imap_command (imap_store, NULL, ex, "SELECT %F", folder_name);
- if (!response) {
- char *folder_real, *parent_name, *parent_real;
- const char *c;
-
- if (camel_exception_get_id(ex) == CAMEL_EXCEPTION_USER_CANCEL) {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- return NULL;
- }
-
- camel_exception_clear (ex);
-
- if (!(flags & CAMEL_STORE_FOLDER_CREATE)) {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("No such folder %s"), folder_name);
- return NULL;
- }
-
- if ((parent_name = strrchr (folder_name, '/'))) {
- parent_name = g_strndup (folder_name, parent_name - folder_name);
- parent_real = camel_imap_store_summary_path_to_full (imap_store->summary, parent_name, imap_store->dir_sep);
- } else {
- parent_real = NULL;
- }
-
- c = parent_name ? parent_name : folder_name;
- while (*c && *c != imap_store->dir_sep && !strchr ("#%*", *c))
- c++;
-
- if (*c != '\0') {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_PATH,
- _("The folder name \"%s\" is invalid because it contains the character \"%c\""),
- folder_name, *c);
- g_free (parent_name);
- g_free (parent_real);
- return NULL;
- }
-
- if (parent_real != NULL) {
- gboolean need_convert = FALSE;
- char *resp, *thisone;
- guint32 flags;
- int i;
-
- if (!(response = camel_imap_command (imap_store, NULL, ex, "LIST \"\" %S", parent_real))) {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- g_free (parent_name);
- 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 (parent_name, thisone)) {
- if (flags & CAMEL_FOLDER_NOINFERIORS)
- need_convert = TRUE;
- }
-
- g_free (thisone);
- }
-
- camel_imap_response_free (imap_store, response);
-
- /* if not, check if we can delete it and recreate it */
- if (need_convert) {
- struct imap_status_item *items, *item;
- guint32 messages = 0;
- CamelException lex;
- char *name;
-
- item = items = get_folder_status (imap_store, parent_name, "MESSAGES");
- while (item != NULL) {
- if (!g_ascii_strcasecmp (item->name, "MESSAGES")) {
- messages = item->value;
- break;
- }
-
- item = item->next;
- }
-
- imap_status_item_free (items);
-
- if (messages > 0) {
- camel_exception_set (ex, CAMEL_EXCEPTION_FOLDER_INVALID_STATE,
- _("The parent folder is not allowed to contain subfolders"));
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- g_free (parent_name);
- g_free (parent_real);
- return NULL;
- }
-
- /* delete the old parent and recreate it */
- camel_exception_init (&lex);
- delete_folder (store, parent_name, &lex);
- if (camel_exception_is_set (&lex)) {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- camel_exception_xfer (ex, &lex);
- g_free (parent_name);
- g_free (parent_real);
- 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) {
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
- g_free (parent_name);
- g_free (parent_real);
- return NULL;
- } else
- camel_imap_response_free (imap_store, response);
- }
-
- g_free (parent_real);
- }
-
- g_free (parent_name);
-
- folder_real = camel_imap_store_summary_path_to_full(imap_store->summary, folder_name, imap_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, imap_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;
- }
- } else if (flags & CAMEL_STORE_FOLDER_EXCL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder `%s': folder exists."),
- folder_name);
-
- camel_imap_response_free_without_processing (imap_store, response);
-
- CAMEL_SERVICE_UNLOCK (imap_store, connect_lock);
-
- return NULL;
- }
-
- storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- folder_dir = imap_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 (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 (imap_store->current_folder);
- imap_store->current_folder = NULL;
- camel_object_unref (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 (!g_ascii_strcasecmp (folder_name, "INBOX"))
- folder_name = "INBOX";
-
- storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- folder_dir = imap_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 (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 (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, imap_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 = imap_path_to_physical (storage_path, old_name);
- newpath = imap_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;
- const char *c;
-
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
- return NULL;
- if (!parent_name)
- parent_name = "";
-
- c = folder_name;
- while (*c && *c != imap_store->dir_sep && !strchr ("#%*", *c))
- c++;
-
- if (*c != '\0') {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_PATH,
- _("The folder name \"%s\" is invalid because it contains the character \"%c\""),
- folder_name, *c);
- 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) {
- struct imap_status_item *items, *item;
- guint32 messages = 0;
- char *name;
-
- item = items = get_folder_status (imap_store, parent_name, "MESSAGES");
- while (item != NULL) {
- if (!g_ascii_strcasecmp (item->name, "MESSAGES")) {
- messages = item->value;
- break;
- }
-
- item = item->next;
- }
-
- imap_status_item_free (items);
-
- if (messages > 0) {
- 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, imap_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, imap_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));
- fi->flags |= CAMEL_FOLDER_NOCHILDREN;
- 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, *path;
- 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:'/');
- if (si == NULL)
- return NULL;
-
- 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->name = g_strdup(camel_store_info_name(imap_store->summary, si));
- fi->full_name = g_strdup(camel_store_info_path(imap_store->summary, si));
- if (!g_ascii_strcasecmp(fi->full_name, "inbox"))
- flags |= CAMEL_FOLDER_SYSTEM;
- /* HACK: some servers report noinferiors for all folders (uw-imapd)
- We just translate this into nochildren, and let the imap layer enforce
- it. See create folder */
- if (flags & CAMEL_FOLDER_NOINFERIORS)
- flags = (fi->flags & ~CAMEL_FOLDER_NOINFERIORS) | CAMEL_FOLDER_NOCHILDREN;
- fi->flags = flags;
-
- url = camel_url_new (imap_store->base_url, NULL);
- path = alloca(strlen(fi->full_name)+2);
- sprintf(path, "/%s", fi->full_name);
- camel_url_set_path(url, path);
-
- if (flags & CAMEL_FOLDER_NOSELECT || fi->name[0] == 0)
- camel_url_set_param (url, "noselect", "yes");
- fi->uri = camel_url_to_string (url, 0);
- camel_url_free (url);
-
- /* FIXME: redundant */
- if (flags & CAMEL_IMAP_FOLDER_UNMARKED)
- fi->unread = -1;
-
- return fi;
-}
-
-/* returns true if full_name is a sub-folder of top, or is top */
-static int
-imap_is_subfolder(const char *full_name, const char *top)
-{
- size_t len = strlen(top);
-
- /* Looks for top being a full-path subset of full_name.
- Handle IMAP Inbox case insensitively */
-
- if (g_ascii_strncasecmp(top, "inbox", 5) == 0
- && (top[5] == 0 || top[5] == '/')
- && g_ascii_strncasecmp(full_name, "inbox", 5) == 0
- && (full_name[5] == 0 || full_name[5] == '/')) {
- full_name += 5;
- top += 5;
- len -= 5;
- }
-
- return top[0] == 0
- || (strncmp(full_name, top, len) == 0
- && (full_name[len] == 0
- || full_name[len] == '/'));
-}
-
-/* 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;
- CamelStoreInfo *si;
- CamelImapResponse *response;
- CamelFolderInfo *fi;
- char *result;
- int haveinbox = FALSE;
-
- if (camel_debug("imap:folder_info"))
- printf(" get_subscribed folders\n");
-
- 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
- && imap_is_subfolder(camel_store_info_path(imap_store->summary, si), top)) {
- g_ptr_array_add(names, (char *)camel_imap_store_info_full_name(imap_store->summary, si));
- haveinbox = haveinbox || g_ascii_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);
- g_free (result);
- if (!fi)
- continue;
-
- if (!imap_is_subfolder(fi->full_name, top)) {
- 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(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
-fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
-{
- CamelFolder *folder;
-
- fi->unread = -1;
- fi->total = -1;
- folder = camel_object_bag_peek(store->folders, fi->full_name);
- if (folder) {
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- /* we use connect lock for everything, so this should be safe */
- CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->refresh_info(folder, NULL);
- fi->unread = camel_folder_get_unread_message_count(folder);
- fi->total = camel_folder_get_message_count(folder);
- camel_object_unref(folder);
- } else {
- char *storage_path, *folder_dir, *path;
- CamelFolderSummary *s;
-
- /* This is a lot of work for one path! */
- storage_path = g_strdup_printf("%s/folders", ((CamelImapStore *)store)->storage_path);
- folder_dir = imap_path_to_physical(storage_path, fi->full_name);
- path = g_strdup_printf("%s/summary", folder_dir);
- s = (CamelFolderSummary *)camel_object_new(camel_imap_summary_get_type());
- camel_folder_summary_set_build_content(s, TRUE);
- camel_folder_summary_set_filename(s, path);
- if (camel_folder_summary_header_load(s) != -1) {
- fi->unread = s->unread_count;
- fi->total = s->saved_count;
- }
- g_free(storage_path);
- g_free(folder_dir);
- g_free(path);
-
- camel_object_unref(s);
- }
-}
-
-/* NB: We should have connect_lock at this point */
-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)
- || g_ascii_strcasecmp(fi->full_name, "inbox") == 0) ) {
-
- /* 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 = camel_folder_get_unread_message_count (imap_store->current_folder);
- fi->total = camel_folder_get_message_count(imap_store->current_folder);
- } else {
- struct imap_status_item *items, *item;
-
- fi->unread = -1;
- fi->total = -1;
-
- item = items = get_folder_status (imap_store, fi->full_name, "MESSAGES UNSEEN");
- while (item != NULL) {
- if (!g_ascii_strcasecmp (item->name, "MESSAGES")) {
- fi->total = item->value;
- } else if (!g_ascii_strcasecmp (item->name, "UNSEEN")) {
- fi->unread = item->value;
- }
-
- item = item->next;
- }
-
- imap_status_item_free (items);
-
- /* if we have this folder open, and the unread count has changed, update */
- folder = camel_object_bag_peek(CAMEL_STORE(imap_store)->folders, fi->full_name);
- if (folder) {
- if (fi->unread != camel_folder_get_unread_message_count(folder)) {
- CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->refresh_info(folder, ex);
- fi->unread = camel_folder_get_unread_message_count(folder);
- fi->total = camel_folder_get_message_count(folder);
- }
- camel_object_unref(folder);
- }
- }
- } else {
- /* since its cheap, get it if they're open/consult summary file */
- fill_fi((CamelStore *)imap_store, fi, 0);
- }
-
- if (fi->child)
- q = g_slist_append(q, fi->child);
- fi = fi->next;
- }
- }
-}
-
-/* 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 (g_ascii_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 (g_ascii_strcasecmp(a, "INBOX") == 0)
- a = "INBOX";
- if (g_ascii_strcasecmp(b, "INBOX") == 0)
- b = "INBOX";
-
- return g_str_equal(a, b);
-}
-
-static GSList *
-get_folders_add_folders(GSList *p, int recurse, GHashTable *infos, GPtrArray *folders, GPtrArray *folders_out)
-{
- CamelFolderInfo *oldfi, *fi;
- int i;
-
- /* This is a nasty mess, because some servers will return
- broken results from LIST or LSUB if you use '%'. e.g. you
- may get (many) duplicate names, and worse, names may have
- conflicting flags. */
- for (i=0; i<folders->len; i++) {
- fi = folders->pdata[i];
- oldfi = g_hash_table_lookup(infos, fi->full_name);
- if (oldfi == NULL) {
- d(printf(" new folder '%s'\n", fi->full_name));
- g_hash_table_insert(infos, fi->full_name, fi);
- if (recurse)
- p = g_slist_prepend(p, fi);
- g_ptr_array_add(folders_out, fi);
- } else {
- d(printf(" old folder '%s', old flags %08x new flags %08x\n", fi->full_name, oldfi->flags, fi->flags));
-
- /* need to special-case noselect, since it also affects the uri */
- if ((oldfi->flags & CAMEL_FOLDER_NOSELECT) != 0
- && (fi->flags & CAMEL_FOLDER_NOSELECT) == 0) {
- g_free(oldfi->uri);
- oldfi->uri = fi->uri;
- fi->uri = NULL;
- }
-
- /* some flags are anded together, some are or'd */
-
- oldfi->flags = (oldfi->flags & fi->flags & (CAMEL_FOLDER_NOSELECT|CAMEL_FOLDER_NOINFERIORS))
- | ((oldfi->flags | fi->flags) & ~(CAMEL_FOLDER_NOSELECT|CAMEL_FOLDER_NOINFERIORS));
-
- camel_folder_info_free(fi);
- }
- }
-
- g_ptr_array_set_size(folders, 0);
-
- return p;
-}
-
-static GPtrArray *
-get_folders(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- GSList *q, *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;
-
- if (camel_debug("imap:folder_info"))
- printf(" get_folders\n");
-
- /* 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] == imap_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, imap_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 = (g_ascii_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;
- }
-
- p = get_folders_add_folders(p, TRUE, infos, folders, folders_out);
-
- /* p is a reversed list of pending folders for the next level, q is the list of folders for this */
- while (p) {
- q = g_slist_reverse(p);
-
- p = NULL;
- while (q) {
- fi = q->data;
-
- q = g_slist_remove_link(q, q);
-
- d(printf("Checking parent 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_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS)) != 0) {
- /* do nothing */
- d(printf(" not interested in folder right now ...\n"));
- }
- /* Otherwise, if this has (or might have) children, scan it */
- else if ( (fi->flags & (CAMEL_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 (camel_exception_is_set (ex))
- goto fail;
-
- if (folders->len > 0)
- fi->flags |= CAMEL_FOLDER_CHILDREN;
-
- p = get_folders_add_folders(p, (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) && depth<imap_max_depth,
- infos, folders, folders_out);
- }
- }
- 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_slist_free (p);
- 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 = NULL;
- GPtrArray *folders;
-
- if (top == NULL)
- top = "";
-
- if (camel_debug("imap:folder_info"))
- printf("get folder info online\n");
-
- CAMEL_SERVICE_LOCK(store, connect_lock);
-
- 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)
- goto done;
-
- 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);
-done:
- CAMEL_SERVICE_UNLOCK(store, connect_lock);
-
- 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;
- /* HACK: some servers report noinferiors for all folders (uw-imapd)
- We just translate this into nochildren, and let the imap layer enforce
- it. See create folder */
- if (fi->flags & CAMEL_FOLDER_NOINFERIORS)
- fi->flags = (fi->flags & ~CAMEL_FOLDER_NOINFERIORS) | CAMEL_FOLDER_NOCHILDREN;
-
- if (si->flags & CAMEL_FOLDER_NOSELECT) {
- CamelURL *url = camel_url_new(fi->uri, NULL);
-
- camel_url_set_param (url, "noselect", "yes");
- g_free(fi->uri);
- fi->uri = camel_url_to_string (url, 0);
- camel_url_free (url);
- } else {
- fill_fi((CamelStore *)imap_store, fi, 0);
- }
- 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 (camel_debug("imap:folder_info"))
- printf("get folder info offline\n");
-
- 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 (!imap_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);
- fi->flags |= CAMEL_FOLDER_NOCHILDREN;
-
- 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))
- 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 b1e3226969..0000000000
--- a/camel/providers/imap/camel-imap-store.h
+++ /dev/null
@@ -1,149 +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 <libedataserver/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,
- CAMEL_IMAP_STORE_ARG_FILTER_JUNK,
- CAMEL_IMAP_STORE_ARG_FILTER_JUNK_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)
-#define CAMEL_IMAP_STORE_FILTER_JUNK (CAMEL_IMAP_STORE_ARG_FILTER_JUNK | CAMEL_ARG_BOO)
-#define CAMEL_IMAP_STORE_FILTER_JUNK_INBOX (CAMEL_IMAP_STORE_ARG_FILTER_JUNK_INBOX | CAMEL_ARG_BOO)
-
-/* CamelFolderInfo flags */
-#define CAMEL_IMAP_FOLDER_MARKED (1<<16)
-#define CAMEL_IMAP_FOLDER_UNMARKED (1<<17)
-
-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)
-#define IMAP_PARAM_FILTER_JUNK (1 << 3)
-#define IMAP_PARAM_FILTER_JUNK_INBOX (1 << 4)
-
-struct _CamelImapStore {
- CamelDiscoStore parent_object;
-
- CamelStream *istream;
- CamelStream *ostream;
-
- struct _CamelImapStoreSummary *summary;
-
- /* Information about the command channel / connection status */
- guint connected:1;
- guint preauthed:1;
- char tag_prefix;
- guint32 command;
- CamelFolder *current_folder;
-
- /* Information about the server */
- CamelImapServerLevel server_level;
- guint32 capabilities, parameters;
- guint braindamaged:1;
- /* NB: namespace should be handled by summary->namespace */
- char *namespace, dir_sep, *base_url, *storage_path;
- GHashTable *authtypes;
-
- guint renaming:1;
-};
-
-
-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 3e1d024ab4..0000000000
--- a/camel/providers/imap/camel-imap-summary.c
+++ /dev/null
@@ -1,276 +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 (1)
-
-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 CamelMessageInfo *
-imap_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
-{
- CamelImapMessageInfo *to;
- const CamelImapMessageInfo *from = (const CamelImapMessageInfo *)mi;
-
- to = (CamelImapMessageInfo *)camel_imap_summary_parent->message_info_clone(s, mi);
- to->server_flags = from->server_flags;
-
- /* FIXME: parent clone should do this */
- to->info.content = camel_folder_summary_content_info_new(s);
-
- return (CamelMessageInfo *)to;
-}
-
-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->message_info_clone = imap_message_info_clone;
-
- 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);
-}
-
-/**
- * camel_imap_summary_new:
- * @folder: Parent folder.
- * @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 (struct _CamelFolder *folder, const char *filename)
-{
- CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (camel_object_new (camel_imap_summary_get_type ()));
-
- summary->folder = folder;
-
- 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;
-
- /* Legacy version */
- if (s->version == 0x30c)
- return camel_file_util_decode_uint32(in, &ims->validity);
-
- /* Version 1 */
- if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1
- || camel_file_util_decode_fixed_int32(in, &ims->validity) == -1)
- return -1;
-
- if (ims->version > CAMEL_IMAP_SUMMARY_VERSION) {
- g_warning("Unkown summary version\n");
- errno = EINVAL;
- return -1;
- }
-
- return 0;
-}
-
-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;
-
- camel_file_util_encode_fixed_int32(out, CAMEL_IMAP_SUMMARY_VERSION);
-
- return camel_file_util_encode_fixed_int32(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_message_info_free(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)
-{
- CamelImapMessageInfo *mi;
- const CamelFlag *flag;
- const CamelTag *tag;
-
- /* Create summary entry */
- mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message);
-
- /* Copy flags 'n' tags */
- mi->info.flags = camel_message_info_flags(info);
-
- flag = camel_message_info_user_flags(info);
- while (flag) {
- camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE);
- flag = flag->next;
- }
- tag = camel_message_info_user_tags(info);
- while (tag) {
- camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value);
- tag = tag->next;
- }
-
- mi->info.size = camel_message_info_size(info);
- mi->info.uid = g_strdup (uid);
-
- camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
-}
-
-void
-camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, const char *uid,
- const CamelMessageInfo *info)
-{
- CamelImapMessageInfo *mi;
-
- mi = camel_message_info_clone(info);
- mi->info.uid = g_strdup(uid);
- camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
-}
diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h
deleted file mode 100644
index 04fb9b829a..0000000000
--- a/camel/providers/imap/camel-imap-summary.h
+++ /dev/null
@@ -1,80 +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 << 17)
-
-typedef struct _CamelImapSummaryClass CamelImapSummaryClass;
-
-typedef struct _CamelImapMessageContentInfo {
- CamelMessageContentInfo info;
-
-} CamelImapMessageContentInfo;
-
-typedef struct _CamelImapMessageInfo {
- CamelMessageInfoBase info;
-
- guint32 server_flags;
-} CamelImapMessageInfo;
-
-struct _CamelImapSummary {
- CamelFolderSummary parent;
-
- guint32 version;
- guint32 validity;
-};
-
-struct _CamelImapSummaryClass {
- CamelFolderSummaryClass parent_class;
-
-};
-
-CamelType camel_imap_summary_get_type (void);
-CamelFolderSummary *camel_imap_summary_new (struct _CamelFolder *folder, 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 06028ef79d..0000000000
--- a/camel/providers/imap/camel-imap-utils.c
+++ /dev/null
@@ -1,1429 +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 <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.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)
-
-#define SUBFOLDER_DIR_NAME "subfolders"
-#define SUBFOLDER_DIR_NAME_LEN 10
-
-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 (g_ascii_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 (!g_ascii_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 (g_ascii_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 (g_ascii_strncasecmp (word, "LIST", 4) && g_ascii_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 (!g_ascii_strncasecmp (word, "\\NoInferiors", len))
- *flags |= CAMEL_FOLDER_NOINFERIORS;
- else if (!g_ascii_strncasecmp (word, "\\NoSelect", len))
- *flags |= CAMEL_FOLDER_NOSELECT;
- else if (!g_ascii_strncasecmp (word, "\\Marked", len))
- *flags |= CAMEL_IMAP_FOLDER_MARKED;
- else if (!g_ascii_strncasecmp (word, "\\Unmarked", len))
- *flags |= CAMEL_IMAP_FOLDER_UNMARKED;
- else if (!g_ascii_strncasecmp (word, "\\HasChildren", len))
- *flags |= CAMEL_FOLDER_CHILDREN;
- else if (!g_ascii_strncasecmp (word, "\\HasNoChildren", len))
- *flags |= CAMEL_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 && !g_ascii_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 (!g_ascii_strncasecmp (flag_list, "\\Answered", len))
- flags |= CAMEL_MESSAGE_ANSWERED;
- else if (!g_ascii_strncasecmp (flag_list, "\\Deleted", len))
- flags |= CAMEL_MESSAGE_DELETED;
- else if (!g_ascii_strncasecmp (flag_list, "\\Draft", len))
- flags |= CAMEL_MESSAGE_DRAFT;
- else if (!g_ascii_strncasecmp (flag_list, "\\Flagged", len))
- flags |= CAMEL_MESSAGE_FLAGGED;
- else if (!g_ascii_strncasecmp (flag_list, "\\Seen", len))
- flags |= CAMEL_MESSAGE_SEEN;
- else if (!g_ascii_strncasecmp (flag_list, "\\Recent", len))
- flags |= CAMEL_IMAP_MESSAGE_RECENT;
- else if (!g_ascii_strncasecmp(flag_list, "\\*", len))
- flags |= CAMEL_MESSAGE_USER;
-
- 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 / resp_secials
-
-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 ::= <"> / "\"
-
-resp_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, 0, 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 && !g_ascii_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 (!g_ascii_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 (g_ascii_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 (g_ascii_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 (g_ascii_strncasecmp (inptr, "nil", 3) != 0) {
- subtype = imap_parse_string (&inptr, &len);
- if (inptr == NULL) {
- g_free (type);
- return NULL;
- }
- } else {
- if (!g_ascii_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 (g_ascii_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 (g_ascii_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 (g_ascii_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_message_info_free(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);
-}
-
-char *
-imap_path_to_physical (const char *prefix, const char *vpath)
-{
- const char *p, *newp;
- char *dp;
- char *ppath;
- int ppath_len;
- int prefix_len;
-
- while (*vpath == '/')
- vpath++;
- if (!prefix)
- prefix = "";
-
- /* Calculate the length of the real path. */
- ppath_len = strlen (vpath);
- ppath_len++; /* For the ending zero. */
-
- prefix_len = strlen (prefix);
- ppath_len += prefix_len;
- ppath_len++; /* For the separating slash. */
-
- /* Take account of the fact that we need to translate every
- * separator into `subfolders/'.
- */
- p = vpath;
- while (1) {
- newp = strchr (p, '/');
- if (newp == NULL)
- break;
-
- ppath_len += SUBFOLDER_DIR_NAME_LEN;
- ppath_len++; /* For the separating slash. */
-
- /* Skip consecutive slashes. */
- while (*newp == '/')
- newp++;
-
- p = newp;
- };
-
- ppath = g_malloc (ppath_len);
- dp = ppath;
-
- memcpy (dp, prefix, prefix_len);
- dp += prefix_len;
- *(dp++) = '/';
-
- /* Copy the mangled path. */
- p = vpath;
- while (1) {
- newp = strchr (p, '/');
- if (newp == NULL) {
- strcpy (dp, p);
- break;
- }
-
- memcpy (dp, p, newp - p + 1); /* `+ 1' to copy the slash too. */
- dp += newp - p + 1;
-
- memcpy (dp, SUBFOLDER_DIR_NAME, SUBFOLDER_DIR_NAME_LEN);
- dp += SUBFOLDER_DIR_NAME_LEN;
-
- *(dp++) = '/';
-
- /* Skip consecutive slashes. */
- while (*newp == '/')
- newp++;
-
- p = newp;
- }
-
- return ppath;
-}
-
-static gboolean
-find_folders_recursive (const char *physical_path, const char *path,
- IMAPPathFindFoldersCallback callback, gpointer data)
-{
- DIR *dir;
- char *subfolder_directory_path;
- gboolean ok;
-
- if (*path) {
- if (!callback (physical_path, path, data))
- return FALSE;
-
- subfolder_directory_path = g_strdup_printf ("%s/%s", physical_path, SUBFOLDER_DIR_NAME);
- } else {
- /* On the top level, we have no folders and,
- * consequently, no subfolder directory.
- */
-
- subfolder_directory_path = g_strdup (physical_path);
- }
-
- /* Now scan the subfolders and load them. */
- dir = opendir (subfolder_directory_path);
- if (dir == NULL) {
- g_free (subfolder_directory_path);
- return TRUE;
- }
-
- ok = TRUE;
- while (ok) {
- struct stat file_stat;
- struct dirent *dirent;
- char *file_path;
- char *new_path;
-
- dirent = readdir (dir);
- if (dirent == NULL)
- break;
-
- if (strcmp (dirent->d_name, ".") == 0 || strcmp (dirent->d_name, "..") == 0)
- continue;
-
- file_path = g_strdup_printf ("%s/%s", subfolder_directory_path,
- dirent->d_name);
-
- if (stat (file_path, &file_stat) < 0 ||
- ! S_ISDIR (file_stat.st_mode)) {
- g_free (file_path);
- continue;
- }
-
- new_path = g_strdup_printf ("%s/%s", path, dirent->d_name);
-
- ok = find_folders_recursive (file_path, new_path, callback, data);
-
- g_free (file_path);
- g_free (new_path);
- }
-
- closedir (dir);
- g_free (subfolder_directory_path);
-
- return ok;
-}
-
-/**
- * imap_path_find_folders:
- * @prefix: directory to start from
- * @callback: Callback to invoke on each folder
- * @data: Data for @callback
- *
- * Walks the folder tree starting at @prefix and calls @callback
- * on each folder.
- *
- * Return value: %TRUE on success, %FALSE if an error occurs at any point
- **/
-gboolean
-imap_path_find_folders (const char *prefix, IMAPPathFindFoldersCallback callback, gpointer data)
-{
- return find_folders_recursive (prefix, "", callback, data);
-}
diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h
deleted file mode 100644
index 7278843a6b..0000000000
--- a/camel/providers/imap/camel-imap-utils.h
+++ /dev/null
@@ -1,100 +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);
-
-typedef gboolean (*IMAPPathFindFoldersCallback) (const char *physical_path, const char *path, gpointer user_data);
-
-char *imap_path_to_physical (const char *prefix, const char *vpath);
-gboolean imap_path_find_folders (const char *prefix, IMAPPathFindFoldersCallback callback, gpointer data);
-
-#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 7ee496dd5f..0000000000
--- a/camel/providers/imap/camel-imap-wrapper.c
+++ /dev/null
@@ -1,187 +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, CamelTransferEncoding encoding,
- 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;
- ((CamelDataWrapper *)imap_wrapper)->encoding = encoding;
-
- 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 bbb4c9468b..0000000000
--- a/camel/providers/imap/camel-imap-wrapper.h
+++ /dev/null
@@ -1,71 +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,
- CamelTransferEncoding encoding,
- 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/imap4/.cvsignore b/camel/providers/imap4/.cvsignore
deleted file mode 100644
index 08f5ed37d8..0000000000
--- a/camel/providers/imap4/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-Makefile
-Makefile.in
-*.o
-*.lo
-*.la
-.deps
-.libs
diff --git a/camel/providers/imap4/Makefile.am b/camel/providers/imap4/Makefile.am
deleted file mode 100644
index 3cdf897f6a..0000000000
--- a/camel/providers/imap4/Makefile.am
+++ /dev/null
@@ -1,42 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-camel_provider_LTLIBRARIES = libcamelimap4.la
-camel_provider_DATA = libcamelimap4.urls
-
-INCLUDES = \
- -I$(top_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-imap4-provider\"
-
-libcamelimap4_la_SOURCES = \
- camel-imap4-command.c \
- camel-imap4-command.h \
- camel-imap4-engine.c \
- camel-imap4-engine.h \
- camel-imap4-folder.c \
- camel-imap4-folder.h \
- camel-imap4-provider.c \
- camel-imap4-search.c \
- camel-imap4-search.h \
- camel-imap4-specials.c \
- camel-imap4-specials.h \
- camel-imap4-store.c \
- camel-imap4-store.h \
- camel-imap4-store-summary.c \
- camel-imap4-store-summary.h \
- camel-imap4-stream.c \
- camel-imap4-stream.h \
- camel-imap4-summary.c \
- camel-imap4-summary.h \
- camel-imap4-utils.c \
- camel-imap4-utils.h
-
-libcamelimap4_la_LDFLAGS = -avoid-version -module
-
-EXTRA_DIST = libcamelimap4.urls
diff --git a/camel/providers/imap4/camel-imap4-command.c b/camel/providers/imap4/camel-imap4-command.c
deleted file mode 100644
index e869bee9c3..0000000000
--- a/camel/providers/imap4/camel-imap4-command.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <camel/camel-stream-null.h>
-#include <camel/camel-stream-filter.h>
-#include <camel/camel-mime-filter-crlf.h>
-#include <camel/camel-i18n.h>
-
-#include "camel-imap4-stream.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-specials.h"
-
-#include "camel-imap4-command.h"
-
-
-#define d(x) x
-
-
-enum {
- IMAP4_STRING_ATOM,
- IMAP4_STRING_QSTRING,
- IMAP4_STRING_LITERAL,
-};
-
-static int
-imap4_string_get_type (const char *str)
-{
- int type = 0;
-
- while (*str) {
- if (!is_atom (*str)) {
- if (is_qsafe (*str))
- type = IMAP4_STRING_QSTRING;
- else
- return IMAP4_STRING_LITERAL;
- }
- str++;
- }
-
- return type;
-}
-
-#if 0
-static gboolean
-imap4_string_is_atom_safe (const char *str)
-{
- while (is_atom (*str))
- str++;
-
- return *str == '\0';
-}
-
-static gboolean
-imap4_string_is_quote_safe (const char *str)
-{
- while (is_qsafe (*str))
- str++;
-
- return *str == '\0';
-}
-#endif
-
-static size_t
-camel_imap4_literal_length (CamelIMAP4Literal *literal)
-{
- CamelStream *stream, *null;
- CamelMimeFilter *crlf;
- size_t len;
-
- if (literal->type == CAMEL_IMAP4_LITERAL_STRING)
- return strlen (literal->literal.string);
-
- null = camel_stream_null_new ();
- crlf = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- stream = (CamelStream *) camel_stream_filter_new_with_stream (null);
- camel_stream_filter_add ((CamelStreamFilter *) stream, crlf);
- camel_object_unref (crlf);
-
- switch (literal->type) {
- case CAMEL_IMAP4_LITERAL_STREAM:
- camel_stream_write_to_stream (literal->literal.stream, stream);
- camel_stream_reset (literal->literal.stream);
- break;
- case CAMEL_IMAP4_LITERAL_WRAPPER:
- camel_data_wrapper_write_to_stream (literal->literal.wrapper, stream);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- len = ((CamelStreamNull *) null)->written;
-
- camel_object_unref (stream);
- camel_object_unref (null);
-
- return len;
-}
-
-static CamelIMAP4CommandPart *
-command_part_new (void)
-{
- CamelIMAP4CommandPart *part;
-
- part = g_new (CamelIMAP4CommandPart, 1);
- part->next = NULL;
- part->buffer = NULL;
- part->buflen = 0;
- part->literal = NULL;
-
- return part;
-}
-
-static void
-imap4_command_append_string (CamelIMAP4Engine *engine, CamelIMAP4CommandPart **tail, GString *str, const char *string)
-{
- CamelIMAP4CommandPart *part;
- CamelIMAP4Literal *literal;
-
- switch (imap4_string_get_type (string)) {
- case IMAP4_STRING_ATOM:
- /* string is safe as it is... */
- g_string_append (str, string);
- break;
- case IMAP4_STRING_QSTRING:
- /* we need to quote the string */
- /* FIXME: need to escape stuff */
- g_string_append_printf (str, "\"%s\"", string);
- break;
- case IMAP4_STRING_LITERAL:
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_LITERALPLUS) {
- /* we have to send a literal, but the server supports LITERAL+ so use that */
- g_string_append_printf (str, "{%u+}\r\n%s", strlen (string), string);
- } else {
- /* we have to make it a literal */
- literal = g_new (CamelIMAP4Literal, 1);
- literal->type = CAMEL_IMAP4_LITERAL_STRING;
- literal->literal.string = g_strdup (string);
-
- g_string_append_printf (str, "{%u}\r\n", strlen (string));
-
- (*tail)->buffer = g_strdup (str->str);
- (*tail)->buflen = str->len;
- (*tail)->literal = literal;
-
- part = command_part_new ();
- (*tail)->next = part;
- (*tail) = part;
-
- g_string_truncate (str, 0);
- }
- break;
- }
-}
-
-CamelIMAP4Command *
-camel_imap4_command_newv (CamelIMAP4Engine *engine, CamelIMAP4Folder *imap4_folder, const char *format, va_list args)
-{
- CamelIMAP4CommandPart *parts, *part, *tail;
- CamelIMAP4Command *ic;
- const char *start;
- GString *str;
-
- tail = parts = command_part_new ();
-
- str = g_string_new ("");
- start = format;
-
- while (*format) {
- register char ch = *format++;
-
- if (ch == '%') {
- CamelIMAP4Literal *literal;
- CamelIMAP4Folder *folder;
- char *function, **strv;
- unsigned int u;
- char *string;
- size_t len;
- void *obj;
- int c, d;
-
- g_string_append_len (str, start, format - start - 1);
-
- switch (*format) {
- case '%':
- /* literal % */
- g_string_append_c (str, '%');
- break;
- case 'c':
- /* character */
- c = va_arg (args, int);
- g_string_append_c (str, c);
- break;
- case 'd':
- /* integer */
- d = va_arg (args, int);
- g_string_append_printf (str, "%d", d);
- break;
- case 'u':
- /* unsigned integer */
- u = va_arg (args, unsigned int);
- g_string_append_printf (str, "%u", u);
- break;
- case 'F':
- /* CamelIMAP4Folder */
- folder = va_arg (args, CamelIMAP4Folder *);
- string = (char *) camel_imap4_folder_utf7_name (folder);
- imap4_command_append_string (engine, &tail, str, string);
- break;
- case 'L':
- /* Literal */
- obj = va_arg (args, void *);
-
- literal = g_new (CamelIMAP4Literal, 1);
- if (CAMEL_IS_DATA_WRAPPER (obj)) {
- literal->type = CAMEL_IMAP4_LITERAL_WRAPPER;
- literal->literal.wrapper = obj;
- } else if (CAMEL_IS_STREAM (obj)) {
- literal->type = CAMEL_IMAP4_LITERAL_STREAM;
- literal->literal.stream = obj;
- } else {
- g_assert_not_reached ();
- }
-
- camel_object_ref (obj);
-
- /* FIXME: take advantage of LITERAL+? */
- len = camel_imap4_literal_length (literal);
- g_string_append_printf (str, "{%u}\r\n", len);
-
- tail->buffer = g_strdup (str->str);
- tail->buflen = str->len;
- tail->literal = literal;
-
- part = command_part_new ();
- tail->next = part;
- tail = part;
-
- g_string_truncate (str, 0);
-
- break;
- case 'V':
- /* a string vector of arguments which may need to be quoted or made into literals */
- function = str->str + str->len - 2;
- while (*function != ' ')
- function--;
- function++;
-
- function = g_strdup (function);
-
- strv = va_arg (args, char **);
- for (d = 0; strv[d]; d++) {
- if (d > 0)
- g_string_append (str, function);
- imap4_command_append_string (engine, &tail, str, strv[d]);
- }
-
- g_free (function);
- break;
- case 'S':
- /* string which may need to be quoted or made into a literal */
- string = va_arg (args, char *);
- imap4_command_append_string (engine, &tail, str, string);
- break;
- case 's':
- /* safe atom string */
- string = va_arg (args, char *);
- g_string_append (str, string);
- break;
- default:
- g_warning ("unknown formatter %%%c", *format);
- g_string_append_c (str, '%');
- g_string_append_c (str, *format);
- break;
- }
-
- format++;
-
- start = format;
- }
- }
-
- g_string_append (str, start);
- tail->buffer = str->str;
- tail->buflen = str->len;
- tail->literal = NULL;
- g_string_free (str, FALSE);
-
- ic = g_new0 (CamelIMAP4Command, 1);
- ((EDListNode *) ic)->next = NULL;
- ((EDListNode *) ic)->prev = NULL;
- ic->untagged = g_hash_table_new (g_str_hash, g_str_equal);
- ic->status = CAMEL_IMAP4_COMMAND_QUEUED;
- ic->resp_codes = g_ptr_array_new ();
- ic->engine = engine;
- ic->ref_count = 1;
- ic->parts = parts;
- ic->part = parts;
-
- camel_exception_init (&ic->ex);
-
- if (imap4_folder) {
- camel_object_ref (imap4_folder);
- ic->folder = imap4_folder;
- } else
- ic->folder = NULL;
-
- return ic;
-}
-
-CamelIMAP4Command *
-camel_imap4_command_new (CamelIMAP4Engine *engine, CamelIMAP4Folder *folder, const char *format, ...)
-{
- CamelIMAP4Command *command;
- va_list args;
-
- va_start (args, format);
- command = camel_imap4_command_newv (engine, folder, format, args);
- va_end (args);
-
- return command;
-}
-
-void
-camel_imap4_command_register_untagged (CamelIMAP4Command *ic, const char *atom, CamelIMAP4UntaggedCallback untagged)
-{
- g_hash_table_insert (ic->untagged, g_strdup (atom), untagged);
-}
-
-void
-camel_imap4_command_ref (CamelIMAP4Command *ic)
-{
- ic->ref_count++;
-}
-
-void
-camel_imap4_command_unref (CamelIMAP4Command *ic)
-{
- CamelIMAP4CommandPart *part, *next;
- int i;
-
- if (ic == NULL)
- return;
-
- ic->ref_count--;
- if (ic->ref_count == 0) {
- if (ic->folder)
- camel_object_unref (ic->folder);
-
- g_free (ic->tag);
-
- for (i = 0; i < ic->resp_codes->len; i++) {
- CamelIMAP4RespCode *resp_code;
-
- resp_code = ic->resp_codes->pdata[i];
- camel_imap4_resp_code_free (resp_code);
- }
- g_ptr_array_free (ic->resp_codes, TRUE);
-
- g_hash_table_foreach (ic->untagged, (GHFunc) g_free, NULL);
- g_hash_table_destroy (ic->untagged);
-
- camel_exception_clear (&ic->ex);
-
- part = ic->parts;
- while (part != NULL) {
- g_free (part->buffer);
- if (part->literal) {
- switch (part->literal->type) {
- case CAMEL_IMAP4_LITERAL_STRING:
- g_free (part->literal->literal.string);
- break;
- case CAMEL_IMAP4_LITERAL_STREAM:
- camel_object_unref (part->literal->literal.stream);
- break;
- case CAMEL_IMAP4_LITERAL_WRAPPER:
- camel_object_unref (part->literal->literal.wrapper);
- break;
- }
-
- g_free (part->literal);
- }
-
- next = part->next;
- g_free (part);
- part = next;
- }
-
- g_free (ic);
- }
-}
-
-
-static int
-imap4_literal_write_to_stream (CamelIMAP4Literal *literal, CamelStream *stream)
-{
- CamelStream *istream, *ostream = NULL;
- CamelDataWrapper *wrapper;
- CamelMimeFilter *crlf;
- char *string;
-
- if (literal->type == CAMEL_IMAP4_LITERAL_STRING) {
- string = literal->literal.string;
- if (camel_stream_write (stream, string, strlen (string)) == -1)
- return -1;
-
- return 0;
- }
-
- crlf = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- ostream = (CamelStream *) camel_stream_filter_new_with_stream (stream);
- camel_stream_filter_add ((CamelStreamFilter *) ostream, crlf);
- camel_object_unref (crlf);
-
- /* write the literal */
- switch (literal->type) {
- case CAMEL_IMAP4_LITERAL_STREAM:
- istream = literal->literal.stream;
- if (camel_stream_write_to_stream (istream, ostream) == -1)
- goto exception;
- break;
- case CAMEL_IMAP4_LITERAL_WRAPPER:
- wrapper = literal->literal.wrapper;
- if (camel_data_wrapper_write_to_stream (wrapper, ostream) == -1)
- goto exception;
- break;
- }
-
- camel_object_unref (ostream);
- ostream = NULL;
-
-#if 0
- if (camel_stream_write (stream, "\r\n", 2) == -1)
- return -1;
-#endif
-
- return 0;
-
- exception:
-
- camel_object_unref (ostream);
-
- return -1;
-}
-
-
-static void
-unexpected_token (camel_imap4_token_t *token)
-{
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_NO_DATA:
- fprintf (stderr, "*** NO DATA ***");
- break;
- case CAMEL_IMAP4_TOKEN_ERROR:
- fprintf (stderr, "*** ERROR ***");
- break;
- case CAMEL_IMAP4_TOKEN_NIL:
- fprintf (stderr, "NIL");
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- fprintf (stderr, "%s", token->v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- fprintf (stderr, "\"%s\"", token->v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- fprintf (stderr, "{%u}", token->v.literal);
- break;
- default:
- fprintf (stderr, "%c", (unsigned char) (token->token & 0xff));
- break;
- }
-}
-
-int
-camel_imap4_command_step (CamelIMAP4Command *ic)
-{
- CamelIMAP4Engine *engine = ic->engine;
- int result = CAMEL_IMAP4_RESULT_NONE;
- CamelIMAP4Literal *literal;
- camel_imap4_token_t token;
- unsigned char *linebuf;
- ssize_t nwritten;
- size_t len;
-
- g_assert (ic->part != NULL);
-
- if (ic->part == ic->parts) {
- ic->tag = g_strdup_printf ("%c%.5u", engine->tagprefix, engine->tag++);
- camel_stream_printf (engine->ostream, "%s ", ic->tag);
- d(fprintf (stderr, "sending: %s ", ic->tag));
- }
-
-#if d(!)0
- {
- int sending = ic->part != ic->parts;
- unsigned char *eoln, *eob;
-
- linebuf = ic->part->buffer;
- eob = linebuf + ic->part->buflen;
-
- do {
- eoln = linebuf;
- while (eoln < eob && *eoln != '\n')
- eoln++;
-
- if (eoln < eob)
- eoln++;
-
- if (sending)
- fwrite ("sending: ", 1, 10, stderr);
- fwrite (linebuf, 1, eoln - linebuf, stderr);
-
- linebuf = eoln + 1;
- sending = 1;
- } while (linebuf < eob);
- }
-#endif
-
- linebuf = ic->part->buffer;
- len = ic->part->buflen;
-
- if ((nwritten = camel_stream_write (engine->ostream, linebuf, len)) == -1) {
- camel_exception_setv (&ic->ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed sending command to IMAP server %s: %s"),
- engine->url->host, g_strerror (errno));
- goto exception;
- }
-
- if (camel_stream_flush (engine->ostream) == -1) {
- camel_exception_setv (&ic->ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed sending command to IMAP server %s: %s"),
- engine->url->host, g_strerror (errno));
- goto exception;
- }
-
- /* now we need to read the response(s) from the IMAP4 server */
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, &ic->ex) == -1)
- goto exception;
-
- if (token.token == '+') {
- /* we got a continuation response from the server */
- literal = ic->part->literal;
-
- if (camel_imap4_engine_line (engine, &linebuf, &len, &ic->ex) == -1)
- goto exception;
-
- if (literal) {
- if (imap4_literal_write_to_stream (literal, engine->ostream) == -1)
- goto exception;
-
- g_free (linebuf);
- linebuf = NULL;
-
- break;
- } else if (ic->plus) {
- /* command expected a '+' response - probably AUTHENTICATE? */
- if (ic->plus (engine, ic, linebuf, len, &ic->ex) == -1) {
- g_free (linebuf);
- return -1;
- }
-
- /* now we need to wait for a "<tag> OK/NO/BAD" response */
- } else {
- /* FIXME: error?? */
- g_assert_not_reached ();
- }
-
- g_free (linebuf);
- linebuf = NULL;
- } else if (token.token == '*') {
- /* we got an untagged response, let the engine handle this */
- if (camel_imap4_engine_handle_untagged_1 (engine, &token, &ic->ex) == -1)
- goto exception;
- } else if (token.token == CAMEL_IMAP4_TOKEN_ATOM && !strcmp (token.v.atom, ic->tag)) {
- /* we got "<tag> OK/NO/BAD" */
- d(fprintf (stderr, "got %s response\n", token.v.atom));
-
- if (camel_imap4_engine_next_token (engine, &token, &ic->ex) == -1)
- goto exception;
-
- if (token.token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!strcmp (token.v.atom, "OK"))
- result = CAMEL_IMAP4_RESULT_OK;
- else if (!strcmp (token.v.atom, "NO"))
- result = CAMEL_IMAP4_RESULT_NO;
- else if (!strcmp (token.v.atom, "BAD"))
- result = CAMEL_IMAP4_RESULT_BAD;
-
- if (result == CAMEL_IMAP4_RESULT_NONE) {
- d(fprintf (stderr, "expected OK/NO/BAD but got %s\n", token.v.atom));
- goto unexpected;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, &ic->ex) == -1)
- goto exception;
-
- if (token.token == '[') {
- /* we have a response code */
- camel_imap4_stream_unget_token (engine->istream, &token);
- if (camel_imap4_engine_parse_resp_code (engine, &ic->ex) == -1)
- goto exception;
- } else if (token.token != '\n') {
- /* just gobble up the rest of the line */
- if (camel_imap4_engine_line (engine, NULL, NULL, &ic->ex) == -1)
- goto exception;
- }
- } else {
-#if d(!)0
- fprintf (stderr, "expected anything but this: ");
- unexpected_token (&token);
- fprintf (stderr, "\n");
-#endif
-
- goto unexpected;
- }
-
- break;
- } else {
-#if d(!)0
- fprintf (stderr, "wtf is this: ");
- unexpected_token (&token);
- fprintf (stderr, "\n");
-#endif
-
- unexpected:
-
- /* no fucking clue what we got... */
- if (camel_imap4_engine_line (engine, &linebuf, &len, &ic->ex) == -1)
- goto exception;
-
- camel_exception_setv (&ic->ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unexpected response from IMAP4 server %s: %s"),
- engine->url->host, linebuf);
-
- g_free (linebuf);
-
- goto exception;
- }
- } while (1);
-
- /* status should always be ACTIVE here... */
- if (ic->status == CAMEL_IMAP4_COMMAND_ACTIVE) {
- ic->part = ic->part->next;
- if (ic->part == NULL || result) {
- ic->status = CAMEL_IMAP4_COMMAND_COMPLETE;
- ic->result = result;
- return 1;
- }
- }
-
- return 0;
-
- exception:
-
- ic->status = CAMEL_IMAP4_COMMAND_ERROR;
-
- return -1;
-}
-
-
-void
-camel_imap4_command_reset (CamelIMAP4Command *ic)
-{
- int i;
-
- for (i = 0; i < ic->resp_codes->len; i++)
- camel_imap4_resp_code_free (ic->resp_codes->pdata[i]);
- g_ptr_array_set_size (ic->resp_codes, 0);
-
- ic->status = CAMEL_IMAP4_COMMAND_QUEUED;
- ic->result = CAMEL_IMAP4_RESULT_NONE;
- ic->part = ic->parts;
- g_free (ic->tag);
- ic->tag = NULL;
-
- camel_exception_clear (&ic->ex);
-}
diff --git a/camel/providers/imap4/camel-imap4-command.h b/camel/providers/imap4/camel-imap4-command.h
deleted file mode 100644
index 112695a0db..0000000000
--- a/camel/providers/imap4/camel-imap4-command.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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_IMAP4_COMMAND_H__
-#define __CAMEL_IMAP4_COMMAND_H__
-
-#include <stdarg.h>
-
-#include <glib.h>
-
-#include <libedataserver/e-msgport.h>
-
-#include <camel/camel-stream.h>
-#include <camel/camel-exception.h>
-#include <camel/camel-data-wrapper.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-struct _CamelIMAP4Engine;
-struct _CamelIMAP4Folder;
-struct _camel_imap4_token_t;
-
-typedef struct _CamelIMAP4Command CamelIMAP4Command;
-typedef struct _CamelIMAP4Literal CamelIMAP4Literal;
-
-typedef int (* CamelIMAP4PlusCallback) (struct _CamelIMAP4Engine *engine,
- CamelIMAP4Command *ic,
- const unsigned char *linebuf,
- size_t linelen, CamelException *ex);
-
-typedef int (* CamelIMAP4UntaggedCallback) (struct _CamelIMAP4Engine *engine,
- CamelIMAP4Command *ic,
- guint32 index,
- struct _camel_imap4_token_t *token,
- CamelException *ex);
-
-enum {
- CAMEL_IMAP4_LITERAL_STRING,
- CAMEL_IMAP4_LITERAL_STREAM,
- CAMEL_IMAP4_LITERAL_WRAPPER,
-};
-
-struct _CamelIMAP4Literal {
- int type;
- union {
- char *string;
- CamelStream *stream;
- CamelDataWrapper *wrapper;
- } literal;
-};
-
-typedef struct _CamelIMAP4CommandPart {
- struct _CamelIMAP4CommandPart *next;
- unsigned char *buffer;
- size_t buflen;
-
- CamelIMAP4Literal *literal;
-} CamelIMAP4CommandPart;
-
-enum {
- CAMEL_IMAP4_COMMAND_QUEUED,
- CAMEL_IMAP4_COMMAND_ACTIVE,
- CAMEL_IMAP4_COMMAND_COMPLETE,
- CAMEL_IMAP4_COMMAND_ERROR,
-};
-
-enum {
- CAMEL_IMAP4_RESULT_NONE,
- CAMEL_IMAP4_RESULT_OK,
- CAMEL_IMAP4_RESULT_NO,
- CAMEL_IMAP4_RESULT_BAD,
-};
-
-struct _CamelIMAP4Command {
- EDListNode node;
-
- struct _CamelIMAP4Engine *engine;
-
- unsigned int ref_count:26;
- unsigned int status:3;
- unsigned int result:3;
- int id;
-
- char *tag;
-
- GPtrArray *resp_codes;
-
- struct _CamelIMAP4Folder *folder;
- CamelException ex;
-
- /* command parts - logical breaks in the overall command based on literals */
- CamelIMAP4CommandPart *parts;
-
- /* current part */
- CamelIMAP4CommandPart *part;
-
- /* untagged handlers */
- GHashTable *untagged;
-
- /* '+' callback/data */
- CamelIMAP4PlusCallback plus;
- void *user_data;
-};
-
-CamelIMAP4Command *camel_imap4_command_new (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Folder *folder,
- const char *format, ...);
-CamelIMAP4Command *camel_imap4_command_newv (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Folder *folder,
- const char *format, va_list args);
-
-void camel_imap4_command_register_untagged (CamelIMAP4Command *ic, const char *atom, CamelIMAP4UntaggedCallback untagged);
-
-void camel_imap4_command_ref (CamelIMAP4Command *ic);
-void camel_imap4_command_unref (CamelIMAP4Command *ic);
-
-/* returns 1 when complete, 0 if there is more to do, or -1 on error */
-int camel_imap4_command_step (CamelIMAP4Command *ic);
-
-void camel_imap4_command_reset (CamelIMAP4Command *ic);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_COMMAND_H__ */
diff --git a/camel/providers/imap4/camel-imap4-engine.c b/camel/providers/imap4/camel-imap4-engine.c
deleted file mode 100644
index d6f17532ee..0000000000
--- a/camel/providers/imap4/camel-imap4-engine.c
+++ /dev/null
@@ -1,1698 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <camel/camel-sasl.h>
-#include <camel/camel-stream-buffer.h>
-#include <camel/camel-i18n.h>
-
-#include "camel-imap4-summary.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-utils.h"
-
-#include "camel-imap4-engine.h"
-
-#define d(x) x
-
-
-static void camel_imap4_engine_class_init (CamelIMAP4EngineClass *klass);
-static void camel_imap4_engine_init (CamelIMAP4Engine *engine, CamelIMAP4EngineClass *klass);
-static void camel_imap4_engine_finalize (CamelObject *object);
-
-
-static CamelObjectClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_engine_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (camel_object_get_type (),
- "CamelIMAP4Engine",
- sizeof (CamelIMAP4Engine),
- sizeof (CamelIMAP4EngineClass),
- (CamelObjectClassInitFunc) camel_imap4_engine_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_engine_init,
- (CamelObjectFinalizeFunc) camel_imap4_engine_finalize);
- }
-
- return type;
-}
-
-static void
-camel_imap4_engine_class_init (CamelIMAP4EngineClass *klass)
-{
- parent_class = camel_type_get_global_classfuncs (CAMEL_OBJECT_TYPE);
-
- klass->tagprefix = 'A';
-}
-
-static void
-camel_imap4_engine_init (CamelIMAP4Engine *engine, CamelIMAP4EngineClass *klass)
-{
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
- engine->level = CAMEL_IMAP4_LEVEL_UNKNOWN;
-
- engine->session = NULL;
- engine->service = NULL;
- engine->url = NULL;
-
- engine->istream = NULL;
- engine->ostream = NULL;
-
- engine->authtypes = g_hash_table_new (g_str_hash, g_str_equal);
-
- engine->capa = 0;
-
- /* this is the suggested default, impacts the max command line length we'll send */
- engine->maxlentype = CAMEL_IMAP4_ENGINE_MAXLEN_LINE;
- engine->maxlen = 1000;
-
- engine->namespaces.personal = NULL;
- engine->namespaces.other = NULL;
- engine->namespaces.shared = NULL;
-
- if (klass->tagprefix > 'Z')
- klass->tagprefix = 'A';
-
- engine->tagprefix = klass->tagprefix++;
- engine->tag = 0;
-
- engine->nextid = 1;
-
- engine->folder = NULL;
-
- e_dlist_init (&engine->queue);
-}
-
-static void
-camel_imap4_engine_finalize (CamelObject *object)
-{
- CamelIMAP4Engine *engine = (CamelIMAP4Engine *) object;
- EDListNode *node;
-
- if (engine->istream)
- camel_object_unref (engine->istream);
-
- if (engine->ostream)
- camel_object_unref (engine->ostream);
-
- g_hash_table_foreach (engine->authtypes, (GHFunc) g_free, NULL);
- g_hash_table_destroy (engine->authtypes);
-
- camel_imap4_namespace_clear (&engine->namespaces.personal);
- camel_imap4_namespace_clear (&engine->namespaces.other);
- camel_imap4_namespace_clear (&engine->namespaces.shared);
-
- if (engine->folder)
- camel_object_unref (engine->folder);
-
- while ((node = e_dlist_remhead (&engine->queue))) {
- node->next = NULL;
- node->prev = NULL;
-
- camel_imap4_command_unref ((CamelIMAP4Command *) node);
- }
-}
-
-
-/**
- * camel_imap4_engine_new:
- * @service: service
- * @reconnect: reconnect callback function
- *
- * Returns a new imap4 engine
- **/
-CamelIMAP4Engine *
-camel_imap4_engine_new (CamelService *service, CamelIMAP4ReconnectFunc reconnect)
-{
- CamelIMAP4Engine *engine;
-
- g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL);
-
- engine = (CamelIMAP4Engine *) camel_object_new (CAMEL_TYPE_IMAP4_ENGINE);
- engine->session = service->session;
- engine->url = service->url;
- engine->service = service;
- engine->reconnect = reconnect;
-
- return engine;
-}
-
-
-/**
- * camel_imap4_engine_take_stream:
- * @engine: imap4 engine
- * @stream: tcp stream
- * @ex: exception
- *
- * Gives ownership of @stream to @engine and reads the greeting from
- * the stream.
- *
- * Returns 0 on success or -1 on fail.
- *
- * Note: on error, @stream will be unref'd.
- **/
-int
-camel_imap4_engine_take_stream (CamelIMAP4Engine *engine, CamelStream *stream, CamelException *ex)
-{
- camel_imap4_token_t token;
- int code;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_ENGINE (engine), -1);
- g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
-
- if (engine->istream)
- camel_object_unref (engine->istream);
-
- if (engine->ostream)
- camel_object_unref (engine->ostream);
-
- engine->istream = (CamelIMAP4Stream *) camel_imap4_stream_new (stream);
- engine->ostream = camel_stream_buffer_new (stream, CAMEL_STREAM_BUFFER_WRITE);
- engine->state = CAMEL_IMAP4_ENGINE_CONNECTED;
- camel_object_unref (stream);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != '*') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if ((code = camel_imap4_engine_handle_untagged_1 (engine, &token, ex)) == -1) {
- goto exception;
- } else if (code != CAMEL_IMAP4_UNTAGGED_OK && code != CAMEL_IMAP4_UNTAGGED_PREAUTH) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Unexpected greeting from IMAP server %s."),
- engine->url->host);
- goto exception;
- }
-
- return 0;
-
- exception:
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-
- camel_object_unref (engine->istream);
- engine->istream = NULL;
- camel_object_unref (engine->ostream);
- engine->ostream = NULL;
-
- return -1;
-}
-
-
-/**
- * camel_imap4_engine_capability:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Forces the IMAP4 engine to query the IMAP4 server for a list of capabilities.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_capability (CamelIMAP4Engine *engine, CamelException *ex)
-{
- CamelIMAP4Command *ic;
- int id, retval = 0;
-
- ic = camel_imap4_engine_prequeue (engine, NULL, "CAPABILITY\r\n");
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- retval = -1;
- }
-
- camel_imap4_command_unref (ic);
-
- return retval;
-}
-
-
-/**
- * camel_imap4_engine_namespace:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Forces the IMAP4 engine to query the IMAP4 server for a list of namespaces.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_list_t *list;
- GPtrArray *array = NULL;
- CamelIMAP4Command *ic;
- int id, i;
-
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_NAMESPACE) {
- ic = camel_imap4_engine_prequeue (engine, NULL, "NAMESPACE\r\n");
- } else {
- ic = camel_imap4_engine_prequeue (engine, NULL, "LIST \"\" \"\"\r\n");
- camel_imap4_command_register_untagged (ic, "LIST", camel_imap4_untagged_list);
- ic->user_data = array = g_ptr_array_new ();
- }
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
-
- if (array != NULL)
- g_ptr_array_free (array, TRUE);
-
- return -1;
- }
-
- if (array != NULL) {
- if (ic->result == CAMEL_IMAP4_RESULT_OK) {
- CamelIMAP4Namespace *namespace;
-
- g_assert (array->len == 1);
- list = array->pdata[0];
-
- namespace = g_new (CamelIMAP4Namespace, 1);
- namespace->next = NULL;
- namespace->path = g_strdup ("");
- namespace->sep = list->delim;
-
- engine->namespaces.personal = namespace;
- } else {
- /* should never *ever* happen */
- }
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- g_free (list->name);
- g_free (list);
- }
-
- g_ptr_array_free (array, TRUE);
- }
-
- camel_imap4_command_unref (ic);
-
- return 0;
-}
-
-
-/**
- * camel_imap4_engine_select_folder:
- * @engine: IMAP4 engine
- * @folder: folder to select
- * @ex: exception
- *
- * Convenience function to select @folder.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_select_folder (CamelIMAP4Engine *engine, CamelFolder *folder, CamelException *ex)
-{
- CamelIMAP4RespCode *resp;
- CamelIMAP4Command *ic;
- int id, retval = 0;
- int i;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_ENGINE (engine), -1);
- g_return_val_if_fail (CAMEL_IS_IMAP4_FOLDER (folder), -1);
-
- /* POSSIBLE FIXME: if the folder to be selected will already
- * be selected by the time the queue is emptied, simply
- * no-op? */
-
- ic = camel_imap4_engine_queue (engine, folder, "SELECT %F\r\n", folder);
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- return -1;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /*folder->mode = 0;*/
- for (i = 0; i < ic->resp_codes->len; i++) {
- resp = ic->resp_codes->pdata[i];
- switch (resp->code) {
- case CAMEL_IMAP4_RESP_CODE_PERM_FLAGS:
- folder->permanent_flags = resp->v.flags;
- break;
- case CAMEL_IMAP4_RESP_CODE_READONLY:
- /*folder->mode = CAMEL_FOLDER_MODE_READ_ONLY;*/
- break;
- case CAMEL_IMAP4_RESP_CODE_READWRITE:
- /*folder->mode = CAMEL_FOLDER_MODE_READ_WRITE;*/
- break;
- case CAMEL_IMAP4_RESP_CODE_UIDNEXT:
- camel_imap4_summary_set_uidnext (folder->summary, resp->v.uidnext);
- break;
- case CAMEL_IMAP4_RESP_CODE_UIDVALIDITY:
- camel_imap4_summary_set_uidvalidity (folder->summary, resp->v.uidvalidity);
- break;
- case CAMEL_IMAP4_RESP_CODE_UNSEEN:
- camel_imap4_summary_set_unseen (folder->summary, resp->v.unseen);
- break;
- default:
- break;
- }
- }
-
- /*if (folder->mode == 0) {
- folder->mode = CAMEL_FOLDER_MODE_READ_ONLY;
- g_warning ("Expected to find [READ-ONLY] or [READ-WRITE] in SELECT response");
- }*/
-
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot select folder `%s': Invalid mailbox name"),
- folder->full_name);
- retval = -1;
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot select folder `%s': Bad command"),
- folder->full_name);
- retval = -1;
- break;
- default:
- g_assert_not_reached ();
- retval = -1;
- }
-
- camel_imap4_command_unref (ic);
-
- return retval;
-}
-
-
-static struct {
- const char *name;
- guint32 flag;
-} imap4_capabilities[] = {
- { "IMAP4", CAMEL_IMAP4_CAPABILITY_IMAP4 },
- { "IMAP4REV1", CAMEL_IMAP4_CAPABILITY_IMAP4REV1 },
- { "STATUS", CAMEL_IMAP4_CAPABILITY_STATUS },
- { "NAMESPACE", CAMEL_IMAP4_CAPABILITY_NAMESPACE }, /* rfc2342 */
- { "UIDPLUS", CAMEL_IMAP4_CAPABILITY_UIDPLUS }, /* rfc2359 */
- { "LITERAL+", CAMEL_IMAP4_CAPABILITY_LITERALPLUS }, /* rfc2088 */
- { "LOGINDISABLED", CAMEL_IMAP4_CAPABILITY_LOGINDISABLED },
- { "STARTTLS", CAMEL_IMAP4_CAPABILITY_STARTTLS },
- { "QUOTA", CAMEL_IMAP4_CAPABILITY_QUOTA }, /* rfc2087 */
- { "ACL", CAMEL_IMAP4_CAPABILITY_ACL }, /* rfc2086 */
- { "IDLE", CAMEL_IMAP4_CAPABILITY_IDLE }, /* rfc2177 */
- { "MULTIAPPEND", CAMEL_IMAP4_CAPABILITY_MULTIAPPEND }, /* rfc3502 */
- { NULL, 0 }
-};
-
-static gboolean
-auth_free (gpointer key, gpointer value, gpointer user_data)
-{
- g_free (key);
- return TRUE;
-}
-
-static int
-engine_parse_capability (CamelIMAP4Engine *engine, int sentinel, CamelException *ex)
-{
- camel_imap4_token_t token;
- int i;
-
- engine->capa = CAMEL_IMAP4_CAPABILITY_utf8_search;
- engine->level = 0;
-
- g_hash_table_foreach_remove (engine->authtypes, (GHRFunc) auth_free, NULL);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- while (token.token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!g_ascii_strncasecmp ("AUTH=", token.v.atom, 5)) {
- CamelServiceAuthType *auth;
-
- if ((auth = camel_sasl_authtype (token.v.atom + 5)) != NULL)
- g_hash_table_insert (engine->authtypes, g_strdup (token.v.atom + 5), auth);
- } else {
- for (i = 0; imap4_capabilities[i].name; i++) {
- if (!g_ascii_strcasecmp (imap4_capabilities[i].name, token.v.atom))
- engine->capa |= imap4_capabilities[i].flag;
- }
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
- }
-
- if (token.token != sentinel) {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- /* unget our sentinel token */
- camel_imap4_stream_unget_token (engine->istream, &token);
-
- /* figure out which version of IMAP4 we are dealing with */
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_IMAP4REV1) {
- engine->level = CAMEL_IMAP4_LEVEL_IMAP4REV1;
- engine->capa |= CAMEL_IMAP4_CAPABILITY_STATUS;
- } else if (engine->capa & CAMEL_IMAP4_CAPABILITY_IMAP4) {
- engine->level = CAMEL_IMAP4_LEVEL_IMAP4;
- } else {
- engine->level = CAMEL_IMAP4_LEVEL_UNKNOWN;
- }
-
- return 0;
-}
-
-static int
-engine_parse_flags_list (CamelIMAP4Engine *engine, CamelIMAP4RespCode *resp, int perm, CamelException *ex)
-{
- guint32 flags = 0;
-
- if (camel_imap4_parse_flags_list (engine, &flags, ex) == -1)
- return-1;
-
- if (resp != NULL)
- resp->v.flags = flags;
-
- if (engine->current && engine->current->folder) {
- if (perm)
- ((CamelFolder *) engine->current->folder)->permanent_flags = flags;
- /*else
- ((CamelFolder *) engine->current->folder)->folder_flags = flags;*/
- } else if (engine->folder) {
- if (perm)
- ((CamelFolder *) engine->folder)->permanent_flags = flags;
- /*else
- ((CamelFolder *) engine->folder)->folder_flags = flags;*/
- } else {
- fprintf (stderr, "We seem to be in a bit of a pickle. we've just parsed an untagged %s\n"
- "response for a folder, yet we do not currently have a folder selected?\n",
- perm ? "PERMANENTFLAGS" : "FLAGS");
- }
-
- return 0;
-}
-
-static int
-engine_parse_flags (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_token_t token;
-
- if (engine_parse_flags_list (engine, NULL, FALSE, ex) == -1)
- return -1;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != '\n') {
- d(fprintf (stderr, "Expected to find a '\\n' token after the FLAGS response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-static int
-engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
-{
- CamelIMAP4Namespace *namespaces[3], *node, *tail;
- camel_imap4_token_t token;
- int i, n = 0;
-
- camel_imap4_namespace_clear (&engine->namespaces.personal);
- camel_imap4_namespace_clear (&engine->namespaces.other);
- camel_imap4_namespace_clear (&engine->namespaces.shared);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- do {
- namespaces[n] = NULL;
- tail = (CamelIMAP4Namespace *) &namespaces[n];
-
- if (token.token == '(') {
- /* decode the list of namespace pairs */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- while (token.token == '(') {
- /* decode a namespace pair */
-
- /* get the path name token */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != CAMEL_IMAP4_TOKEN_QSTRING) {
- d(fprintf (stderr, "Expected to find a qstring token as first element in NAMESPACE pair\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- node = g_new (CamelIMAP4Namespace, 1);
- node->next = NULL;
- node->path = g_strdup (token.v.qstring);
-
- /* get the path delimiter token */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1) {
- g_free (node->path);
- g_free (node);
-
- goto exception;
- }
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- node->sep = '\0';
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- if (strlen (token.v.qstring) == 1) {
- node->sep = *token.v.qstring;
- break;
- } else {
- /* invalid, fall thru */
- }
- default:
- d(fprintf (stderr, "Expected to find a nil or a valid qstring token as second element in NAMESPACE pair\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- g_free (node->path);
- g_free (node);
-
- goto exception;
- }
-
- tail->next = node;
- tail = node;
-
- /* canonicalise the namespace path */
- if (node->path[strlen (node->path) - 1] == node->sep)
- node->path[strlen (node->path) - 1] = '\0';
-
- /* canonicalise if this is an INBOX namespace */
- if (!g_ascii_strncasecmp (node->path, "INBOX", 5) &&
- (node->path[6] == '\0' || node->path[6] == node->sep))
- memcpy (node->path, "INBOX", 5);
-
- /* get the closing ')' for this namespace pair */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != ')') {
- d(fprintf (stderr, "Expected to find a ')' token to close the current namespace pair\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
-
- goto exception;
- }
-
- /* get the next token (should be either '(' or ')') */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
- }
-
- if (token.token != ')') {
- d(fprintf (stderr, "Expected to find a ')' to close the current namespace list\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
- } else if (token.token == CAMEL_IMAP4_TOKEN_NIL) {
- /* namespace list is NIL */
- namespaces[n] = NULL;
- } else {
- d(fprintf (stderr, "Expected to find either NIL or '(' token in untagged NAMESPACE response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- /* get the next token (should be either '(', NIL, or '\n') */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- n++;
- } while (n < 3);
-
- engine->namespaces.personal = namespaces[0];
- engine->namespaces.other = namespaces[1];
- engine->namespaces.shared = namespaces[2];
-
- return 0;
-
- exception:
-
- for (i = 0; i <= n; i++)
- camel_imap4_namespace_clear (&namespaces[i]);
-
- return -1;
-}
-
-
-/**
- *
- * resp-text-code = "ALERT" /
- * "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
- * capability-data / "PARSE" /
- * "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
- * "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
- * "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
- * "UNSEEN" SP nz-number /
- * atom [SP 1*<any TEXT-CHAR except "]">]
- **/
-
-static struct {
- const char *name;
- camel_imap4_resp_code_t code;
- int save;
-} imap4_resp_codes[] = {
- { "ALERT", CAMEL_IMAP4_RESP_CODE_ALERT, 0 },
- { "BADCHARSET", CAMEL_IMAP4_RESP_CODE_BADCHARSET, 0 },
- { "CAPABILITY", CAMEL_IMAP4_RESP_CODE_CAPABILITY, 0 },
- { "PARSE", CAMEL_IMAP4_RESP_CODE_PARSE, 1 },
- { "PERMANENTFLAGS", CAMEL_IMAP4_RESP_CODE_PERM_FLAGS, 1 },
- { "READ-ONLY", CAMEL_IMAP4_RESP_CODE_READONLY, 1 },
- { "READ-WRITE", CAMEL_IMAP4_RESP_CODE_READWRITE, 1 },
- { "TRYCREATE", CAMEL_IMAP4_RESP_CODE_TRYCREATE, 1 },
- { "UIDNEXT", CAMEL_IMAP4_RESP_CODE_UIDNEXT, 1 },
- { "UIDVALIDITY", CAMEL_IMAP4_RESP_CODE_UIDVALIDITY, 1 },
- { "UNSEEN", CAMEL_IMAP4_RESP_CODE_UNSEEN, 1 },
- { "NEWNAME", CAMEL_IMAP4_RESP_CODE_NEWNAME, 1 },
- { "APPENDUID", CAMEL_IMAP4_RESP_CODE_APPENDUID, 1 },
- { "COPYUID", CAMEL_IMAP4_RESP_CODE_COPYUID, 1 },
- { NULL, CAMEL_IMAP4_RESP_CODE_UNKNOWN, 0 }
-};
-
-
-/**
- * camel_imap4_engine_parse_resp_code:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Parses a RESP-CODE
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex)
-{
- CamelIMAP4RespCode *resp = NULL;
- camel_imap4_resp_code_t code;
- camel_imap4_token_t token;
- unsigned char *linebuf;
- size_t len;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != '[') {
- d(fprintf (stderr, "Expected a '[' token (followed by a RESP-CODE)\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM) {
- d(fprintf (stderr, "Expected an atom token containing a RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- for (code = 0; imap4_resp_codes[code].name; code++) {
- if (!strcmp (imap4_resp_codes[code].name, token.v.atom)) {
- if (engine->current && imap4_resp_codes[code].save) {
- resp = g_new0 (CamelIMAP4RespCode, 1);
- resp->code = code;
- }
- break;
- }
- }
-
- switch (code) {
- case CAMEL_IMAP4_RESP_CODE_BADCHARSET:
- /* apparently we don't support UTF-8 afterall */
- engine->capa &= ~CAMEL_IMAP4_CAPABILITY_utf8_search;
- break;
- case CAMEL_IMAP4_RESP_CODE_CAPABILITY:
- /* capability list follows */
- if (engine_parse_capability (engine, ']', ex) == -1)
- goto exception;
- break;
- case CAMEL_IMAP4_RESP_CODE_PERM_FLAGS:
- /* flag list follows */
- if (engine_parse_flags_list (engine, resp, TRUE, ex) == -1)
- goto exception;
- break;
- case CAMEL_IMAP4_RESP_CODE_READONLY:
- break;
- case CAMEL_IMAP4_RESP_CODE_READWRITE:
- break;
- case CAMEL_IMAP4_RESP_CODE_TRYCREATE:
- break;
- case CAMEL_IMAP4_RESP_CODE_UIDNEXT:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as an argument to the UIDNEXT RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.uidnext = token.v.number;
-
- break;
- case CAMEL_IMAP4_RESP_CODE_UIDVALIDITY:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as an argument to the UIDVALIDITY RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.uidvalidity = token.v.number;
-
- break;
- case CAMEL_IMAP4_RESP_CODE_UNSEEN:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as an argument to the UNSEEN RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.unseen = token.v.number;
-
- break;
- case CAMEL_IMAP4_RESP_CODE_NEWNAME:
- /* this RESP-CODE may actually be removed - see here:
- * http://www.washington.edu/imap4/listarch/2001/msg00058.html */
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_QSTRING) {
- d(fprintf (stderr, "Expected an atom or qstring token as the first argument to the NEWNAME RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.newname[0] = g_strdup (token.v.atom);
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_QSTRING) {
- d(fprintf (stderr, "Expected an atom or qstring token as the second argument to the NEWNAME RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.newname[1] = g_strdup (token.v.atom);
-
- break;
- case CAMEL_IMAP4_RESP_CODE_APPENDUID:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as the first argument to the APPENDUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.appenduid.uidvalidity = token.v.number;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as the second argument to the APPENDUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.appenduid.uid = token.v.number;
-
- break;
- case CAMEL_IMAP4_RESP_CODE_COPYUID:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as the first argument to the COPYUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.copyuid.uidvalidity = token.v.number;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an atom or numeric token as the second argument to the COPYUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL) {
- if (token.token == CAMEL_IMAP4_TOKEN_NUMBER)
- resp->v.copyuid.srcset = g_strdup_printf ("%u", token.v.number);
- else
- resp->v.copyuid.srcset = g_strdup (token.v.atom);
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an atom or numeric token as the third argument to the APPENDUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL) {
- if (token.token == CAMEL_IMAP4_TOKEN_NUMBER)
- resp->v.copyuid.destset = g_strdup_printf ("%u", token.v.number);
- else
- resp->v.copyuid.destset = g_strdup (token.v.atom);
- }
-
- break;
- default:
- d(fprintf (stderr, "Unknown RESP-CODE encountered: %s\n", token.v.atom));
-
- /* extensions are of the form: "[" atom [SPACE 1*<any TEXT_CHAR except "]">] "]" */
-
- /* eat up the TEXT_CHARs */
- while (token.token != ']' && token.token != '\n') {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
- }
-
- break;
- }
-
- while (token.token != ']' && token.token != '\n') {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
- }
-
- if (token.token != ']') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- d(fprintf (stderr, "Expected to find a ']' token after the RESP-CODE\n"));
- return -1;
- }
-
- if (code == CAMEL_IMAP4_RESP_CODE_ALERT) {
- if (camel_imap4_engine_line (engine, &linebuf, &len, ex) == -1)
- goto exception;
-
- camel_session_alert_user (engine->session, CAMEL_SESSION_ALERT_INFO, linebuf, FALSE);
- g_free (linebuf);
- } else if (resp != NULL && code == CAMEL_IMAP4_RESP_CODE_PARSE) {
- if (camel_imap4_engine_line (engine, &linebuf, &len, ex) == -1)
- goto exception;
-
- resp->v.parse = linebuf;
- } else {
- /* eat up the rest of the response */
- if (camel_imap4_engine_line (engine, NULL, NULL, ex) == -1)
- goto exception;
- }
-
- if (resp != NULL)
- g_ptr_array_add (engine->current->resp_codes, resp);
-
- return 0;
-
- exception:
-
- if (resp != NULL)
- camel_imap4_resp_code_free (resp);
-
- return -1;
-}
-
-
-/**
- * camel_imap4_engine_handle_untagged_1:
- * @engine: IMAP4 engine
- * @token: IMAP4 token
- * @ex: exception
- *
- * Handles a single untagged response
- *
- * Returns -1 on error or one of
- * CAMEL_IMAP4_UNTAGGED_[OK,NO,BAD,PREAUTH,HANDLED] on success
- **/
-int
-camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
-{
- int code = CAMEL_IMAP4_UNTAGGED_HANDLED;
- CamelIMAP4Command *ic = engine->current;
- CamelIMAP4UntaggedCallback untagged;
- CamelFolder *folder;
- unsigned int v;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!strcmp ("BYE", token->v.atom)) {
- /* we don't care if we fail here, either way we've been disconnected */
- if (camel_imap4_engine_next_token (engine, token, NULL) == 0) {
- if (token->token == '[') {
- camel_imap4_stream_unget_token (engine->istream, token);
- camel_imap4_engine_parse_resp_code (engine, NULL);
- } else {
- camel_imap4_engine_line (engine, NULL, NULL, NULL);
- }
- }
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-
- /* we don't return -1 here because there may be more untagged responses after the BYE */
- } else if (!strcmp ("CAPABILITY", token->v.atom)) {
- /* capability tokens follow */
- if (engine_parse_capability (engine, '\n', ex) == -1)
- return -1;
-
- /* find the eoln token */
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != '\n') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
- } else if (!strcmp ("FLAGS", token->v.atom)) {
- /* flags list follows */
- if (engine_parse_flags (engine, ex) == -1)
- return -1;
- } else if (!strcmp ("NAMESPACE", token->v.atom)) {
- if (engine_parse_namespace (engine, ex) == -1)
- return -1;
- } else if (!strcmp ("NO", token->v.atom) || !strcmp ("BAD", token->v.atom)) {
- code = !strcmp ("NO", token->v.atom) ? CAMEL_IMAP4_UNTAGGED_NO : CAMEL_IMAP4_UNTAGGED_BAD;
-
- /* our command has been rejected */
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token == '[') {
- /* we have a resp code */
- camel_imap4_stream_unget_token (engine->istream, token);
- if (camel_imap4_engine_parse_resp_code (engine, ex) == -1)
- return -1;
- } else if (token->token != '\n') {
- /* we just have resp text */
- if (camel_imap4_engine_line (engine, NULL, NULL, ex) == -1)
- return -1;
- }
- } else if (!strcmp ("OK", token->v.atom)) {
- code = CAMEL_IMAP4_UNTAGGED_OK;
-
- if (engine->state == CAMEL_IMAP4_ENGINE_CONNECTED) {
- /* initial server greeting */
- engine->state = CAMEL_IMAP4_ENGINE_PREAUTH;
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token == '[') {
- /* we have a resp code */
- camel_imap4_stream_unget_token (engine->istream, token);
- if (camel_imap4_engine_parse_resp_code (engine, ex) == -1)
- return -1;
- } else {
- /* we just have resp text */
- if (camel_imap4_engine_line (engine, NULL, NULL, ex) == -1)
- return -1;
- }
- } else if (!strcmp ("PREAUTH", token->v.atom)) {
- code = CAMEL_IMAP4_UNTAGGED_PREAUTH;
-
- if (engine->state == CAMEL_IMAP4_ENGINE_CONNECTED)
- engine->state = CAMEL_IMAP4_ENGINE_AUTHENTICATED;
-
- if (camel_imap4_engine_parse_resp_code (engine, ex) == -1)
- return -1;
- } else if (ic && (untagged = g_hash_table_lookup (ic->untagged, token->v.atom))) {
- /* registered untagged handler for imap4 command */
- if (untagged (engine, ic, 0, token, ex) == -1)
- return -1;
- } else {
- d(fprintf (stderr, "Unhandled atom token in untagged response: %s", token->v.atom));
-
- if (camel_imap4_engine_eat_line (engine, ex) == -1)
- return -1;
- }
- } else if (token->token == CAMEL_IMAP4_TOKEN_NUMBER) {
- /* we probably have something like "* 1 EXISTS" */
- v = token->v.number;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != CAMEL_IMAP4_TOKEN_ATOM) {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- return -1;
- }
-
- /* which folder is this EXISTS/EXPUNGE/RECENT acting on? */
- if (engine->current && engine->current->folder)
- folder = (CamelFolder *) engine->current->folder;
- else if (engine->folder)
- folder = (CamelFolder *) engine->folder;
- else
- folder = NULL;
-
- /* NOTE: these can be over-ridden by a registered untagged response handler */
- if (!strcmp ("EXISTS", token->v.atom)) {
- camel_imap4_summary_set_exists (folder->summary, v);
- } else if (!strcmp ("EXPUNGE", token->v.atom)) {
- camel_imap4_summary_expunge (folder->summary, (int) v);
- } else if (!strcmp ("RECENT", token->v.atom)) {
- camel_imap4_summary_set_recent (folder->summary, v);
- } else if (ic && (untagged = g_hash_table_lookup (ic->untagged, token->v.atom))) {
- /* registered untagged handler for imap4 command */
- if (untagged (engine, ic, v, token, ex) == -1)
- return -1;
- } else {
- d(fprintf (stderr, "Unrecognized untagged response: * %u %s\n", v, token->v.atom));
- }
-
- /* find the eoln token */
- if (camel_imap4_engine_eat_line (engine, ex) == -1)
- return -1;
- } else {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- return -1;
- }
-
- return code;
-}
-
-
-/**
- * camel_imap4_engine_handle_untagged:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Handle a stream of untagged responses.
- **/
-void
-camel_imap4_engine_handle_untagged (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_token_t token;
-
- g_return_if_fail (CAMEL_IS_IMAP4_ENGINE (engine));
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != '*')
- break;
-
- if (camel_imap4_engine_handle_untagged_1 (engine, &token, ex) == -1)
- goto exception;
- } while (1);
-
- camel_imap4_stream_unget_token (engine->istream, &token);
-
- return;
-
- exception:
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-}
-
-
-static int
-imap4_process_command (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
-{
- int retval;
-
- while ((retval = camel_imap4_command_step (ic)) == 0)
- ;
-
- if (retval == -1) {
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
- return -1;
- }
-
- return 0;
-}
-
-
-static void
-engine_prequeue_folder_select (CamelIMAP4Engine *engine)
-{
- CamelIMAP4Command *ic;
- const char *cmd;
-
- ic = (CamelIMAP4Command *) engine->queue.head;
- cmd = (const char *) ic->parts->buffer;
-
- if (!ic->folder || ic->folder == engine->folder ||
- !strncmp (cmd, "SELECT ", 7) || !strncmp (cmd, "EXAMINE ", 8)) {
- /* no need to pre-queue a SELECT */
- return;
- }
-
- /* we need to pre-queue a SELECT */
- ic = camel_imap4_engine_prequeue (engine, (CamelFolder *) ic->folder, "SELECT %F\r\n", ic->folder);
- ic->user_data = engine;
-
- camel_imap4_command_unref (ic);
-}
-
-
-static int
-engine_state_change (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
-{
- const char *cmd;
- int retval = 0;
-
- cmd = ic->parts->buffer;
- if (!strncmp (cmd, "SELECT ", 7) || !strncmp (cmd, "EXAMINE ", 8)) {
- if (ic->result == CAMEL_IMAP4_RESULT_OK) {
- /* Update the selected folder */
- camel_object_ref (ic->folder);
- if (engine->folder)
- camel_object_unref (engine->folder);
- engine->folder = ic->folder;
-
- engine->state = CAMEL_IMAP4_ENGINE_SELECTED;
- } else if (ic->user_data == engine) {
- /* the engine pre-queued this SELECT command */
- retval = -1;
- }
- } else if (!strncmp (cmd, "CLOSE", 5)) {
- if (ic->result == CAMEL_IMAP4_RESULT_OK)
- engine->state = CAMEL_IMAP4_ENGINE_AUTHENTICATED;
- } else if (!strncmp (cmd, "LOGOUT", 6)) {
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
- }
-
- return retval;
-}
-
-
-/**
- * camel_imap4_engine_iterate:
- * @engine: IMAP4 engine
- *
- * Processes the first command in the queue.
- *
- * Returns the id of the processed command, 0 if there were no
- * commands to process, or -1 on error.
- *
- * Note: more details on the error will be held on the
- * CamelIMAP4Command that failed.
- **/
-int
-camel_imap4_engine_iterate (CamelIMAP4Engine *engine)
-{
- CamelIMAP4Command *ic, *nic;
- GPtrArray *resp_codes;
- int retval = -1;
-
- if (e_dlist_empty (&engine->queue))
- return 0;
-
- /* This sucks... it would be nicer if we didn't have to check the stream's disconnected status */
- if ((engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED || engine->istream->disconnected) && !engine->reconnecting) {
- CamelException rex;
- gboolean connected;
-
- camel_exception_init (&rex);
- engine->reconnecting = TRUE;
- connected = engine->reconnect (engine, &rex);
- engine->reconnecting = FALSE;
-
- if (!connected) {
- /* pop the first command and act as tho it failed (which, technically, it did...) */
- ic = (CamelIMAP4Command *) e_dlist_remhead (&engine->queue);
- ic->status = CAMEL_IMAP4_COMMAND_ERROR;
- camel_exception_xfer (&ic->ex, &rex);
- return -1;
- }
- }
-
- /* check to see if we need to pre-queue a SELECT, if so do it */
- engine_prequeue_folder_select (engine);
-
- engine->current = ic = (CamelIMAP4Command *) e_dlist_remhead (&engine->queue);
- ic->status = CAMEL_IMAP4_COMMAND_ACTIVE;
-
- if (imap4_process_command (engine, ic) != -1) {
- if (engine_state_change (engine, ic) == -1) {
- /* This can ONLY happen if @ic was the pre-queued SELECT command
- * and it got a NO or BAD response.
- *
- * We have to pop the next imap4 command or we'll get into an
- * infinite loop. In order to provide @nic's owner with as much
- * information as possible, we move all @ic status information
- * over to @nic and pretend we just processed @nic.
- **/
-
- nic = (CamelIMAP4Command *) e_dlist_remhead (&engine->queue);
-
- nic->status = ic->status;
- nic->result = ic->result;
- resp_codes = nic->resp_codes;
- nic->resp_codes = ic->resp_codes;
- ic->resp_codes = resp_codes;
-
- camel_exception_xfer (&nic->ex, &ic->ex);
-
- camel_imap4_command_unref (ic);
- ic = nic;
- }
-
- retval = ic->id;
- }
-
- camel_imap4_command_unref (ic);
-
- return retval;
-}
-
-
-/**
- * camel_imap4_engine_queue:
- * @engine: IMAP4 engine
- * @folder: IMAP4 folder that the command will affect (or %NULL if it doesn't matter)
- * @format: command format
- * @Varargs: arguments
- *
- * Basically the same as camel_imap4_command_new() except that this
- * function also places the command in the engine queue.
- *
- * Returns the CamelIMAP4Command.
- **/
-CamelIMAP4Command *
-camel_imap4_engine_queue (CamelIMAP4Engine *engine, CamelFolder *folder, const char *format, ...)
-{
- CamelIMAP4Command *ic;
- va_list args;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_ENGINE (engine), NULL);
-
- va_start (args, format);
- ic = camel_imap4_command_newv (engine, (CamelIMAP4Folder *) folder, format, args);
- va_end (args);
-
- ic->id = engine->nextid++;
- e_dlist_addtail (&engine->queue, (EDListNode *) ic);
- camel_imap4_command_ref (ic);
-
- return ic;
-}
-
-
-/**
- * camel_imap4_engine_prequeue:
- * @engine: IMAP4 engine
- * @folder: IMAP4 folder that the command will affect (or %NULL if it doesn't matter)
- * @format: command format
- * @Varargs: arguments
- *
- * Same as camel_imap4_engine_queue() except this places the new
- * command at the head of the queue.
- *
- * Returns the CamelIMAP4Command.
- **/
-CamelIMAP4Command *
-camel_imap4_engine_prequeue (CamelIMAP4Engine *engine, CamelFolder *folder, const char *format, ...)
-{
- CamelIMAP4Command *ic;
- va_list args;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_ENGINE (engine), NULL);
-
- va_start (args, format);
- ic = camel_imap4_command_newv (engine, (CamelIMAP4Folder *) folder, format, args);
- va_end (args);
-
- if (e_dlist_empty (&engine->queue)) {
- e_dlist_addtail (&engine->queue, (EDListNode *) ic);
- ic->id = engine->nextid++;
- } else {
- CamelIMAP4Command *nic;
- EDListNode *node;
-
- node = (EDListNode *) ic;
- e_dlist_addhead (&engine->queue, node);
- nic = (CamelIMAP4Command *) node->next;
- ic->id = nic->id - 1;
-
- if (ic->id == 0) {
- /* increment all command ids */
- node = engine->queue.head;
- while (node->next) {
- nic = (CamelIMAP4Command *) node;
- node = node->next;
- nic->id++;
- }
- }
- }
-
- camel_imap4_command_ref (ic);
-
- return ic;
-}
-
-
-/**
- * camel_imap4_engine_dequeue:
- * @engine: IMAP4 engine
- * @ic: IMAP4 command
- *
- * Removes @ic from the processing queue.
- **/
-void
-camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
-{
- EDListNode *node = (EDListNode *) ic;
-
- if (node->next == NULL && node->prev == NULL)
- return;
-
- e_dlist_remove (node);
- node->next = NULL;
- node->prev = NULL;
-
- camel_imap4_command_unref (ic);
-}
-
-
-/**
- * camel_imap4_engine_next_token:
- * @engine: IMAP4 engine
- * @token: IMAP4 token
- * @ex: exception
- *
- * Wraps camel_imap4_stream_next_token() to set an exception on
- * failure and updates the engine state to DISCONNECTED if the stream
- * gets disconencted.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
-{
- if (camel_imap4_stream_next_token (engine->istream, token) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_engine_eat_line:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Gobbles up the remainder of the response line.
- *
- * Returns 0 on success or -1 on fail
- **/
-int
-camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_token_t token;
- unsigned char *literal;
- int retval;
- size_t n;
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token == CAMEL_IMAP4_TOKEN_LITERAL) {
- while ((retval = camel_imap4_stream_literal (engine->istream, &literal, &n)) == 1)
- ;
-
- if (retval == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-
- return -1;
- }
- }
- } while (token.token != '\n');
-
- return 0;
-}
-
-
-/**
- * camel_imap4_engine_line:
- * @engine: IMAP4 engine
- * @line: line pointer
- * @len: length pointer
- * @ex: exception
- *
- * Reads in a single line of input from the IMAP4 server and updates
- * @line to point to the line buffer. @len is set to the length of the
- * line buffer. @line must be free'd using g_free().
- *
- * Returns 0 on success or -1 on fail
- **/
-int
-camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t *len, CamelException *ex)
-{
- GByteArray *linebuf = NULL;
- unsigned char *buf;
- size_t buflen;
- int retval;
-
- if (line != NULL)
- linebuf = g_byte_array_new ();
-
- while ((retval = camel_imap4_stream_line (engine->istream, &buf, &buflen)) > 0) {
- if (linebuf != NULL)
- g_byte_array_append (linebuf, buf, buflen);
- }
-
- if (retval == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
-
- if (linebuf != NULL)
- g_byte_array_free (linebuf, TRUE);
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-
- return -1;
- }
-
- if (linebuf != NULL) {
- g_byte_array_append (linebuf, buf, buflen);
-
- *line = linebuf->data;
- *len = linebuf->len;
-
- g_byte_array_free (linebuf, FALSE);
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_engine_literal:
- * @engine: IMAP4 engine
- * @literal: literal pointer
- * @len: len pointer
- * @ex: exception
- *
- * Reads in an entire literal string and updates @literal to point to
- * it. @len is set to the length of the literal. @literal will also
- * conveniently be terminated with a nul-byte. @literal must be free'd
- * using g_free().
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, size_t *len, CamelException *ex)
-{
- GByteArray *literalbuf = NULL;
- unsigned char *buf;
- size_t buflen;
- int retval;
-
- if (literal != NULL)
- literalbuf = g_byte_array_new ();
-
- while ((retval = camel_imap4_stream_literal (engine->istream, &buf, &buflen)) > 0) {
- if (literalbuf != NULL)
- g_byte_array_append (literalbuf, buf, buflen);
- }
-
- if (retval == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
-
- if (literalbuf != NULL)
- g_byte_array_free (literalbuf, TRUE);
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-
- return -1;
- }
-
- if (literalbuf != NULL) {
- g_byte_array_append (literalbuf, buf, buflen);
- g_byte_array_append (literalbuf, "", 1);
-
- *literal = literalbuf->data;
- *len = literalbuf->len - 1;
-
- g_byte_array_free (literalbuf, FALSE);
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_engine_nstring:
- * @engine: IMAP4 engine
- * @nstring: nstring pointer
- * @ex: exception
- *
- * Reads in an nstring (NIL, atom, qstring or literal) and updates
- * @nstring to point to it. @nstring must be free'd using g_free().
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_nstring (CamelIMAP4Engine *engine, unsigned char **nstring, CamelException *ex)
-{
- camel_imap4_token_t token;
- size_t n;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- *nstring = NULL;
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- *nstring = g_strdup (token.v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- *nstring = g_strdup (token.v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, nstring, &n, ex) == -1)
- return -1;
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_resp_code_free:
- * @rcode: RESP-CODE
- *
- * Free's the RESP-CODE
- **/
-void
-camel_imap4_resp_code_free (CamelIMAP4RespCode *rcode)
-{
- switch (rcode->code) {
- case CAMEL_IMAP4_RESP_CODE_PARSE:
- g_free (rcode->v.parse);
- break;
- case CAMEL_IMAP4_RESP_CODE_NEWNAME:
- g_free (rcode->v.newname[0]);
- g_free (rcode->v.newname[1]);
- break;
- case CAMEL_IMAP4_RESP_CODE_COPYUID:
- g_free (rcode->v.copyuid.srcset);
- g_free (rcode->v.copyuid.destset);
- break;
- default:
- break;
- }
-
- g_free (rcode);
-}
diff --git a/camel/providers/imap4/camel-imap4-engine.h b/camel/providers/imap4/camel-imap4-engine.h
deleted file mode 100644
index b4d8df2e8d..0000000000
--- a/camel/providers/imap4/camel-imap4-engine.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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_IMAP4_ENGINE_H__
-#define __CAMEL_IMAP4_ENGINE_H__
-
-#include <stdarg.h>
-
-#include <glib.h>
-
-#include <libedataserver/e-msgport.h>
-
-#include <camel/camel-stream.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-session.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_ENGINE (camel_imap4_engine_get_type ())
-#define CAMEL_IMAP4_ENGINE(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_ENGINE, CamelIMAP4Engine))
-#define CAMEL_IMAP4_ENGINE_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP4_ENGINE, CamelIMAP4EngineClass))
-#define CAMEL_IS_IMAP4_ENGINE(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP4_ENGINE))
-#define CAMEL_IS_IMAP4_ENGINE_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP4_ENGINE))
-#define CAMEL_IMAP4_ENGINE_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_IMAP4_ENGINE, CamelIMAP4EngineClass))
-
-typedef struct _CamelIMAP4Engine CamelIMAP4Engine;
-typedef struct _CamelIMAP4EngineClass CamelIMAP4EngineClass;
-
-struct _camel_imap4_token_t;
-struct _CamelIMAP4Command;
-struct _CamelIMAP4Folder;
-struct _CamelIMAP4Stream;
-
-typedef enum {
- CAMEL_IMAP4_ENGINE_DISCONNECTED,
- CAMEL_IMAP4_ENGINE_CONNECTED,
- CAMEL_IMAP4_ENGINE_PREAUTH,
- CAMEL_IMAP4_ENGINE_AUTHENTICATED,
- CAMEL_IMAP4_ENGINE_SELECTED,
-} camel_imap4_engine_t;
-
-typedef enum {
- CAMEL_IMAP4_LEVEL_UNKNOWN,
- CAMEL_IMAP4_LEVEL_IMAP4,
- CAMEL_IMAP4_LEVEL_IMAP4REV1
-} camel_imap4_level_t;
-
-enum {
- CAMEL_IMAP4_CAPABILITY_IMAP4 = (1 << 0),
- CAMEL_IMAP4_CAPABILITY_IMAP4REV1 = (1 << 1),
- CAMEL_IMAP4_CAPABILITY_STATUS = (1 << 2),
- CAMEL_IMAP4_CAPABILITY_NAMESPACE = (1 << 3),
- CAMEL_IMAP4_CAPABILITY_UIDPLUS = (1 << 4),
- CAMEL_IMAP4_CAPABILITY_LITERALPLUS = (1 << 5),
- CAMEL_IMAP4_CAPABILITY_LOGINDISABLED = (1 << 6),
- CAMEL_IMAP4_CAPABILITY_STARTTLS = (1 << 7),
- CAMEL_IMAP4_CAPABILITY_IDLE = (1 << 8),
- CAMEL_IMAP4_CAPABILITY_QUOTA = (1 << 9),
- CAMEL_IMAP4_CAPABILITY_ACL = (1 << 10),
- CAMEL_IMAP4_CAPABILITY_MULTIAPPEND = (1 << 11),
- CAMEL_IMAP4_CAPABILITY_useful_lsub = (1 << 12),
- CAMEL_IMAP4_CAPABILITY_utf8_search = (1 << 13),
-};
-
-typedef enum {
- CAMEL_IMAP4_RESP_CODE_ALERT,
- CAMEL_IMAP4_RESP_CODE_BADCHARSET,
- CAMEL_IMAP4_RESP_CODE_CAPABILITY,
- CAMEL_IMAP4_RESP_CODE_PARSE,
- CAMEL_IMAP4_RESP_CODE_PERM_FLAGS,
- CAMEL_IMAP4_RESP_CODE_READONLY,
- CAMEL_IMAP4_RESP_CODE_READWRITE,
- CAMEL_IMAP4_RESP_CODE_TRYCREATE,
- CAMEL_IMAP4_RESP_CODE_UIDNEXT,
- CAMEL_IMAP4_RESP_CODE_UIDVALIDITY,
- CAMEL_IMAP4_RESP_CODE_UNSEEN,
- CAMEL_IMAP4_RESP_CODE_NEWNAME,
- CAMEL_IMAP4_RESP_CODE_APPENDUID,
- CAMEL_IMAP4_RESP_CODE_COPYUID,
- CAMEL_IMAP4_RESP_CODE_UNKNOWN,
-} camel_imap4_resp_code_t;
-
-typedef struct _CamelIMAP4RespCode {
- camel_imap4_resp_code_t code;
- union {
- guint32 flags;
- char *parse;
- guint32 uidnext;
- guint32 uidvalidity;
- guint32 unseen;
- char *newname[2];
- struct {
- guint32 uidvalidity;
- guint32 uid;
- } appenduid;
- struct {
- guint32 uidvalidity;
- char *srcset;
- char *destset;
- } copyuid;
- } v;
-} CamelIMAP4RespCode;
-
-enum {
- CAMEL_IMAP4_UNTAGGED_ERROR = -1,
- CAMEL_IMAP4_UNTAGGED_OK,
- CAMEL_IMAP4_UNTAGGED_NO,
- CAMEL_IMAP4_UNTAGGED_BAD,
- CAMEL_IMAP4_UNTAGGED_PREAUTH,
- CAMEL_IMAP4_UNTAGGED_HANDLED,
-};
-
-typedef struct _CamelIMAP4Namespace {
- struct _CamelIMAP4Namespace *next;
- char *path;
- char sep;
-} CamelIMAP4Namespace;
-
-typedef struct _CamelIMAP4NamespaceList {
- CamelIMAP4Namespace *personal;
- CamelIMAP4Namespace *other;
- CamelIMAP4Namespace *shared;
-} CamelIMAP4NamespaceList;
-
-enum {
- CAMEL_IMAP4_ENGINE_MAXLEN_LINE,
- CAMEL_IMAP4_ENGINE_MAXLEN_TOKEN
-};
-
-typedef gboolean (* CamelIMAP4ReconnectFunc) (CamelIMAP4Engine *engine, CamelException *ex);
-
-struct _CamelIMAP4Engine {
- CamelObject parent_object;
-
- CamelIMAP4ReconnectFunc reconnect;
- gboolean reconnecting;
-
- CamelSession *session;
- CamelService *service;
- CamelURL *url;
-
- camel_imap4_engine_t state;
- camel_imap4_level_t level;
- guint32 capa;
-
- guint32 maxlen:31;
- guint32 maxlentype:1;
-
- CamelIMAP4NamespaceList namespaces;
- GHashTable *authtypes; /* supported authtypes */
-
- struct _CamelIMAP4Stream *istream;
- CamelStream *ostream;
-
- unsigned char tagprefix; /* 'A'..'Z' */
- unsigned int tag; /* next command tag */
- int nextid;
-
- struct _CamelIMAP4Folder *folder; /* currently selected folder */
-
- EDList queue; /* queue of waiting commands */
- struct _CamelIMAP4Command *current;
-};
-
-struct _CamelIMAP4EngineClass {
- CamelObjectClass parent_class;
-
- unsigned char tagprefix;
-};
-
-
-CamelType camel_imap4_engine_get_type (void);
-
-CamelIMAP4Engine *camel_imap4_engine_new (CamelService *service, CamelIMAP4ReconnectFunc reconnect);
-
-/* returns 0 on success or -1 on error */
-int camel_imap4_engine_take_stream (CamelIMAP4Engine *engine, CamelStream *stream, CamelException *ex);
-
-int camel_imap4_engine_capability (CamelIMAP4Engine *engine, CamelException *ex);
-int camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex);
-
-int camel_imap4_engine_select_folder (CamelIMAP4Engine *engine, CamelFolder *folder, CamelException *ex);
-
-struct _CamelIMAP4Command *camel_imap4_engine_queue (CamelIMAP4Engine *engine, CamelFolder *folder,
- const char *format, ...);
-struct _CamelIMAP4Command *camel_imap4_engine_prequeue (CamelIMAP4Engine *engine, CamelFolder *folder,
- const char *format, ...);
-
-void camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, struct _CamelIMAP4Command *ic);
-
-int camel_imap4_engine_iterate (CamelIMAP4Engine *engine);
-
-
-/* untagged response utility functions */
-int camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, struct _camel_imap4_token_t *token, CamelException *ex);
-void camel_imap4_engine_handle_untagged (CamelIMAP4Engine *engine, CamelException *ex);
-
-/* stream wrapper utility functions */
-int camel_imap4_engine_next_token (CamelIMAP4Engine *engine, struct _camel_imap4_token_t *token, CamelException *ex);
-int camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t *len, CamelException *ex);
-int camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, size_t *len, CamelException *ex);
-int camel_imap4_engine_nstring (CamelIMAP4Engine *engine, unsigned char **nstring, CamelException *ex);
-int camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex);
-
-
-/* response code stuff */
-int camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex);
-void camel_imap4_resp_code_free (CamelIMAP4RespCode *rcode);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_ENGINE_H__ */
diff --git a/camel/providers/imap4/camel-imap4-folder.c b/camel/providers/imap4/camel-imap4-folder.c
deleted file mode 100644
index 9326dd418f..0000000000
--- a/camel/providers/imap4/camel-imap4-folder.c
+++ /dev/null
@@ -1,1178 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <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 <time.h>
-
-#include <camel/camel-utf8.h>
-#include <camel/camel-private.h>
-#include <camel/camel-file-utils.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-stream-filter.h>
-#include <camel/camel-mime-filter-crlf.h>
-#include <camel/camel-i18n.h>
-
-#include "camel-imap4-utils.h"
-#include "camel-imap4-store.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-summary.h"
-#include "camel-imap4-search.h"
-
-#define d(x) x
-
-static GSList *imap4_folder_props = NULL;
-
-static CamelProperty imap4_prop_list[] = {
- { CAMEL_IMAP4_FOLDER_SYNC_OFFLINE, "sync_offline", N_("Copy folder content locally for offline operation") },
-};
-
-static void camel_imap4_folder_class_init (CamelIMAP4FolderClass *klass);
-static void camel_imap4_folder_init (CamelIMAP4Folder *folder, CamelIMAP4FolderClass *klass);
-static void camel_imap4_folder_finalize (CamelObject *object);
-
-static int imap4_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args);
-static int imap4_setv (CamelObject *object, CamelException *ex, CamelArgV *args);
-
-static void imap4_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
-static void imap4_refresh_info (CamelFolder *folder, CamelException *ex);
-static void imap4_expunge (CamelFolder *folder, CamelException *ex);
-static CamelMimeMessage *imap4_get_message (CamelFolder *folder, const char *uid, CamelException *ex);
-static void imap4_append_message (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid, CamelException *ex);
-static void imap4_transfer_messages_to (CamelFolder *src, GPtrArray *uids, CamelFolder *dest,
- GPtrArray **transferred_uids, gboolean move, CamelException *ex);
-static GPtrArray *imap4_search_by_expression (CamelFolder *folder, const char *expr, CamelException *ex);
-static GPtrArray *imap4_search_by_uids (CamelFolder *folder, const char *expr, GPtrArray *uids, CamelException *ex);
-static void imap4_search_free (CamelFolder *folder, GPtrArray *uids);
-
-
-static CamelFolderClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_folder_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (CAMEL_FOLDER_TYPE,
- "CamelIMAP4Folder",
- sizeof (CamelIMAP4Folder),
- sizeof (CamelIMAP4FolderClass),
- (CamelObjectClassInitFunc) camel_imap4_folder_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_folder_init,
- (CamelObjectFinalizeFunc) camel_imap4_folder_finalize);
- }
-
- return type;
-}
-
-static void
-camel_imap4_folder_class_init (CamelIMAP4FolderClass *klass)
-{
- CamelFolderClass *folder_class = (CamelFolderClass *) klass;
- CamelObjectClass *object_class = (CamelObjectClass *) klass;
- int i;
-
- parent_class = (CamelFolderClass *) camel_type_get_global_classfuncs (CAMEL_FOLDER_TYPE);
-
- for (i = 0; i < G_N_ELEMENTS (imap4_prop_list); i++) {
- imap4_prop_list[i].description = _(imap4_prop_list[i].description);
- imap4_folder_props = g_slist_prepend (imap4_folder_props, &imap4_prop_list[i]);
- }
-
- object_class->getv = imap4_getv;
- object_class->setv = imap4_setv;
-
- folder_class->sync = imap4_sync;
- folder_class->refresh_info = imap4_refresh_info;
- folder_class->expunge = imap4_expunge;
- folder_class->get_message = imap4_get_message;
- folder_class->append_message = imap4_append_message;
- folder_class->transfer_messages_to = imap4_transfer_messages_to;
- folder_class->search_by_expression = imap4_search_by_expression;
- folder_class->search_by_uids = imap4_search_by_uids;
- folder_class->search_free = imap4_search_free;
-}
-
-static void
-camel_imap4_folder_init (CamelIMAP4Folder *folder, CamelIMAP4FolderClass *klass)
-{
- ((CamelFolder *) folder)->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY | CAMEL_FOLDER_HAS_SEARCH_CAPABILITY;
-
- folder->sync_offline = FALSE;
- folder->utf7_name = NULL;
- folder->cachedir = NULL;
- folder->search = NULL;
-}
-
-static void
-camel_imap4_folder_finalize (CamelObject *object)
-{
- CamelIMAP4Folder *folder = (CamelIMAP4Folder *) object;
-
- camel_object_unref (folder->search);
-
- if (folder->cache)
- camel_object_unref (folder->cache);
-
- g_free (folder->utf7_name);
- g_free (folder->cachedir);
-}
-
-static int
-imap4_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
-{
- CamelArgGetV props;
- int i, count = 0;
- 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_PERSISTENT_PROPERTIES:
- case CAMEL_FOLDER_ARG_PROPERTIES:
- 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 (imap4_folder_props));
- break;
- case CAMEL_IMAP4_FOLDER_ARG_SYNC_OFFLINE:
- *arg->ca_int = ((CamelIMAP4Folder *) object)->sync_offline;
- 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 int
-imap4_setv (CamelObject *object, CamelException *ex, CamelArgV *args)
-{
- CamelIMAP4Folder *folder = (CamelIMAP4Folder *) object;
- gboolean save = FALSE;
- guint32 tag;
- int i;
-
- for (i = 0; i < args->argc; i++) {
- CamelArg *arg = &args->argv[i];
-
- tag = arg->tag;
-
- switch (tag & CAMEL_ARG_TAG) {
- case CAMEL_IMAP4_FOLDER_ARG_SYNC_OFFLINE:
- if (folder->sync_offline != arg->ca_int) {
- folder->sync_offline = arg->ca_int;
- save = TRUE;
- }
- break;
- default:
- continue;
- }
-
- arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
- }
-
- if (save)
- camel_object_state_write (object);
-
- return ((CamelObjectClass *) parent_class)->setv (object, ex, args);
-}
-
-
-static char *
-imap_get_summary_filename (const char *path)
-{
- /* /path/to/imap/summary */
- return g_build_filename (path, "summary", NULL);
-}
-
-static char *
-imap_build_filename (const char *toplevel_dir, const char *full_name)
-{
- const char *inptr = full_name;
- int subdirs = 0;
- char *path, *p;
-
- if (*full_name == '\0')
- return g_strdup (toplevel_dir);
-
- while (*inptr != '\0') {
- if (*inptr == '/')
- subdirs++;
- inptr++;
- }
-
- path = g_malloc (strlen (toplevel_dir) + (inptr - full_name) + (12 * subdirs) + 2);
- p = g_stpcpy (path, toplevel_dir);
-
- if (p[-1] != '/')
- *p++ = '/';
-
- inptr = full_name;
- while (*inptr != '\0') {
- while (*inptr != '/' && *inptr != '\0')
- *p++ = *inptr++;
-
- if (*inptr == '/') {
- p = g_stpcpy (p, "/subfolders/");
- inptr++;
-
- /* strip extranaeous '/'s */
- while (*inptr == '/')
- inptr++;
- }
- }
-
- *p = '\0';
-
- return path;
-}
-
-static char *
-imap_store_build_filename (void *store, const char *full_name)
-{
- CamelIMAP4Store *imap_store = (CamelIMAP4Store *) store;
- char *toplevel_dir;
- char *path;
-
- toplevel_dir = g_strdup_printf ("%s/folders", imap_store->storage_path);
- path = imap_build_filename (toplevel_dir, full_name);
- g_free (toplevel_dir);
-
- return path;
-}
-
-
-CamelFolder *
-camel_imap4_folder_new (CamelStore *store, const char *full_name, CamelException *ex)
-{
- CamelIMAP4Folder *imap_folder;
- char *utf7_name, *name, *p;
- CamelFolder *folder;
- char *path;
- char sep;
-
- if (!(p = strrchr (full_name, '/')))
- p = (char *) full_name;
- else
- p++;
-
- name = g_alloca (strlen (p) + 1);
- strcpy (name, p);
-
- utf7_name = g_alloca (strlen (full_name) + 1);
- strcpy (utf7_name, full_name);
-
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, full_name);
- if (sep != '/') {
- p = utf7_name;
- while (*p != '\0') {
- if (*p == '/')
- *p = sep;
- p++;
- }
- }
-
- utf7_name = camel_utf8_utf7 (utf7_name);
-
- folder = (CamelFolder *) (imap_folder = (CamelIMAP4Folder *) camel_object_new (CAMEL_TYPE_IMAP4_FOLDER));
- camel_folder_construct (folder, store, full_name, name);
- imap_folder->utf7_name = utf7_name;
-
- folder->summary = camel_imap4_summary_new (folder);
- imap_folder->cachedir = imap_store_build_filename (store, folder->full_name);
- camel_mkdir (imap_folder->cachedir, 0777);
-
- imap_folder->cache = camel_data_cache_new (imap_folder->cachedir, 0, NULL);
-
- path = imap_get_summary_filename (imap_folder->cachedir);
- camel_folder_summary_set_filename (folder->summary, path);
- g_free (path);
-
- imap_folder->search = camel_imap4_search_new (((CamelIMAP4Store *) store)->engine, imap_folder->cachedir);
-
- if (camel_session_is_online (((CamelService *) store)->session)) {
- /* we don't care if the summary loading fails here */
- camel_folder_summary_load (folder->summary);
-
- if (camel_imap4_engine_select_folder (((CamelIMAP4Store *) store)->engine, folder, ex) == -1) {
- camel_object_unref (folder);
- folder = NULL;
- }
-
- if (folder && camel_imap4_summary_flush_updates (folder->summary, ex) == -1) {
- camel_object_unref (folder);
- folder = NULL;
- }
- } else {
- /* we *do* care if summary loading fails here though */
- if (camel_folder_summary_load (folder->summary) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_PATH,
- _("Cannot access folder `%s': %s"),
- full_name, g_strerror (ENOENT));
-
- camel_object_unref (folder);
- folder = NULL;
- }
- }
-
- return folder;
-}
-
-const char *
-camel_imap4_folder_utf7_name (CamelIMAP4Folder *folder)
-{
- return folder->utf7_name;
-}
-
-
-static struct {
- const char *name;
- guint32 flag;
-} imap4_flags[] = {
- { "\\Answered", CAMEL_MESSAGE_ANSWERED },
- { "\\Deleted", CAMEL_MESSAGE_DELETED },
- { "\\Draft", CAMEL_MESSAGE_DRAFT },
- { "\\Flagged", CAMEL_MESSAGE_FLAGGED },
- /*{ "$Forwarded", CAMEL_MESSAGE_FORWARDED },*/
- { "\\Seen", CAMEL_MESSAGE_SEEN },
-};
-
-
-static int
-imap4_sync_flag (CamelFolder *folder, GPtrArray *infos, char onoff, const char *flag, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelIMAP4Command *ic;
- int i, id, retval = 0;
- char *set = NULL;
-
- for (i = 0; i < infos->len; ) {
- i += camel_imap4_get_uid_set (engine, folder->summary, infos, i, 30 + strlen (flag), &set);
-
- ic = camel_imap4_engine_queue (engine, folder, "UID STORE %s %cFLAGS.SILENT (%s)\r\n", set, onoff, flag);
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- g_free (set);
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
-
- return -1;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot sync flags to folder `%s': Unknown"),
- folder->full_name);
- retval = -1;
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot sync flags to folder `%s': Bad command"),
- folder->full_name);
- retval = -1;
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- if (retval == -1)
- return -1;
- }
-
- return 0;
-}
-
-static int
-imap4_sync_changes (CamelFolder *folder, GPtrArray *sync, CamelException *ex)
-{
- CamelIMAP4MessageInfo *iinfo;
- GPtrArray *on_set, *off_set;
- CamelMessageInfo *info;
- flags_diff_t diff;
- int retval = 0;
- int i, j;
-
- if (folder->permanent_flags == 0)
- return 0;
-
- on_set = g_ptr_array_new ();
- off_set = g_ptr_array_new ();
-
- /* construct commands to sync system and user flags */
- for (i = 0; i < G_N_ELEMENTS (imap4_flags); i++) {
- if (!(imap4_flags[i].flag & folder->permanent_flags))
- continue;
-
- for (j = 0; j < sync->len; j++) {
- iinfo = (CamelIMAP4MessageInfo *) (info = sync->pdata[j]);
- camel_imap4_flags_diff (&diff, iinfo->server_flags, iinfo->info.flags);
- if (diff.changed & imap4_flags[i].flag) {
- if (diff.bits & imap4_flags[i].flag) {
- g_ptr_array_add (on_set, info);
- } else {
- g_ptr_array_add (off_set, info);
- }
- }
- }
-
- if (on_set->len > 0) {
- if ((retval = imap4_sync_flag (folder, on_set, '+', imap4_flags[i].name, ex)) == -1)
- break;
-
- g_ptr_array_set_size (on_set, 0);
- }
-
- if (off_set->len > 0) {
- if ((retval = imap4_sync_flag (folder, off_set, '-', imap4_flags[i].name, ex)) == -1)
- break;
-
- g_ptr_array_set_size (off_set, 0);
- }
- }
-
- g_ptr_array_free (on_set, TRUE);
- g_ptr_array_free (off_set, TRUE);
-
- if (retval == -1)
- return-1;
-
- for (i = 0; i < sync->len; i++) {
- iinfo = (CamelIMAP4MessageInfo *) (info = sync->pdata[i]);
- iinfo->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- iinfo->server_flags = iinfo->info.flags & folder->permanent_flags;
- }
-
- return 0;
-}
-
-static void
-imap4_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelSession *session = ((CamelService *) folder->parent_store)->session;
- CamelIMAP4MessageInfo *iinfo;
- CamelMessageInfo *info;
- CamelIMAP4Command *ic;
- flags_diff_t diff;
- GPtrArray *sync;
- int id, max, i;
- int retval;
-
- if (!camel_session_is_online (session))
- return;
-
- CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
-
- /* gather a list of changes to sync to the server */
- sync = g_ptr_array_new ();
- max = camel_folder_summary_count (folder->summary);
- for (i = 0; i < max; i++) {
- iinfo = (CamelIMAP4MessageInfo *) (info = camel_folder_summary_index (folder->summary, i));
- if (iinfo->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) {
- camel_imap4_flags_diff (&diff, iinfo->server_flags, iinfo->info.flags);
- diff.changed &= folder->permanent_flags;
-
- /* weed out flag changes that we can't sync to the server */
- if (!diff.changed)
- camel_message_info_free(info);
- else
- g_ptr_array_add (sync, info);
- } else {
- camel_message_info_free(info);
- }
- }
-
- if (sync->len > 0) {
- retval = imap4_sync_changes (folder, sync, ex);
-
- for (i = 0; i < sync->len; i++)
- camel_message_info_free(sync->pdata[i]);
-
- g_ptr_array_free (sync, TRUE);
-
- if (retval == -1)
- goto done;
- } else {
- g_ptr_array_free (sync, TRUE);
- }
-
- if (expunge) {
- ic = camel_imap4_engine_queue (engine, folder, "EXPUNGE\r\n");
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- camel_imap4_summary_flush_updates (folder->summary, ex);
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot expunge folder `%s': Unknown"),
- folder->full_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot expunge folder `%s': Bad command"),
- folder->full_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
- } else {
- camel_imap4_summary_flush_updates (folder->summary, ex);
- }
-
- camel_folder_summary_save (folder->summary);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
-}
-
-static void
-imap4_expunge (CamelFolder *folder, CamelException *ex)
-{
- imap4_sync (folder, TRUE, ex);
-}
-
-static void
-imap4_refresh_info (CamelFolder *folder, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelSession *session = ((CamelService *) folder->parent_store)->session;
- CamelFolder *selected = (CamelFolder *) engine->folder;
- CamelIMAP4Command *ic;
- int id;
-
- if (!camel_session_is_online (session))
- return;
-
- CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
-
- if (folder != selected) {
- if (camel_imap4_engine_select_folder (engine, folder, ex) == -1)
- goto done;
-
- ((CamelIMAP4Summary *) folder->summary)->update_flags = TRUE;
- } else {
- ic = camel_imap4_engine_queue (engine, NULL, "NOOP\r\n");
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE)
- camel_exception_xfer (ex, &ic->ex);
-
- camel_imap4_command_unref (ic);
-
- if (camel_exception_is_set (ex))
- goto done;
- }
-
- camel_imap4_summary_flush_updates (folder->summary, ex);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
-}
-
-static int
-untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
-{
- CamelFolderSummary *summary = ((CamelFolder *) engine->folder)->summary;
- CamelStream *fstream, *stream = ic->user_data;
- CamelFolderChangeInfo *changes;
- CamelIMAP4MessageInfo *iinfo;
- CamelMessageInfo *info;
- CamelMimeFilter *crlf;
- guint32 flags;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- /* parse the FETCH response list */
- if (token->token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- do {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token == ')' || token->token == '\n')
- break;
-
- if (token->token != CAMEL_IMAP4_TOKEN_ATOM)
- goto unexpected;
-
- if (!strcmp (token->v.atom, "BODY[")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != ']')
- goto unexpected;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_LITERAL)
- goto unexpected;
-
- fstream = (CamelStream *) camel_stream_filter_new_with_stream (stream);
- crlf = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- camel_stream_filter_add ((CamelStreamFilter *) fstream, crlf);
- camel_object_unref (crlf);
-
- camel_stream_write_to_stream ((CamelStream *) engine->istream, fstream);
- camel_stream_flush (fstream);
- camel_object_unref (fstream);
- } else if (!strcmp (token->v.atom, "UID")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NUMBER || token->v.number == 0)
- goto unexpected;
- } else if (!strcmp (token->v.atom, "FLAGS")) {
- /* even though we didn't request this bit of information, it might be
- * given to us if another client recently changed the flags... */
- if (camel_imap4_parse_flags_list (engine, &flags, ex) == -1)
- goto exception;
-
- if ((info = camel_folder_summary_index (summary, index - 1))) {
- iinfo = (CamelIMAP4MessageInfo *) info;
- iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, flags);
- iinfo->server_flags = flags;
-
- changes = camel_folder_change_info_new ();
- camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
- camel_object_trigger_event (engine->folder, "folder_changed", changes);
- camel_folder_change_info_free (changes);
-
- camel_message_info_free(info);
- }
- } else {
- /* wtf? */
- fprintf (stderr, "huh? %s?...\n", token->v.atom);
- }
- } while (1);
-
- if (token->token != ')') {
- fprintf (stderr, "expected ')' to close untagged FETCH response\n");
- goto unexpected;
- }
-
- return 0;
-
- unexpected:
-
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- exception:
-
- return -1;
-}
-
-static CamelMimeMessage *
-imap4_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelSession *session = ((CamelService *) folder->parent_store)->session;
- CamelIMAP4Folder *imap_folder = (CamelIMAP4Folder *) folder;
- CamelMimeMessage *message = NULL;
- CamelStream *stream, *cache;
- CamelIMAP4Command *ic;
- int id;
-
- CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
-
- if (imap_folder->cache && (stream = camel_data_cache_get (imap_folder->cache, "cache", uid, ex))) {
- message = camel_mime_message_new ();
-
- if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream) == -1) {
- if (errno == EINTR) {
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
- camel_exception_setv (ex, CAMEL_EXCEPTION_USER_CANCEL, _("User cancelled"));
- camel_object_unref (message);
- camel_object_unref (stream);
- return NULL;
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get message %s: %s"),
- uid, g_strerror (errno));
- camel_object_unref (message);
- message = NULL;
- }
- }
-
- camel_object_unref (stream);
- }
-
- if (message != NULL) {
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
- return message;
- }
-
- if (!camel_session_is_online (session)) {
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("This message is not available in offline mode."));
- return NULL;
- }
-
- /* Note: While some hard-core IMAP extremists are probably
- * going to flame me for fetching entire messages here, it's
- * the *only* sure-fire way of working with all IMAP
- * servers. There are numerous problems with fetching
- * individual MIME parts from a good handful of IMAP servers
- * which makes this a pain to do the Right Way (tm). For
- * example: Courier-IMAP has "issues" parsing some multipart
- * messages apparently, because BODY responses are often
- * inaccurate. I'm also not very trusting of the free German
- * IMAP hosting either (such as mail.gmx.net and imap.web.de)
- * as they have proven themselves to be quite flakey wrt FETCH
- * requests (they seem to be written exclusively for
- * Outlook). Also, some IMAP servers such as GroupWise don't
- * store mail in MIME format and so must re-construct the
- * entire message in order to extract the requested part, so
- * it is *mush* more efficient (generally) to just request the
- * entire message anyway. */
- ic = camel_imap4_engine_queue (engine, folder, "UID FETCH %s BODY.PEEK[]\r\n", uid);
- camel_imap4_command_register_untagged (ic, "FETCH", untagged_fetch);
- ic->user_data = stream = camel_stream_mem_new ();
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- camel_object_unref (stream);
- goto done;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- camel_stream_reset (stream);
- message = camel_mime_message_new ();
- camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream);
- camel_stream_reset (stream);
-
- /* cache the message locally */
- if (imap_folder->cache && (cache = camel_data_cache_add (imap_folder->cache, "cache", uid, NULL))) {
- if (camel_stream_write_to_stream (stream, cache) == -1
- || camel_stream_flush (cache) == -1)
- camel_data_cache_remove (imap_folder->cache, "cache", uid, NULL);
- camel_object_unref (cache);
- }
-
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get message %s from folder `%s': No such message"),
- uid, folder->full_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get message %s from folder `%s': Bad command"),
- uid, folder->full_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- camel_object_unref (stream);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
-
- return message;
-}
-
-static char *tm_months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static void
-imap4_append_message (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelSession *session = ((CamelService *) folder->parent_store)->session;
- CamelIMAP4Summary *summary = (CamelIMAP4Summary *) folder->summary;
- const CamelIMAP4MessageInfo *iinfo = (const CamelIMAP4MessageInfo *)info;
- CamelIMAP4RespCode *resp;
- CamelIMAP4Command *ic;
- CamelFolderInfo *fi;
- CamelException lex;
- char flags[100], *p;
- char date[50];
- struct tm tm;
- int id, i;
-
- if (appended_uid)
- *appended_uid = NULL;
-
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot append messages to IMAP folders in offline mode."));
- return;
- }
-
- CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
-
- /* construct the option flags list */
- if (iinfo->info.flags & folder->permanent_flags) {
- p = g_stpcpy (flags, " (");
-
- for (i = 0; i < G_N_ELEMENTS (imap4_flags); i++) {
- if ((iinfo->info.flags & imap4_flags[i].flag) & folder->permanent_flags) {
- p = g_stpcpy (p, imap4_flags[i].name);
- *p++ = ' ';
- }
- }
-
- p[-1] = ')';
- *p = '\0';
- } else {
- flags[0] = '\0';
- }
-
- /* construct the optional date_time string */
- if (iinfo->info.date_received != (time_t) -1) {
- int tzone;
-
-#ifdef HAVE_LOCALTIME_R
- localtime_r (&info->date_received, &tm);
-#else
- memcpy (&tm, localtime (&iinfo->info.date_received), sizeof (tm));
-#endif
-
-#if defined (HAVE_TM_GMTOFF)
- tzone = -tm.tm_gmtoff;
-#elif defined (HAVE_TIMEZONE)
- if (tm.tm_isdst > 0) {
-#if defined (HAVE_ALTZONE)
- tzone = altzone;
-#else /* !defined (HAVE_ALTZONE) */
- tzone = (timezone - 3600);
-#endif
- } else {
- tzone = timezone;
- }
-#else
-#error Neither HAVE_TIMEZONE nor HAVE_TM_GMTOFF defined. Rerun autoheader, autoconf, etc.
-#endif
-
- sprintf (date, " \"%02d-%s-%04d %02d:%02d:%02d %+05d\"",
- tm.tm_mday, tm_months[tm.tm_mon], tm.tm_year + 1900,
- tm.tm_hour, tm.tm_min, tm.tm_sec, tzone);
- } else {
- date[0] = '\0';
- }
-
- retry:
-
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_UIDPLUS)
- ic = camel_imap4_engine_queue (engine, NULL, "UID APPEND %F%s%s %L\r\n", flags, date, message);
- else
- ic = camel_imap4_engine_queue (engine, NULL, "APPEND %F%s%s %L\r\n", flags, date, message);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
- return;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- if (!(engine->capa & CAMEL_IMAP4_CAPABILITY_UIDPLUS))
- break;
-
- if (!appended_uid)
- break;
-
- for (i = 0; i < ic->resp_codes->len; i++) {
- resp = ic->resp_codes->pdata[i];
- if (resp->code == CAMEL_IMAP4_RESP_CODE_APPENDUID) {
- if (resp->v.appenduid.uidvalidity == summary->uidvalidity)
- *appended_uid = g_strdup_printf ("%u", resp->v.appenduid.uid);
- break;
- }
- }
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: can we give the user any more information? */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to folder `%s': Unknown error"),
- folder->full_name);
-
- for (i = 0; i < ic->resp_codes->len; i++) {
- resp = ic->resp_codes->pdata[i];
- if (resp->code == CAMEL_IMAP4_RESP_CODE_TRYCREATE) {
- char *parent_name, *p;
-
- parent_name = g_alloca (strlen (folder->full_name) + 1);
- if (!(p = strrchr (parent_name, '/')))
- *parent_name = '\0';
- else
- *p = '\0';
-
- if (!(fi = camel_store_create_folder (folder->parent_store, parent_name, folder->name, &lex))) {
- camel_exception_clear (&lex);
- break;
- }
-
- camel_store_free_folder_info (folder->parent_store, fi);
- camel_imap4_command_unref (ic);
- camel_exception_clear (ex);
- goto retry;
- }
- }
-
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to folder `%s': Bad command"),
- folder->full_name);
-
- break;
- default:
- g_assert_not_reached ();
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
-}
-
-
-static int
-info_uid_sort (const CamelMessageInfo **info0, const CamelMessageInfo **info1)
-{
- guint32 uid0, uid1;
-
- uid0 = strtoul (camel_message_info_uid (*info0), NULL, 10);
- uid1 = strtoul (camel_message_info_uid (*info1), NULL, 10);
-
- if (uid0 == uid1)
- return 0;
-
- return uid0 < uid1 ? -1 : 1;
-}
-
-static void
-imap4_transfer_messages_to (CamelFolder *src, GPtrArray *uids, CamelFolder *dest,
- GPtrArray **transferred_uids, gboolean move, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) src->parent_store)->engine;
- CamelSession *session = ((CamelService *) src->parent_store)->session;
- int i, j, n, id, dest_namelen;
- CamelMessageInfo *info;
- CamelIMAP4Command *ic;
- GPtrArray *infos;
- char *set;
-
- if (!camel_session_is_online (session)) {
- if (move)
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot move messages to or from IMAP folders in offline mode."));
- else
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot copy messages to or from IMAP folders in offline mode."));
-
- return;
- }
-
- infos = g_ptr_array_new ();
- for (i = 0; i < uids->len; i++) {
- if (!(info = camel_folder_summary_uid (src->summary, uids->pdata[i])))
- continue;
-
- g_ptr_array_add (infos, info);
- }
-
- if (infos->len == 0) {
- g_ptr_array_free (infos, TRUE);
- return;
- }
-
- g_ptr_array_sort (infos, (GCompareFunc) info_uid_sort);
-
- CAMEL_SERVICE_LOCK (src->parent_store, connect_lock);
-
- dest_namelen = strlen (camel_imap4_folder_utf7_name ((CamelIMAP4Folder *) dest));
-
- for (i = 0; i < infos->len; i += n) {
- n = camel_imap4_get_uid_set (engine, src->summary, infos, i, 10 + dest_namelen, &set);
-
- ic = camel_imap4_engine_queue (engine, src, "UID COPY %s %F\r\n", set, dest);
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- g_free (set);
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- g_free (set);
- goto done;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- if (move) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot move messages from folder `%s' to folder `%s': Unknown"),
- src->full_name, dest->full_name);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot copy messages from folder `%s' to folder `%s': Unknown"),
- src->full_name, dest->full_name);
- }
-
- goto done;
- case CAMEL_IMAP4_RESULT_BAD:
- if (move) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot move messages from folder `%s' to folder `%s': Bad command"),
- src->full_name, dest->full_name);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot copy messages from folder `%s' to folder `%s': Bad command"),
- src->full_name, dest->full_name);
- }
-
- goto done;
- }
-
- camel_imap4_command_unref (ic);
-
- if (move) {
- for (j = i; j < n; j++) {
- info = infos->pdata[j];
- camel_folder_set_message_flags (src, camel_message_info_uid (info),
- CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED);
- }
-
- camel_folder_summary_touch (src->summary);
- }
- }
-
- done:
-
- for (i = 0; i < infos->len; i++)
- camel_message_info_free(infos->pdata[i]);
- g_ptr_array_free (infos, TRUE);
-
- CAMEL_SERVICE_LOCK (src->parent_store, connect_lock);
-}
-
-static GPtrArray *
-imap4_search_by_expression (CamelFolder *folder, const char *expr, CamelException *ex)
-{
- CamelIMAP4Folder *imap4_folder = (CamelIMAP4Folder *) folder;
- GPtrArray *matches;
-
- CAMEL_SERVICE_LOCK(folder->parent_store, connect_lock);
-
- camel_folder_search_set_folder (imap4_folder->search, folder);
- matches = camel_folder_search_search (imap4_folder->search, expr, NULL, ex);
-
- CAMEL_SERVICE_UNLOCK(folder->parent_store, connect_lock);
-
- return matches;
-}
-
-static GPtrArray *
-imap4_search_by_uids (CamelFolder *folder, const char *expr, GPtrArray *uids, CamelException *ex)
-{
- CamelIMAP4Folder *imap4_folder = (CamelIMAP4Folder *) folder;
- GPtrArray *matches;
-
- if (uids->len == 0)
- return g_ptr_array_new ();
-
- CAMEL_SERVICE_LOCK(folder->parent_store, connect_lock);
-
- camel_folder_search_set_folder (imap4_folder->search, folder);
- matches = camel_folder_search_search (imap4_folder->search, expr, uids, ex);
-
- CAMEL_SERVICE_UNLOCK(folder->parent_store, connect_lock);
-
- return matches;
-}
-
-static void
-imap4_search_free (CamelFolder *folder, GPtrArray *uids)
-{
- CamelIMAP4Folder *imap4_folder = (CamelIMAP4Folder *) folder;
-
- g_return_if_fail (imap4_folder->search);
-
- CAMEL_SERVICE_LOCK(folder->parent_store, connect_lock);
-
- camel_folder_search_free_result (imap4_folder->search, uids);
-
- CAMEL_SERVICE_UNLOCK(folder->parent_store, connect_lock);
-}
diff --git a/camel/providers/imap4/camel-imap4-folder.h b/camel/providers/imap4/camel-imap4-folder.h
deleted file mode 100644
index ae0263f31d..0000000000
--- a/camel/providers/imap4/camel-imap4-folder.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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_IMAP4_FOLDER_H__
-#define __CAMEL_IMAP4_FOLDER_H__
-
-#include <camel/camel-store.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-data-cache.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_FOLDER (camel_imap4_folder_get_type ())
-#define CAMEL_IMAP4_FOLDER(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_FOLDER, CamelIMAP4Folder))
-#define CAMEL_IMAP4_FOLDER_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP4_FOLDER, CamelIMAP4FolderClass))
-#define CAMEL_IS_IMAP4_FOLDER(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP4_FOLDER))
-#define CAMEL_IS_IMAP4_FOLDER_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP4_FOLDER))
-#define CAMEL_IMAP4_FOLDER_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_IMAP4_FOLDER, CamelIMAP4FolderClass))
-
-typedef struct _CamelIMAP4Folder CamelIMAP4Folder;
-typedef struct _CamelIMAP4FolderClass CamelIMAP4FolderClass;
-
-enum {
- CAMEL_IMAP4_FOLDER_ARG_SYNC_OFFLINE = CAMEL_FOLDER_ARG_LAST,
- CAMEL_IMAP4_FOLDER_ARG_LAST = CAMEL_FOLDER_ARG_LAST + 0x100
-};
-
-
-enum {
- CAMEL_IMAP4_FOLDER_SYNC_OFFLINE = CAMEL_IMAP4_FOLDER_ARG_SYNC_OFFLINE | CAMEL_ARG_BOO,
-};
-
-struct _CamelIMAP4Folder {
- CamelFolder parent_object;
-
- unsigned int sync_offline:1;
-
- CamelFolderSearch *search;
- CamelDataCache *cache;
-
- char *cachedir;
- char *utf7_name;
-};
-
-struct _CamelIMAP4FolderClass {
- CamelFolderClass parent_class;
-
-};
-
-
-CamelType camel_imap4_folder_get_type (void);
-
-CamelFolder *camel_imap4_folder_new (CamelStore *store, const char *full_name, CamelException *ex);
-
-const char *camel_imap4_folder_utf7_name (CamelIMAP4Folder *folder);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_FOLDER_H__ */
diff --git a/camel/providers/imap4/camel-imap4-provider.c b/camel/providers/imap4/camel-imap4-provider.c
deleted file mode 100644
index fa529e0c2a..0000000000
--- a/camel/providers/imap4/camel-imap4-provider.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <string.h>
-
-#include <camel/camel-sasl.h>
-#include <camel/camel-provider.h>
-#include <camel/camel-i18n.h>
-
-#include "camel-imap4-store.h"
-
-
-CamelProviderConfEntry imap4_conf_entries[] = {
- { 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_SECTION_START, "general", NULL, N_("Options") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL,
- N_("Apply filters to new messages in INBOX on this server"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter_junk", NULL,
- N_("Check new messages for Junk contents"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter_junk_inbox", "filter_junk",
- N_("Only check for Junk messages in the INBOX folder"), "0" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "sync_offline", NULL,
- N_("Automatically synchronize remote mail locally"), "0" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider imap4_provider = {
- "imap4",
- N_("IMAPv4rev1"),
-
- N_("For reading and storing mail on IMAPv4rev1 servers. EXPERIMENTAL !!"),
-
- "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 | CAMEL_URL_FRAGMENT_IS_PATH,
-
- imap4_conf_entries,
-
- /* ... */
-};
-
-CamelServiceAuthType camel_imap4_password_authtype = {
- N_("Password"),
-
- N_("This option will connect to the IMAPv4rev1 server using a "
- "plaintext password."),
-
- "",
- TRUE
-};
-
-
-static void
-add_hash (guint *hash, char *s)
-{
- if (s)
- *hash ^= g_str_hash(s);
-}
-
-static guint
-imap4_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 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
-imap4_url_equal (gconstpointer a, gconstpointer b)
-{
- const CamelURL *u1 = a, *u2 = b;
-
- return check_equal (u1->protocol, u2->protocol)
- && check_equal (u1->user, u2->user)
- && check_equal (u1->authmech, u2->authmech)
- && check_equal (u1->host, u2->host)
- && u1->port == u2->port;
-}
-
-
-void
-camel_provider_module_init (void)
-{
- imap4_provider.object_types[CAMEL_PROVIDER_STORE] = camel_imap4_store_get_type ();
- imap4_provider.url_hash = imap4_url_hash;
- imap4_provider.url_equal = imap4_url_equal;
- imap4_provider.authtypes = camel_sasl_authtype_list (FALSE);
- imap4_provider.authtypes = g_list_prepend (imap4_provider.authtypes, &camel_imap4_password_authtype);
-
- camel_provider_register (&imap4_provider);
-}
diff --git a/camel/providers/imap4/camel-imap4-search.c b/camel/providers/imap4/camel-imap4-search.c
deleted file mode 100644
index 7102e2fa0f..0000000000
--- a/camel/providers/imap4/camel-imap4-search.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@novell.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright 2004 Novell, Inc. (www.novell.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 <string.h>
-#include <ctype.h>
-
-#include "camel-imap4-command.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-utils.h"
-
-#include "camel-imap4-search.h"
-
-
-static void camel_imap4_search_class_init (CamelIMAP4SearchClass *klass);
-static void camel_imap4_search_init (CamelIMAP4Search *search, CamelIMAP4SearchClass *klass);
-static void camel_imap4_search_finalize (CamelObject *object);
-
-static ESExpResult *imap4_body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
-
-
-static CamelFolderSearchClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_search_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (camel_folder_search_get_type (),
- "CamelIMAP4Search",
- sizeof (CamelIMAP4Search),
- sizeof (CamelIMAP4SearchClass),
- (CamelObjectClassInitFunc) camel_imap4_search_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_search_init,
- (CamelObjectFinalizeFunc) camel_imap4_search_finalize);
- }
-
- return type;
-}
-
-static void
-camel_imap4_search_class_init (CamelIMAP4SearchClass *klass)
-{
- CamelFolderSearchClass *search_class = (CamelFolderSearchClass *) klass;
-
- parent_class = (CamelFolderSearchClass *) camel_type_get_global_classfuncs (CAMEL_FOLDER_SEARCH_TYPE);
-
- search_class->body_contains = imap4_body_contains;
-}
-
-static void
-camel_imap4_search_init (CamelIMAP4Search *search, CamelIMAP4SearchClass *klass)
-{
- search->engine = NULL;
-}
-
-static void
-camel_imap4_search_finalize (CamelObject *object)
-{
- ;
-}
-
-
-CamelFolderSearch *
-camel_imap4_search_new (CamelIMAP4Engine *engine, const char *cachedir)
-{
- CamelIMAP4Search *search;
-
- search = (CamelIMAP4Search *) camel_object_new (camel_imap4_search_get_type ());
- camel_folder_search_construct ((CamelFolderSearch *) search);
- search->engine = engine;
-
- return (CamelFolderSearch *) search;
-}
-
-
-static int
-untagged_search (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
-{
- CamelFolderSummary *summary = ((CamelFolder *) engine->folder)->summary;
- GPtrArray *matches = ic->user_data;
- CamelMessageInfo *info;
- char uid[12];
-
- while (1) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token == '\n')
- break;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NUMBER || token->v.number == 0)
- goto unexpected;
-
- sprintf (uid, "%u", token->v.number);
- if ((info = camel_folder_summary_uid (summary, uid))) {
- g_ptr_array_add (matches, (char *) camel_message_info_uid (info));
- camel_message_info_free(info);
- }
- }
-
- return 0;
-
- unexpected:
-
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- return -1;
-}
-
-static ESExpResult *
-imap4_body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search)
-{
- CamelIMAP4Search *imap4_search = (CamelIMAP4Search *) search;
- CamelIMAP4Engine *engine = imap4_search->engine;
- GPtrArray *strings, *matches, *infos;
- register const unsigned char *inptr;
- gboolean utf8_search = FALSE;
- GPtrArray *summary_set;
- CamelMessageInfo *info;
- CamelIMAP4Command *ic;
- const char *expr;
- ESExpResult *r;
- int id, i, n;
- size_t used;
- char *set;
-
- summary_set = search->summary_set ? search->summary_set : search->summary;
-
- /* check the simple cases */
- if (argc == 0 || summary_set->len == 0) {
- /* match nothing */
- if (search->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 ();
- }
-
- return r;
- } else if (argc == 1 && argv[0]->type == ESEXP_RES_STRING && argv[0]->value.string[0] == '\0') {
- /* match everything */
- if (search->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 ();
- g_ptr_array_set_size (r->value.ptrarray, summary_set->len);
- r->value.ptrarray->len = summary_set->len;
- for (i = 0; i < summary_set->len; i++) {
- info = g_ptr_array_index (summary_set, i);
- r->value.ptrarray->pdata[i] = (char *) camel_message_info_uid (info);
- }
- }
-
- return r;
- }
-
- strings = g_ptr_array_new ();
- for (i = 0; i < argc; i++) {
- if (argv[i]->type == ESEXP_RES_STRING && argv[i]->value.string[0] != '\0') {
- g_ptr_array_add (strings, argv[i]->value.string);
- if (!utf8_search) {
- inptr = (unsigned char *) argv[i]->value.string;
- while (*inptr != '\0') {
- if (!isascii ((int) *inptr)) {
- utf8_search = TRUE;
- break;
- }
-
- inptr++;
- }
- }
- }
- }
-
- if (strings->len == 0) {
- /* match everything */
- g_ptr_array_free (strings, TRUE);
-
- if (search->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 ();
- g_ptr_array_set_size (r->value.ptrarray, summary_set->len);
- r->value.ptrarray->len = summary_set->len;
- for (i = 0; i < summary_set->len; i++) {
- info = g_ptr_array_index (summary_set, i);
- r->value.ptrarray->pdata[i] = (char *) camel_message_info_uid (info);
- }
- }
-
- return r;
- }
-
- g_ptr_array_add (strings, NULL);
- matches = g_ptr_array_new ();
- infos = g_ptr_array_new ();
-
- if (search->current) {
- g_ptr_array_add (infos, search->current);
- } else {
- g_ptr_array_set_size (infos, summary_set->len);
- infos->len = summary_set->len;
- for (i = 0; i < summary_set->len; i++)
- infos->pdata[i] = summary_set->pdata[i];
- }
-
- retry:
- if (utf8_search && (engine->capa & CAMEL_IMAP4_CAPABILITY_utf8_search))
- expr = "UID SEARCH CHARSET UTF-8 UID %s BODY %V\r\n";
- else
- expr = "UID SEARCH UID %s BODY %V\r\n";
-
- used = strlen (expr) + (5 * (strings->len - 2));
-
- for (i = 0; i < infos->len; i += n) {
- n = camel_imap4_get_uid_set (engine, search->folder->summary, infos, i, used, &set);
-
- ic = camel_imap4_engine_queue (engine, search->folder, expr, set, strings->pdata);
- camel_imap4_command_register_untagged (ic, "SEARCH", untagged_search);
- ic->user_data = matches;
- g_free (set);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_imap4_command_unref (ic);
- goto done;
- }
-
-
- if (ic->result == CAMEL_IMAP4_RESULT_NO && utf8_search && (engine->capa & CAMEL_IMAP4_CAPABILITY_utf8_search)) {
- int j;
-
- /* might be because the server is lame and doesn't support UTF-8 */
- for (j = 0; j < ic->resp_codes->len; j++) {
- CamelIMAP4RespCode *resp = ic->resp_codes->pdata[j];
-
- if (resp->code == CAMEL_IMAP4_RESP_CODE_BADCHARSET) {
- engine->capa &= ~CAMEL_IMAP4_CAPABILITY_utf8_search;
- camel_imap4_command_unref (ic);
- goto retry;
- }
- }
- }
-
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_imap4_command_unref (ic);
- break;
- }
-
- camel_imap4_command_unref (ic);
- }
-
- done:
-
- g_ptr_array_free (strings, TRUE);
- g_ptr_array_free (infos, TRUE);
-
- if (search->current) {
- const char *uid;
-
- uid = camel_message_info_uid (search->current);
- r = e_sexp_result_new (f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
- for (i = 0; i < matches->len; i++) {
- if (!strcmp (matches->pdata[i], uid)) {
- r->value.bool = TRUE;
- break;
- }
- }
-
- g_ptr_array_free (matches, TRUE);
- } else {
- r = e_sexp_result_new (f, ESEXP_RES_ARRAY_PTR);
- r->value.ptrarray = matches;
- }
-
- return r;
-}
diff --git a/camel/providers/imap4/camel-imap4-search.h b/camel/providers/imap4/camel-imap4-search.h
deleted file mode 100644
index 5165367cfb..0000000000
--- a/camel/providers/imap4/camel-imap4-search.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@novell.com>
- *
- * Copyright 2004 Novell, Inc. (www.novell.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_IMAP4_SEARCH_H__
-#define __CAMEL_IMAP4_SEARCH_H__
-
-#include <camel/camel-folder-search.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_IMAP4_SEARCH_TYPE (camel_imap4_search_get_type ())
-#define CAMEL_IMAP4_SEARCH(obj) CAMEL_CHECK_CAST (obj, camel_imap4_search_get_type (), CamelIMAP4Search)
-#define CAMEL_IMAP4_SEARCH_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imap4_search_get_type (), CamelIMAP4SearchClass)
-#define CAMEL_IS_IMAP4_SEARCH(obj) CAMEL_CHECK_TYPE (obj, camel_imap4_search_get_type ())
-
-typedef struct _CamelIMAP4Search CamelIMAP4Search;
-typedef struct _CamelIMAP4SearchClass CamelIMAP4SearchClass;
-
-struct _CamelIMAP4Engine;
-
-struct _CamelIMAP4Search {
- CamelFolderSearch parent_object;
-
- struct _CamelIMAP4Engine *engine;
-};
-
-struct _CamelIMAP4SearchClass {
- CamelFolderSearchClass parent_class;
-
-};
-
-
-CamelType camel_imap4_search_get_type (void);
-
-CamelFolderSearch *camel_imap4_search_new (struct _CamelIMAP4Engine *engine, const char *cachedir);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_SEARCH_H__ */
diff --git a/camel/providers/imap4/camel-imap4-specials.c b/camel/providers/imap4/camel-imap4-specials.c
deleted file mode 100644
index 4682a403e4..0000000000
--- a/camel/providers/imap4/camel-imap4-specials.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <string.h>
-
-#include "camel-imap4-specials.h"
-
-#define CHARS_ATOM_SPECIALS "(){]"
-#define CHARS_LWSP " \t\r\n"
-#define CHARS_QUOTED_SPECIALS "\\\""
-#define CHARS_LIST_WILDCARDS "*%"
-
-unsigned char camel_imap4_specials[256] = {
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 6, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 20, 0, 8, 0, 0, 32, 0, 0, 1, 1, 32, 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, 8, 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, 1, 0, 0, 0, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-};
-
-
-static void
-imap4_init_bits (unsigned short bit, unsigned short bitcopy, int remove, unsigned char *vals)
-{
- int i, len = strlen (vals);
-
- if (!remove) {
- for (i = 0; i < len; i++)
- camel_imap4_specials[vals[i]] |= bit;
- if (bitcopy) {
- for (i = 0; i < 256; i++) {
- if (camel_imap4_specials[i] & bitcopy)
- camel_imap4_specials[i] |= bit;
- }
- }
- } else {
- for (i = 0; i < 256; i++)
- camel_imap4_specials[i] |= bit;
- for (i = 0; i < len; i++)
- camel_imap4_specials[vals[i]] &= ~bit;
- if (bitcopy) {
- for (i = 0; i < 256; i++) {
- if (camel_imap4_specials[i] & bitcopy)
- camel_imap4_specials[i] &= ~bit;
- }
- }
- }
-}
-
-
-void
-camel_imap4_specials_init (void)
-{
- int i;
-
- for (i = 0; i < 256; i++) {
- camel_imap4_specials[i] = 0;
- if (i <= 0x1f || i >= 0x7f)
- camel_imap4_specials[i] |= IS_CTRL;
- }
-
- camel_imap4_specials[' '] |= IS_SPACE;
-
- imap4_init_bits (IS_LWSP, 0, 0, CHARS_LWSP);
- imap4_init_bits (IS_ASPECIAL, 0, 0, CHARS_ATOM_SPECIALS);
- imap4_init_bits (IS_QSPECIAL, 0, 0, CHARS_QUOTED_SPECIALS);
- imap4_init_bits (IS_WILDCARD, 0, 0, CHARS_LIST_WILDCARDS);
-}
diff --git a/camel/providers/imap4/camel-imap4-specials.h b/camel/providers/imap4/camel-imap4-specials.h
deleted file mode 100644
index 36765cdc6b..0000000000
--- a/camel/providers/imap4/camel-imap4-specials.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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_IMAP4_SPECIALS_H__
-#define __CAMEL_IMAP4_SPECIALS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-enum {
- IS_ASPECIAL = (1 << 0),
- IS_CTRL = (1 << 1),
- IS_LWSP = (1 << 2),
- IS_QSPECIAL = (1 << 3),
- IS_SPACE = (1 << 4),
- IS_WILDCARD = (1 << 5),
-};
-
-extern unsigned char camel_imap4_specials[256];
-
-#define is_atom(x) ((camel_imap4_specials[(unsigned char)(x)] & (IS_ASPECIAL|IS_SPACE|IS_CTRL|IS_WILDCARD|IS_QSPECIAL)) == 0)
-#define is_ctrl(x) ((camel_imap4_specials[(unsigned char)(x)] & IS_CTRL) != 0)
-#define is_lwsp(x) ((camel_imap4_specials[(unsigned char)(x)] & IS_LWSP) != 0)
-#define is_type(x, t) ((camel_imap4_specials[(unsigned char)(x)] & (t)) != 0)
-#define is_qsafe(x) ((camel_imap4_specials[(unsigned char)(x)] & (IS_QSPECIAL|IS_CTRL)) == 0)
-#define is_wild(x) ((camel_imap4_specials[(unsigned char)(x)] & IS_WILDCARD) != 0)
-
-void camel_imap4_specials_init (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_SPECIALS_H__ */
diff --git a/camel/providers/imap4/camel-imap4-store-summary.c b/camel/providers/imap4/camel-imap4-store-summary.c
deleted file mode 100644
index ffa4bd05f1..0000000000
--- a/camel/providers/imap4/camel-imap4-store-summary.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@novell.com>
- *
- * Copyright 2004 Novell, Inc. (www.novell.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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <camel/camel-store.h>
-#include <camel/camel-file-utils.h>
-
-#include "camel-imap4-utils.h"
-#include "camel-imap4-store-summary.h"
-
-
-#define CAMEL_IMAP4_STORE_SUMMARY_VERSION_0 (0)
-#define CAMEL_IMAP4_STORE_SUMMARY_VERSION (0)
-
-static void camel_imap4_store_summary_class_init (CamelIMAP4StoreSummaryClass *klass);
-static void camel_imap4_store_summary_init (CamelIMAP4StoreSummary *obj);
-static void camel_imap4_store_summary_finalize (CamelObject *obj);
-
-static int summary_header_load (CamelStoreSummary *s, FILE *in);
-static int summary_header_save (CamelStoreSummary *s, FILE *out);
-
-static CamelStoreInfo *store_info_load (CamelStoreSummary *s, FILE *in);
-static int store_info_save (CamelStoreSummary *s, FILE *out, CamelStoreInfo *info);
-static void store_info_free (CamelStoreSummary *s, CamelStoreInfo *info);
-
-
-static CamelStoreSummaryClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_store_summary_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register (camel_store_summary_get_type (),
- "CamelIMAP4StoreSummary",
- sizeof (CamelIMAP4StoreSummary),
- sizeof (CamelIMAP4StoreSummaryClass),
- (CamelObjectClassInitFunc) camel_imap4_store_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_store_summary_init,
- (CamelObjectFinalizeFunc) camel_imap4_store_summary_finalize);
- }
-
- return type;
-}
-
-
-static void
-camel_imap4_store_summary_class_init (CamelIMAP4StoreSummaryClass *klass)
-{
- CamelStoreSummaryClass *ssklass = (CamelStoreSummaryClass *) klass;
-
- parent_class = (CamelStoreSummaryClass *) camel_store_summary_get_type ();
-
- ssklass->summary_header_load = summary_header_load;
- ssklass->summary_header_save = summary_header_save;
-
- ssklass->store_info_load = store_info_load;
- ssklass->store_info_save = store_info_save;
- ssklass->store_info_free = store_info_free;
-}
-
-static void
-camel_imap4_store_summary_init (CamelIMAP4StoreSummary *s)
-{
- ((CamelStoreSummary *) s)->store_info_size = sizeof (CamelIMAP4StoreInfo);
- s->version = CAMEL_IMAP4_STORE_SUMMARY_VERSION;
- s->namespaces = NULL;
-}
-
-static void
-camel_imap4_store_summary_finalize (CamelObject *obj)
-{
- CamelIMAP4StoreSummary *s = (CamelIMAP4StoreSummary *) obj;
-
- if (s->namespaces)
- camel_imap4_namespace_list_free (s->namespaces);
-}
-
-
-static CamelIMAP4NamespaceList *
-load_namespaces (FILE *in)
-{
- CamelIMAP4Namespace *ns, *tail;
- CamelIMAP4NamespaceList *nsl;
- guint32 i, j, n;
-
- nsl = g_malloc (sizeof (CamelIMAP4NamespaceList));
- nsl->personal = NULL;
- nsl->shared = NULL;
- nsl->other = NULL;
-
- for (j = 0; j < 3; j++) {
- switch (j) {
- case 0:
- tail = (CamelIMAP4Namespace *) &nsl->personal;
- break;
- case 1:
- tail = (CamelIMAP4Namespace *) &nsl->shared;
- break;
- case 2:
- tail = (CamelIMAP4Namespace *) &nsl->other;
- break;
- }
-
- if (camel_file_util_decode_fixed_int32 (in, &n) == -1)
- goto exception;
-
- for (i = 0; i < n; i++) {
- guint32 sep;
- char *path;
-
- if (camel_file_util_decode_string (in, &path) == -1)
- goto exception;
-
- if (camel_file_util_decode_uint32 (in, &sep) == -1) {
- g_free (path);
- goto exception;
- }
-
- tail->next = ns = g_malloc (sizeof (CamelIMAP4Namespace));
- ns->sep = sep & 0xff;
- ns->path = path;
- ns->next = NULL;
- tail = ns;
- }
- }
-
- return nsl;
-
- exception:
-
- camel_imap4_namespace_list_free (nsl);
-
- return NULL;
-}
-
-static int
-summary_header_load (CamelStoreSummary *s, FILE *in)
-{
- CamelIMAP4StoreSummary *is = (CamelIMAP4StoreSummary *) s;
- guint32 version, capa;
-
- if (parent_class->summary_header_load (s, in) == -1)
- return -1;
-
- if (camel_file_util_decode_fixed_int32 (in, &version) == -1)
- return -1;
-
- is->version = version;
- if (version < CAMEL_IMAP4_STORE_SUMMARY_VERSION_0) {
- g_warning ("IMAP4 store summary header version too low");
- errno = EINVAL;
- return -1;
- }
-
- if (camel_file_util_decode_fixed_int32 (in, &capa) == -1)
- return -1;
-
- is->capa = capa;
-
- if (!(is->namespaces = load_namespaces (in)))
- return -1;
-
- return 0;
-}
-
-static int
-save_namespaces (FILE *out, CamelIMAP4NamespaceList *nsl)
-{
- CamelIMAP4Namespace *cur, *ns;
- guint32 i, n;
-
- for (i = 0; i < 3; i++) {
- switch (i) {
- case 0:
- cur = nsl->personal;
- break;
- case 1:
- cur = nsl->shared;
- break;
- case 2:
- cur = nsl->other;
- break;
- }
-
- for (ns = cur, n = 0; ns; n++)
- ns = ns->next;
-
- if (camel_file_util_encode_fixed_int32 (out, n) == -1)
- return -1;
-
- ns = cur;
- while (ns != NULL) {
- if (camel_file_util_encode_string (out, ns->path) == -1)
- return -1;
-
- if (camel_file_util_encode_uint32 (out, ns->sep) == -1)
- return -1;
-
- ns = ns->next;
- }
- }
-
- return 0;
-}
-
-static int
-summary_header_save (CamelStoreSummary *s, FILE *out)
-{
- CamelIMAP4StoreSummary *is = (CamelIMAP4StoreSummary *) s;
-
- if (parent_class->summary_header_save (s, out) == -1)
- return -1;
-
- if (camel_file_util_encode_fixed_int32 (out, is->version) == -1)
- return -1;
-
- if (camel_file_util_encode_fixed_int32 (out, is->capa) == -1)
- return -1;
-
- if (save_namespaces (out, is->namespaces) == -1)
- return -1;
-
- return 0;
-}
-
-static CamelStoreInfo *
-store_info_load (CamelStoreSummary *s, FILE *in)
-{
- return parent_class->store_info_load (s, in);
-}
-
-static int
-store_info_save (CamelStoreSummary *s, FILE *out, CamelStoreInfo *info)
-{
- return parent_class->store_info_save (s, out, info);
-}
-
-static void
-store_info_free (CamelStoreSummary *s, CamelStoreInfo *info)
-{
- parent_class->store_info_free (s, info);
-}
-
-
-/**
- * camel_imap4_store_summary_new:
- *
- * Create a new CamelIMAP4StoreSummary object.
- *
- * Returns a new CamelIMAP4StoreSummary object.
- **/
-CamelIMAP4StoreSummary *
-camel_imap4_store_summary_new (void)
-{
- return (CamelIMAP4StoreSummary *) camel_object_new (camel_imap4_store_summary_get_type ());
-}
-
-
-void
-camel_imap4_store_summary_set_capabilities (CamelIMAP4StoreSummary *s, guint32 capa)
-{
- s->capa = capa;
-}
-
-
-void
-camel_imap4_store_summary_set_namespaces (CamelIMAP4StoreSummary *s, const CamelIMAP4NamespaceList *ns)
-{
- if (s->namespaces)
- camel_imap4_namespace_list_free (s->namespaces);
- s->namespaces = camel_imap4_namespace_list_copy (ns);
-}
-
-
-void
-camel_imap4_store_summary_note_info (CamelIMAP4StoreSummary *s, CamelFolderInfo *fi)
-{
- CamelStoreSummary *ss = (CamelStoreSummary *) s;
- CamelStoreInfo *si;
-
- if ((si = camel_store_summary_path (ss, fi->full_name))) {
- if (fi->unread != -1) {
- si->unread = fi->unread;
- ss->flags |= CAMEL_STORE_SUMMARY_DIRTY;
- }
-
- if (fi->total != -1) {
- si->total = fi->total;
- ss->flags |= CAMEL_STORE_SUMMARY_DIRTY;
- }
-
- camel_store_summary_info_free (ss, si);
- return;
- }
-
- si = camel_store_summary_info_new (ss);
- si->path = g_strdup (fi->full_name);
- si->uri = g_strdup (fi->uri);
- si->flags = fi->flags;
- si->unread = fi->unread;
- si->total = fi->total;
-
- camel_store_summary_add (ss, si);
-
- /* FIXME: should this be recursive? */
-}
-
-
-void
-camel_imap4_store_summary_unnote_info (CamelIMAP4StoreSummary *s, CamelFolderInfo *fi)
-{
- CamelStoreSummary *ss = (CamelStoreSummary *) s;
-
- camel_store_summary_remove_path (ss, fi->full_name);
-}
-
-
-static CamelFolderInfo *
-store_info_to_folder_info (CamelStoreSummary *s, CamelStoreInfo *si)
-{
- CamelFolderInfo *fi;
-
- fi = g_malloc0 (sizeof (CamelFolderInfo));
- fi->full_name = g_strdup (camel_store_info_path (s, si));
- fi->name = g_strdup (camel_store_info_name (s, si));
- fi->uri = g_strdup (camel_store_info_uri (s, si));
- fi->flags = si->flags;
- fi->unread = si->unread;
- fi->total = si->total;
-
- return fi;
-}
-
-CamelFolderInfo *
-camel_imap4_store_summary_get_folder_info (CamelIMAP4StoreSummary *s, const char *top, guint32 flags)
-{
- CamelStoreSummary *ss = (CamelStoreSummary *) s;
- CamelFolderInfo *fi;
- GPtrArray *folders;
- CamelStoreInfo *si;
- size_t toplen, len;
- int i;
-
- toplen = strlen (top);
- folders = g_ptr_array_new ();
-
- for (i = 0; i < ss->folders->len; i++) {
- si = ss->folders->pdata[i];
- if (strncmp (si->path, top, toplen) != 0)
- continue;
-
- if (toplen > 0 && (len = strlen (si->path)) > toplen && si->path[toplen] != '/')
- continue;
-
- if (len == toplen) {
- /* found toplevel folder */
- g_ptr_array_add (folders, store_info_to_folder_info (ss, si));
- continue;
- }
-
- if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || !strchr (si->path + toplen + 1, '/'))
- g_ptr_array_add (folders, store_info_to_folder_info (ss, si));
- }
-
- fi = camel_folder_info_build (folders, top, '/', TRUE);
- g_ptr_array_free (folders, TRUE);
-
- return fi;
-}
diff --git a/camel/providers/imap4/camel-imap4-store-summary.h b/camel/providers/imap4/camel-imap4-store-summary.h
deleted file mode 100644
index 4a5af80d03..0000000000
--- a/camel/providers/imap4/camel-imap4-store-summary.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@novell.com>
- *
- * Copyright 2004 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#ifndef __CAMEL_IMAP_STORE_SUMMARY_H__
-#define __CAMEL_IMAP_STORE_SUMMARY_H__
-
-#include <camel/camel-store-summary.h>
-#include "camel-imap4-engine.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_IMAP4_STORE_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_imap4_store_summary_get_type (), CamelIMAP4StoreSummary)
-#define CAMEL_IMAP4_STORE_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imap4_store_summary_get_type (), CamelIMAP4StoreSummaryClass)
-#define CAMEL_IS_IMAP4_STORE_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_imap4_store_summary_get_type ())
-
-typedef struct _CamelIMAP4StoreSummary CamelIMAP4StoreSummary;
-typedef struct _CamelIMAP4StoreSummaryClass CamelIMAP4StoreSummaryClass;
-
-typedef struct _CamelIMAP4StoreInfo CamelIMAP4StoreInfo;
-
-enum {
- CAMEL_IMAP4_STORE_INFO_FULL_NAME = CAMEL_STORE_INFO_LAST,
- CAMEL_IMAP4_STORE_INFO_LAST,
-};
-
-
-struct _CamelFolderInfo;
-
-
-struct _CamelIMAP4StoreInfo {
- CamelStoreInfo info;
-};
-
-struct _CamelIMAP4StoreSummary {
- CamelStoreSummary summary;
-
- struct _CamelIMAP4StoreSummaryPrivate *priv;
-
- /* header info */
- guint32 version;
-
- CamelIMAP4NamespaceList *namespaces;
- guint32 capa;
-};
-
-struct _CamelIMAP4StoreSummaryClass {
- CamelStoreSummaryClass summary_class;
-};
-
-
-CamelType camel_imap4_store_summary_get_type (void);
-
-CamelIMAP4StoreSummary *camel_imap4_store_summary_new (void);
-
-void camel_imap4_store_summary_set_capabilities (CamelIMAP4StoreSummary *s, guint32 capa);
-void camel_imap4_store_summary_set_namespaces (CamelIMAP4StoreSummary *s, const CamelIMAP4NamespaceList *ns);
-
-/* add the info to the cache if we don't already have it, otherwise do nothing */
-void camel_imap4_store_summary_note_info (CamelIMAP4StoreSummary *s, struct _CamelFolderInfo *fi);
-
-void camel_imap4_store_summary_unnote_info (CamelIMAP4StoreSummary *s, struct _CamelFolderInfo *fi);
-
-struct _CamelFolderInfo *camel_imap4_store_summary_get_folder_info (CamelIMAP4StoreSummary *s, const char *top, guint32 flags);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_STORE_SUMMARY_H__ */
diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c
deleted file mode 100644
index 2e7308d75d..0000000000
--- a/camel/providers/imap4/camel-imap4-store.c
+++ /dev/null
@@ -1,1448 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <camel/camel-sasl.h>
-#include <camel/camel-utf8.h>
-#include <camel/camel-tcp-stream-raw.h>
-#include <camel/camel-tcp-stream-ssl.h>
-
-#include <camel/camel-private.h>
-
-#include <camel/camel-i18n.h>
-#include <camel/camel-net-utils.h>
-
-#include "camel-imap4-store.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-utils.h"
-#include "camel-imap4-summary.h"
-#include "camel-imap4-store-summary.h"
-
-#define d(x) x
-
-static void camel_imap4_store_class_init (CamelIMAP4StoreClass *klass);
-static void camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass);
-static void camel_imap4_store_finalize (CamelObject *object);
-
-/* service methods */
-static void imap4_construct (CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- CamelException *ex);
-static char *imap4_get_name (CamelService *service, gboolean brief);
-static gboolean imap4_connect (CamelService *service, CamelException *ex);
-static gboolean imap4_reconnect (CamelIMAP4Engine *engine, CamelException *ex);
-static gboolean imap4_disconnect (CamelService *service, gboolean clean, CamelException *ex);
-static GList *imap4_query_auth_types (CamelService *service, CamelException *ex);
-
-/* store methods */
-static CamelFolder *imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
-static CamelFolderInfo *imap4_create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex);
-static void imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex);
-static void imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
-static CamelFolderInfo *imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
-static void imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
-static void imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
-static void imap4_noop (CamelStore *store, CamelException *ex);
-
-
-static CamelStoreClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_store_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (CAMEL_STORE_TYPE,
- "CamelIMAP4Store",
- sizeof (CamelIMAP4Store),
- sizeof (CamelIMAP4StoreClass),
- (CamelObjectClassInitFunc) camel_imap4_store_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_store_init,
- (CamelObjectFinalizeFunc) camel_imap4_store_finalize);
- }
-
- return type;
-}
-
-static guint
-imap4_hash_folder_name (gconstpointer key)
-{
- if (g_ascii_strcasecmp (key, "INBOX") == 0)
- return g_str_hash ("INBOX");
- else
- return g_str_hash (key);
-}
-
-static int
-imap4_compare_folder_name (gconstpointer a, gconstpointer b)
-{
- gconstpointer aname = a, bname = b;
-
- if (g_ascii_strcasecmp (a, "INBOX") == 0)
- aname = "INBOX";
- if (g_ascii_strcasecmp (b, "INBOX") == 0)
- bname = "INBOX";
-
- return g_str_equal (aname, bname);
-}
-
-static void
-camel_imap4_store_class_init (CamelIMAP4StoreClass *klass)
-{
- CamelServiceClass *service_class = (CamelServiceClass *) klass;
- CamelStoreClass *store_class = (CamelStoreClass *) klass;
-
- parent_class = (CamelStoreClass *) camel_type_get_global_classfuncs (CAMEL_STORE_TYPE);
-
- service_class->construct = imap4_construct;
- service_class->get_name = imap4_get_name;
- service_class->connect = imap4_connect;
- service_class->disconnect = imap4_disconnect;
- service_class->query_auth_types = imap4_query_auth_types;
-
- store_class->hash_folder_name = imap4_hash_folder_name;
- store_class->compare_folder_name = imap4_compare_folder_name;
-
- store_class->get_folder = imap4_get_folder;
- store_class->create_folder = imap4_create_folder;
- store_class->delete_folder = imap4_delete_folder;
- store_class->rename_folder = imap4_rename_folder;
- store_class->get_folder_info = imap4_get_folder_info;
- store_class->subscribe_folder = imap4_subscribe_folder;
- store_class->unsubscribe_folder = imap4_unsubscribe_folder;
- store_class->noop = imap4_noop;
-}
-
-static void
-camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass)
-{
- store->engine = NULL;
- store->summary = NULL;
-}
-
-static void
-camel_imap4_store_finalize (CamelObject *object)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) object;
-
- if (store->summary) {
- camel_store_summary_save ((CamelStoreSummary *) store->summary);
- camel_object_unref (store->summary);
- }
-
- if (store->engine)
- camel_object_unref (store->engine);
-
- g_free (store->storage_path);
-}
-
-
-static void
-imap4_construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- char *buf;
-
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
- if (camel_exception_is_set (ex))
- return;
-
- store->storage_path = camel_session_get_storage_path (session, service, ex);
- store->engine = camel_imap4_engine_new (service, imap4_reconnect);
-
- /* setup/load the summary */
- buf = g_alloca (strlen (store->storage_path) + 32);
- sprintf (buf, "%s/.summary", store->storage_path);
- store->summary = camel_imap4_store_summary_new ();
- camel_store_summary_set_filename ((CamelStoreSummary *) store->summary, buf);
-
- buf = camel_url_to_string (service->url, CAMEL_URL_HIDE_ALL);
- url = camel_url_new (buf, NULL);
- g_free (buf);
- camel_store_summary_set_uri_base ((CamelStoreSummary *) store->summary, url);
- camel_url_free (url);
-
- camel_store_summary_load ((CamelStoreSummary *) store->summary);
-}
-
-static char *
-imap4_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);
-}
-
-enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
-#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 (CamelIMAP4Engine *engine, struct addrinfo *ai, int ssl_mode, CamelException *ex)
-{
- CamelService *service = engine->service;
- CamelStream *tcp_stream;
- CamelIMAP4Command *ic;
- int id, ret;
-
- if (ssl_mode != MODE_CLEAR) {
-#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
-
- return FALSE;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -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: %s"),
- service->url->host,
- g_strerror (errno));
-
- camel_object_unref (tcp_stream);
-
- return FALSE;
- }
-
- if (camel_imap4_engine_take_stream (engine, tcp_stream, ex) == -1)
- return FALSE;
-
- if (camel_imap4_engine_capability (engine, ex) == -1)
- return FALSE;
-
- camel_imap4_store_summary_set_capabilities (((CamelIMAP4Store *) service)->summary, engine->capa);
-
- if (ssl_mode != MODE_TLS) {
- /* we're done */
- return TRUE;
- }
-
- if (!(engine->capa & CAMEL_IMAP4_CAPABILITY_STARTTLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to IMAP server %s in secure mode: %s"),
- service->url->host, _("SSL negotiations failed"));
-
- return FALSE;
- }
-
- ic = camel_imap4_engine_prequeue (engine, NULL, "STARTTLS\r\n");
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->result != CAMEL_IMAP4_RESULT_OK) {
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to IMAP server %s in secure mode: %s"),
- service->url->host, _("Unknown error"));
- } else {
- camel_exception_xfer (ex, &ic->ex);
- }
-
- camel_imap4_command_unref (ic);
-
- return FALSE;
- }
-
- camel_imap4_command_unref (ic);
-
- return TRUE;
-}
-
-static struct {
- char *value;
- char *serv;
- char *port;
- int mode;
-} ssl_options[] = {
- { "", "imaps", "993", MODE_SSL }, /* really old (1.x) */
- { "always", "imaps", "993", MODE_SSL },
- { "when-possible", "imap", "143", MODE_TLS },
- { "never", "imap", "143", MODE_CLEAR },
- { NULL, "imap", "143", MODE_CLEAR },
-};
-
-static gboolean
-connect_to_server_wrapper (CamelIMAP4Engine *engine, CamelException *ex)
-{
- CamelService *service = engine->service;
- struct addrinfo *ai, hints;
- const char *ssl_mode;
- int mode, ret, i;
- const char *port;
- char *serv;
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
- break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
- } else {
- mode = MODE_CLEAR;
- serv = "imap";
- port = "143";
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo (service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo (service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (engine, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (engine, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (engine, ai, MODE_CLEAR, ex);
- }
-
- camel_freeaddrinfo (ai);
-
- return ret;
-}
-
-static int
-sasl_auth (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, const unsigned char *linebuf, size_t linelen, CamelException *ex)
-{
- /* Perform a single challenge iteration */
- CamelSasl *sasl = ic->user_data;
- char *challenge;
-
- if (camel_sasl_authenticated (sasl)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Cannot authenticate to IMAP server %s using the %s authentication mechanism"),
- engine->url->host, engine->url->authmech);
- return -1;
- }
-
- while (isspace (*linebuf))
- linebuf++;
-
- if (*linebuf == '\0')
- linebuf = NULL;
-
- if (!(challenge = camel_sasl_challenge_base64 (sasl, (const char *) linebuf, ex)))
- return -1;
-
- d(fprintf (stderr, "sending : %s\r\n", challenge));
-
- if (camel_stream_printf (engine->ostream, "%s\r\n", challenge) == -1) {
- g_free (challenge);
- return -1;
- }
-
- g_free (challenge);
-
- if (camel_stream_flush (engine->ostream) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-imap4_try_authenticate (CamelIMAP4Engine *engine, gboolean reprompt, const char *errmsg, CamelException *ex)
-{
- CamelService *service = engine->service;
- CamelSession *session = service->session;
- CamelSasl *sasl = NULL;
- CamelIMAP4Command *ic;
- int id;
-
- if (!service->url->passwd) {
- guint32 flags = CAMEL_SESSION_PASSWORD_SECRET;
- char *prompt;
-
- if (reprompt)
- flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
-
- prompt = g_strdup_printf (_("%sPlease enter the IMAP password for %s on host %s"),
- errmsg ? errmsg : "",
- service->url->user,
- service->url->host);
-
- service->url->passwd = camel_session_get_password (session, service, NULL, prompt, "password", flags, ex);
-
- g_free (prompt);
-
- if (!service->url->passwd)
- return FALSE;
- }
-
- if (service->url->authmech) {
- CamelServiceAuthType *mech;
-
- mech = g_hash_table_lookup (engine->authtypes, service->url->authmech);
- sasl = camel_sasl_new ("imap", mech->authproto, service);
-
- ic = camel_imap4_engine_prequeue (engine, NULL, "AUTHENTICATE %s\r\n", service->url->authmech);
- ic->plus = sasl_auth;
- ic->user_data = sasl;
- } else {
- ic = camel_imap4_engine_prequeue (engine, NULL, "LOGIN %S %S\r\n",
- service->url->user, service->url->passwd);
- }
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (sasl != NULL)
- camel_object_unref (sasl);
-
- if (id == -1 || ic->status == CAMEL_IMAP4_COMMAND_ERROR) {
- /* unrecoverable error */
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
-
- return FALSE;
- }
-
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_imap4_command_unref (ic);
-
- /* try again */
-
- return TRUE;
- }
-
- camel_imap4_command_unref (ic);
-
- return FALSE;
-}
-
-static gboolean
-imap4_reconnect (CamelIMAP4Engine *engine, CamelException *ex)
-{
- CamelService *service = engine->service;
- CamelServiceAuthType *mech;
- gboolean reprompt = FALSE;
- char *errmsg = NULL;
- CamelException lex;
-
- if (!connect_to_server_wrapper (engine, ex))
- return FALSE;
-
-#define CANT_USE_AUTHMECH (!(mech = g_hash_table_lookup (engine->authtypes, service->url->authmech)))
- if (service->url->authmech && CANT_USE_AUTHMECH) {
- /* Oops. We can't AUTH using the requested mechanism */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Cannot authenticate to IMAP server %s using %s"),
- service->url->host, service->url->authmech);
-
- return FALSE;
- }
-
- camel_exception_init (&lex);
- while (imap4_try_authenticate (engine, reprompt, errmsg, &lex)) {
- g_free (errmsg);
- errmsg = g_strdup (lex.desc);
- camel_exception_clear (&lex);
- g_free (service->url->passwd);
- service->url->passwd = NULL;
- reprompt = TRUE;
- }
- g_free (errmsg);
-
- if (camel_exception_is_set (&lex)) {
- camel_exception_xfer (ex, &lex);
- return FALSE;
- }
-
- if (camel_imap4_engine_namespace (engine, ex) == -1)
- return FALSE;
-
- camel_imap4_store_summary_set_namespaces (((CamelIMAP4Store *) service)->summary, &engine->namespaces);
-
- return TRUE;
-}
-
-static gboolean
-imap4_connect (CamelService *service, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- gboolean retval;
-
- if (!camel_session_is_online (service->session))
- return TRUE;
-
- CAMEL_SERVICE_LOCK (service, connect_lock);
- if (store->engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED)
- retval = imap4_reconnect (store->engine, ex);
- else
- retval = TRUE;
- CAMEL_SERVICE_UNLOCK (service, connect_lock);
-
- return retval;
-}
-
-static gboolean
-imap4_disconnect (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- CamelIMAP4Command *ic;
- int id;
-
- if (!camel_session_is_online (service->session))
- return TRUE;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- if (clean && store->engine->state != CAMEL_IMAP4_ENGINE_DISCONNECTED) {
- ic = camel_imap4_engine_queue (store->engine, NULL, "LOGOUT\r\n");
- while ((id = camel_imap4_engine_iterate (store->engine)) < ic->id && id != -1)
- ;
-
- camel_imap4_command_unref (ic);
- }
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return 0;
-}
-
-extern CamelServiceAuthType camel_imap4_password_authtype;
-
-static GList *
-imap4_query_auth_types (CamelService *service, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- CamelServiceAuthType *authtype;
- GList *sasl_types, *t, *next;
- gboolean connected;
-
- if (!camel_session_is_online (service->session))
- return NULL;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- connected = connect_to_server_wrapper (store->engine, 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->engine->authtypes, authtype->authproto)) {
- sasl_types = g_list_remove_link (sasl_types, t);
- g_list_free_1 (t);
- }
- }
-
- return g_list_prepend (sasl_types, &camel_imap4_password_authtype);
-}
-
-static char *
-imap4_folder_utf7_name (CamelStore *store, const char *folder_name, char wildcard)
-{
- char *real_name, *p;
- char sep = '\0';
- int len;
-
- if (*folder_name) {
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, folder_name);
-
- if (sep != '/') {
- p = real_name = g_alloca (strlen (folder_name) + 1);
- strcpy (real_name, folder_name);
- while (*p != '\0') {
- if (*p == '/')
- *p = sep;
- p++;
- }
-
- folder_name = real_name;
- }
-
- real_name = camel_utf8_utf7 (folder_name);
- } else
- real_name = g_strdup ("");
-
- if (wildcard) {
- len = strlen (real_name);
- real_name = g_realloc (real_name, len + 3);
-
- if (len > 0)
- real_name[len++] = sep;
-
- real_name[len++] = wildcard;
- real_name[len] = '\0';
- }
-
- return real_name;
-}
-
-static CamelFolder *
-imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
- CamelFolder *folder = NULL;
- camel_imap4_list_t *list;
- CamelIMAP4Command *ic;
- CamelFolderInfo *fi;
- GPtrArray *array;
- char *utf7_name;
- int create;
- int id, i;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- if (!camel_session_is_online (session)) {
- if ((flags & CAMEL_STORE_FOLDER_CREATE) != 0) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create IMAP folders in offline mode."));
- } else {
- folder = camel_imap4_folder_new (store, folder_name, ex);
- }
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return folder;
- }
-
- /* make sure the folder exists - try LISTing it? */
- utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "LIST \"\" %S\r\n", utf7_name);
- camel_imap4_command_register_untagged (ic, "LIST", camel_imap4_untagged_list);
- ic->user_data = array = g_ptr_array_new ();
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- g_ptr_array_free (array, TRUE);
- goto done;
- }
-
- create = array->len == 0;
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- g_free (list->name);
- g_free (list);
- }
-
- g_ptr_array_free (array, TRUE);
-
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get folder `%s' on IMAP server %s: Unknown"),
- folder_name, ((CamelService *) store)->url->host);
- camel_imap4_command_unref (ic);
- goto done;
- }
-
- camel_imap4_command_unref (ic);
-
- if (create) {
- const char *basename;
- char *parent;
- int len;
-
- if (!(flags & CAMEL_STORE_FOLDER_CREATE))
- goto done;
-
- if (!(basename = strrchr (folder_name, '/')))
- basename = folder_name;
- else
- basename++;
-
- len = basename > folder_name ? (basename - folder_name) - 1 : 0;
- parent = g_alloca (len + 1);
- memcpy (parent, folder_name, len);
- parent[len] = '\0';
-
- if (!(fi = imap4_create_folder (store, parent, basename, ex)))
- goto done;
-
- camel_store_free_folder_info (store, fi);
- }
-
- folder = camel_imap4_folder_new (store, folder_name, ex);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return folder;
-}
-
-static CamelFolderInfo *
-imap4_create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex)
-{
- /* FIXME: also need to deal with parent folders that can't
- * contain subfolders - delete them and re-create with the
- * proper hint */
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
- CamelFolderInfo *fi = NULL;
- CamelIMAP4Command *ic;
- char *utf7_name;
- CamelURL *url;
- const char *c;
- char *name;
- char sep;
- int id;
-
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, parent_name);
-
- c = folder_name;
- while (*c != '\0') {
- if (*c == sep || strchr ("/#%*", *c)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_PATH,
- _("The folder name \"%s\" is invalid because "
- "it contains the character \"%c\""),
- folder_name, *c);
- return NULL;
- }
-
- c++;
- }
-
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create IMAP folders in offline mode."));
- return NULL;
- }
-
- if (parent_name != NULL && *parent_name)
- name = g_strdup_printf ("%s/%s", parent_name, folder_name);
- else
- name = g_strdup (folder_name);
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- utf7_name = imap4_folder_utf7_name (store, name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "CREATE %S\r\n", utf7_name);
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- g_free (name);
- goto done;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- url = camel_url_copy (engine->url);
- camel_url_set_fragment (url, name);
-
- c = strrchr (name, '/');
-
- fi = g_malloc0 (sizeof (CamelFolderInfo));
- fi->full_name = name;
- fi->name = g_strdup (c ? c + 1: name);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
- fi->flags = 0;
- fi->unread = -1;
- fi->total = -1;
-
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
-
- camel_object_trigger_event (store, "folder_created", fi);
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder `%s': Invalid mailbox name"),
- name);
- g_free (name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder `%s': Bad command"),
- name);
- g_free (name);
- break;
- default:
- g_assert_not_reached ();
- }
-
- camel_imap4_command_unref (ic);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return fi;
-}
-
-static void
-imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
- CamelFolder *selected = (CamelFolder *) engine->folder;
- CamelIMAP4Command *ic, *ic0 = NULL;
- CamelFolderInfo *fi;
- char *utf7_name;
- CamelURL *url;
- const char *p;
- int id;
-
- if (!g_ascii_strcasecmp (folder_name, "INBOX")) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot delete folder `%s': Special folder"),
- folder_name);
-
- return;
- }
-
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot delete IMAP folders in offline mode."));
- return;
- }
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- if (selected && !strcmp (folder_name, selected->full_name))
- ic0 = camel_imap4_engine_queue (engine, NULL, "CLOSE\r\n");
-
- utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "DELETE %S\r\n", utf7_name);
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- if (ic0 && ic0->status != CAMEL_IMAP4_COMMAND_COMPLETE)
- camel_exception_xfer (ex, &ic0->ex);
- else
- camel_exception_xfer (ex, &ic->ex);
-
- if (ic0 != NULL)
- camel_imap4_command_unref (ic0);
-
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- if (ic0 != NULL)
- camel_imap4_command_unref (ic0);
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /* deleted */
- url = camel_url_copy (engine->url);
- camel_url_set_fragment (url, folder_name);
-
- p = strrchr (folder_name, '/');
-
- fi = g_malloc0 (sizeof (CamelFolderInfo));
- fi->full_name = g_strdup (folder_name);
- fi->name = g_strdup (p ? p + 1: folder_name);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
- fi->flags = 0;
- fi->unread = -1;
- fi->total = -1;
-
- camel_imap4_store_summary_unnote_info (((CamelIMAP4Store *) store)->summary, fi);
-
- camel_object_trigger_event (store, "folder_deleted", fi);
-
- camel_folder_info_free (fi);
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot delete folder `%s': Invalid mailbox name"),
- folder_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot delete folder `%s': Bad command"),
- folder_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static void
-imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
- char *old_uname, *new_uname;
- CamelIMAP4Command *ic;
- int id;
-
- if (!g_ascii_strcasecmp (old_name, "INBOX")) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot rename folder `%s' to `%s': Special folder"),
- old_name, new_name);
-
- return;
- }
-
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot rename IMAP folders in offline mode."));
- return;
- }
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- old_uname = imap4_folder_utf7_name (store, old_name, '\0');
- new_uname = imap4_folder_utf7_name (store, new_name, '\0');
-
- ic = camel_imap4_engine_queue (engine, NULL, "RENAME %S %S\r\n", old_uname, new_uname);
- g_free (old_uname);
- g_free (new_uname);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /* FIXME: need to update state on the renamed folder object */
- /* FIXME: need to update cached summary info too */
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot rename folder `%s' to `%s': Invalid mailbox name"),
- old_name, new_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot rename folder `%s' to `%s': Bad command"),
- old_name, new_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static int
-list_sort (const camel_imap4_list_t **list0, const camel_imap4_list_t **list1)
-{
- return strcmp ((*list0)->name, (*list1)->name);
-}
-
-static void
-list_remove_duplicates (GPtrArray *array)
-{
- camel_imap4_list_t *list, *last;
- int i;
-
- last = array->pdata[0];
- for (i = 1; i < array->len; i++) {
- list = array->pdata[i];
- if (!strcmp (list->name, last->name)) {
- g_ptr_array_remove_index (array, i--);
- last->flags |= list->flags;
- g_free (list->name);
- g_free (list);
- }
- }
-}
-
-static void
-imap4_status (CamelStore *store, CamelFolderInfo *fi)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- camel_imap4_status_attr_t *attr, *next;
- camel_imap4_status_t *status;
- CamelIMAP4Command *ic;
- GPtrArray *array;
- char *mailbox;
- int id, i;
-
- mailbox = imap4_folder_utf7_name (store, fi->full_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "STATUS %S (MESSAGES UNSEEN)\r\n", mailbox);
- g_free (mailbox);
-
- camel_imap4_command_register_untagged (ic, "STATUS", camel_imap4_untagged_status);
- ic->user_data = array = g_ptr_array_new ();
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_imap4_command_unref (ic);
- g_ptr_array_free (array, TRUE);
- return;
- }
-
- for (i = 0; i < array->len; i++) {
- status = array->pdata[i];
- attr = status->attr_list;
- while (attr != NULL) {
- next = attr->next;
- if (attr->type == CAMEL_IMAP4_STATUS_MESSAGES)
- fi->total = attr->value;
- else if (attr->type == CAMEL_IMAP4_STATUS_UNSEEN)
- fi->unread = attr->value;
- g_free (attr);
- attr = next;
- }
-
- g_free (status->mailbox);
- g_free (status);
- }
-
- camel_imap4_command_unref (ic);
- g_ptr_array_free (array, TRUE);
-}
-
-static CamelFolderInfo *
-imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtrArray *array)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelFolder *folder = (CamelFolder *) engine->folder;
- camel_imap4_list_t *list;
- CamelFolderInfo *fi;
- char *name, *p;
- CamelURL *url;
- int i;
-
- if (array->len == 0) {
- g_ptr_array_free (array, TRUE);
- return NULL;
- }
-
- g_ptr_array_sort (array, (GCompareFunc) list_sort);
-
- list_remove_duplicates (array);
-
- url = camel_url_copy (engine->url);
-
- if (!strcmp (top, "") && (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)) {
- /* clear the folder-info cache */
- camel_store_summary_clear ((CamelStoreSummary *) ((CamelIMAP4Store *) store)->summary);
- }
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- fi = g_malloc0 (sizeof (CamelFolderInfo));
-
- p = name = camel_utf7_utf8 (list->name);
- while (*p != '\0') {
- if (*p == list->delim)
- *p = '/';
- p++;
- }
-
- p = strrchr (name, '/');
- camel_url_set_fragment (url, name);
-
- fi->full_name = name;
- fi->name = g_strdup (p ? p + 1: name);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- fi->flags = list->flags;
- fi->unread = -1;
- fi->total = -1;
-
- /* SELECTED folder, just get it from the folder */
- if (folder && !strcmp (folder->full_name, fi->full_name)) {
- camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &fi->total, CAMEL_FOLDER_UNREAD, &fi->unread, 0);
- } else if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
- imap4_status (store, fi);
- }
-
- g_free (list->name);
- g_free (list);
-
- array->pdata[i] = fi;
-
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
- }
-
- fi = camel_folder_info_build (array, top, '/', TRUE);
-
- camel_url_free (url);
-
- g_ptr_array_free (array, TRUE);
-
- camel_store_summary_save ((CamelStoreSummary *) ((CamelIMAP4Store *) store)->summary);
-
- return fi;
-}
-
-static CamelFolderInfo *
-imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
- CamelIMAP4Command *ic, *ic0 = NULL;
- CamelFolderInfo *fi = NULL;
- camel_imap4_list_t *list;
- GPtrArray *array;
- const char *cmd;
- char *pattern;
- char wildcard;
- int id, i;
-
- if (top == NULL)
- top = "";
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- if (!camel_session_is_online (session) || engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED) {
- fi = camel_imap4_store_summary_get_folder_info (((CamelIMAP4Store *) store)->summary, top, flags);
- if (fi == NULL && camel_session_is_online (session)) {
- /* folder info hasn't yet been cached and the store hasn't been
- * connected yet, but the network is available so we can connect
- * and query the server. */
- goto check_online;
- }
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return fi;
- }
-
- check_online:
-
- if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
- cmd = "LSUB";
- else
- cmd = "LIST";
-
- wildcard = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? '*' : '%';
- pattern = imap4_folder_utf7_name (store, top, wildcard);
- array = g_ptr_array_new ();
-
- if (*top != '\0') {
- size_t len;
- char sep;
-
- len = strlen (pattern);
- sep = pattern[len - 2];
- pattern[len - 2] = '\0';
-
- ic0 = camel_imap4_engine_queue (engine, NULL, "%s \"\" %S\r\n", cmd, pattern);
- camel_imap4_command_register_untagged (ic0, cmd, camel_imap4_untagged_list);
- ic0->user_data = array;
-
- pattern[len - 2] = sep;
- }
-
- ic = camel_imap4_engine_queue (engine, NULL, "%s \"\" %S\r\n", cmd, pattern);
- camel_imap4_command_register_untagged (ic, cmd, camel_imap4_untagged_list);
- ic->user_data = array;
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- if (ic0 && ic0->status != CAMEL_IMAP4_COMMAND_COMPLETE)
- camel_exception_xfer (ex, &ic0->ex);
- else
- camel_exception_xfer (ex, &ic->ex);
-
- if (ic0 != NULL)
- camel_imap4_command_unref (ic0);
- camel_imap4_command_unref (ic);
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- g_free (list->name);
- g_free (list);
- }
-
- g_ptr_array_free (array, TRUE);
- g_free (pattern);
-
- goto done;
- }
-
- if (ic0 != NULL)
- camel_imap4_command_unref (ic0);
-
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_imap4_command_unref (ic);
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get %s information for pattern `%s' on IMAP server %s: %s"),
- cmd, pattern, engine->url->host, ic->result == CAMEL_IMAP4_RESULT_BAD ?
- _("Bad command") : _("Unknown"));
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- g_free (list->name);
- g_free (list);
- }
-
- g_ptr_array_free (array, TRUE);
-
- g_free (pattern);
-
- goto done;
- }
-
- g_free (pattern);
-
- fi = imap4_build_folder_info (store, top, flags, array);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return fi;
-}
-
-static void
-imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
- CamelIMAP4Command *ic;
- CamelFolderInfo *fi;
- char *utf7_name;
- CamelURL *url;
- const char *p;
- int id;
-
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot subscribe to IMAP folders in offline mode."));
- return;
- }
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "SUBSCRIBE %S\r\n", utf7_name);
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /* subscribed */
- url = camel_url_copy (engine->url);
- camel_url_set_fragment (url, folder_name);
-
- p = strrchr (folder_name, '/');
-
- fi = g_malloc0 (sizeof (CamelFolderInfo));
- fi->full_name = g_strdup (folder_name);
- fi->name = g_strdup (p ? p + 1: folder_name);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
- fi->flags = CAMEL_FOLDER_NOCHILDREN;
- fi->unread = -1;
- fi->total = -1;
-
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
-
- camel_object_trigger_event (store, "folder_subscribed", fi);
- camel_folder_info_free (fi);
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot subscribe to folder `%s': Invalid mailbox name"),
- folder_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot subscribe to folder `%s': Bad command"),
- folder_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static void
-imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
- CamelIMAP4Command *ic;
- CamelFolderInfo *fi;
- char *utf7_name;
- CamelURL *url;
- const char *p;
- int id;
-
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot unsubscribe from IMAP folders in offline mode."));
- return;
- }
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "UNSUBSCRIBE %S\r\n", utf7_name);
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /* unsubscribed */
- url = camel_url_copy (engine->url);
- camel_url_set_fragment (url, folder_name);
-
- p = strrchr (folder_name, '/');
-
- fi = g_malloc0 (sizeof (CamelFolderInfo));
- fi->full_name = g_strdup (folder_name);
- fi->name = g_strdup (p ? p + 1: folder_name);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
- fi->flags = 0;
- fi->unread = -1;
- fi->total = -1;
-
- camel_imap4_store_summary_unnote_info (((CamelIMAP4Store *) store)->summary, fi);
-
- camel_object_trigger_event (store, "folder_unsubscribed", fi);
- camel_folder_info_free (fi);
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot unsubscribe from folder `%s': Invalid mailbox name"),
- folder_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot unsubscribe from folder `%s': Bad command"),
- folder_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static void
-imap4_noop (CamelStore *store, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
- CamelFolder *folder = (CamelFolder *) engine->folder;
- CamelIMAP4Command *ic;
- int id;
-
- if (!camel_session_is_online (session))
- return;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- if (folder) {
- camel_folder_sync (folder, FALSE, ex);
- if (camel_exception_is_set (ex)) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
- }
-
- ic = camel_imap4_engine_queue (engine, NULL, "NOOP\r\n");
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE)
- camel_exception_xfer (ex, &ic->ex);
-
- camel_imap4_command_unref (ic);
-
- if (folder && !camel_exception_is_set (ex))
- camel_imap4_summary_flush_updates (folder->summary, ex);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
diff --git a/camel/providers/imap4/camel-imap4-store.h b/camel/providers/imap4/camel-imap4-store.h
deleted file mode 100644
index aef3c6c6a4..0000000000
--- a/camel/providers/imap4/camel-imap4-store.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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_IMAP4_STORE_H__
-#define __CAMEL_IMAP4_STORE_H__
-
-#include <camel/camel-store.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_STORE (camel_imap4_store_get_type ())
-#define CAMEL_IMAP4_STORE(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_STORE, CamelIMAP4Store))
-#define CAMEL_IMAP4_STORE_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP4_STORE, CamelIMAP4StoreClass))
-#define CAMEL_IS_IMAP4_STORE(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP4_STORE))
-#define CAMEL_IS_IMAP4_STORE_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP4_STORE))
-#define CAMEL_IMAP4_STORE_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_IMAP4_STORE, CamelIMAP4StoreClass))
-
-typedef struct _CamelIMAP4Store CamelIMAP4Store;
-typedef struct _CamelIMAP4StoreClass CamelIMAP4StoreClass;
-
-struct _CamelIMAP4Engine;
-
-struct _CamelIMAP4Store {
- CamelStore parent_object;
-
- struct _CamelIMAP4StoreSummary *summary;
- struct _CamelIMAP4Engine *engine;
- char *storage_path;
-};
-
-struct _CamelIMAP4StoreClass {
- CamelStoreClass parent_class;
-
-};
-
-
-CamelType camel_imap4_store_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_STORE_H__ */
diff --git a/camel/providers/imap4/camel-imap4-stream.c b/camel/providers/imap4/camel-imap4-stream.c
deleted file mode 100644
index 4a48fe5cf2..0000000000
--- a/camel/providers/imap4/camel-imap4-stream.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "camel-imap4-specials.h"
-
-#include "camel-imap4-stream.h"
-
-#define d(x) x
-
-#define IMAP4_TOKEN_LEN 128
-
-static void camel_imap4_stream_class_init (CamelIMAP4StreamClass *klass);
-static void camel_imap4_stream_init (CamelIMAP4Stream *stream, CamelIMAP4StreamClass *klass);
-static void camel_imap4_stream_finalize (CamelObject *object);
-
-static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n);
-static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n);
-static int stream_flush (CamelStream *stream);
-static int stream_close (CamelStream *stream);
-static gboolean stream_eos (CamelStream *stream);
-
-
-static CamelStreamClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_stream_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (CAMEL_STREAM_TYPE,
- "CamelIMAP4Stream",
- sizeof (CamelIMAP4Stream),
- sizeof (CamelIMAP4StreamClass),
- (CamelObjectClassInitFunc) camel_imap4_stream_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_stream_init,
- (CamelObjectFinalizeFunc) camel_imap4_stream_finalize);
- }
-
- return type;
-}
-
-static void
-camel_imap4_stream_class_init (CamelIMAP4StreamClass *klass)
-{
- CamelStreamClass *stream_class = (CamelStreamClass *) klass;
-
- parent_class = (CamelStreamClass *) camel_type_get_global_classfuncs (CAMEL_STREAM_TYPE);
-
- /* virtual method overload */
- stream_class->read = stream_read;
- stream_class->write = stream_write;
- stream_class->flush = stream_flush;
- stream_class->close = stream_close;
- stream_class->eos = stream_eos;
-}
-
-static void
-camel_imap4_stream_init (CamelIMAP4Stream *imap4, CamelIMAP4StreamClass *klass)
-{
- imap4->stream = NULL;
-
- imap4->mode = CAMEL_IMAP4_STREAM_MODE_TOKEN;
- imap4->disconnected = FALSE;
- imap4->have_unget = FALSE;
- imap4->eol = FALSE;
-
- imap4->literal = 0;
-
- imap4->inbuf = imap4->realbuf + IMAP4_READ_PRELEN;
- imap4->inptr = imap4->inbuf;
- imap4->inend = imap4->inbuf;
-
- imap4->tokenbuf = g_malloc (IMAP4_TOKEN_LEN);
- imap4->tokenptr = imap4->tokenbuf;
- imap4->tokenleft = IMAP4_TOKEN_LEN;
-}
-
-static void
-camel_imap4_stream_finalize (CamelObject *object)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) object;
-
- if (imap4->stream)
- camel_object_unref (imap4->stream);
-
- g_free (imap4->tokenbuf);
-}
-
-
-static ssize_t
-imap4_fill (CamelIMAP4Stream *imap4)
-{
- unsigned char *inbuf, *inptr, *inend;
- ssize_t nread;
- size_t inlen;
-
- if (imap4->disconnected) {
- errno = EINVAL;
- return -1;
- }
-
- inbuf = imap4->inbuf;
- inptr = imap4->inptr;
- inend = imap4->inend;
- inlen = inend - inptr;
-
- g_assert (inptr <= inend);
-
- /* attempt to align 'inend' with realbuf + SCAN_HEAD */
- if (inptr >= inbuf) {
- inbuf -= inlen < IMAP4_READ_PRELEN ? inlen : IMAP4_READ_PRELEN;
- memmove (inbuf, inptr, inlen);
- inptr = inbuf;
- inbuf += inlen;
- } else if (inptr > imap4->realbuf) {
- size_t shift;
-
- shift = MIN (inptr - imap4->realbuf, inend - inbuf);
- memmove (inptr - shift, inptr, inlen);
- inptr -= shift;
- inbuf = inptr + inlen;
- } else {
- /* we can't shift... */
- inbuf = inend;
- }
-
- imap4->inptr = inptr;
- imap4->inend = inbuf;
- inend = imap4->realbuf + IMAP4_READ_PRELEN + IMAP4_READ_BUFLEN - 1;
-
- if ((nread = camel_stream_read (imap4->stream, inbuf, inend - inbuf)) == -1)
- return -1;
- else if (nread == 0)
- imap4->disconnected = TRUE;
-
- imap4->inend += nread;
-
- return imap4->inend - imap4->inptr;
-}
-
-static ssize_t
-stream_read (CamelStream *stream, char *buffer, size_t n)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
- ssize_t len, nread = 0;
-
- if (imap4->mode == CAMEL_IMAP4_STREAM_MODE_LITERAL) {
- /* don't let our caller read past the end of the literal */
- n = MIN (n, imap4->literal);
- }
-
- if (imap4->inptr < imap4->inend) {
- len = MIN (n, imap4->inend - imap4->inptr);
- memcpy (buffer, imap4->inptr, len);
- imap4->inptr += len;
- nread = len;
- }
-
- if (nread < n) {
- if ((len = camel_stream_read (imap4->stream, buffer + nread, n - nread)) == 0)
- imap4->disconnected = TRUE;
- else if (len == -1)
- return -1;
-
- nread += len;
- }
-
- if (imap4->mode == CAMEL_IMAP4_STREAM_MODE_LITERAL) {
- imap4->literal -= nread;
-
- if (imap4->literal == 0) {
- imap4->mode = CAMEL_IMAP4_STREAM_MODE_TOKEN;
- imap4->eol = TRUE;
- }
- }
-
- return nread;
-}
-
-static ssize_t
-stream_write (CamelStream *stream, const char *buffer, size_t n)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
- ssize_t nwritten;
-
- if (imap4->disconnected) {
- errno = EINVAL;
- return -1;
- }
-
- if ((nwritten = camel_stream_write (imap4->stream, buffer, n)) == 0)
- imap4->disconnected = TRUE;
-
- return nwritten;
-}
-
-static int
-stream_flush (CamelStream *stream)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
-
- return camel_stream_flush (imap4->stream);
-}
-
-static int
-stream_close (CamelStream *stream)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
-
- if (camel_stream_close (imap4->stream) == -1)
- return -1;
-
- camel_object_unref (imap4->stream);
- imap4->stream = NULL;
-
- imap4->disconnected = TRUE;
-
- return 0;
-}
-
-static gboolean
-stream_eos (CamelStream *stream)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
-
- if (imap4->eol)
- return TRUE;
-
- if (imap4->disconnected && imap4->inptr == imap4->inend)
- return TRUE;
-
- if (camel_stream_eos (imap4->stream))
- return TRUE;
-
- return FALSE;
-}
-
-
-/**
- * camel_imap4_stream_new:
- * @stream: tcp stream
- *
- * Returns a new imap4 stream
- **/
-CamelStream *
-camel_imap4_stream_new (CamelStream *stream)
-{
- CamelIMAP4Stream *imap4;
-
- g_return_val_if_fail (CAMEL_IS_STREAM (stream), NULL);
-
- imap4 = (CamelIMAP4Stream *) camel_object_new (CAMEL_TYPE_IMAP4_STREAM);
- camel_object_ref (stream);
- imap4->stream = stream;
-
- return (CamelStream *) imap4;
-}
-
-
-
-#define token_save(imap4, start, len) G_STMT_START { \
- if (imap4->tokenleft <= len) { \
- unsigned int tlen, toff; \
- \
- tlen = toff = imap4->tokenptr - imap4->tokenbuf; \
- tlen = tlen ? tlen : 1; \
- \
- while (tlen < toff + len) \
- tlen <<= 1; \
- \
- imap4->tokenbuf = g_realloc (imap4->tokenbuf, tlen + 1); \
- imap4->tokenptr = imap4->tokenbuf + toff; \
- imap4->tokenleft = tlen - toff; \
- } \
- \
- memcpy (imap4->tokenptr, start, len); \
- imap4->tokenptr += len; \
- imap4->tokenleft -= len; \
-} G_STMT_END
-
-#define token_clear(imap4) G_STMT_START { \
- imap4->tokenleft += imap4->tokenptr - imap4->tokenbuf; \
- imap4->tokenptr = imap4->tokenbuf; \
- imap4->literal = 0; \
-} G_STMT_END
-
-
-/**
- * camel_imap4_stream_next_token:
- * @stream: imap4 stream
- * @token: imap4 token
- *
- * Reads the next token from the imap4 stream and saves it in @token.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_stream_next_token (CamelIMAP4Stream *stream, camel_imap4_token_t *token)
-{
- register unsigned char *inptr;
- unsigned char *inend, *start, *p;
- gboolean escaped = FALSE;
- size_t literal = 0;
- guint32 nz_number;
- int ret;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_STREAM (stream), -1);
- g_return_val_if_fail (stream->mode != CAMEL_IMAP4_STREAM_MODE_LITERAL, -1);
- g_return_val_if_fail (token != NULL, -1);
-
- if (stream->have_unget) {
- memcpy (token, &stream->unget, sizeof (camel_imap4_token_t));
- stream->have_unget = FALSE;
- return 0;
- }
-
- token_clear (stream);
-
- inptr = stream->inptr;
- inend = stream->inend;
- *inend = '\0';
-
- do {
- if (inptr == inend) {
- if ((ret = imap4_fill (stream)) < 0) {
- token->token = CAMEL_IMAP4_TOKEN_ERROR;
- return -1;
- } else if (ret == 0) {
- token->token = CAMEL_IMAP4_TOKEN_NO_DATA;
- return 0;
- }
-
- inptr = stream->inptr;
- inend = stream->inend;
- *inend = '\0';
- }
-
- while (*inptr == ' ' || *inptr == '\r')
- inptr++;
- } while (inptr == inend);
-
- do {
- if (inptr < inend) {
- if (*inptr == '"') {
- /* qstring token */
- escaped = FALSE;
- start = inptr;
-
- /* eat the beginning " */
- inptr++;
-
- p = inptr;
- while (inptr < inend) {
- if (*inptr == '"' && !escaped)
- break;
-
- if (*inptr == '\\' && !escaped) {
- token_save (stream, p, inptr - p);
- escaped = TRUE;
- inptr++;
- p = inptr;
- } else {
- inptr++;
- escaped = FALSE;
- }
- }
-
- token_save (stream, p, inptr - p);
-
- if (inptr == inend) {
- stream->inptr = start;
- goto refill;
- }
-
- /* eat the ending " */
- inptr++;
-
- /* nul-terminate the atom token */
- token_save (stream, "", 1);
-
- token->token = CAMEL_IMAP4_TOKEN_QSTRING;
- token->v.qstring = stream->tokenbuf;
-
- d(fprintf (stderr, "token: \"%s\"\n", token->v.qstring));
-
- break;
- } else if (strchr ("+*()[]\n", *inptr)) {
- /* special character token */
- token->token = *inptr++;
-#if d(!)0
- if (token->token != '\n')
- fprintf (stderr, "token: %c\n", token->token);
- else
- fprintf (stderr, "token: \\n\n");
-#endif
- break;
- } else if (*inptr == '{') {
- /* literal identifier token */
- if ((p = strchr (inptr, '}')) && strchr (p, '\n')) {
- inptr++;
-
- while (isdigit ((int) *inptr) && literal < UINT_MAX / 10)
- literal = (literal * 10) + (*inptr++ - '0');
-
- if (*inptr != '}') {
- if (isdigit ((int) *inptr))
- g_warning ("illegal literal identifier: literal too large");
- else if (*inptr != '+')
- g_warning ("illegal literal identifier: garbage following size");
-
- while (*inptr != '}')
- inptr++;
- }
-
- /* skip over '}' */
- inptr++;
-
- /* skip over any trailing whitespace */
- while (*inptr == ' ' || *inptr == '\r')
- inptr++;
-
- if (*inptr != '\n') {
- g_warning ("illegal token following literal identifier: %s", inptr);
-
- /* skip ahead to the eoln */
- inptr = strchr (inptr, '\n');
- }
-
- /* skip over '\n' */
- inptr++;
-
- token->token = CAMEL_IMAP4_TOKEN_LITERAL;
- token->v.literal = literal;
-
- d(fprintf (stderr, "token: {%u}\n", literal));
-
- stream->mode = CAMEL_IMAP4_STREAM_MODE_LITERAL;
- stream->literal = literal;
- stream->eol = FALSE;
-
- break;
- } else {
- stream->inptr = inptr;
- goto refill;
- }
- } else if (*inptr >= '0' && *inptr <= '9') {
- /* number token */
- *inend = '\0';
- nz_number = strtoul ((char *) inptr, (char **) &start, 10);
- if (start == inend)
- goto refill;
-
- if (*start == ':' || *start == ',') {
- /* workaround for 'set' tokens (APPENDUID / COPYUID) */
- goto atom_token;
- }
-
- inptr = start;
- token->token = CAMEL_IMAP4_TOKEN_NUMBER;
- token->v.number = nz_number;
-
- d(fprintf (stderr, "token: %u\n", nz_number));
-
- break;
- } else if (is_atom (*inptr)) {
- atom_token:
- /* simple atom token */
- start = inptr;
-
- while (inptr < inend && is_atom (*inptr))
- inptr++;
-
- if (inptr == inend) {
- stream->inptr = start;
- goto refill;
- }
-
- token_save (stream, start, inptr - start);
-
- /* nul-terminate the atom token */
- token_save (stream, "", 1);
-
- if (!strcmp (stream->tokenbuf, "NIL")) {
- /* special atom token */
- token->token = CAMEL_IMAP4_TOKEN_NIL;
- d(fprintf (stderr, "token: NIL\n"));
- } else {
- token->token = CAMEL_IMAP4_TOKEN_ATOM;
- token->v.atom = stream->tokenbuf;
- d(fprintf (stderr, "token: %s\n", token->v.atom));
- }
-
- break;
- } else if (*inptr == '\\') {
- /* possible flag token ("\" atom) */
- start = inptr++;
-
- while (inptr < inend && is_atom (*inptr))
- inptr++;
-
- if (inptr == inend) {
- stream->inptr = start;
- goto refill;
- }
-
- /* handle the \* case */
- if ((inptr - start) == 1 && *inptr == '*')
- inptr++;
-
- if ((inptr - start) > 1) {
- token_save (stream, start, inptr - start);
-
- /* nul-terminate the flag token */
- token_save (stream, "", 1);
-
- token->token = CAMEL_IMAP4_TOKEN_FLAG;
- token->v.atom = stream->tokenbuf;
- d(fprintf (stderr, "token: %s\n", token->v.atom));
- } else {
- token->token = '\\';
- d(fprintf (stderr, "token: %c\n", token->token));
- }
- break;
- } else if (is_lwsp (*inptr)) {
- inptr++;
- } else {
- /* unknown character token? */
- token->token = *inptr++;
- d(fprintf (stderr, "token: %c\n", token->token));
- break;
- }
- } else {
- refill:
- token_clear (stream);
-
- if (imap4_fill (stream) <= 0) {
- token->token = CAMEL_IMAP4_TOKEN_ERROR;
- return -1;
- }
-
- inptr = stream->inptr;
- inend = stream->inend;
- *inend = '\0';
- }
- } while (inptr < inend);
-
- stream->inptr = inptr;
-
- return 0;
-}
-
-
-/**
- * camel_imap4_stream_unget_token:
- * @stream: imap4 stream
- * @token: token to 'unget'
- *
- * Ungets an imap4 token (as in ungetc()).
- *
- * Note: you may *ONLY* unget a single token. Trying to unget another
- * token will fail.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_stream_unget_token (CamelIMAP4Stream *stream, camel_imap4_token_t *token)
-{
- if (stream->have_unget)
- return -1;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NO_DATA) {
- memcpy (&stream->unget, token, sizeof (camel_imap4_token_t));
- stream->have_unget = TRUE;
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_stream_line:
- * @stream: imap4 stream
- * @line: line pointer
- * @len: line length
- *
- * Reads a single line from the imap4 stream and points @line at an
- * internal buffer containing the line read and sets @len to the
- * length of the line buffer.
- *
- * Returns -1 on error, 0 if the line read is complete, or 1 if the
- * read is incomplete.
- **/
-int
-camel_imap4_stream_line (CamelIMAP4Stream *stream, unsigned char **line, size_t *len)
-{
- register unsigned char *inptr;
- unsigned char *inend;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_STREAM (stream), -1);
- g_return_val_if_fail (stream->mode != CAMEL_IMAP4_STREAM_MODE_LITERAL, -1);
- g_return_val_if_fail (line != NULL, -1);
- g_return_val_if_fail (len != NULL, -1);
-
- inptr = stream->inptr;
- inend = stream->inend;
-
- if (inptr == inend || ((inend - inptr) < 2 && *inptr != '\n')) {
- if (imap4_fill (stream) == -1 && stream->inptr == stream->inend)
- return -1;
- }
-
- *line = stream->inptr;
- inptr = stream->inptr;
- inend = stream->inend;
- *inend = '\n';
-
- while (*inptr != '\n')
- inptr++;
-
- *len = (inptr - stream->inptr);
-
- if (inptr > stream->inptr && inptr[-1] == '\r')
- inptr[-1] = '\0';
-
- if (inptr < inend) {
- /* got the eoln */
- inptr[0] = '\0';
- *len += 1;
-
- stream->inptr = inptr + 1;
-
- return 0;
- }
-
- stream->inptr = inptr;
-
- return 1;
-}
-
-
-/**
- * camel_imap4_stream_literal:
- * @stream: IMAP stream
- * @literal: literal pointer
- * @len: literal length
- *
- * Sets @literal to the beginning of the next chunk of the literal
- * buffer from the IMAP stream and sets @len to the length of the
- * @literal buffer.
- *
- * Returns >0 if more literal data exists, 0 if the end of the literal
- * has been reached or -1 on fail.
- **/
-int
-camel_imap4_stream_literal (CamelIMAP4Stream *stream, unsigned char **literal, size_t *len)
-{
- unsigned char *inptr, *inend;
- size_t nread;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_STREAM (stream), -1);
- g_return_val_if_fail (stream->mode == CAMEL_IMAP4_STREAM_MODE_LITERAL, -1);
- g_return_val_if_fail (literal != NULL, -1);
- g_return_val_if_fail (len != NULL, -1);
-
- if (stream->eol) {
- *len = 0;
- return 0;
- }
-
- if ((stream->inend - stream->inptr) < 1) {
- /* keep our buffer full to the optimal size */
- if (imap4_fill (stream) == -1 && stream->inptr == stream->inend)
- return -1;
- }
-
- *literal = inptr = stream->inptr;
- inend = stream->inend;
- if ((inend - inptr) > stream->literal)
- inend = inptr + stream->literal;
- else
- inend = stream->inend;
-
- *len = nread = inend - inptr;
-
- stream->literal -= nread;
- stream->inptr += nread;
-
- if (stream->literal == 0) {
- stream->mode = CAMEL_IMAP4_STREAM_MODE_TOKEN;
- stream->eol = TRUE;
- return 0;
- }
-
- return 1;
-}
diff --git a/camel/providers/imap4/camel-imap4-stream.h b/camel/providers/imap4/camel-imap4-stream.h
deleted file mode 100644
index c0f870a0bd..0000000000
--- a/camel/providers/imap4/camel-imap4-stream.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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_IMAP4_STREAM_H__
-#define __CAMEL_IMAP4_STREAM_H__
-
-#include <camel/camel-stream.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_STREAM (camel_imap4_stream_get_type ())
-#define CAMEL_IMAP4_STREAM(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_STREAM, CamelIMAP4Stream))
-#define CAMEL_IMAP4_STREAM_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_TYPE_IMAP4_STREAM, CamelIMAP4StreamClass))
-#define CAMEL_IS_IMAP4_STREAM(o) (CAMEL_CHECK_TYPE((o), CAMEL_TYPE_IMAP4_STREAM))
-
-typedef struct _CamelIMAP4Stream CamelIMAP4Stream;
-typedef struct _CamelIMAP4StreamClass CamelIMAP4StreamClass;
-
-#define IMAP4_READ_PRELEN 128
-#define IMAP4_READ_BUFLEN 4096
-
-enum {
- CAMEL_IMAP4_TOKEN_NO_DATA = -8,
- CAMEL_IMAP4_TOKEN_ERROR = -7,
- CAMEL_IMAP4_TOKEN_NIL = -6,
- CAMEL_IMAP4_TOKEN_ATOM = -5,
- CAMEL_IMAP4_TOKEN_FLAG = -4,
- CAMEL_IMAP4_TOKEN_NUMBER = -3,
- CAMEL_IMAP4_TOKEN_QSTRING = -2,
- CAMEL_IMAP4_TOKEN_LITERAL = -1,
- /* CAMEL_IMAP4_TOKEN_CHAR would just be the char we got */
- CAMEL_IMAP4_TOKEN_EOLN = '\n',
- CAMEL_IMAP4_TOKEN_LPAREN = '(',
- CAMEL_IMAP4_TOKEN_RPAREN = ')',
- CAMEL_IMAP4_TOKEN_ASTERISK = '*',
- CAMEL_IMAP4_TOKEN_PLUS = '+',
- CAMEL_IMAP4_TOKEN_LBRACKET = '[',
- CAMEL_IMAP4_TOKEN_RBRACKET = ']',
-};
-
-typedef struct _camel_imap4_token_t {
- int token;
- union {
- char *atom;
- char *flag;
- char *qstring;
- size_t literal;
- guint32 number;
- } v;
-} camel_imap4_token_t;
-
-enum {
- CAMEL_IMAP4_STREAM_MODE_TOKEN = 0,
- CAMEL_IMAP4_STREAM_MODE_LITERAL = 1,
-};
-
-struct _CamelIMAP4Stream {
- CamelStream parent_object;
-
- CamelStream *stream;
-
- guint disconnected:1; /* disconnected state */
- guint have_unget:1; /* have an unget token */
- guint mode:1; /* TOKEN vs LITERAL */
- guint eol:1; /* end-of-literal */
-
- size_t literal;
-
- /* i/o buffers */
- unsigned char realbuf[IMAP4_READ_PRELEN + IMAP4_READ_BUFLEN + 1];
- unsigned char *inbuf;
- unsigned char *inptr;
- unsigned char *inend;
-
- /* token buffers */
- unsigned char *tokenbuf;
- unsigned char *tokenptr;
- unsigned int tokenleft;
-
- camel_imap4_token_t unget;
-};
-
-struct _CamelIMAP4StreamClass {
- CamelStreamClass parent_class;
-
- /* Virtual methods */
-};
-
-
-/* Standard Camel function */
-CamelType camel_imap4_stream_get_type (void);
-
-CamelStream *camel_imap4_stream_new (CamelStream *stream);
-
-int camel_imap4_stream_next_token (CamelIMAP4Stream *stream, camel_imap4_token_t *token);
-int camel_imap4_stream_unget_token (CamelIMAP4Stream *stream, camel_imap4_token_t *token);
-
-int camel_imap4_stream_line (CamelIMAP4Stream *stream, unsigned char **line, size_t *len);
-int camel_imap4_stream_literal (CamelIMAP4Stream *stream, unsigned char **literal, size_t *len);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_STREAM_H__ */
diff --git a/camel/providers/imap4/camel-imap4-summary.c b/camel/providers/imap4/camel-imap4-summary.c
deleted file mode 100644
index e38928ef43..0000000000
--- a/camel/providers/imap4/camel-imap4-summary.c
+++ /dev/null
@@ -1,1319 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <limits.h>
-#include <utime.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <libedataserver/md5-utils.h>
-
-#include <camel/camel-file-utils.h>
-#include <camel/camel-string-utils.h>
-#include <camel/camel-i18n.h>
-
-#include "camel-imap4-store.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-utils.h"
-
-#include "camel-imap4-summary.h"
-
-#define d(x) x
-
-#define IMAP4_SUMMARY_VERSION 1
-
-static void camel_imap4_summary_class_init (CamelIMAP4SummaryClass *klass);
-static void camel_imap4_summary_init (CamelIMAP4Summary *summary, CamelIMAP4SummaryClass *klass);
-static void camel_imap4_summary_finalize (CamelObject *object);
-
-static int imap4_header_load (CamelFolderSummary *summary, FILE *fin);
-static int imap4_header_save (CamelFolderSummary *summary, FILE *fout);
-static CamelMessageInfo *imap4_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header);
-static CamelMessageInfo *imap4_message_info_load (CamelFolderSummary *summary, FILE *fin);
-static int imap4_message_info_save (CamelFolderSummary *summary, FILE *fout, CamelMessageInfo *info);
-
-
-static CamelFolderSummaryClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_summary_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (CAMEL_FOLDER_SUMMARY_TYPE,
- "CamelIMAP4Summary",
- sizeof (CamelIMAP4Summary),
- sizeof (CamelIMAP4SummaryClass),
- (CamelObjectClassInitFunc) camel_imap4_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_summary_init,
- (CamelObjectFinalizeFunc) camel_imap4_summary_finalize);
- }
-
- return type;
-}
-
-
-static void
-camel_imap4_summary_class_init (CamelIMAP4SummaryClass *klass)
-{
- CamelFolderSummaryClass *summary_class = (CamelFolderSummaryClass *) klass;
-
- parent_class = (CamelFolderSummaryClass *) camel_type_get_global_classfuncs (camel_folder_summary_get_type ());
-
- summary_class->summary_header_load = imap4_header_load;
- summary_class->summary_header_save = imap4_header_save;
- summary_class->message_info_new_from_header = imap4_message_info_new_from_header;
- summary_class->message_info_load = imap4_message_info_load;
- summary_class->message_info_save = imap4_message_info_save;
-}
-
-static void
-camel_imap4_summary_init (CamelIMAP4Summary *summary, CamelIMAP4SummaryClass *klass)
-{
- CamelFolderSummary *folder_summary = (CamelFolderSummary *) summary;
-
- folder_summary->version += IMAP4_SUMMARY_VERSION;
- folder_summary->flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED |
- CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN;
-
- folder_summary->message_info_size = sizeof (CamelIMAP4MessageInfo);
-
- summary->update_flags = TRUE;
- summary->uidvalidity_changed = FALSE;
-}
-
-static void
-camel_imap4_summary_finalize (CamelObject *object)
-{
- ;
-}
-
-
-CamelFolderSummary *
-camel_imap4_summary_new (CamelFolder *folder)
-{
- CamelFolderSummary *summary;
-
- summary = (CamelFolderSummary *) camel_object_new (CAMEL_TYPE_IMAP4_SUMMARY);
- summary->folder = folder;
-
- return summary;
-}
-
-static int
-imap4_header_load (CamelFolderSummary *summary, FILE *fin)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- if (CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->summary_header_load (summary, fin) == -1)
- return -1;
-
- if (camel_file_util_decode_uint32 (fin, &imap4_summary->uidvalidity) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-imap4_header_save (CamelFolderSummary *summary, FILE *fout)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- if (CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->summary_header_save (summary, fout) == -1)
- return -1;
-
- if (camel_file_util_encode_uint32 (fout, imap4_summary->uidvalidity) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-envelope_decode_address (CamelIMAP4Engine *engine, GString *addrs, CamelException *ex)
-{
- char *addr, *name = NULL, *user = NULL;
- struct _camel_header_address *cia;
- unsigned char *literal = NULL;
- camel_imap4_token_t token;
- const char *domain = NULL;
- int part = 0;
- size_t n;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token == CAMEL_IMAP4_TOKEN_NIL) {
- return 0;
- } else if (token.token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- if (addrs->len > 0)
- g_string_append (addrs, ", ");
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- literal = NULL;
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- case CAMEL_IMAP4_TOKEN_QSTRING:
- switch (part) {
- case 0:
- name = camel_header_decode_string (token.v.qstring, NULL);
- break;
- case 2:
- user = g_strdup (token.v.qstring);
- break;
- case 3:
- domain = token.v.qstring;
- break;
- }
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, &literal, &n, ex) == -1)
- goto exception;
-
- switch (part) {
- case 0:
- name = camel_header_decode_string (literal, NULL);
- g_free (literal);
- break;
- case 2:
- user = literal;
- break;
- case 3:
- domain = literal;
- break;
- }
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- part++;
- } while (part < 4);
-
- addr = g_strdup_printf ("%s@%s", user, domain);
- g_free (literal);
- g_free (user);
-
- cia = camel_header_address_new_name (name, addr);
- g_free (name);
- g_free (addr);
-
- addr = camel_header_address_list_format (cia);
- camel_header_address_unref (cia);
-
- g_string_append (addrs, addr);
- g_free (addr);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != ')') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-
- exception:
-
- g_free (name);
- g_free (user);
-
- return -1;
-}
-
-static int
-envelope_decode_addresses (CamelIMAP4Engine *engine, char **addrlist, CamelException *ex)
-{
- camel_imap4_token_t token;
- GString *addrs;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token == CAMEL_IMAP4_TOKEN_NIL) {
- *addrlist = NULL;
- return 0;
- } else if (token.token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- addrs = g_string_new ("");
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1) {
- g_string_free (addrs, TRUE);
- return -1;
- }
-
- if (token.token == '(') {
- camel_imap4_stream_unget_token (engine->istream, &token);
-
- if (envelope_decode_address (engine, addrs, ex) == -1) {
- g_string_free (addrs, TRUE);
- return -1;
- }
- } else if (token.token == ')') {
- break;
- } else {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
- } while (1);
-
- *addrlist = addrs->str;
- g_string_free (addrs, FALSE);
-
- return 0;
-}
-
-static int
-envelope_decode_date (CamelIMAP4Engine *engine, time_t *date, CamelException *ex)
-{
- unsigned char *literal = NULL;
- camel_imap4_token_t token;
- const char *nstring;
- size_t n;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- *date = (time_t) -1;
- return 0;
- case CAMEL_IMAP4_TOKEN_ATOM:
- nstring = token.v.atom;
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- nstring = token.v.qstring;
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, &literal, &n, ex) == -1)
- return -1;
-
- nstring = literal;
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- *date = camel_header_decode_date (nstring, NULL);
-
- g_free (literal);
-
- return 0;
-}
-
-static int
-envelope_decode_nstring (CamelIMAP4Engine *engine, char **nstring, gboolean rfc2047, CamelException *ex)
-{
- camel_imap4_token_t token;
- unsigned char *literal;
- size_t n;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- *nstring = NULL;
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- if (rfc2047)
- *nstring = camel_header_decode_string (token.v.atom, NULL);
- else
- *nstring = g_strdup (token.v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- if (rfc2047)
- *nstring = camel_header_decode_string (token.v.qstring, NULL);
- else
- *nstring = g_strdup (token.v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, &literal, &n, ex) == -1)
- return -1;
-
- if (rfc2047) {
- *nstring = camel_header_decode_string (literal, NULL);
- g_free (literal);
- } else
- *nstring = literal;
-
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-static CamelSummaryReferences *
-decode_references (const char *string)
-{
- struct _camel_header_references *refs, *r;
- CamelSummaryReferences *references;
- unsigned char md5sum[16];
- guint32 i, n = 0;
- MD5Context md5;
-
- if (!(r = refs = camel_header_references_inreplyto_decode (string)))
- return NULL;
-
- while (r != NULL) {
- r = r->next;
- n++;
- }
-
- references = g_malloc (sizeof (CamelSummaryReferences) + (sizeof (CamelSummaryMessageID) * (n - 1)));
- references->size = n;
-
- for (i = 0, r = refs; i < n; i++, r = r->next) {
- md5_init (&md5);
- md5_update (&md5, r->id, strlen (r->id));
- md5_final (&md5, md5sum);
- memcpy (references->references[i].id.hash, md5sum, sizeof (references->references[i].id.hash));
- }
-
- camel_header_references_list_clear (&refs);
-
- return references;
-}
-
-static int
-decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_token_t *token, CamelException *ex)
-{
- unsigned char md5sum[16];
- char *nstring;
- CamelIMAP4MessageInfo *iinfo = (CamelIMAP4MessageInfo *)info;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- if (envelope_decode_date (engine, &iinfo->info.date_sent, ex) == -1)
- goto exception;
-
- /* subject */
- if (envelope_decode_nstring (engine, &nstring, TRUE, ex) == -1)
- goto exception;
- iinfo->info.subject = camel_pstring_strdup(nstring);
- g_free(nstring);
-
- /* from */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- iinfo->info.from = camel_pstring_strdup(nstring);
- g_free(nstring);
-
- /* sender */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- g_free (nstring);
-
- /* reply-to */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- g_free (nstring);
-
- /* to */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- iinfo->info.to = camel_pstring_strdup(nstring);
- g_free(nstring);
-
- /* cc */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- iinfo->info.cc = camel_pstring_strdup(nstring);
- g_free(nstring);
-
- /* bcc */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- g_free (nstring);
-
- /* in-reply-to */
- if (envelope_decode_nstring (engine, &nstring, FALSE, ex) == -1)
- goto exception;
-
- if (nstring != NULL) {
- iinfo->info.references = decode_references (nstring);
- g_free (nstring);
- }
-
- /* message-id */
- if (envelope_decode_nstring (engine, &nstring, FALSE, ex) == -1)
- goto exception;
-
- if (nstring != NULL) {
- md5_get_digest (nstring, strlen (nstring), md5sum);
- memcpy (iinfo->info.message_id.id.hash, md5sum, sizeof (iinfo->info.message_id.id.hash));
- g_free (nstring);
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != ')') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- goto exception;
- }
-
- return 0;
-
- exception:
-
- return -1;
-}
-
-static char *tm_months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static gboolean
-decode_time (const char **in, int *hour, int *min, int *sec)
-{
- register const unsigned char *inptr = (const unsigned char *) *in;
- int *val, colons = 0;
-
- *hour = *min = *sec = 0;
-
- val = hour;
- for ( ; *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
-mktime_utc (struct tm *tm)
-{
- time_t tt;
-
- tm->tm_isdst = -1;
- tt = mktime (tm);
-
-#if defined (HAVE_TM_GMTOFF)
- tt += tm->tm_gmtoff;
-#elif defined (HAVE_TIMEZONE)
- if (tm->tm_isdst > 0) {
-#if defined (HAVE_ALTZONE)
- tt -= altzone;
-#else /* !defined (HAVE_ALTZONE) */
- tt -= (timezone - 3600);
-#endif
- } else
- tt -= timezone;
-#endif
-
- return tt;
-}
-
-static time_t
-decode_internaldate (const char *in)
-{
- const char *inptr = in;
- int hour, min, sec, n;
- struct tm tm;
- time_t date;
- char *buf;
-
- memset ((void *) &tm, 0, sizeof (struct tm));
-
- tm.tm_mday = strtoul (inptr, &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, &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 = 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;
-}
-
-enum {
- IMAP4_FETCH_ENVELOPE = (1 << 1),
- IMAP4_FETCH_FLAGS = (1 << 2),
- IMAP4_FETCH_INTERNALDATE = (1 << 3),
- IMAP4_FETCH_RFC822SIZE = (1 << 4),
- IMAP4_FETCH_UID = (1 << 5),
-};
-
-#define IMAP4_FETCH_ALL (IMAP4_FETCH_ENVELOPE | IMAP4_FETCH_FLAGS | IMAP4_FETCH_INTERNALDATE | IMAP4_FETCH_RFC822SIZE | IMAP4_FETCH_UID)
-
-struct imap4_envelope_t {
- CamelMessageInfo *info;
- guint changed;
-};
-
-struct imap4_fetch_all_t {
- CamelFolderChangeInfo *changes;
- CamelFolderSummary *summary;
- GHashTable *uid_hash;
- GPtrArray *added;
- guint32 first;
- guint32 need;
- int count;
- int total;
-};
-
-static void
-imap4_fetch_all_free (struct imap4_fetch_all_t *fetch)
-{
- struct imap4_envelope_t *envelope;
- int i;
-
- for (i = 0; i < fetch->added->len; i++) {
- if (!(envelope = fetch->added->pdata[i]))
- continue;
-
- camel_message_info_free(envelope->info);
- g_free (envelope);
- }
-
- g_ptr_array_free (fetch->added, TRUE);
- g_hash_table_destroy (fetch->uid_hash);
- camel_folder_change_info_free (fetch->changes);
- g_free (fetch);
-}
-
-static void
-courier_imap_is_a_piece_of_shit (CamelFolderSummary *summary, guint32 msg)
-{
- CamelSession *session = ((CamelService *) summary->folder->parent_store)->session;
- char *warning;
-
- warning = g_strdup_printf ("IMAP server did not respond with an untagged FETCH response "
- "for message #%u. This is illegal according to rfc3501 (and "
- "the older rfc2060). You will need to contact your\n"
- "Administrator(s) (or ISP) and have them resolve this issue.\n\n"
- "Hint: If your IMAP server is Courier-IMAP, it is likely that this "
- "message is simply unreadable by the IMAP server and will need "
- "to be given read permissions.", msg);
-
- camel_session_alert_user (session, CAMEL_SESSION_ALERT_WARNING, warning, FALSE);
- g_free (warning);
-}
-
-static void
-imap4_fetch_all_add (struct imap4_fetch_all_t *fetch)
-{
- CamelFolderChangeInfo *changes = NULL;
- struct imap4_envelope_t *envelope;
- CamelMessageInfo *info;
- int i;
-
- changes = fetch->changes;
-
- for (i = 0; i < fetch->added->len; i++) {
- if (!(envelope = fetch->added->pdata[i])) {
- courier_imap_is_a_piece_of_shit (fetch->summary, i + fetch->first);
- break;
- }
-
- if (envelope->changed != IMAP4_FETCH_ALL) {
- d(fprintf (stderr, "Hmmm, IMAP4 server didn't give us everything for message %d\n", i + 1));
- camel_message_info_free(envelope->info);
- g_free (envelope);
- continue;
- }
-
- if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (envelope->info)))) {
- camel_message_info_free(envelope->info);
- g_free (envelope);
- continue;
- }
-
- camel_folder_change_info_add_uid (changes, camel_message_info_uid (envelope->info));
-
- camel_folder_summary_add (fetch->summary, envelope->info);
- g_free (envelope);
- }
-
- g_ptr_array_free (fetch->added, TRUE);
- g_hash_table_destroy (fetch->uid_hash);
-
- if (camel_folder_change_info_changed (changes))
- camel_object_trigger_event (fetch->summary->folder, "folder_changed", changes);
- camel_folder_change_info_free (changes);
-
- g_free (fetch);
-}
-
-static guint32
-imap4_fetch_all_update (struct imap4_fetch_all_t *fetch)
-{
- CamelIMAP4MessageInfo *iinfo, *new_iinfo;
- CamelFolderChangeInfo *changes = NULL;
- struct imap4_envelope_t *envelope;
- CamelMessageInfo *info;
- guint32 first = 0;
- guint32 flags;
- int scount, i;
-
- changes = fetch->changes;
-
- scount = camel_folder_summary_count (fetch->summary);
- for (i = fetch->first - 1; i < scount; i++) {
- info = camel_folder_summary_index (fetch->summary, i);
- if (!(envelope = g_hash_table_lookup (fetch->uid_hash, camel_message_info_uid (info)))) {
- /* remove it */
- camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
- camel_folder_summary_remove (fetch->summary, info);
- scount--;
- i--;
- } else if (envelope->changed & IMAP4_FETCH_FLAGS) {
- /* update it with the new flags */
- new_iinfo = (CamelIMAP4MessageInfo *) envelope->info;
- iinfo = (CamelIMAP4MessageInfo *) info;
-
- flags = iinfo->info.flags;
- iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, new_iinfo->server_flags);
- iinfo->server_flags = new_iinfo->server_flags;
- if (iinfo->info.flags != flags)
- camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
- }
-
- camel_message_info_free(info);
- }
-
- for (i = 0; i < fetch->added->len; i++) {
- if (!(envelope = fetch->added->pdata[i])) {
- courier_imap_is_a_piece_of_shit (fetch->summary, i + fetch->first);
- break;
- }
-
- info = envelope->info;
- if (!first && camel_message_info_uid (info)) {
- if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (info)))) {
- camel_message_info_free(info);
- } else {
- first = i + fetch->first;
- }
- }
-
- camel_message_info_free(envelope->info);
- g_free (envelope);
- }
-
- g_ptr_array_free (fetch->added, TRUE);
- g_hash_table_destroy (fetch->uid_hash);
-
- if (camel_folder_change_info_changed (changes))
- camel_object_trigger_event (fetch->summary->folder, "folder_changed", changes);
- camel_folder_change_info_free (changes);
-
- g_free (fetch);
-
- return first;
-}
-
-static int
-untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
-{
- struct imap4_fetch_all_t *fetch = ic->user_data;
- CamelFolderSummary *summary = fetch->summary;
- struct imap4_envelope_t *envelope = NULL;
- GPtrArray *added = fetch->added;
- CamelIMAP4MessageInfo *iinfo;
- CamelMessageInfo *info;
- guint32 changed = 0;
- const char *iuid;
- char uid[12];
-
- if (index < fetch->first) {
- /* we already have this message envelope cached -
- * server is probably notifying us of a FLAGS change
- * by another client? */
- g_assert (index < summary->messages->len);
- iinfo = (CamelIMAP4MessageInfo *)(info = summary->messages->pdata[index - 1]);
- g_assert (info != NULL);
- } else {
- if (index > (added->len + fetch->first - 1))
- g_ptr_array_set_size (added, index - fetch->first + 1);
-
- if (!(envelope = added->pdata[index - fetch->first])) {
- iinfo = (CamelIMAP4MessageInfo *) (info = camel_message_info_new (summary));
- envelope = g_new (struct imap4_envelope_t, 1);
- added->pdata[index - fetch->first] = envelope;
- envelope->info = info;
- envelope->changed = 0;
- } else {
- iinfo = (CamelIMAP4MessageInfo *) (info = envelope->info);
- }
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- /* parse the FETCH response list */
- if (token->token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- do {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token == ')' || token->token == '\n')
- break;
-
- if (token->token != CAMEL_IMAP4_TOKEN_ATOM)
- goto unexpected;
-
- if (!strcmp (token->v.atom, "ENVELOPE")) {
- if (envelope) {
- if (decode_envelope (engine, info, token, ex) == -1)
- goto exception;
-
- changed |= IMAP4_FETCH_ENVELOPE;
- } else {
- CamelMessageInfo *tmp;
- int rv;
-
- g_warning ("Hmmm, server is sending us ENVELOPE data for a message we didn't ask for (message %u)\n",
- index);
- tmp = camel_message_info_new (summary);
- rv = decode_envelope (engine, tmp, token, ex);
- camel_message_info_free(tmp);
-
- if (rv == -1)
- goto exception;
- }
- } else if (!strcmp (token->v.atom, "FLAGS")) {
- guint32 server_flags = 0;
-
- if (camel_imap4_parse_flags_list (engine, &server_flags, ex) == -1)
- return -1;
-
- iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, server_flags);
- iinfo->server_flags = server_flags;
-
- changed |= IMAP4_FETCH_FLAGS;
- } else if (!strcmp (token->v.atom, "INTERNALDATE")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- iinfo->info.date_received = (time_t) -1;
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- case CAMEL_IMAP4_TOKEN_QSTRING:
- iinfo->info.date_received = decode_internaldate (token->v.qstring);
- break;
- default:
- goto unexpected;
- }
-
- changed |= IMAP4_FETCH_INTERNALDATE;
- } else if (!strcmp (token->v.atom, "RFC822.SIZE")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NUMBER)
- goto unexpected;
-
- iinfo->info.size = token->v.number;
-
- changed |= IMAP4_FETCH_RFC822SIZE;
- } else if (!strcmp (token->v.atom, "UID")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NUMBER || token->v.number == 0)
- goto unexpected;
-
- sprintf (uid, "%u", token->v.number);
- iuid = camel_message_info_uid (info);
- if (iuid != NULL && iuid[0] != '\0') {
- if (strcmp (iuid, uid) != 0) {
- d(fprintf (stderr, "Hmmm, UID mismatch for message %u\n", index));
- g_assert_not_reached ();
- }
- } else {
- g_free(info->uid);
- info->uid = g_strdup (uid);
- g_hash_table_insert (fetch->uid_hash, (void *) camel_message_info_uid (info), envelope);
- changed |= IMAP4_FETCH_UID;
- }
- } else {
- /* wtf? */
- d(fprintf (stderr, "huh? %s?...\n", token->v.atom));
- }
- } while (1);
-
- if (envelope) {
- envelope->changed |= changed;
- if ((envelope->changed & fetch->need) == fetch->need)
- camel_operation_progress (NULL, (++fetch->count * 100.0f) / fetch->total);
- } else if (changed & IMAP4_FETCH_FLAGS) {
- camel_folder_change_info_change_uid (fetch->changes, camel_message_info_uid (info));
- }
-
- if (token->token != ')')
- goto unexpected;
-
- return 0;
-
- unexpected:
-
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- exception:
-
- return -1;
-}
-
-#define IMAP4_ALL "FLAGS INTERNALDATE RFC822.SIZE ENVELOPE"
-
-static CamelIMAP4Command *
-imap4_summary_fetch_all (CamelFolderSummary *summary, guint32 first, guint32 last)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelFolder *folder = summary->folder;
- struct imap4_fetch_all_t *fetch;
- CamelIMAP4Engine *engine;
- CamelIMAP4Command *ic;
- int total;
-
- engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
-
- total = last ? (last - first) + 1 : (imap4_summary->exists - first) + 1;
- fetch = g_new (struct imap4_fetch_all_t, 1);
- fetch->uid_hash = g_hash_table_new (g_str_hash, g_str_equal);
- fetch->changes = camel_folder_change_info_new ();
- fetch->added = g_ptr_array_sized_new (total);
- fetch->summary = summary;
- fetch->first = first;
- fetch->need = IMAP4_FETCH_ALL;
- fetch->total = total;
- fetch->count = 0;
-
- if (last != 0)
- ic = camel_imap4_engine_queue (engine, folder, "FETCH %u:%u (UID " IMAP4_ALL ")\r\n", first, last);
- else
- ic = camel_imap4_engine_queue (engine, folder, "FETCH %u:* (UID " IMAP4_ALL ")\r\n", first);
-
- camel_imap4_command_register_untagged (ic, "FETCH", untagged_fetch_all);
- ic->user_data = fetch;
-
- return ic;
-}
-
-static CamelIMAP4Command *
-imap4_summary_fetch_flags (CamelFolderSummary *summary, guint32 first, guint32 last)
-{
- CamelFolder *folder = summary->folder;
- struct imap4_fetch_all_t *fetch;
- CamelIMAP4Engine *engine;
- CamelIMAP4Command *ic;
- int total;
-
- engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
-
- total = (last - first) + 1;
- fetch = g_new (struct imap4_fetch_all_t, 1);
- fetch->uid_hash = g_hash_table_new (g_str_hash, g_str_equal);
- fetch->changes = camel_folder_change_info_new ();
- fetch->added = g_ptr_array_sized_new (total);
- fetch->summary = summary;
- fetch->first = first;
- fetch->need = IMAP4_FETCH_UID | IMAP4_FETCH_FLAGS;
- fetch->total = total;
- fetch->count = 0;
-
- if (last != 0)
- ic = camel_imap4_engine_queue (engine, folder, "FETCH %u:%u (UID FLAGS)\r\n", first, last);
- else
- ic = camel_imap4_engine_queue (engine, folder, "FETCH %u:* (UID FLAGS)\r\n", first);
-
- camel_imap4_command_register_untagged (ic, "FETCH", untagged_fetch_all);
- ic->user_data = fetch;
-
- return ic;
-}
-
-#if 0
-static int
-imap4_build_summary (CamelFolderSummary *summary, guint32 first, guint32 last)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelFolder *folder = summary->folder;
- struct imap4_fetch_all_t *fetch;
- CamelIMAP4Engine *engine;
- CamelIMAP4Command *ic;
- int id;
-
- engine = ((CamelIMAP4Store *) folder->store)->engine;
-
- ic = imap4_summary_fetch_all (summary, first, last);
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- fetch = ic->user_data;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_imap4_command_unref (ic);
- imap4_fetch_all_free (fetch);
- return -1;
- }
-
- imap4_fetch_all_add (fetch);
-
- camel_imap4_command_unref (ic);
-
- return 0;
-}
-#endif
-
-static CamelMessageInfo *
-imap4_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header)
-{
- CamelMessageInfo *info;
-
- info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header (summary, header);
-
- ((CamelIMAP4MessageInfo *) info)->server_flags = 0;
-
- return info;
-}
-
-static CamelMessageInfo *
-imap4_message_info_load (CamelFolderSummary *summary, FILE *fin)
-{
- CamelIMAP4MessageInfo *minfo;
- CamelMessageInfo *info;
-
- if (!(info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_load (summary, fin)))
- return NULL;
-
- minfo = (CamelIMAP4MessageInfo *) info;
-
- if (camel_file_util_decode_uint32 (fin, &minfo->server_flags) == -1)
- goto exception;
-
- return info;
-
- exception:
-
- camel_message_info_free(info);
-
- return NULL;
-}
-
-static int
-imap4_message_info_save (CamelFolderSummary *summary, FILE *fout, CamelMessageInfo *info)
-{
- CamelIMAP4MessageInfo *minfo = (CamelIMAP4MessageInfo *) info;
-
- if (CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_save (summary, fout, info) == -1)
- return -1;
-
- if (camel_file_util_encode_uint32 (fout, minfo->server_flags) == -1)
- return -1;
-
- return 0;
-}
-
-
-void
-camel_imap4_summary_set_exists (CamelFolderSummary *summary, guint32 exists)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- imap4_summary->exists = exists;
-}
-
-void
-camel_imap4_summary_set_recent (CamelFolderSummary *summary, guint32 recent)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- imap4_summary->recent = recent;
-}
-
-void
-camel_imap4_summary_set_unseen (CamelFolderSummary *summary, guint32 unseen)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- imap4_summary->unseen = unseen;
-}
-
-void
-camel_imap4_summary_set_uidnext (CamelFolderSummary *summary, guint32 uidnext)
-{
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- summary->nextuid = uidnext;
-}
-
-void
-camel_imap4_summary_set_uidvalidity (CamelFolderSummary *summary, guint32 uidvalidity)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelFolderChangeInfo *changes;
- CamelMessageInfo *info;
- int i, count;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- if (imap4_summary->uidvalidity == uidvalidity)
- return;
-
- changes = camel_folder_change_info_new ();
- count = camel_folder_summary_count (summary);
- for (i = 0; i < count; i++) {
- if (!(info = camel_folder_summary_index (summary, i)))
- continue;
-
- camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
- camel_message_info_free(info);
- }
-
- camel_folder_summary_clear (summary);
- camel_data_cache_clear (((CamelIMAP4Folder *) summary->folder)->cache, "cache", NULL);
-
- if (camel_folder_change_info_changed (changes))
- camel_object_trigger_event (summary->folder, "folder_changed", changes);
- camel_folder_change_info_free (changes);
-
- imap4_summary->uidvalidity = uidvalidity;
-
- imap4_summary->uidvalidity_changed = TRUE;
-}
-
-void
-camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelFolderChangeInfo *changes;
- CamelMessageInfo *info;
- const char *uid;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- seqid--;
- if (!(info = camel_folder_summary_index (summary, seqid)))
- return;
-
- imap4_summary->exists--;
-
- uid = camel_message_info_uid (info);
- camel_data_cache_remove (((CamelIMAP4Folder *) summary->folder)->cache, "cache", uid, NULL);
-
- changes = camel_folder_change_info_new ();
- camel_folder_change_info_remove_uid (changes, uid);
-
- camel_message_info_free(info);
- camel_folder_summary_remove_index (summary, seqid);
-
- camel_object_trigger_event (summary->folder, "folder_changed", changes);
- camel_folder_change_info_free (changes);
-}
-
-#if 0
-static int
-info_uid_sort (const CamelMessageInfo **info0, const CamelMessageInfo **info1)
-{
- guint32 uid0, uid1;
-
- uid0 = strtoul (camel_message_info_uid (*info0), NULL, 10);
- uid1 = strtoul (camel_message_info_uid (*info1), NULL, 10);
-
- if (uid0 == uid1)
- return 0;
-
- return uid0 < uid1 ? -1 : 1;
-}
-#endif
-
-int
-camel_imap4_summary_flush_updates (CamelFolderSummary *summary, CamelException *ex)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelIMAP4Engine *engine;
- CamelIMAP4Command *ic;
- guint32 first = 0;
- int scount, id;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary), -1);
-
- engine = ((CamelIMAP4Store *) summary->folder->parent_store)->engine;
- scount = camel_folder_summary_count (summary);
-
- if (imap4_summary->uidvalidity_changed) {
- first = 1;
- } else if (imap4_summary->update_flags || imap4_summary->exists < scount) {
- /* this both updates flags and removes messages which
- * have since been expunged from the server by another
- * client */
- ic = imap4_summary_fetch_flags (summary, 1, scount);
-
- camel_operation_start (NULL, _("Scanning for changed messages"));
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- imap4_fetch_all_free (ic->user_data);
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- camel_operation_end (NULL);
- return -1;
- }
-
- if (!(first = imap4_fetch_all_update (ic->user_data)) && imap4_summary->exists > scount)
- first = scount + 1;
-
- camel_imap4_command_unref (ic);
- camel_operation_end (NULL);
- } else {
- first = scount + 1;
- }
-
- if (first != 0 && first <= imap4_summary->exists) {
- ic = imap4_summary_fetch_all (summary, first, 0);
-
- camel_operation_start (NULL, _("Fetching envelopes for new messages"));
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- imap4_fetch_all_free (ic->user_data);
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- camel_operation_end (NULL);
- return -1;
- }
-
- imap4_fetch_all_add (ic->user_data);
- camel_imap4_command_unref (ic);
- camel_operation_end (NULL);
-
-#if 0
- /* Note: this should not be needed - the code that adds envelopes to the summary
- * adds them in proper order */
-
- /* it's important for these to be sorted sequentially for EXPUNGE events to work */
- g_ptr_array_sort (summary->messages, (GCompareFunc) info_uid_sort);
-#endif
- }
-
- imap4_summary->update_flags = FALSE;
- imap4_summary->uidvalidity_changed = FALSE;
-
- return 0;
-}
diff --git a/camel/providers/imap4/camel-imap4-summary.h b/camel/providers/imap4/camel-imap4-summary.h
deleted file mode 100644
index 0145e4ac52..0000000000
--- a/camel/providers/imap4/camel-imap4-summary.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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_IMAP4_SUMMARY_H__
-#define __CAMEL_IMAP4_SUMMARY_H__
-
-#include <sys/types.h>
-
-#include <camel/camel-folder.h>
-#include <camel/camel-folder-summary.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_SUMMARY (camel_imap4_summary_get_type ())
-#define CAMEL_IMAP4_SUMMARY(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_SUMMARY, CamelIMAP4Summary))
-#define CAMEL_IMAP4_SUMMARY_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP4_SUMMARY, CamelIMAP4SummaryClass))
-#define CAMEL_IS_IMAP4_SUMMARY(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP4_SUMMARY))
-#define CAMEL_IS_IMAP4_SUMMARY_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP4_SUMMARY))
-#define CAMEL_IMAP4_SUMMARY_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_FOLDER_SUMMARY, CamelIMAP4SummaryClass))
-
-typedef struct _CamelIMAP4MessageInfo CamelIMAP4MessageInfo;
-typedef struct _CamelIMAP4Summary CamelIMAP4Summary;
-typedef struct _CamelIMAP4SummaryClass CamelIMAP4SummaryClass;
-
-#define CAMEL_IMAP4_MESSAGE_RECENT (1 << 17)
-
-struct _CamelIMAP4MessageInfo {
- CamelMessageInfoBase info;
-
- guint32 server_flags;
-};
-
-struct _CamelIMAP4Summary {
- CamelFolderSummary parent_object;
-
- guint32 exists;
- guint32 recent;
- guint32 unseen;
-
- guint32 uidvalidity;
-
- guint uidvalidity_changed:1;
- guint update_flags:1;
-};
-
-struct _CamelIMAP4SummaryClass {
- CamelFolderSummaryClass parent_class;
-
-};
-
-
-CamelType camel_imap4_summary_get_type (void);
-
-CamelFolderSummary *camel_imap4_summary_new (CamelFolder *folder);
-
-void camel_imap4_summary_set_exists (CamelFolderSummary *summary, guint32 exists);
-void camel_imap4_summary_set_recent (CamelFolderSummary *summary, guint32 recent);
-void camel_imap4_summary_set_unseen (CamelFolderSummary *summary, guint32 unseen);
-void camel_imap4_summary_set_uidnext (CamelFolderSummary *summary, guint32 uidnext);
-
-void camel_imap4_summary_set_uidvalidity (CamelFolderSummary *summary, guint32 uidvalidity);
-
-void camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid);
-
-int camel_imap4_summary_flush_updates (CamelFolderSummary *summary, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_SUMMARY_H__ */
diff --git a/camel/providers/imap4/camel-imap4-utils.c b/camel/providers/imap4/camel-imap4-utils.c
deleted file mode 100644
index 8a0e92f502..0000000000
--- a/camel/providers/imap4/camel-imap4-utils.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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 <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <camel/camel-store.h>
-#include <camel/camel-i18n.h>
-#include <camel/camel-net-utils.h>
-
-#include "camel-imap4-engine.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-summary.h"
-#include "camel-imap4-store-summary.h"
-
-#include "camel-imap4-utils.h"
-
-#define d(x) x
-
-
-void
-camel_imap4_flags_diff (flags_diff_t *diff, guint32 old, guint32 new)
-{
- diff->changed = old ^ new;
- diff->bits = new & diff->changed;
-}
-
-
-guint32
-camel_imap4_flags_merge (flags_diff_t *diff, guint32 flags)
-{
- return (flags & ~diff->changed) | diff->bits;
-}
-
-
-/**
- * camel_imap4_merge_flags:
- * @original: original server flags
- * @local: local flags (after changes)
- * @server: new server flags (another client updated the server flags)
- *
- * Merge the local flag changes into the new server flags.
- *
- * Returns the merged flags.
- **/
-guint32
-camel_imap4_merge_flags (guint32 original, guint32 local, guint32 server)
-{
- flags_diff_t diff;
-
- camel_imap4_flags_diff (&diff, original, local);
-
- return camel_imap4_flags_merge (&diff, server);
-}
-
-
-void
-camel_imap4_namespace_clear (CamelIMAP4Namespace **ns)
-{
- CamelIMAP4Namespace *node, *next;
-
- node = *ns;
- while (node != NULL) {
- next = node->next;
- g_free (node->path);
- g_free (node);
- node = next;
- }
-
- *ns = NULL;
-}
-
-static CamelIMAP4Namespace *
-imap4_namespace_copy (const CamelIMAP4Namespace *ns)
-{
- CamelIMAP4Namespace *list, *node, *tail;
-
- list = NULL;
- tail = (CamelIMAP4Namespace *) &list;
-
- while (ns != NULL) {
- tail->next = node = g_malloc (sizeof (CamelIMAP4Namespace));
- node->path = g_strdup (ns->path);
- node->sep = ns->sep;
- ns = ns->next;
- tail = node;
- }
-
- tail->next = NULL;
-
- return list;
-}
-
-CamelIMAP4NamespaceList *
-camel_imap4_namespace_list_copy (const CamelIMAP4NamespaceList *nsl)
-{
- CamelIMAP4NamespaceList *new;
-
- new = g_malloc (sizeof (CamelIMAP4NamespaceList));
- new->personal = imap4_namespace_copy (nsl->personal);
- new->other = imap4_namespace_copy (nsl->other);
- new->shared = imap4_namespace_copy (nsl->shared);
-
- return new;
-}
-
-void
-camel_imap4_namespace_list_free (CamelIMAP4NamespaceList *nsl)
-{
- camel_imap4_namespace_clear (&nsl->personal);
- camel_imap4_namespace_clear (&nsl->shared);
- camel_imap4_namespace_clear (&nsl->other);
- g_free (nsl);
-}
-
-
-char
-camel_imap4_get_path_delim (CamelIMAP4StoreSummary *s, const char *full_name)
-{
- CamelIMAP4Namespace *namespace;
- const char *slash;
- size_t len;
- char *top;
-
- g_return_val_if_fail (s->namespaces != NULL, '/');
-
- if ((slash = strchr (full_name, '/')))
- len = (slash - full_name);
- else
- len = strlen (full_name);
-
- top = g_alloca (len + 1);
- memcpy (top, full_name, len);
- top[len] = '\0';
-
- if (!g_ascii_strcasecmp (top, "INBOX"))
- strcpy (top, "INBOX");
-
- retry:
- namespace = s->namespaces->personal;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- namespace = s->namespaces->other;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- namespace = s->namespaces->shared;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- if (top[0] != '\0') {
- /* look for a default namespace? */
- top[0] = '\0';
- goto retry;
- }
-
- return '/';
-}
-
-
-struct _uidset_range {
- struct _uidset_range *next;
- guint32 first, last;
- uint8_t buflen;
- char buf[24];
-};
-
-struct _uidset {
- CamelFolderSummary *summary;
- struct _uidset_range *ranges;
- struct _uidset_range *tail;
- size_t maxlen, setlen;
-};
-
-static void
-uidset_range_free (struct _uidset_range *range)
-{
- struct _uidset_range *next;
-
- while (range != NULL) {
- next = range->next;
- g_free (range);
- range = next;
- }
-}
-
-static void
-uidset_init (struct _uidset *uidset, CamelFolderSummary *summary, size_t maxlen)
-{
- uidset->ranges = g_new (struct _uidset_range, 1);
- uidset->ranges->first = (guint32) -1;
- uidset->ranges->last = (guint32) -1;
- uidset->ranges->next = NULL;
- uidset->ranges->buflen = 0;
-
- uidset->tail = uidset->ranges;
- uidset->summary = summary;
- uidset->maxlen = maxlen;
- uidset->setlen = 0;
-}
-
-/* returns: -1 on full-and-not-added, 0 on added-and-not-full or 1 on added-and-full */
-static int
-uidset_add (struct _uidset *uidset, CamelMessageInfo *info)
-{
- GPtrArray *messages = uidset->summary->messages;
- struct _uidset_range *node, *tail = uidset->tail;
- const char *iuid = camel_message_info_uid (info);
- size_t uidlen, len;
- const char *colon;
- guint32 index;
-
- /* Note: depends on integer overflow for initial 'add' */
- for (index = tail->last + 1; index < messages->len; index++) {
- if (info == messages->pdata[index])
- break;
- }
-
- g_assert (index < messages->len);
-
- uidlen = strlen (iuid);
-
- if (tail->buflen == 0) {
- /* first add */
- tail->first = tail->last = index;
- strcpy (tail->buf, iuid);
- uidset->setlen = uidlen;
- tail->buflen = uidlen;
- } else if (index == (tail->last + 1)) {
- /* add to last range */
- if (tail->last == tail->first) {
- /* make sure we've got enough room to add this one... */
- if ((uidset->setlen + uidlen + 1) > uidset->maxlen)
- return -1;
-
- tail->buf[tail->buflen++] = ':';
- uidset->setlen++;
- } else {
- colon = strchr (tail->buf, ':') + 1;
-
- len = strlen (colon);
- uidset->setlen -= len;
- tail->buflen -= len;
- }
-
- strcpy (tail->buf + tail->buflen, iuid);
- uidset->setlen += uidlen;
- tail->buflen += uidlen;
-
- tail->last = index;
- } else if ((uidset->setlen + uidlen + 1) < uidset->maxlen) {
- /* the beginning of a new range */
- tail->next = node = g_new (struct _uidset_range, 1);
- node->first = node->last = index;
- strcpy (node->buf, iuid);
- uidset->setlen += uidlen + 1;
- node->buflen = uidlen;
- uidset->tail = node;
- node->next = NULL;
- } else {
- /* can't add this one... */
- return -1;
- }
-
- fprintf (stderr, "added uid %s to uidset (summary index = %u)\n", iuid, index);
-
- if (uidset->setlen < uidset->maxlen)
- return 0;
-
- return 1;
-}
-
-static char *
-uidset_to_string (struct _uidset *uidset)
-{
- struct _uidset_range *range;
- GString *string;
- char *str;
-
- string = g_string_new ("");
-
- range = uidset->ranges;
- while (range != NULL) {
- g_string_append (string, range->buf);
- range = range->next;
- if (range)
- g_string_append_c (string, ',');
- }
-
- str = string->str;
- g_string_free (string, FALSE);
-
- return str;
-}
-
-int
-camel_imap4_get_uid_set (CamelIMAP4Engine *engine, CamelFolderSummary *summary, GPtrArray *infos, int cur, size_t linelen, char **set)
-{
- struct _uidset uidset;
- size_t maxlen;
- int rv = 0;
- int i;
-
- if (engine->maxlentype == CAMEL_IMAP4_ENGINE_MAXLEN_LINE)
- maxlen = engine->maxlen - linelen;
- else
- maxlen = engine->maxlen;
-
- uidset_init (&uidset, summary, maxlen);
-
- for (i = cur; i < infos->len && rv != 1; i++) {
- if ((rv = uidset_add (&uidset, infos->pdata[i])) == -1)
- break;
- }
-
- if (i > cur)
- *set = uidset_to_string (&uidset);
-
- uidset_range_free (uidset.ranges);
-
- return (i - cur);
-}
-
-
-void
-camel_imap4_utils_set_unexpected_token_error (CamelException *ex, CamelIMAP4Engine *engine, camel_imap4_token_t *token)
-{
- GString *errmsg;
-
- if (ex == NULL)
- return;
-
- errmsg = g_string_new ("");
- g_string_append_printf (errmsg, _("Unexpected token in response from IMAP server %s: "),
- engine->url->host);
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- g_string_append (errmsg, "NIL");
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- g_string_append (errmsg, token->v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_FLAG:
- g_string_append (errmsg, token->v.flag);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- g_string_append (errmsg, token->v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- g_string_append_printf (errmsg, "{%u}", token->v.literal);
- break;
- case CAMEL_IMAP4_TOKEN_NUMBER:
- g_string_append_printf (errmsg, "%u", token->v.number);
- break;
- case CAMEL_IMAP4_TOKEN_NO_DATA:
- g_string_append (errmsg, _("No data"));
- break;
- default:
- g_string_append_c (errmsg, (unsigned char) (token->token & 0xff));
- break;
- }
-
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, errmsg->str);
-
- g_string_free (errmsg, TRUE);
-}
-
-
-static struct {
- const char *name;
- guint32 flag;
-} imap4_flags[] = {
- { "\\Answered", CAMEL_MESSAGE_ANSWERED },
- { "\\Deleted", CAMEL_MESSAGE_DELETED },
- { "\\Draft", CAMEL_MESSAGE_DRAFT },
- { "\\Flagged", CAMEL_MESSAGE_FLAGGED },
- { "\\Seen", CAMEL_MESSAGE_SEEN },
- { "\\Recent", CAMEL_IMAP4_MESSAGE_RECENT },
- { "\\*", CAMEL_MESSAGE_USER },
-};
-
-#if 0
-static struct {
- const char *name;
- guint32 flag;
-} imap4_user_flags[] = {
- { "$Forwarded", CAMEL_MESSAGE_FORWARDED },
-};
-#endif
-
-
-int
-camel_imap4_parse_flags_list (CamelIMAP4Engine *engine, guint32 *flags, CamelException *ex)
-{
- camel_imap4_token_t token;
- guint32 new = 0;
- int i;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != '(') {
- d(fprintf (stderr, "Expected to find a '(' token starting the flags list\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- while (token.token == CAMEL_IMAP4_TOKEN_ATOM || token.token == CAMEL_IMAP4_TOKEN_FLAG) {
- /* parse the flags list */
- for (i = 0; i < G_N_ELEMENTS (imap4_flags); i++) {
- if (!g_ascii_strcasecmp (imap4_flags[i].name, token.v.atom)) {
- new |= imap4_flags[i].flag;
- break;
- }
- }
-
-#if 0
- if (i == G_N_ELEMENTS (imap4_flags)) {
- for (i = 0; i < G_N_ELEMENTS (imap4_user_flags); i++) {
- if (!g_ascii_strcasecmp (imap4_user_flags[i].name, token.v.atom)) {
- new |= imap4_user_flags[i].flag;
- break;
- }
- }
-
- if (i == G_N_ELEMENTS (imap4_user_flags))
- fprintf (stderr, "Encountered unknown flag: %s\n", token.v.atom);
- }
-#else
- if (i == G_N_ELEMENTS (imap4_flags))
- fprintf (stderr, "Encountered unknown flag: %s\n", token.v.atom);
-#endif
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
- }
-
- if (token.token != ')') {
- d(fprintf (stderr, "Expected to find a ')' token terminating the flags list\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- *flags = new;
-
- return 0;
-}
-
-
-struct {
- const char *name;
- guint32 flag;
-} list_flags[] = {
- { "\\Marked", CAMEL_IMAP4_FOLDER_MARKED },
- { "\\Unmarked", CAMEL_IMAP4_FOLDER_UNMARKED },
- { "\\Noselect", CAMEL_FOLDER_NOSELECT },
- { "\\Noinferiors", CAMEL_FOLDER_NOINFERIORS },
- { "\\HasChildren", CAMEL_FOLDER_CHILDREN },
- { "\\HasNoChildren", CAMEL_FOLDER_NOCHILDREN },
-};
-
-int
-camel_imap4_untagged_list (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
-{
- GPtrArray *array = ic->user_data;
- camel_imap4_list_t *list;
- unsigned char *buf;
- guint32 flags = 0;
- GString *literal;
- char delim;
- size_t n;
- int i;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- /* parse the flag list */
- if (token->token != '(')
- goto unexpected;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- while (token->token == CAMEL_IMAP4_TOKEN_FLAG || token->token == CAMEL_IMAP4_TOKEN_ATOM) {
- for (i = 0; i < G_N_ELEMENTS (list_flags); i++) {
- if (!g_ascii_strcasecmp (list_flags[i].name, token->v.atom)) {
- flags |= list_flags[i].flag;
- break;
- }
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
- }
-
- if (token->token != ')')
- goto unexpected;
-
- /* parse the path delimiter */
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- delim = '\0';
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- delim = *token->v.qstring;
- break;
- default:
- goto unexpected;
- }
-
- /* parse the folder name */
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- list = g_new (camel_imap4_list_t, 1);
- list->flags = flags;
- list->delim = delim;
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_ATOM:
- list->name = g_strdup (token->v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- list->name = g_strdup (token->v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- literal = g_string_new ("");
- while ((i = camel_imap4_stream_literal (engine->istream, &buf, &n)) == 1)
- g_string_append_len (literal, buf, n);
-
- if (i == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
- g_string_free (literal, TRUE);
- return -1;
- }
-
- g_string_append_len (literal, buf, n);
- list->name = literal->str;
- g_string_free (literal, FALSE);
- break;
- default:
- g_free (list);
- goto unexpected;
- }
-
- g_ptr_array_add (array, list);
-
- return camel_imap4_engine_eat_line (engine, ex);
-
- unexpected:
-
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- return -1;
-}
-
-
-static struct {
- const char *name;
- int type;
-} imap4_status[] = {
- { "MESSAGES", CAMEL_IMAP4_STATUS_MESSAGES },
- { "RECENT", CAMEL_IMAP4_STATUS_RECENT },
- { "UIDNEXT", CAMEL_IMAP4_STATUS_UIDNEXT },
- { "UIDVALIDITY", CAMEL_IMAP4_STATUS_UIDVALIDITY },
- { "UNSEEN", CAMEL_IMAP4_STATUS_UNSEEN },
-};
-
-
-void
-camel_imap4_status_free (camel_imap4_status_t *status)
-{
- camel_imap4_status_attr_t *attr, *next;
-
- attr = status->attr_list;
- while (attr != NULL) {
- next = attr->next;
- g_free (attr);
- attr = next;
- }
-
- g_free (status->mailbox);
- g_free (status);
-}
-
-
-int
-camel_imap4_untagged_status (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
-{
- camel_imap4_status_attr_t *attr, *tail, *list = NULL;
- GPtrArray *array = ic->user_data;
- camel_imap4_status_t *status;
- char *mailbox;
- size_t len;
- int type;
- int i;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_ATOM:
- mailbox = g_strdup (token->v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- mailbox = g_strdup (token->v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, (unsigned char **) &mailbox, &len, ex) == -1)
- return -1;
- break;
- default:
- fprintf (stderr, "Unexpected token in IMAP4 untagged STATUS response: %s%c\n",
- token->token == CAMEL_IMAP4_TOKEN_NIL ? "NIL" : "",
- (unsigned char) (token->token & 0xff));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1) {
- g_free (mailbox);
- return -1;
- }
-
- if (token->token != '(') {
- d(fprintf (stderr, "Expected to find a '(' token after the mailbox token in the STATUS response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- g_free (mailbox);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1) {
- g_free (mailbox);
- return -1;
- }
-
- tail = (camel_imap4_status_attr_t *) &list;
-
- while (token->token == CAMEL_IMAP4_TOKEN_ATOM) {
- /* parse the status messages list */
- type = CAMEL_IMAP4_STATUS_UNKNOWN;
- for (i = 0; i < G_N_ELEMENTS (imap4_status); i++) {
- if (!g_ascii_strcasecmp (imap4_status[i].name, token->v.atom)) {
- type = imap4_status[i].type;
- break;
- }
- }
-
- if (type == CAMEL_IMAP4_STATUS_UNKNOWN)
- fprintf (stderr, "unrecognized token in STATUS list: %s\n", token->v.atom);
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NUMBER)
- break;
-
- attr = g_new (camel_imap4_status_attr_t, 1);
- attr->next = NULL;
- attr->type = type;
- attr->value = token->v.number;
-
- tail->next = attr;
- tail = attr;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
- }
-
- status = g_new (camel_imap4_status_t, 1);
- status->mailbox = mailbox;
- status->attr_list = list;
- list = NULL;
-
- g_ptr_array_add (array, status);
-
- if (token->token != ')') {
- d(fprintf (stderr, "Expected to find a ')' token terminating the untagged STATUS response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != '\n') {
- d(fprintf (stderr, "Expected to find a '\\n' token after the STATUS response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- return 0;
-
- exception:
-
- g_free (mailbox);
-
- attr = list;
- while (attr != NULL) {
- list = attr->next;
- g_free (attr);
- attr = list;
- }
-
- return -1;
-}
diff --git a/camel/providers/imap4/camel-imap4-utils.h b/camel/providers/imap4/camel-imap4-utils.h
deleted file mode 100644
index 1bb8b00962..0000000000
--- a/camel/providers/imap4/camel-imap4-utils.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * 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_IMAP4_UTILS_H__
-#define __CAMEL_IMAP4_UTILS_H__
-
-#include <glib.h>
-
-#include <camel/camel-exception.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* IMAP4 flag merging */
-typedef struct {
- guint32 changed;
- guint32 bits;
-} flags_diff_t;
-
-void camel_imap4_flags_diff (flags_diff_t *diff, guint32 old, guint32 new);
-guint32 camel_imap4_flags_merge (flags_diff_t *diff, guint32 flags);
-guint32 camel_imap4_merge_flags (guint32 original, guint32 local, guint32 server);
-
-
-struct _CamelIMAP4Engine;
-struct _CamelIMAP4Command;
-struct _CamelFolderSummary;
-struct _camel_imap4_token_t;
-struct _CamelIMAP4StoreSummary;
-struct _CamelIMAP4NamespaceList;
-struct _CamelIMAP4Namespace;
-
-void camel_imap4_namespace_clear (struct _CamelIMAP4Namespace **ns);
-struct _CamelIMAP4NamespaceList *camel_imap4_namespace_list_copy (const struct _CamelIMAP4NamespaceList *nsl);
-void camel_imap4_namespace_list_free (struct _CamelIMAP4NamespaceList *nsl);
-
-char camel_imap4_get_path_delim (struct _CamelIMAP4StoreSummary *s, const char *full_name);
-
-int camel_imap4_get_uid_set (struct _CamelIMAP4Engine *engine, struct _CamelFolderSummary *summary, GPtrArray *infos, int cur, size_t linelen, char **set);
-
-void camel_imap4_utils_set_unexpected_token_error (CamelException *ex, struct _CamelIMAP4Engine *engine, struct _camel_imap4_token_t *token);
-
-int camel_imap4_parse_flags_list (struct _CamelIMAP4Engine *engine, guint32 *flags, CamelException *ex);
-
-/* Note: make sure these don't clash with any bit flags in camel-store.h */
-#define CAMEL_IMAP4_FOLDER_MARKED (1 << 17)
-#define CAMEL_IMAP4_FOLDER_UNMARKED (1 << 18)
-
-typedef struct {
- guint32 flags;
- char delim;
- char *name;
-} camel_imap4_list_t;
-
-int camel_imap4_untagged_list (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Command *ic,
- guint32 index, struct _camel_imap4_token_t *token, CamelException *ex);
-
-
-enum {
- CAMEL_IMAP4_STATUS_UNKNOWN,
- CAMEL_IMAP4_STATUS_MESSAGES,
- CAMEL_IMAP4_STATUS_RECENT,
- CAMEL_IMAP4_STATUS_UIDNEXT,
- CAMEL_IMAP4_STATUS_UIDVALIDITY,
- CAMEL_IMAP4_STATUS_UNSEEN,
-};
-
-typedef struct _camel_imap4_status_attr {
- struct _camel_imap4_status_attr *next;
- guint32 type;
- guint32 value;
-} camel_imap4_status_attr_t;
-
-typedef struct {
- camel_imap4_status_attr_t *attr_list;
- char *mailbox;
-} camel_imap4_status_t;
-
-void camel_imap4_status_free (camel_imap4_status_t *status);
-
-int camel_imap4_untagged_status (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Command *ic,
- guint32 index, struct _camel_imap4_token_t *token, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_UTILS_H__ */
diff --git a/camel/providers/imap4/libcamelimap4.urls b/camel/providers/imap4/libcamelimap4.urls
deleted file mode 100644
index 7ccb0b0414..0000000000
--- a/camel/providers/imap4/libcamelimap4.urls
+++ /dev/null
@@ -1 +0,0 @@
-imap4
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/ChangeLog b/camel/providers/imapp/ChangeLog
deleted file mode 100644
index 63b46ae57a..0000000000
--- a/camel/providers/imapp/ChangeLog
+++ /dev/null
@@ -1,22 +0,0 @@
-2004-11-11 Not Zed <NotZed@Ximian.com>
-
- * updates for camel folder summary api changes.
-
-2004-09-30 Not Zed <NotZed@Ximian.com>
-
- * camel-imapp-engine.c: make the build again, warnings, doesn't
- work.
-
-2004-09-28 Not Zed <NotZed@Ximian.com>
-
- * camel-imapp-engine.c (camel_imapp_engine_command_free): assume
- the command isn't in a list now.
- (cie_worker): worker thread code.
-
- * camel-imapp-engine.h: make the imappcommand a
- message.
-
-2004-09-28 Not Zed <NotZed@Ximian.com>
-
- * added new changelog.
-
diff --git a/camel/providers/imapp/Makefile.am b/camel/providers/imapp/Makefile.am
deleted file mode 100644
index 8260c58670..0000000000
--- a/camel/providers/imapp/Makefile.am
+++ /dev/null
@@ -1,40 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-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
-
-noinst_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
-
-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 c9a9e45042..0000000000
--- a/camel/providers/imapp/camel-imapp-driver.c
+++ /dev/null
@@ -1,953 +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)
-{
- 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_message_info_free((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_message_info_free((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++) {
- info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, i);
- if (info == NULL)
- continue;
- info->server_flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS;
- camel_message_info_free((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);
- }
-}
-
-#if 0
-static void
-fetch_data_free(CamelIMAPPFetch *fd)
-{
- if (fd->body)
- camel_object_unref(fd->body);
- camel_object_unref(fd->folder);
- g_free(fd->uid);
- g_free(fd->section);
- g_free(fd);
-}
-#endif
-
-struct _CamelStream * camel_imapp_driver_fetch(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder, const char *uid, const char *body)
-{
- return NULL;
-}
-
-#if 0
-void
-camel_imapp_driver_fetch(CamelIMAPPDriver *id, CamelIMAPPFolder *folder, const char *uid, const char *section, CamelIMAPPFetchFunc done, void *data)
-{
- struct _fetch_data *fd;
- CamelIMAPPCommand *ic;
-
- fd = g_malloc0(sizeof(*fd));
- fd->folder = folder;
- camel_object_ref(folder);
- fd->uid = g_strdup(uid);
- fd->section = g_strdup(fd->section);
- fd->done = done;
- fd->data = data;
-
- 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;
-}
-#endif
-
-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_message_info_free(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;
- CamelIMAPPMessageInfo *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 = (CamelIMAPPMessageInfo *)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 = (CamelIMAPPMessageInfo *)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_message_info_free(uinfo);
- }
- /* pad out the summary till we have enough indexes */
- for (i=camel_folder_summary_count(summary);i<id;i++) {
- info = camel_message_info_new(summary);
- if (i == id-1) {
- printf("inserting new info @ %u\n", i);
- info->info.uid = g_strdup(finfo->uid);
- } else {
- char uidtmp[32];
-
- sprintf(uidtmp, "blank-%u", i);
- info->info.uid = g_strdup(uidtmp);
- printf("inserting empty uid %s\n", uidtmp);
- }
-
- camel_folder_summary_add(summary, (CamelMessageInfo *)info);
- }
- info = (CamelIMAPPMessageInfo *)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, (CamelMessageInfo *)info);
- camel_message_info_free(info);
- info = (CamelIMAPPMessageInfo *)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? */
- info->info.subject = g_strdup(camel_message_info_subject(finfo->minfo));
- info->info.from = g_strdup(camel_message_info_from(finfo->minfo));
- info->info.to = g_strdup(camel_message_info_to(finfo->minfo));
- info->info.cc = g_strdup(camel_message_info_cc(finfo->minfo));
- info->info.date_sent = camel_message_info_date_sent(finfo->minfo);
- 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->info.flags & CAMEL_IMAPP_SERVER_FLAGS) != (camel_message_info_flags(finfo) & CAMEL_IMAPP_SERVER_FLAGS)) {
- camel_folder_change_info_change_uid(sdata->folder->changes, camel_message_info_uid(info));
- info->info.flags = (info->info.flags & ~(CAMEL_IMAPP_SERVER_FLAGS)) | (camel_message_info_flags(finfo) & 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)) {
- CamelIMAPPFetch *fd, *fn;
-
- fd = (CamelIMAPPFetch *)sdata->body_fetch.head;
- fn = fd->next;
- while (fn) {
- if (!strcmp(finfo->uid, fd->uid) && !strcmp(finfo->section, fd->section)) {
- fd->done(sdata, fd);
- e_dlist_remove((EDListNode *)fd);
- e_dlist_addtail(&sdata->body_fetch_done, (EDListNode *)fd);
- break;
- }
- fd = fn;
- fn = fn->next;
- }
- }
-
- camel_message_info_free(info);
- } else {
- printf("dont know what to do with message\n");
- }
- done:
- imap_free_fetch(finfo);
-
- return camel_imapp_engine_skip(ie);
-}
-
-
-/* This code is for the separate thread per server idea */
-
-typedef enum {
- CAMEL_IMAPP_MSG_FETCH,
- CAMEL_IMAPP_MSG_LIST,
- CAMEL_IMAPP_MSG_QUIT,
- CAMEL_IMAPP_MSG_SEARCH,
- CAMEL_IMAPP_MSG_SYNC,
- CAMEL_IMAPP_MSG_UPDATE,
-} camel_imapp_msg_t;
-
-typedef struct _CamelIMAPPMsg CamelIMAPPMsg;
-
-struct _CamelIMAPPMsg {
- EMsg msg;
- CamelOperation *cancel;
- CamelException *ex;
- camel_imapp_msg_t type;
- union {
- struct {
- struct _CamelIMAPPFolder *folder;
- char *uid;
- char *section;
- struct _CamelStream *body;
- struct _CamelIMAPPCommand *ic;
- } fetch;
- struct {
- char *name;
- guint32 flags;
- GPtrArray *result;
- GSList *ics;
- } list;
- struct {
- guint32 flags;
- } quit;
- struct {
- struct _CamelIMAPPFolder *folder;
- char *search;
- GPtrArray *results;
- } search;
- struct {
- struct _CamelIMAPPFolder *folder;
- guint32 flags;
- } sync;
- struct {
- struct _CamelIMAPPFolder *folder;
- } update;
- } data;
-};
-
-CamelIMAPPMsg *camel_imapp_msg_new(camel_imapp_msg_t type, struct _CamelException *ex, struct _CamelOperation *cancel, ...);
-void camel_imapp_msg_free(CamelIMAPPMsg *m);
-void camel_imapp_driver_worker(CamelIMAPPDriver *id);
-
-CamelIMAPPMsg *
-camel_imapp_msg_new(camel_imapp_msg_t type, struct _CamelException *ex, struct _CamelOperation *cancel, ...)
-{
- CamelIMAPPMsg *m;
- va_list ap;
-
- m = g_malloc0(sizeof(*m));
- m->type = type;
- m->cancel = cancel;
- camel_operation_ref(cancel);
- m->ex = ex;
-
- va_start(ap, cancel);
- switch (type) {
- case CAMEL_IMAPP_MSG_FETCH:
- m->data.fetch.folder = va_arg(ap, struct _CamelIMAPPFolder *);
- camel_object_ref(m->data.fetch.folder);
- m->data.fetch.uid = g_strdup(va_arg(ap, char *));
- m->data.fetch.section = g_strdup(va_arg(ap, char *));
- break;
- case CAMEL_IMAPP_MSG_LIST:
- m->data.list.name = g_strdup(va_arg(ap, char *));
- m->data.list.flags = va_arg(ap, guint32);
- break;
- case CAMEL_IMAPP_MSG_QUIT:
- m->data.quit.flags = va_arg(ap, guint32);
- break;
- case CAMEL_IMAPP_MSG_SEARCH:
- m->data.search.folder = va_arg(ap, struct _CamelIMAPPFolder *);
- camel_object_ref(m->data.search.folder);
- m->data.search.search = g_strdup(va_arg(ap, char *));
- break;
- case CAMEL_IMAPP_MSG_SYNC:
- m->data.sync.folder = va_arg(ap, struct _CamelIMAPPFolder *);
- camel_object_ref(m->data.sync.folder);
- m->data.sync.flags = va_arg(ap, guint32);
- break;
- case CAMEL_IMAPP_MSG_UPDATE:
- m->data.update.folder = va_arg(ap, struct _CamelIMAPPFolder *);
- camel_object_ref(m->data.update.folder);
- break;
- }
- va_end(ap);
-
- return m;
-}
-
-void
-camel_imapp_msg_free(CamelIMAPPMsg *m)
-{
- switch (m->type) {
- case CAMEL_IMAPP_MSG_FETCH:
- camel_object_unref(m->data.fetch.folder);
- g_free(m->data.fetch.uid);
- g_free(m->data.fetch.section);
-
- if (m->data.fetch.body)
- camel_object_unref(m->data.fetch.body);
- break;
- case CAMEL_IMAPP_MSG_LIST:
- g_free(m->data.list.name);
- if (m->data.list.result)
- /* FIXME: free list data ... */
- g_ptr_array_free(m->data.list.result, TRUE);
- break;
- case CAMEL_IMAPP_MSG_QUIT:
- break;
- case CAMEL_IMAPP_MSG_SEARCH:
- camel_object_unref(m->data.search.folder);
- g_free(m->data.search.search);
- if (m->data.search.results)
- /* FIXME: free search data */
- g_ptr_array_free(m->data.search.results, TRUE);
- break;
- case CAMEL_IMAPP_MSG_SYNC:
- camel_object_unref(m->data.sync.folder);
- break;
- case CAMEL_IMAPP_MSG_UPDATE:
- camel_object_unref(m->data.update.folder);
- break;
- }
-
- camel_operation_unref(m->cancel);
- g_free(m);
-}
-
-void
-camel_imapp_driver_worker(CamelIMAPPDriver *id)
-{
- CamelIMAPPMsg *m;
- int go = TRUE;
-
- do {
- /*m = (CamelIMAPPMsg *)e_msgport_get(id->queue);*/
- switch (m->type) {
- case CAMEL_IMAPP_MSG_FETCH:
- /*e_dlist_addtail(&id->fetch_queue, (EDListNode *)m);*/
- camel_imapp_driver_select(id, m->data.fetch.folder);
- break;
- case CAMEL_IMAPP_MSG_LIST:
- m->data.list.result = camel_imapp_driver_list(id, m->data.list.name, m->data.list.flags);
- break;
- case CAMEL_IMAPP_MSG_QUIT:
- camel_imapp_msg_free(m);
- go = FALSE;
- break;
- case CAMEL_IMAPP_MSG_SEARCH:
- break;
- case CAMEL_IMAPP_MSG_SYNC:
- break;
- case CAMEL_IMAPP_MSG_UPDATE:
- break;
- }
- } while (go);
-}
-
diff --git a/camel/providers/imapp/camel-imapp-driver.h b/camel/providers/imapp/camel-imapp-driver.h
deleted file mode 100644
index 2ecdfe634b..0000000000
--- a/camel/providers/imapp/camel-imapp-driver.h
+++ /dev/null
@@ -1,100 +0,0 @@
-
-#ifndef _CAMEL_IMAPP_DRIVER_H
-#define _CAMEL_IMAPP_DRIVER_H
-
-#include <camel/camel-object.h>
-#include "camel-imapp-stream.h"
-#include <libedataserver/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 struct _CamelIMAPPFetch CamelIMAPPFetch;
-
-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);
-
-typedef void (*CamelIMAPPFetchFunc)(struct _CamelIMAPPDriver *driver, CamelIMAPPFetch *);
-
-struct _CamelIMAPPFetch {
- struct _CamelIMAPPFetch *next;
- struct _CamelIMAPPFetch *prev;
-
- CamelStream *body; /* the content fetched */
-
- struct _CamelIMAPPFolder *folder;
- char *uid;
- char *section;
-
- CamelIMAPPFetchFunc done;
- 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 1eaa4b8025..0000000000
--- a/camel/providers/imapp/camel-imapp-engine.c
+++ /dev/null
@@ -1,1154 +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->done);
-
- ie->port = e_msgport_new();
-
- 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 */
-static 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 */
-static 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;
-
- /* Note the command must not be in any queue? */
-
- if (ic->mem)
- camel_object_unref((CamelObject *)ic->mem);
- imap_free_status(ic->status);
- g_free(ic->select);
-
- while ( (cp = ((CamelIMAPPCommandPart *)e_dlist_remhead(&ic->parts))) ) {
- g_free(cp->data);
- if (cp->ob)
- camel_object_unref(cp->ob);
- g_free(cp);
- }
-
- g_free(ic);
-}
-
-/* FIXME: error handling */
-void
-camel_imapp_engine_command_queue(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic)
-{
- CamelIMAPPCommandPart *cp;
-
- g_assert(ic->msg.reply_port);
-
- if (ic->mem)
- imap_engine_command_complete(imap, ic);
-
- e_msgport_put(imap->port, (EMsg *)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->msg.ln.next;
- while (in) {
- if (strcmp(ic->name, name) == 0)
- return ic;
- ic = in;
- in = in->msg.ln.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->msg.ln.next;
- while (in) {
- if (ic->tag == tag)
- return ic;
- ic = in;
- in = in->msg.ln.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);
-}
-
-#if c(!)0
-static int len(EDList *list)
-{
- int count = 0;
- EDListNode *n = list->head;
-
- while (n->next) {
- n = n->next;
- count++;
- }
- return count;
-}
-#endif
-
-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);
-}
-
-
-static void *
-cie_worker(void *data)
-{
- CamelIMAPPCommand *ic = data;
- CamelIMAPPEngine *imap;
- CamelIMAPPCommandPart *cp;
-
- /* 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);
- }
-}
-
-
-/* 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 2cc19cd21f..0000000000
--- a/camel/providers/imapp/camel-imapp-engine.h
+++ /dev/null
@@ -1,156 +0,0 @@
-
-#ifndef _CAMEL_IMAPP_ENGINE_H
-#define _CAMEL_IMAPP_ENGINE_H
-
-#include <camel/camel-object.h>
-
-#include "camel-imapp-stream.h"
-#include <libedataserver/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);
-
-struct _CamelIMAPPCommand {
- EMsg msg;
-
- 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;
-
- /* incoming requests */
- EMsgPort *port;
-
- 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 a838e7c6e4..0000000000
--- a/camel/providers/imapp/camel-imapp-folder.c
+++ /dev/null
@@ -1,271 +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 <libedataserver/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;
-}
-
-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;
-}
-
-#if 0
-/* experimental interfaces */
-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)
-{
-}
-#endif
-
-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 21ec24cb77..0000000000
--- a/camel/providers/imapp/camel-imapp-provider.c
+++ /dev/null
@@ -1,100 +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/camel-i18n.h"
-
-#include "camel-imapp-store.h"
-
-CamelProviderConfEntry imapp_conf_entries[] = {
- { CAMEL_PROVIDER_CONF_SECTION_START, "storage", 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(void);
-
-void
-camel_imapp_module_init(void)
-{
- 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_provider_register(&imapp_provider);
-}
-
-void
-camel_provider_module_init(void)
-{
- camel_imapp_module_init();
-}
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 0c8d617d1a..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 "libedataserver/md5-utils.h"
-#include "libedataserver/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 03f835da7a..0000000000
--- a/camel/providers/imapp/camel-imapp-store.c
+++ /dev/null
@@ -1,1018 +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/camel-i18n.h"
-
-#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"
-#include "camel-net-utils.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 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);
-
-/* 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->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;
- int ret;
- CamelException *ex;
-
- ex = camel_exception_new();
- CAMEL_TRY {
- char *serv;
- const char *port = NULL;
- struct addrinfo *ai, hints = { 0 };
-
- /* parent class connect initialization */
- CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex);
- if (ex->id)
- camel_exception_throw_ex(ex);
-
- if (service->url->port) {
- serv = g_alloca(16);
- sprintf(serv, "%d", service->url->port);
- } else {
- serv = "imap";
- port = "143";
- }
-
-#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 {
- if (service->url->port == 0) {
- serv = "imaps";
- port = "993";
- }
- 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 */
-
- hints.ai_socktype = SOCK_STREAM;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ex->id && ex->id != CAMEL_EXCEPTION_USER_CANCEL && port != NULL) {
- camel_exception_clear(ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
-
- if (ex->id)
- camel_exception_throw_ex(ex);
-
- ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
- camel_freeaddrinfo(ai);
- 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 %s): %s"),
- service->url->host, serv, 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),
- (CamelService *)store, NULL,
- prompt, "password", CAMEL_SESSION_PASSWORD_SECRET, &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, NULL, "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 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->uri = camel_url_to_string(base, CAMEL_URL_HIDE_ALL);
- fi->name = g_strdup(name);
- fi->full_name = full_name;
- fi->unread = -1;
- fi->total = -1;
- fi->flags = li->flags;
-
- if (!g_ascii_strcasecmp(fi->full_name, "inbox"))
- fi->flags |= CAMEL_FOLDER_SYSTEM;
-
- /* 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->next = 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->uri);
- if (fi->child)
- folder_info_dump(fi->child, depth+2);
- fi = fi->next;
- }
-
-}
-
-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_message_info_free(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_message_info_free(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_message_info_free(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_message_info_free(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_message_info_free(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 c26be59baf..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 "libedataserver/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;
-
- struct _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 1b5a2c7155..0000000000
--- a/camel/providers/imapp/camel-imapp-summary.c
+++ /dev/null
@@ -1,184 +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 (1)
-
-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;
-
- /* Legacy version */
- if (s->version == 0x100c)
- return camel_file_util_decode_uint32(in, &ims->uidvalidity);
-
- if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1
- || camel_file_util_decode_fixed_int32(in, &ims->uidvalidity) == -1)
- return -1;
-
- if (ims->version > CAMEL_IMAPP_SUMMARY_VERSION) {
- g_warning("Unkown summary version\n");
- errno = EINVAL;
- return -1;
- }
-
- return 0;
-}
-
-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;
-
- if (camel_file_util_encode_fixed_int32(out, CAMEL_IMAPP_SUMMARY_VERSION) == -1
- || camel_file_util_encode_fixed_int32(out, ims->uidvalidity) == -1)
- return -1;
-
- return 0;
-}
-
-
-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_message_info_free(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 1189bac075..0000000000
--- a/camel/providers/imapp/camel-imapp-summary.h
+++ /dev/null
@@ -1,66 +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 {
- CamelMessageInfoBase info;
-
- guint32 server_flags;
-} CamelIMAPPMessageInfo;
-
-struct _CamelIMAPPSummary {
- CamelFolderSummary parent;
-
- guint32 version;
- 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 1460157848..0000000000
--- a/camel/providers/imapp/camel-imapp-utils.c
+++ /dev/null
@@ -1,1342 +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/camel-string-utils.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 "libedataserver/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 = CAMEL_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 = CAMEL_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 _CamelMessageInfoBase *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 = (CamelMessageInfoBase *)camel_message_info_new(NULL);
-
- 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);
- minfo->subject = camel_pstring_strdup(token);
-
- /* 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);
- minfo->from = camel_pstring_strdup(addrstr);
- g_free(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);
- minfo->to = camel_pstring_strdup(addrstr);
- g_free(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);
- minfo->cc = camel_pstring_strdup(addrstr);
- g_free(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 (CamelMessageInfo *)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?? */
- ((CamelMessageInfoBase *)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 2734cd0dc3..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 */
- struct _CamelMessageInfo *minfo; /* ENVELOPE */
- struct _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 fbf3199a8b..0000000000
--- a/camel/providers/local/Makefile.am
+++ /dev/null
@@ -1,54 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-camel_provider_LTLIBRARIES = libcamellocal.la
-camel_provider_DATA = libcamellocal.urls
-
-INCLUDES = \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir) \
- $(CAMEL_CFLAGS) \
- -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
-
-noinst_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 \
- camel-local-private.h
-
-libcamellocal_la_LDFLAGS = -avoid-version -module
-
-libcamellocal_la_LIBADD = \
- $(top_builddir)/libedataserver/libedataserver-${BASE_VERSION}.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 70673d9687..0000000000
--- a/camel/providers/local/camel-local-folder.c
+++ /dev/null
@@ -1,631 +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-i18n.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(CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name);
-static char *local_get_meta_path(CamelLocalFolder *lf, 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;
- CamelURL *url;
-
- 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(lf, root_dir_path, full_name);
- lf->summary_path = CLOCALF_CLASS(lf)->get_meta_path(lf, root_dir_path, full_name, ".ev-summary");
- lf->index_path = CLOCALF_CLASS(lf)->get_meta_path(lf, root_dir_path, full_name, ".ibex");
- statepath = CLOCALF_CLASS(lf)->get_meta_path(lf, 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) {
- /* No metadata - load defaults and persitify */
- camel_object_set(lf, NULL, CAMEL_LOCAL_FOLDER_INDEX_BODY, TRUE, 0);
- camel_object_state_write(lf);
- }
-
- /* 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 we have no/invalid index file, force it */
- forceindex = camel_text_index_check(lf->index_path) == -1;
- if (lf->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 */
- lf->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;
- }
-
- folder->summary = (CamelFolderSummary *)CLOCALF_CLASS(lf)->create_summary(lf, lf->summary_path, lf->folder_path, lf->index);
- if (camel_local_summary_load((CamelLocalSummary *)folder->summary, forceindex, NULL) == -1) {
- /* ? */
- }
-
- /*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;
- }
-
- /* TODO: This probably shouldn't be here? */
- if ((flags & CAMEL_STORE_FOLDER_CREATE) != 0) {
- url = camel_url_copy (((CamelService *) parent_store)->url);
- camel_url_set_fragment (url, full_name);
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = g_strdup (full_name);
- fi->name = g_strdup (name);
- fi->uri = camel_url_to_string (url, 0);
- fi->unread = camel_folder_get_unread_message_count(folder);
- fi->flags = CAMEL_FOLDER_NOCHILDREN;
-
- camel_url_free (url);
-
- 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:
- /* 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(CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name)
-{
- return g_strdup_printf("%s/%s", toplevel_dir, full_name);
-}
-
-static char *
-local_get_meta_path(CamelLocalFolder *lf, 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 '%s' , expunge=%s\n", folder->full_name, 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;
- char *statepath;
-
- 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 = CLOCALF_CLASS(lf)->get_full_path(lf, lf->base_path, newname);
- lf->summary_path = CLOCALF_CLASS(lf)->get_meta_path(lf, lf->base_path, newname, ".ev-summary");
- lf->index_path = CLOCALF_CLASS(lf)->get_meta_path(lf, lf->base_path, newname, ".ibex");
- statepath = CLOCALF_CLASS(lf)->get_meta_path(lf, lf->base_path, newname, ".cmeta");
- camel_object_set(lf, NULL, CAMEL_OBJECT_STATE_FILE, statepath, NULL);
- g_free(statepath);
-
- /* 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 *matches;
-
- 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);
- matches = camel_folder_search_search(local_folder->search, expression, NULL, ex);
-
- CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock);
-
- 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 *matches;
-
- if (uids->len == 0)
- return g_ptr_array_new();
-
- 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);
- matches = camel_folder_search_search(local_folder->search, expression, uids, ex);
-
- CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock);
-
- 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 4aec420813..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)(CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name);
- char * (* get_meta_path)(CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name, const char *ext);
-
- /* summary factory, only used at init */
- CamelLocalSummary *(*create_summary)(CamelLocalFolder *lf, 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 7411d8f639..0000000000
--- a/camel/providers/local/camel-local-provider.c
+++ /dev/null
@@ -1,234 +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"
-#include "camel-i18n.h"
-
-#define d(x)
-
-static CamelProviderConfEntry mh_conf_entries[] = {
- CAMEL_PROVIDER_CONF_DEFAULT_PATH,
- { CAMEL_PROVIDER_CONF_SECTION_START, "general", NULL, N_("Options") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "dotfolders", NULL,
- N_("Use the `.folders' folder summary file (exmh)"), "0" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { 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_SECTION_START, "general", NULL, N_("Options") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL,
- N_("Apply filters to new messages in INBOX"), "0" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { 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_SECTION_START, "general", NULL, N_("Options") },
- { 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_SECTION_END },
- { 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(void)
-{
- char *path;
- static int init = 0;
-
- if (init)
- abort();
- init = 1;
-
- 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_provider_register(&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_provider_register(&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_provider_register(&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_provider_register(&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 a89fee16c5..0000000000
--- a/camel/providers/local/camel-local-store.c
+++ /dev/null
@@ -1,477 +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-i18n.h"
-
-#include "camel-local-folder.h"
-#include <camel/camel-text-index.h>
-#include <camel/camel-file-utils.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 *local_get_inbox (CamelStore *store, CamelException *ex);
-static CamelFolder *local_get_junk(CamelStore *store, CamelException *ex);
-static CamelFolder *local_get_trash(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 = local_get_inbox;
- camel_store_class->get_trash = local_get_trash;
- camel_store_class->get_junk = local_get_junk;
- 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)
-{
- char *path = ((CamelLocalStore *)store)->toplevel_dir;
- struct stat st;
-
- 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 */
- if (camel_mkdir (path, 0777) == -1 && errno != EEXIST) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Cannot get folder: %s: %s"),
- path, g_strerror (errno));
- return NULL;
- }
-
- return (CamelFolder *) 0xdeadbeef;
-}
-
-static CamelFolder *
-local_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 CamelFolder *
-local_get_trash(CamelStore *store, CamelException *ex)
-{
- CamelFolder *folder = CAMEL_STORE_CLASS(parent_class)->get_trash(store, ex);
-
- if (folder) {
- char *state = g_build_filename(((CamelLocalStore *)store)->toplevel_dir, ".Trash.cmeta", NULL);
-
- camel_object_set(folder, NULL, CAMEL_OBJECT_STATE_FILE, state, NULL);
- g_free(state);
- /* no defaults? */
- camel_object_state_read(folder);
- }
-
- return folder;
-}
-
-static CamelFolder *
-local_get_junk(CamelStore *store, CamelException *ex)
-{
- CamelFolder *folder = CAMEL_STORE_CLASS(parent_class)->get_junk(store, ex);
-
- if (folder) {
- char *state = g_build_filename(((CamelLocalStore *)store)->toplevel_dir, ".Junk.cmeta", NULL);
-
- camel_object_set(folder, NULL, CAMEL_OBJECT_STATE_FILE, state, NULL);
- g_free(state);
- /* no defaults? */
- camel_object_state_read(folder);
- }
-
- return folder;
-}
-
-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, ".cmeta", TRUE, ex))
- goto cmeta_failed;
-
- if (xrename(old, new, path, "", FALSE, ex))
- goto base_failed;
-
- g_free(newibex);
- g_free(oldibex);
-
- if (folder)
- camel_object_unref(folder);
-
- return;
-
- /* The (f)utility of this recovery effort is quesitonable */
-
-base_failed:
- xrename(new, old, path, ".cmeta", TRUE, ex);
-
-cmeta_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);
-
- str = NULL;
- 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->uri = g_strdup_printf ("%s:%s#%s", ((CamelService *) store)->url->protocol,
- CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
- fi->unread = -1;
-
- 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 0a4f96b552..0000000000
--- a/camel/providers/local/camel-local-summary.c
+++ /dev/null
@@ -1,652 +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"
-#include "camel/camel-file-utils.h"
-#include "camel/camel-i18n.h"
-
-#define w(x)
-#define io(x)
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-#define CAMEL_LOCAL_SUMMARY_VERSION (1)
-
-static int summary_header_load (CamelFolderSummary *, FILE *);
-static int summary_header_save (CamelFolderSummary *, FILE *);
-
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
-
-static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi);
-static char *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *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->summary_header_load = summary_header_load;
- sklass->summary_header_save = summary_header_save;
-
- sklass->message_info_new_from_header = message_info_new_from_header;
-
- 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(CamelLocalMessageInfo);
- 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 CamelLocalMessageInfo *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, CamelLocalMessageInfo *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_message_info_free(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)
-{
- CamelLocalMessageInfo *mi;
- char *xev;
-
- d(printf("Adding message to summary\n"));
-
- mi = (CamelLocalMessageInfo *)camel_folder_summary_add_from_message((CamelFolderSummary *)cls, msg);
- if (mi) {
- d(printf("Added, uid = %s\n", mi->uid));
- if (info) {
- const CamelTag *tag = camel_message_info_user_tags(info);
- const CamelFlag *flag = camel_message_info_user_flags(info);
-
- while (flag) {
- camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE);
- flag = flag->next;
- }
-
- while (tag) {
- camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value);
- tag = tag->next;
- }
-
- mi->info.flags |= (camel_message_info_flags(info) & 0xffff);
- mi->info.size = camel_message_info_size(info);
- }
-
- /* we need to calculate the size ourselves */
- if (mi->info.size == 0) {
- CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new();
-
- camel_data_wrapper_write_to_stream((CamelDataWrapper *)msg, (CamelStream *)sn);
- mi->info.size = sn->written;
- camel_object_unref((CamelObject *)sn);
- }
-
- mi->info.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 (CamelMessageInfo *)mi;
-}
-
-static char *
-local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi)
-{
- GString *out = g_string_new("");
- struct _camel_header_param *params = NULL;
- GString *val = g_string_new("");
- CamelFlag *flag = mi->info.user_flags;
- CamelTag *tag = mi->info.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->info.flags & 0xffff);
- } else {
- g_string_printf (out, "%s-%04x", uidstr, mi->info.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, CamelLocalMessageInfo *mi)
-{
- struct _camel_header_param *params, *scan;
- guint32 uid, flags;
- char *header;
- int i;
- char uidstr[20];
-
- uidstr[0] = 0;
-
- /* check for uid/flags */
- header = camel_header_token_decode(xev);
- if (header && strlen(header) == strlen("00000000-0000")
- && sscanf(header, "%08x-%04x", &uid, &flags) == 2) {
- if (mi)
- sprintf(uidstr, "%u", uid);
- } 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_message_info_set_user_flag((CamelMessageInfo *)mi, 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_message_info_set_user_tag((CamelMessageInfo *)mi, tagv[i], val);
- val[-1]='=';
- }
- }
- g_strfreev(tagv);
- }
- scan = scan->next;
- }
- camel_header_param_list_free(params);
- }
-
- mi->info.uid = g_strdup(uidstr);
- mi->info.flags = flags;
-
- return 0;
-}
-
-static int
-summary_header_load(CamelFolderSummary *s, FILE *in)
-{
- CamelLocalSummary *cls = (CamelLocalSummary *)s;
-
- /* We dont actually add our own headers, but version that we don't anyway */
-
- if (((CamelFolderSummaryClass *)camel_local_summary_parent)->summary_header_load(s, in) == -1)
- return -1;
-
- /* Legacy version, version is in summary only */
- if ((s->version & 0xfff) == 0x20c)
- return 0;
-
- /* otherwise load the version number */
- return camel_file_util_decode_fixed_int32(in, &cls->version);
-}
-
-static int
-summary_header_save(CamelFolderSummary *s, FILE *out)
-{
- /*CamelLocalSummary *cls = (CamelLocalSummary *)s;*/
-
- if (((CamelFolderSummaryClass *)camel_local_summary_parent)->summary_header_save(s, out) == -1)
- return -1;
-
- return camel_file_util_encode_fixed_int32(out, CAMEL_LOCAL_SUMMARY_VERSION);
-}
-
-static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
-{
- CamelLocalMessageInfo *mi;
- CamelLocalSummary *cls = (CamelLocalSummary *)s;
-
- mi = (CamelLocalMessageInfo *)((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new_from_header(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->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
- mi->info.uid = 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 (CamelMessageInfo *)mi;
-}
diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h
deleted file mode 100644
index cc7dc3eb2d..0000000000
--- a/camel/providers/local/camel-local-summary.h
+++ /dev/null
@@ -1,96 +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? */
-};
-
-typedef struct _CamelLocalMessageInfo CamelLocalMessageInfo;
-
-struct _CamelLocalMessageInfo {
- CamelMessageInfoBase info;
-};
-
-struct _CamelLocalSummary {
- CamelFolderSummary parent;
-
- guint32 version; /* file version being loaded */
-
- 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 CamelLocalMessageInfo *info);
- int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *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 CamelLocalMessageInfo *info);
-int camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *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 b74f6e5ace..0000000000
--- a/camel/providers/local/camel-maildir-folder.c
+++ /dev/null
@@ -1,279 +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"
-#include "camel-i18n.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(CamelLocalFolder *lf, 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 int
-maildir_folder_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_FOLDER_ARG_NAME:
- if (!strcmp(folder->full_name, "."))
- *arg->ca_str = _("Inbox");
- else
- *arg->ca_str = folder->name;
- break;
- default:
- continue;
- }
-
- arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
- }
-
- return ((CamelObjectClass *)parent_class)->getv(object, ex, args);
-}
-
-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 */
- ((CamelObjectClass *)camel_folder_class)->getv = maildir_folder_getv;
-
- 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(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
-{
- return (CamelLocalSummary *)camel_maildir_summary_new((CamelFolder *)lf, 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 from folder %s\n %s"),
- uid, lf->folder_path, _("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_message_info_free(info);
-
- if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get message: %s from folder %s\n %s"),
- uid, lf->folder_path, 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_SYSTEM,
- _("Cannot get message: %s from folder %s\n %s"),
- uid, lf->folder_path, _("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 eac22d23c6..0000000000
--- a/camel/providers/local/camel-maildir-store.c
+++ /dev/null
@@ -1,449 +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"
-#include "camel-maildir-summary.h"
-#include "camel-i18n.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 void maildir_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_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->rename_folder = maildir_rename_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,
- _("Cannot get folder `%s': %s"),
- folder_name, g_strerror (errno));
- } else if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Cannot get folder `%s': folder 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,
- _("Cannot create folder `%s': %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_SYSTEM,
- _("Cannot get folder `%s': not a maildir directory."), name);
- } else if (flags & CAMEL_STORE_FOLDER_EXCL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder `%s': folder exists."),
- folder_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 void
-maildir_rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex)
-{
- if (strcmp(old, ".") == 0) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- _("Cannot rename folder: %s: Invalid operation"), _("Inbox"));
- return;
- }
-
- ((CamelStoreClass *)parent_class)->rename_folder(store, old, new, ex);
-}
-
-static CamelFolderInfo *camel_folder_info_new(CamelURL *url, const char *full, const char *name)
-{
- CamelFolderInfo *fi;
-
- fi = g_malloc0(sizeof(*fi));
- fi->uri = camel_url_to_string(url, 0);
- fi->full_name = g_strdup(full);
- if (!strcmp(full, ".")) {
- fi->flags |= CAMEL_FOLDER_SYSTEM;
- fi->name = g_strdup(_("Inbox"));
- } else
- fi->name = g_strdup(name);
- fi->unread = -1;
- fi->total = -1;
-
- d(printf("Adding maildir info: '%s' '%s' '%s' '%s'\n", fi->path, fi->name, fi->full_name, fi->url));
-
- return fi;
-}
-
-static void
-fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
-{
- CamelFolder *folder;
-
- folder = camel_object_bag_get(store->folders, fi->full_name);
-
- if (folder == NULL
- && (flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- folder = camel_store_get_folder(store, fi->full_name, 0, NULL);
-
- if (folder) {
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- camel_folder_refresh_info(folder, NULL);
- fi->unread = camel_folder_get_unread_message_count(folder);
- fi->total = camel_folder_get_message_count(folder);
- camel_object_unref(folder);
- } else {
- char *path, *folderpath;
- CamelFolderSummary *s;
- const char *root;
-
- /* This should be fast enough not to have to test for INFO_FAST */
- root = camel_local_store_get_toplevel_dir((CamelLocalStore *)store);
- path = g_strdup_printf("%s/%s.ev-summary", root, fi->full_name);
- folderpath = g_strdup_printf("%s/%s", root, fi->full_name);
- s = (CamelFolderSummary *)camel_maildir_summary_new(NULL, path, folderpath, NULL);
- if (camel_folder_summary_header_load(s) != -1) {
- fi->unread = s->unread_count;
- fi->total = s->saved_count;
- }
- camel_object_unref(s);
- g_free(folderpath);
- g_free(path);
- }
-}
-
-/* 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, CamelURL *url, const char *path, guint32 flags, CamelFolderInfo *parent, CamelFolderInfo **fip, CamelException *ex)
-{
- DIR *dir;
- struct dirent *d;
- char *name, *tmp, *cur, *new;
- const char *base, *root = ((CamelService *)store)->url->path;
- CamelFolderInfo *fi = NULL;
- struct stat st;
-
- /* 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);
-
- base = strrchr(path, '/');
- if (base)
- base++;
- else
- base = path;
-
- camel_url_set_fragment(url, path);
-
- fi = camel_folder_info_new(url, path, base);
- fill_fi(store, fi, flags);
-
- 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)))
- fi->flags |= CAMEL_FOLDER_NOSELECT;
-
- d(printf("found! uri = %s\n", fi->uri));
- d(printf(" full_name = %s\n name = '%s'\n", fi->full_name, fi->name));
-
- fi->parent = parent;
- fi->next = *fip;
- *fip = fi;
-
- g_free(tmp);
- g_free(cur);
- g_free(new);
-
- /* always look further if asked */
- if (((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || parent == NULL)) {
- int children = 0;
-
- 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));
-
- children++;
-
- *inew = in;
- g_hash_table_insert(visited, inew, inew);
- new = g_strdup_printf("%s/%s", path, d->d_name);
- if (scan_dir(store, visited, url, 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);
-
- if (children)
- fi->flags |= CAMEL_FOLDER_CHILDREN;
- else
- fi->flags |= CAMEL_FOLDER_NOCHILDREN;
- }
-
- 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;
- CamelURL *url;
-
- visited = g_hash_table_new(inode_hash, inode_equal);
-
- url = camel_url_new("maildir:", NULL);
- camel_url_set_path(url, ((CamelService *)local_store)->url->path);
-
- if (scan_dir(store, visited, url, top == NULL || top[0] == 0?".":top, flags, NULL, &fi, ex) == -1 && fi != NULL) {
- camel_store_free_folder_info_full(store, fi);
- fi = NULL;
- }
-
- camel_url_free(url);
- 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 95b8bdc8c8..0000000000
--- a/camel/providers/local/camel-maildir-summary.c
+++ /dev/null
@@ -1,815 +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 "libedataserver/e-memory.h"
-#include "camel-i18n.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_from_header(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, CamelLocalMessageInfo *mi);
-static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *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_from_header = message_info_new_from_header;
- 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:
- * @folder: parent folder.
- * @filename: Path to root of this maildir directory (containing new/tmp/cur directories).
- * @index: Index if one is reqiured.
- *
- * Create a new CamelMaildirSummary object.
- *
- * Return value: A new #CamelMaildirSummary object.
- **/
-CamelMaildirSummary *camel_maildir_summary_new(struct _CamelFolder *folder, const char *filename, const char *maildirdir, CamelIndex *index)
-{
- CamelMaildirSummary *o = (CamelMaildirSummary *)camel_object_new(camel_maildir_summary_get_type ());
-
- ((CamelFolderSummary *)o)->folder = folder;
-
- 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[] = {
- { 'D', CAMEL_MESSAGE_DRAFT },
- { 'F', CAMEL_MESSAGE_FLAGGED },
- /*{ 'P', CAMEL_MESSAGE_FORWARDED },*/
- { '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 CamelMaildirMessageInfo *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->info.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(CamelMaildirMessageInfo *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->info.info.flags & flagbits[i].flagbit) == 0) {
- set |= flagbits[i].flagbit;
- }
- /*all |= flagbits[i].flagbit;*/
- }
- }
-
- /* changed? */
- /*if ((info->flags & all) != set) {*/
- if ((info->info.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->info.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, CamelLocalMessageInfo *mi)
-{
- return -1;
-}
-
-static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *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)
-{
- CamelMaildirMessageInfo *mi;
-
- mi = (CamelMaildirMessageInfo *)((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 (CamelMessageInfo *)mi;
-}
-
-static CamelMessageInfo *message_info_new_from_header(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_from_header(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)
- mdi->info.info.uid = 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_message_info_free(mi);
- mdi = (CamelMaildirMessageInfo *)(mi = info);
- }
-
- /* with maildir we know the real received date, from the filename */
- mdi->info.info.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(mdi, 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(mdi));
- 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((CamelMaildirMessageInfo *)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_message_info_free(info);
-}
-
-static int
-sort_receive_cmp(const void *ap, const void *bp)
-{
- const CamelMaildirMessageInfo
- *a = *((CamelMaildirMessageInfo **)ap),
- *b = *((CamelMaildirMessageInfo **)bp);
-
- if (a->info.info.date_received < b->info.info.date_received)
- return -1;
- else if (a->info.info.date_received > b->info.info.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_message_info_free(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_message_info_free(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_message_info_free(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 (mdi && (mdi->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 (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- char *newname = camel_maildir_summary_info_to_name(mdi);
- 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 */
- mdi->info.info.flags &= 0xffff;
- }
- camel_message_info_free(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 4ecaf368f5..0000000000
--- a/camel/providers/local/camel-maildir-summary.h
+++ /dev/null
@@ -1,76 +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;
-
-enum {
- CAMEL_MAILDIR_INFO_FILENAME = CAMEL_MESSAGE_INFO_LAST,
- CAMEL_MAILDIR_INFO_LAST,
-};
-
-typedef struct _CamelMaildirMessageInfo {
- CamelLocalMessageInfo info;
-
- char *filename; /* maildir has this annoying status shit on the end of the filename, use this to get the real message id */
-} 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 (struct _CamelFolder *folder, const char *filename, const char *maildirdir, CamelIndex *index);
-
-/* convert some info->flags to/from the messageinfo */
-char *camel_maildir_summary_info_to_name(const CamelMaildirMessageInfo *info);
-int camel_maildir_summary_name_to_info(CamelMaildirMessageInfo *info, const char *name);
-
-/* TODO: could proably use get_string stuff */
-#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 /* ! _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 d213b444fc..0000000000
--- a/camel/providers/local/camel-mbox-folder.c
+++ /dev/null
@@ -1,482 +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"
-#include "camel-i18n.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))
-
-static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex);
-static void mbox_unlock(CamelLocalFolder *lf);
-
-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(CamelLocalFolder *lf, 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;
-
- 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 (CamelLocalFolder *lf, 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 (CamelLocalFolder *lf, 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 (lf, toplevel_dir, name);
-#else
- char *full_path, *path;
-
- full_path = camel_mbox_folder_get_full_path (lf, 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(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
-{
- return (CamelLocalSummary *)camel_mbox_summary_new((CamelFolder *)lf, 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 from folder %s\n %s"),
- uid, lf->folder_path, _("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_message_info_free((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_SYSTEM,
- _("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,
- _("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_SYSTEM,
- _("Cannot get message: %s from folder %s\n %s"), uid, lf->folder_path,
- _("Message construction failed."));
- 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;
-}
diff --git a/camel/providers/local/camel-mbox-folder.h b/camel/providers/local/camel-mbox-folder.h
deleted file mode 100644
index fa76001849..0000000000
--- a/camel/providers/local/camel-mbox-folder.h
+++ /dev/null
@@ -1,66 +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);
-
-/* utilities */
-char *camel_mbox_folder_get_full_path (CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name);
-char *camel_mbox_folder_get_meta_path (CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name, const char *ext);
-
-#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 a9e581cdd7..0000000000
--- a/camel/providers/local/camel-mbox-store.c
+++ /dev/null
@@ -1,838 +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"
-#include "camel-i18n.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))
-
-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(NULL, 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(NULL, toplevel_dir, folder_name, ext);
-}
-
-static char *extensions[] = {
- ".msf", ".ev-summary", ".ibex.index", ".ibex.index.data", ".cmeta", ".lock"
-};
-
-static gboolean
-ignore_file(const char *filename, gboolean sbd)
-{
- int flen, len, i;
-
- /* TODO: Should probably just be 1 regex */
- flen = strlen(filename);
- if (flen > 0 && filename[flen-1] == '~')
- return TRUE;
-
- 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) {
- const char *basename;
- char *dirname;
- int fd;
-
- if (errno != ENOENT) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get folder `%s': %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,
- _("Cannot get folder `%s': folder does not exist."),
- folder_name);
- g_free(name);
- return NULL;
- }
-
- /* sanity check the folder name */
- if (!(basename = strrchr (folder_name, '/')))
- basename = folder_name;
- else
- basename++;
-
- if (basename[0] == '.' || ignore_file (basename, TRUE)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create a folder by this 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_SYSTEM,
- _("Cannot create folder `%s': %s"),
- folder_name, 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,
- _("Cannot create folder `%s': %s"),
- folder_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_SYSTEM,
- _("Cannot get folder `%s': not a regular file."),
- folder_name);
- g_free(name);
- return NULL;
- } else if (flags & CAMEL_STORE_FOLDER_EXCL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder `%s': folder exists."),
- folder_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);
-
- path = NULL;
- 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->uri = g_strdup_printf("mbox:%s#%s",((CamelService *) store)->url->path, folder_name);
- fi->unread = -1;
-
- 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)
-{
- 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(NULL, toplevel_dir, old_name, ext);
- newpath = camel_mbox_folder_get_meta_path(NULL, toplevel_dir, new_name, ext);
- } else {
- oldpath = camel_mbox_folder_get_full_path(NULL, toplevel_dir, old_name);
- newpath = camel_mbox_folder_get_full_path(NULL, 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;
- }
-
- 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, *newdir;
- int errnosav;
-
- if (new[0] == '.' || ignore_file(new, TRUE)) {
- 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");
-
- newdir = g_path_get_dirname(newibex);
- if (camel_mkdir(newdir, 0777) == -1) {
- if (errno != EEXIST) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not rename `%s': `%s': %s"),
- old, new, g_strerror(errno));
- g_free(oldibex);
- g_free(newibex);
- g_free(newdir);
-
- return;
- }
-
- g_free(newdir);
- newdir = NULL;
- }
-
- folder = camel_object_bag_get(store->folders, old);
- if (folder && folder->index) {
- if (camel_index_rename(folder->index, newibex) == -1 && errno != ENOENT) {
- errnosav = errno;
- 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 && errno != ENOENT) {
- errnosav = errno;
- goto ibex_failed;
- }
- }
-
- if (xrename(store, old, new, ".ev-summary", TRUE) == -1) {
- errnosav = errno;
- goto summary_failed;
- }
-
- if (xrename(store, old, new, ".cmeta", TRUE) == -1) {
- errnosav = errno;
- goto cmeta_failed;
- }
-
- if (xrename(store, old, new, ".sbd", TRUE) == -1) {
- errnosav = errno;
- goto subdir_failed;
- }
-
- if (xrename(store, old, new, NULL, FALSE) == -1) {
- errnosav = errno;
- goto base_failed;
- }
-
- g_free(oldibex);
- g_free(newibex);
-
- if (folder)
- camel_object_unref(folder);
-
- return;
-
-base_failed:
- xrename(store, new, old, ".sbd", TRUE);
-subdir_failed:
- xrename(store, new, old, ".cmeta", TRUE);
-cmeta_failed:
- xrename(store, new, old, ".ev-summary", TRUE);
-summary_failed:
- if (folder) {
- if (folder->index)
- camel_index_rename(folder->index, oldibex);
- } else
- camel_text_index_rename(newibex, oldibex);
-ibex_failed:
- if (newdir) {
- /* newdir is only non-NULL if we needed to mkdir */
- rmdir(newdir);
- g_free(newdir);
- }
-
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not rename '%s' to %s: %s"),
- old, new, g_strerror(errnosav));
-
- 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);
-}
-
-/* NB: duplicated in maildir store */
-static void
-fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
-{
- CamelFolder *folder;
-
- fi->unread = -1;
- fi->total = -1;
- folder = camel_object_bag_get(store->folders, fi->full_name);
- if (folder) {
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- camel_folder_refresh_info(folder, NULL);
- fi->unread = camel_folder_get_unread_message_count(folder);
- fi->total = camel_folder_get_message_count(folder);
- camel_object_unref(folder);
- } else {
- char *path, *folderpath;
- CamelMboxSummary *mbs;
- const char *root;
-
- /* This should be fast enough not to have to test for INFO_FAST */
- root = camel_local_store_get_toplevel_dir((CamelLocalStore *)store);
- path = camel_mbox_folder_get_meta_path(NULL, root, fi->full_name, ".ev-summary");
- folderpath = camel_mbox_folder_get_full_path(NULL, root, fi->full_name);
-
- mbs = (CamelMboxSummary *)camel_mbox_summary_new(NULL, path, folderpath, NULL);
- if (camel_folder_summary_header_load((CamelFolderSummary *)mbs) != -1) {
- fi->unread = ((CamelFolderSummary *)mbs)->unread_count;
- fi->total = ((CamelFolderSummary *)mbs)->saved_count;
- }
-
- camel_object_unref(mbs);
- g_free(folderpath);
- g_free(path);
- }
-}
-
-static CamelFolderInfo *
-scan_dir(CamelStore *store, CamelURL *url, 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;
- struct stat st;
-
- 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 ((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_NOCHILDREN) | CAMEL_FOLDER_CHILDREN;
- } else {
- fi->flags &= ~CAMEL_FOLDER_NOSELECT;
- }
- } else {
- fi = g_new0(CamelFolderInfo, 1);
- fi->parent = parent;
-
- camel_url_set_fragment (url, full_name);
-
- fi->uri = camel_url_to_string (url, 0);
- fi->name = short_name;
- fi->full_name = full_name;
- fi->unread = -1;
- fi->total = -1;
-
- if (S_ISDIR(st.st_mode))
- fi->flags = CAMEL_FOLDER_NOSELECT;
- else
- fi->flags = CAMEL_FOLDER_NOCHILDREN;
-
- if (tail == NULL)
- folders = fi;
- else
- tail->next = fi;
-
- tail = fi;
-
- g_hash_table_insert(folder_hash, fi->name, fi);
- }
-
- if (!S_ISDIR(st.st_mode)) {
- fill_fi(store, fi, flags);
- } else if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)) {
- 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, url, visited, fi, path, fi->full_name, flags, ex)))
- fi->flags |= CAMEL_FOLDER_CHILDREN;
- else
- fi->flags =(fi->flags & ~CAMEL_FOLDER_CHILDREN) | CAMEL_FOLDER_NOCHILDREN;
- }
- }
-
- 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;
- const char *base;
- struct stat st;
- CamelURL *url;
-
- 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_malloc0(sizeof(*inode));
- inode->dnode = st.st_dev;
- inode->inode = st.st_ino;
-
- g_hash_table_insert(visited, inode, inode);
-
- url = camel_url_copy (((CamelService *) store)->url);
- fi = scan_dir (store, url, visited, NULL, path, NULL, flags, ex);
- g_hash_table_foreach(visited, inode_free, NULL);
- g_hash_table_destroy(visited);
- camel_url_free (url);
- 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++;
-
- url = camel_url_copy (((CamelService *) store)->url);
- camel_url_set_fragment (url, top);
-
- fi = g_new0(CamelFolderInfo, 1);
- fi->parent = NULL;
- fi->uri = camel_url_to_string (url, 0);
- fi->name = g_strdup(base);
- fi->full_name = g_strdup(top);
- fi->unread = -1;
- fi->total = -1;
-
- subdir = g_strdup_printf("%s.sbd", path);
- if (stat(subdir, &st) == 0) {
- if (S_ISDIR(st.st_mode))
- fi->child = scan_dir (store, url, visited, fi, subdir, top, flags, ex);
- else
- fill_fi(store, fi, flags);
- } else
- fill_fi(store, fi, flags);
-
- camel_url_free (url);
-
- if (fi->child)
- fi->flags |= CAMEL_FOLDER_CHILDREN;
- else
- fi->flags |= CAMEL_FOLDER_NOCHILDREN;
-
- 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 9dcee0a9c8..0000000000
--- a/camel/providers/local/camel-mbox-summary.c
+++ /dev/null
@@ -1,1109 +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 <ctype.h>
-
-#include "camel-mbox-summary.h"
-#include "camel/camel-file-utils.h"
-#include "camel/camel-mime-message.h"
-#include "camel/camel-operation.h"
-#include "camel-i18n.h"
-
-#define io(x)
-#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-
-#define CAMEL_MBOX_SUMMARY_VERSION (1)
-
-static int summary_header_load (CamelFolderSummary *, FILE *);
-static int summary_header_save (CamelFolderSummary *, FILE *);
-
-static CamelMessageInfo * message_info_new_from_header(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 char *mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi);
-
-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 gboolean
-mbox_info_set_user_flag(CamelMessageInfo *mi, const char *name, gboolean value)
-{
- int res;
-
- res = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_user_flag(mi, name, value);
- if (res)
- ((CamelLocalMessageInfo *)mi)->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
-
- return res;
-}
-
-static gboolean
-mbox_info_set_user_tag(CamelMessageInfo *mi, const char *name, const char *value)
-{
- int res;
-
- res = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_user_tag(mi, name, value);
- if (res)
- ((CamelLocalMessageInfo *)mi)->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
-
- return res;
-}
-
-#ifdef STATUS_PINE
-static gboolean
-mbox_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
-{
- /* Basically, if anything could change the Status line, presume it does */
- if (((CamelMboxSummary *)mi->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;
- }
-
- return ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_flags(mi, flags, set);
-}
-#endif
-
-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_from_header = message_info_new_from_header;
- 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;*/
-
- sklass->info_set_user_flag = mbox_info_set_user_flag;
- sklass->info_set_user_tag = mbox_info_set_user_tag;
-#ifdef STATUS_PINE
- sklass->info_set_flags = mbox_info_set_flags;
-#endif
-
- lklass->encode_x_evolution = mbox_summary_encode_x_evolution;
- 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(struct _CamelFolder *folder, const char *filename, const char *mbox_name, CamelIndex *index)
-{
- CamelMboxSummary *new = (CamelMboxSummary *)camel_object_new(camel_mbox_summary_get_type());
-
- ((CamelFolderSummary *)new)->folder = folder;
-
- 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 char *
-mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi)
-{
- const char *p, *uidstr;
- guint32 uid;
-
- /* This is busted, it is supposed to encode ALL DATA */
- p = uidstr = camel_message_info_uid(mi);
- while (*p && isdigit(*p))
- p++;
-
- if (*p == 0 && sscanf(uidstr, "%u", &uid) == 1) {
- return g_strdup_printf("%08x-%04x", uid, mi->info.flags & 0xffff);
- } else {
- return g_strdup_printf("%s-%04x", uidstr, mi->info.flags & 0xffff);
- }
-}
-
-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;
-
- /* legacy version */
- if (s->version == 0x120c)
- return camel_file_util_decode_uint32(in, (guint32 *) &mbs->folder_size);
-
- /* version 1 */
- if (camel_file_util_decode_fixed_int32(in, &mbs->version) == -1
- || camel_file_util_decode_size_t(in, &mbs->folder_size) == -1)
- return -1;
-
- return 0;
-}
-
-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;
-
- camel_file_util_encode_fixed_int32(out, CAMEL_MBOX_SUMMARY_VERSION);
-
- return camel_file_util_encode_size_t(out, mbs->folder_size);
-}
-
-static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
-{
- CamelMboxMessageInfo *mi;
- CamelMboxSummary *mbs = (CamelMboxSummary *)s;
-
- mi = (CamelMboxMessageInfo *)((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new_from_header(s, h);
- if (mi) {
- const char *xev, *uid;
- CamelMboxMessageInfo *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->info) == 0) {
- uid = camel_message_info_uid(mi);
- d(printf("found valid x-evolution: %s\n", uid));
- info = (CamelMboxMessageInfo *)camel_folder_summary_uid(s, uid);
- if (info) {
- if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
- info->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
- camel_message_info_free(mi);
- mi = info;
- } else {
- add = 7;
- d(printf("seen '%s' before, adding anew\n", uid));
- camel_message_info_free(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->info.info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
- mi->info.info.uid = 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->info.info.flags = (mi->info.info.flags & ~(STATUS_STATUS)) | (flags & STATUS_STATUS);
- if (xstatus)
- mi->info.info.flags = (mi->info.info.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));
- }
-
- mi->frompos = -1;
- }
-
- return (CamelMessageInfo *)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_message_info_free(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;
- CamelMboxMessageInfo *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 = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
- if (offset == 0)
- mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN;
- else
- mi->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
- camel_message_info_free(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 = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
- /* must've dissapeared from the file? */
- if (mi->info.info.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, (CamelMessageInfo *)mi);
- count--;
- i--;
- }
- camel_message_info_free(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_message_info_free(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.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
- camel_message_info_free((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, &info->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.info.flags &= 0xffff;
- camel_message_info_free((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_message_info_free((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++) {
- CamelMboxMessageInfo *info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
-
- g_assert(info);
- if ((expunge && (info->info.info.flags & CAMEL_MESSAGE_DELETED)) ||
- (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_XEVCHANGE)))
- quick = FALSE;
- else
- work |= (info->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0;
- camel_message_info_free(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.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_message_info_free((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.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, &info->info);
-#ifdef STATUS_PINE
- if (mbs->xstatus) {
- encode_status(info->info.info.flags & STATUS_STATUS, statnew);
- encode_status(info->info.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.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_message_info_free((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_message_info_free((CamelMessageInfo *)info);
-
- return -1;
-}
-
-#ifdef STATUS_PINE
-static CamelMessageInfo *
-mbox_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex)
-{
- CamelMboxMessageInfo *mi;
-
- mi = (CamelMboxMessageInfo *)((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->info.info.flags & STATUS_STATUS, status);
- camel_medium_set_header((CamelMedium *)msg, "Status", status);
- encode_status(mi->info.info.flags & STATUS_XSTATUS, status);
- camel_medium_set_header((CamelMedium *)msg, "X-Status", status);
- }
-
- return (CamelMessageInfo *)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 9089fe7c8e..0000000000
--- a/camel/providers/local/camel-mbox-summary.h
+++ /dev/null
@@ -1,76 +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 {
- CamelLocalMessageInfo info;
-
- off_t frompos;
-} CamelMboxMessageInfo;
-
-struct _CamelMboxSummary {
- CamelLocalSummary parent;
-
- CamelFolderChangeInfo *changes; /* used to build change sets */
-
- guint32 version;
- 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 (struct _CamelFolder *, 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 1b054a4547..0000000000
--- a/camel/providers/local/camel-mh-folder.c
+++ /dev/null
@@ -1,234 +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"
-#include "camel-i18n.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(CamelLocalFolder *lf, 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(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
-{
- return (CamelLocalSummary *)camel_mh_summary_new((CamelFolder *)lf, 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 from folder %s\n %s"), uid, lf->folder_path,
- _("No such message"));
- return NULL;
- }
-
- /* we only need it to check the message exists */
- camel_message_info_free(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_SYSTEM,
- _("Cannot get message: %s from folder %s\n %s"), name, lf->folder_path,
- 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_SYSTEM,
- _("Cannot get message: %s from folder %s\n %s"), name, lf->folder_path,
- _("Message construction failed."));
- 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 03b6db92bd..0000000000
--- a/camel/providers/local/camel-mh-store.c
+++ /dev/null
@@ -1,579 +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-i18n.h"
-
-#include <camel/camel-stream-fs.h>
-#include <camel/camel-stream-buffer.h>
-
-#include "camel-mh-summary.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,
- _("Cannot get folder `%s': %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,
- _("Cannot get folder `%s': folder does not exist."),
- folder_name);
- g_free (name);
- return NULL;
- }
-
- if (mkdir(name, 0777) != 0) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create folder `%s': %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,
- _("Cannot get folder `%s': not a directory."), folder_name);
- g_free (name);
- return NULL;
- } else if (flags & CAMEL_STORE_FOLDER_EXCL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder `%s': folder exists."), folder_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 void
-fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
-{
- CamelFolder *folder;
-
- folder = camel_object_bag_get(store->folders, fi->full_name);
-
- if (folder == NULL
- && (flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- folder = camel_store_get_folder(store, fi->full_name, 0, NULL);
-
- if (folder) {
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- camel_folder_refresh_info(folder, NULL);
- fi->unread = camel_folder_get_unread_message_count(folder);
- fi->total = camel_folder_get_message_count(folder);
- camel_object_unref(folder);
- } else {
- char *path, *folderpath;
- CamelFolderSummary *s;
- const char *root;
-
- /* This should be fast enough not to have to test for INFO_FAST */
-
- /* 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 */
-
- root = camel_local_store_get_toplevel_dir((CamelLocalStore *)store);
- path = g_strdup_printf("%s/%s.ev-summary", root, fi->full_name);
- folderpath = g_strdup_printf("%s/%s", root, fi->full_name);
- s = (CamelFolderSummary *)camel_mh_summary_new(NULL, path, folderpath, NULL);
- if (camel_folder_summary_header_load(s) != -1) {
- fi->unread = s->unread_count;
- fi->total = s->saved_count;
- }
- camel_object_unref(s);
- g_free(folderpath);
- g_free(path);
- }
-}
-
-static CamelFolderInfo *
-folder_info_new (CamelStore *store, CamelURL *url, const char *root, const char *path, guint32 flags)
-{
- /* FIXME: need to set fi->flags = CAMEL_FOLDER_NOSELECT (and possibly others) when appropriate */
- CamelFolderInfo *fi;
- char *base;
-
- base = strrchr(path, '/');
-
- camel_url_set_fragment (url, path);
-
- /* Build the folder info structure. */
- fi = g_malloc0(sizeof(*fi));
- fi->uri = camel_url_to_string (url, 0);
- fi->full_name = g_strdup(path);
- fi->name = g_strdup(base?base+1:path);
- fill_fi(store, fi, flags);
-
- d(printf("New folderinfo:\n '%s'\n '%s'\n '%s'\n", fi->full_name, fi->uri, 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, CamelURL *url, CamelFolderInfo **fip, CamelFolderInfo *parent,
- GHashTable *visited, const char *root, const char *path, guint32 flags)
-{
- 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, url, root, path, flags);
- fi->parent = parent;
- fi->next = *fip;
- *fip = fi;
-
- if (((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, url, &fi->child, fi, visited, root, tmp, flags);
- g_free(tmp);
- } else {
- recursive_scan(store, url, &fi->child, fi, visited, root, d->d_name, flags);
- }
- }
-
- closedir(dp);
- }
-}
-
-/* scan a .folders file */
-static void
-folders_scan(CamelStore *store, CamelURL *url, const char *root, const char *top, CamelFolderInfo **fip, guint32 flags)
-{
- 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 ((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, url, root, line, flags);
- 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;
- CamelURL *url;
- char *root;
-
- root = ((CamelService *)store)->url->path;
-
- url = camel_url_copy (((CamelService *) store)->url);
-
- /* use .folders if we are supposed to */
- if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) {
- folders_scan(store, url, root, top, &fi, flags);
- } else {
- GHashTable *visited = g_hash_table_new(inode_hash, inode_equal);
-
- if (top == NULL)
- top = "";
-
- recursive_scan(store, url, &fi, NULL, visited, root, top, flags);
-
- /* 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);
- }
-
- camel_url_free (url);
-
- 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 fe0201e4f2..0000000000
--- a/camel/providers/local/camel-mh-summary.c
+++ /dev/null
@@ -1,423 +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"
-#include "camel-i18n.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(struct _CamelFolder *folder, const char *filename, const char *mhdir, CamelIndex *index)
-{
- CamelMhSummary *o = (CamelMhSummary *)camel_object_new(camel_mh_summary_get_type ());
-
- ((CamelFolderSummary *)o)->folder = folder;
-
- 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_message_info_free(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_message_info_free(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_message_info_free(old);
- g_hash_table_remove(left, uid);
- }
- camel_message_info_free(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, CamelLocalMessageInfo *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;
- CamelLocalMessageInfo *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 = (CamelLocalMessageInfo *)camel_folder_summary_index((CamelFolderSummary *)cls, i);
- g_assert(info);
- if (expunge && (info->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, (CamelMessageInfo *)info);
- }
- g_free(name);
- } else if (info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- if (mh_summary_sync_message(cls, info, ex) != -1) {
- info->info.flags &= 0xffff;
- } else {
- g_warning("Problem occured when trying to expunge, ignored");
- }
- }
- camel_message_info_free(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 d2fdcd1e4a..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(struct _CamelFolder *, 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 c4c7da91b6..0000000000
--- a/camel/providers/local/camel-spool-folder.c
+++ /dev/null
@@ -1,217 +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-session.h"
-#include "camel-file-utils.h"
-#include "camel-lock-client.h"
-#include "camel-local-private.h"
-#include "camel-i18n.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 char *spool_get_full_path(CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name);
-static char *spool_get_meta_path(CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name, const char *ext);
-static CamelLocalSummary *spool_create_summary(CamelLocalFolder *lf, 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();
-
- lklass->get_full_path = spool_get_full_path;
- lklass->get_meta_path = spool_get_meta_path;
- 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 char *
-spool_get_full_path(CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name)
-{
- return g_strdup_printf ("%s/%s", toplevel_dir, full_name);
-}
-
-static char *
-spool_get_meta_path(CamelLocalFolder *lf, const char *toplevel_dir, const char *full_name, const char *ext)
-{
- CamelService *service = (CamelService *)((CamelFolder *)lf)->parent_store;
- char *root = camel_session_get_storage_path(service->session, service, NULL);
- char *path;
-
- if (root == NULL)
- return NULL;
-
-
- camel_mkdir(root, 0777);
- path = g_strdup_printf("%s/%s%s", root, full_name, ext);
- g_free(root);
-
- return path;
-}
-
-static CamelLocalSummary *
-spool_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
-{
- return (CamelLocalSummary *)camel_spool_summary_new((CamelFolder *)lf, 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++;
- }
-
- close (mf->lockfd);
- mf->lockfd = -1;
-
- 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 3dc21886c8..0000000000
--- a/camel/providers/local/camel-spool-store.c
+++ /dev/null
@@ -1,466 +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"
-#include "camel-i18n.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->uri);
- g_free(fi->name);
- g_free(fi->full_name);
- g_free(fi);
- }
-}
-
-/* partially copied from mbox */
-static void
-spool_fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
-{
- CamelFolder *folder;
-
- fi->unread = -1;
- fi->total = -1;
- folder = camel_object_bag_get(store->folders, fi->full_name);
- if (folder) {
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
- camel_folder_refresh_info(folder, NULL);
- fi->unread = camel_folder_get_unread_message_count(folder);
- fi->total = camel_folder_get_message_count(folder);
- camel_object_unref(folder);
- }
-}
-
-static CamelFolderInfo *
-spool_new_fi(CamelStore *store, CamelFolderInfo *parent, CamelFolderInfo **fip, const char *full, guint32 flags)
-{
- CamelFolderInfo *fi;
- const char *name;
- CamelURL *url;
-
- name = strrchr(full, '/');
- if (name)
- name++;
- else
- name = full;
-
- fi = g_malloc0(sizeof(*fi));
- url = camel_url_copy(((CamelService *)store)->url);
- camel_url_set_fragment(url, full);
- fi->uri = camel_url_to_string(url, 0);
- camel_url_free(url);
- fi->full_name = g_strdup(full);
- fi->name = g_strdup(name);
- fi->unread = -1;
- fi->total = -1;
- fi->flags = flags;
-
- fi->parent = parent;
- fi->next = *fip;
- *fip = 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, *tmp, *fname;
- CamelFolderInfo *fi = NULL;
- struct stat st;
- CamelFolder *folder;
- 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) {
- fi = spool_new_fi(store, parent, fip, path, CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN);
- spool_fill_fi(store, fi, flags);
- }
- 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) {
- fi = spool_new_fi(store, parent, fip, path, CAMEL_FOLDER_NOSELECT);
- 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)) {
- int isfolder = FALSE;
-
- /* first, see if we already have it open */
- folder = camel_object_bag_get(store->folders, fname);
- if (folder == NULL) {
- fp = fopen(tmp, "r");
- if (fp != NULL) {
- isfolder = (st.st_size == 0
- || (fgets(from, sizeof(from), fp) != NULL
- && strncmp(from, "From ", 5) == 0));
- fclose(fp);
- }
- }
-
- if (folder != NULL || isfolder) {
- fi = spool_new_fi(store, parent, fip, fname, CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN);
- spool_fill_fi(store, fi, flags);
- }
- if (folder)
- camel_object_unref(folder);
-
- } 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, *fip = NULL;
-
- if (top == NULL || strcmp(top, "INBOX") == 0) {
- fi = spool_new_fi(store, NULL, &fip, "INBOX", CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_SYSTEM);
- g_free(fi->name);
- fi->name = g_strdup(_("Inbox"));
- spool_fill_fi(store, fi, flags);
- }
-
- 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 c8e074ae99..0000000000
--- a/camel/providers/local/camel-spool-summary.c
+++ /dev/null
@@ -1,347 +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"
-#include "camel-i18n.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(struct _CamelFolder *folder, const char *mbox_name)
-{
- CamelSpoolSummary *new = (CamelSpoolSummary *)camel_object_new(camel_spool_summary_get_type());
-
- ((CamelFolderSummary *)new)->folder = folder;
-
- 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++) {
- CamelMboxMessageInfo *info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
- g_assert(info);
- work = (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0;
- camel_message_info_free((CamelMessageInfo *)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 2849c8cc20..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(struct _CamelFolder *, 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 207c19a98f..0000000000
--- a/camel/providers/local/libcamellocal.urls
+++ /dev/null
@@ -1,4 +0,0 @@
-mh
-mbox
-maildir
-spool
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 bc8b82ccad..0000000000
--- a/camel/providers/nntp/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-camel_provider_LTLIBRARIES = libcamelnntp.la
-camel_provider_DATA = libcamelnntp.urls
-
-INCLUDES = -I../.. \
- -I$(top_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-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 \
- camel-nntp-store-summary.c
-
-noinst_HEADERS = \
- camel-nntp-store.h \
- camel-nntp-folder.h \
- camel-nntp-resp-codes.h \
- camel-nntp-stream.h \
- camel-nntp-summary.h \
- camel-nntp-store-summary.h \
- 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 de0f4cd222..0000000000
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ /dev/null
@@ -1,533 +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/camel-mime-filter-crlf.h"
-#include "camel/camel-stream-filter.h"
-#include "camel/camel-mime-message.h"
-#include "camel/camel-multipart.h"
-#include "camel/camel-mime-part.h"
-#include "camel/camel-stream-buffer.h"
-#include "camel/camel-i18n.h"
-#include "camel/camel-private.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 *folder_class = NULL;
-static CamelDiscoFolderClass *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))
-
-void
-camel_nntp_folder_selected(CamelNNTPFolder *folder, char *line, CamelException *ex)
-{
- camel_nntp_summary_check((CamelNNTPSummary *)((CamelFolder *)folder)->summary,
- (CamelNNTPStore *)((CamelFolder *)folder)->parent_store,
- line, folder->changes, ex);
-}
-
-static void
-nntp_folder_refresh_info_online (CamelFolder *folder, CamelException *ex)
-{
- CamelNNTPStore *nntp_store;
- CamelFolderChangeInfo *changes = NULL;
- CamelNNTPFolder *nntp_folder;
- char *line;
-
- nntp_store = (CamelNNTPStore *) folder->parent_store;
- nntp_folder = (CamelNNTPFolder *) folder;
-
- CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
-
- camel_nntp_command(nntp_store, ex, nntp_folder, &line, NULL);
-
- if (camel_folder_change_info_changed(nntp_folder->changes)) {
- changes = nntp_folder->changes;
- nntp_folder->changes = camel_folder_change_info_new();
- }
-
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
-
- if (changes) {
- camel_object_trigger_event ((CamelObject *) folder, "folder_changed", changes);
- camel_folder_change_info_free (changes);
- }
-}
-
-static void
-nntp_folder_sync_online (CamelFolder *folder, CamelException *ex)
-{
- CAMEL_SERVICE_LOCK(folder->parent_store, connect_lock);
- camel_folder_summary_save (folder->summary);
- CAMEL_SERVICE_UNLOCK(folder->parent_store, connect_lock);
-}
-
-static void
-nntp_folder_sync_offline (CamelFolder *folder, CamelException *ex)
-{
- CAMEL_SERVICE_LOCK(folder->parent_store, connect_lock);
- camel_folder_summary_save (folder->summary);
- CAMEL_SERVICE_UNLOCK(folder->parent_store, connect_lock);
-}
-
-static gboolean
-nntp_folder_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
-{
- return ((CamelFolderClass *) folder_class)->set_message_flags (folder, uid, flags, set);
-}
-
-static CamelStream *
-nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const char *id, const char *msgid, CamelException *ex)
-{
- CamelNNTPStore *nntp_store = (CamelNNTPStore *) ((CamelFolder *) nntp_folder)->parent_store;
- CamelStream *stream = NULL;
- int ret;
- char *line;
-
- ret = camel_nntp_command (nntp_store, ex, nntp_folder, &line, "article %s", id);
- 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 fail;
- if (camel_stream_reset (stream) == -1)
- goto fail;
- } else {
- stream = (CamelStream *) nntp_store->stream;
- camel_object_ref (stream);
- }
- } else if (ret == 423 || ret == 430) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message %s: %s"), msgid, line);
- } else if (ret != -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get message %s: %s"), msgid, line);
- }
-
- return stream;
-
- fail:
- 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"), msgid, g_strerror (errno));
-
- return NULL;
-}
-
-
-static void
-nntp_folder_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex)
-{
- CamelNNTPStore *nntp_store = (CamelNNTPStore *)((CamelFolder *) disco_folder)->parent_store;
- CamelStream *stream;
- char *article, *msgid;
-
- article = alloca(strlen(uid)+1);
- strcpy(article, uid);
- msgid = strchr(article, ',');
- if (!msgid) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Internal error: uid in invalid format: %s"), uid);
- return;
- }
- *msgid++ = 0;
-
- CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
-
- stream = nntp_folder_download_message ((CamelNNTPFolder *) disco_folder, article, msgid, ex);
- if (stream)
- camel_object_unref (stream);
-
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
-}
-
-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;
- char *article, *msgid;
-
- nntp_store = (CamelNNTPStore *) folder->parent_store;
- nntp_folder = (CamelNNTPFolder *) folder;
-
- article = alloca(strlen(uid)+1);
- strcpy(article, uid);
- msgid = strchr (article, ',');
- if (msgid == NULL) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Internal error: uid in invalid format: %s"), uid);
- return NULL;
- }
- *msgid++ = 0;
-
- CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
-
- /* 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) {
- if (camel_disco_store_status ((CamelDiscoStore *) nntp_store) == CAMEL_DISCO_STORE_OFFLINE) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("This message is not currently available"));
- goto fail;
- }
-
- stream = nntp_folder_download_message (nntp_folder, article, msgid, ex);
- if (stream == NULL)
- goto fail;
- }
-
- 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(message);
- message = NULL;
- }
-
- camel_object_unref (stream);
-fail:
- 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_SERVICE_UNLOCK(nntp_store, connect_lock);
-
- if (changes) {
- camel_object_trigger_event ((CamelObject *) folder, "folder_changed", changes);
- camel_folder_change_info_free (changes);
- }
-
- return message;
-}
-
-static GPtrArray*
-nntp_folder_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
-{
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
- GPtrArray *matches;
-
- 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);
- matches = camel_folder_search_search(nntp_folder->search, expression, NULL, ex);
-
- CAMEL_NNTP_FOLDER_UNLOCK(nntp_folder, search_lock);
-
- return matches;
-}
-
-static GPtrArray *
-nntp_folder_search_by_uids (CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
-{
- CamelNNTPFolder *nntp_folder = (CamelNNTPFolder *) folder;
- GPtrArray *matches;
-
- if (uids->len == 0)
- return g_ptr_array_new();
-
- 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);
- matches = camel_folder_search_search(nntp_folder->search, expression, uids, ex);
-
- CAMEL_NNTP_FOLDER_UNLOCK(folder, search_lock);
-
- 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_append_message_online (CamelFolder *folder, CamelMimeMessage *mime_message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex)
-{
- CamelNNTPStore *nntp_store = (CamelNNTPStore *) folder->parent_store;
- CamelStream *stream = (CamelStream*)nntp_store->stream;
- CamelStreamFilter *filtered_stream;
- CamelMimeFilter *crlffilter;
- int ret;
- unsigned int u;
- struct _camel_header_raw *header, *savedhdrs, *n, *tail;
- char *group, *line;
-
- CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
-
- /* send 'POST' command */
- ret = camel_nntp_command (nntp_store, ex, NULL, &line, "post");
- if (ret != 340) {
- if (ret == 440)
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
- _("Posting failed: %s"), line);
- else if (ret != -1)
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Posting failed: %s"), line);
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
- return;
- }
-
- /* the 'Newsgroups: ' header */
- group = g_strdup_printf ("Newsgroups: %s\r\n", folder->full_name);
-
- /* 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 (stream);
- camel_stream_filter_add (filtered_stream, crlffilter);
- camel_object_unref (crlffilter);
-
- /* remove mail 'To', 'CC', and 'BCC' headers */
- savedhdrs = NULL;
- tail = (struct _camel_header_raw *) &savedhdrs;
-
- header = (struct _camel_header_raw *) &CAMEL_MIME_PART (mime_message)->headers;
- n = header->next;
- while (n != NULL) {
- if (!g_ascii_strcasecmp (n->name, "To") || !g_ascii_strcasecmp (n->name, "Cc") || !g_ascii_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 */
- if (camel_stream_write(stream, group, strlen(group)) == -1
- || camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (mime_message), CAMEL_STREAM (filtered_stream)) == -1
- || camel_stream_flush (CAMEL_STREAM (filtered_stream)) == -1
- || camel_stream_write (stream, "\r\n.\r\n", 5) == -1
- || (ret = camel_nntp_stream_line (nntp_store->stream, (unsigned char **)&line, &u)) == -1) {
- if (errno == EINTR)
- camel_exception_setv (ex, CAMEL_EXCEPTION_USER_CANCEL, _("User cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Posting failed: %s"), g_strerror (errno));
- } else if (atoi(line) != 240) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Posting failed: %s"), line);
- }
-
- camel_object_unref (filtered_stream);
- g_free(group);
- header->next = savedhdrs;
-
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
-
- return;
-}
-
-static void
-nntp_folder_append_message_offline (CamelFolder *folder, CamelMimeMessage *mime_message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex)
-{
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("You cannot post NNTP messages while working offline!"));
-}
-
-/* I do not know what to do this exactly. Looking at the IMAP implementation for this, it
- seems to assume the message is copied to a folder on the same store. In that case, an
- NNTP implementation doesn't seem to make any sense. */
-static void
-nntp_folder_transfer_message (CamelFolder *source, GPtrArray *uids, CamelFolder *dest,
- GPtrArray **transferred_uids, gboolean delete_orig, CamelException *ex)
-{
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("You cannot copy messages from a NNTP folder!"));
-}
-
-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;
-
- camel_folder_summary_save (((CamelFolder*) nntp_folder)->summary);
-
- 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)
-{
- CamelDiscoFolderClass *camel_disco_folder_class = CAMEL_DISCO_FOLDER_CLASS (camel_nntp_folder_class);
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_nntp_folder_class);
-
- parent_class = CAMEL_DISCO_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_disco_folder_get_type ()));
- folder_class = CAMEL_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_folder_get_type ()));
-
- /* virtual method definition */
-
- /* virtual method overload */
- camel_disco_folder_class->sync_online = nntp_folder_sync_online;
- camel_disco_folder_class->sync_resyncing = nntp_folder_sync_offline;
- camel_disco_folder_class->sync_offline = nntp_folder_sync_offline;
- camel_disco_folder_class->cache_message = nntp_folder_cache_message;
- camel_disco_folder_class->append_online = nntp_folder_append_message_online;
- camel_disco_folder_class->append_resyncing = nntp_folder_append_message_online;
- camel_disco_folder_class->append_offline = nntp_folder_append_message_offline;
- camel_disco_folder_class->transfer_online = nntp_folder_transfer_message;
- camel_disco_folder_class->transfer_resyncing = nntp_folder_transfer_message;
- camel_disco_folder_class->transfer_offline = nntp_folder_transfer_message;
- camel_disco_folder_class->refresh_info_online = nntp_folder_refresh_info_online;
-
- 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_DISCO_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;
-}
-
-CamelFolder *
-camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelException *ex)
-{
- CamelFolder *folder;
- CamelNNTPFolder *nntp_folder;
- char *root;
- CamelService *service;
- CamelStoreInfo *si;
- gboolean subscribed = TRUE;
-
- 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_build_filename (root, folder->full_name, NULL);
- g_free (root);
-
- root = g_strdup_printf ("%s.cmeta", nntp_folder->storage_path);
- camel_object_set(nntp_folder, NULL, CAMEL_OBJECT_STATE_FILE, root, NULL);
- camel_object_state_read(nntp_folder);
- g_free(root);
-
- root = g_strdup_printf("%s.ev-summary", nntp_folder->storage_path);
- folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (folder, root);
- g_free(root);
- camel_folder_summary_load (folder->summary);
-
- si = camel_store_summary_path ((CamelStoreSummary *) ((CamelNNTPStore*) parent)->summary, folder_name);
- if (si) {
- subscribed = (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0;
- camel_store_summary_info_free ((CamelStoreSummary *) ((CamelNNTPStore*) parent)->summary, si);
- }
-
- if (subscribed) {
- camel_folder_refresh_info(folder, ex);
- if (camel_exception_is_set(ex)) {
- camel_object_unref (folder);
- folder = NULL;
- }
- }
-
- 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 0914ee4cad..0000000000
--- a/camel/providers/nntp/camel-nntp-folder.h
+++ /dev/null
@@ -1,75 +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/camel-disco-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 {
- CamelDiscoFolder parent;
-
- struct _CamelNNTPFolderPrivate *priv;
-
- struct _CamelFolderChangeInfo *changes;
- char *storage_path;
- CamelFolderSearch *search;
-} CamelNNTPFolder;
-
-typedef struct _CamelNNTPFolderClass {
- CamelDiscoFolderClass 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);
-
-void camel_nntp_folder_selected(CamelNNTPFolder *folder, char *line, 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 cbcf2b30b2..0000000000
--- a/camel/providers/nntp/camel-nntp-grouplist.c
+++ /dev/null
@@ -1,218 +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, &line, "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 b45d352cd8..0000000000
--- a/camel/providers/nntp/camel-nntp-grouplist.h
+++ /dev/null
@@ -1,51 +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;
-};
-
-typedef struct CamelNNTPGroupList _CamelNNTPGroupList;
-typedef struct CamelNNTPGroupListEntry _CamelNNTPGroupListEntry;
-
-struct CamelNNTPGroupList* camel_nntp_grouplist_fetch (CamelNNTPStore *store, CamelException *ex);
-gint camel_nntp_grouplist_update (struct CamelNNTPGroupList *group_list, CamelException *ex);
-void camel_nntp_grouplist_save (struct CamelNNTPGroupList *group_list, CamelException *ex);
-void camel_nntp_grouplist_free (struct 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 520c9db134..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 "libedataserver/e-msgport.h"
-
-struct _CamelNNTPStorePrivate {
- int dummy;
-};
-
-#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 5780c41f9d..0000000000
--- a/camel/providers/nntp/camel-nntp-provider.c
+++ /dev/null
@@ -1,138 +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"
-#include "camel-i18n.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);
-
-CamelProviderConfEntry nntp_conf_entries[] = {
- { CAMEL_PROVIDER_CONF_SECTION_START, "folders", NULL,
- N_("Folders") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "show_short_notation", NULL,
- N_("Show folders in short notation (e.g. c.o.linux rather than comp.os.linux)"), "1" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "folder_hierarchy_relative", NULL,
- N_("In the subscription dialog, show relative folder names"), "1" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-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_PROVIDER_SUPPORTS_SSL,
-
- CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_USER |
- CAMEL_URL_ALLOW_PASSWORD | CAMEL_URL_ALLOW_AUTH,
-
- nntp_conf_entries
-
- /* ... */
-};
-
-CamelServiceAuthType camel_nntp_password_authtype = {
- N_("Password"),
-
- N_("This option will authenticate with the NNTP server using a "
- "plaintext password."),
-
- "",
- TRUE
-};
-
-void
-camel_provider_module_init(void)
-{
- 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;
- news_provider.authtypes = g_list_append (NULL, &camel_nntp_password_authtype);
-
- camel_provider_register(&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->protocol, u2->protocol)
- && 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-summary.c b/camel/providers/nntp/camel-nntp-store-summary.c
deleted file mode 100644
index 4c7e3df1aa..0000000000
--- a/camel/providers/nntp/camel-nntp-store-summary.c
+++ /dev/null
@@ -1,438 +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-nntp-store-summary.h"
-
-#include "camel-file-utils.h"
-
-#include "libedataserver/md5-utils.h"
-#include "libedataserver/e-memory.h"
-
-#include "camel-private.h"
-#include "camel-utf8.h"
-
-#define d(x)
-#define io(x) /* io debug */
-
-#define CAMEL_NNTP_STORE_SUMMARY_VERSION_0 (0)
-#define CAMEL_NNTP_STORE_SUMMARY_VERSION_1 (1)
-
-#define CAMEL_NNTP_STORE_SUMMARY_VERSION (1)
-
-#define _PRIVATE(o) (((CamelNNTPStoreSummary *)(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_nntp_store_summary_class_init (CamelNNTPStoreSummaryClass *klass);
-static void camel_nntp_store_summary_init (CamelNNTPStoreSummary *obj);
-static void camel_nntp_store_summary_finalise (CamelObject *obj);
-
-static CamelStoreSummaryClass *camel_nntp_store_summary_parent;
-
-static void
-camel_nntp_store_summary_class_init (CamelNNTPStoreSummaryClass *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_nntp_store_summary_init (CamelNNTPStoreSummary *s)
-{
- /*struct _CamelNNTPStoreSummaryPrivate *p;
-
- p = _PRIVATE(s) = g_malloc0(sizeof(*p));*/
-
- ((CamelStoreSummary *) s)->store_info_size = sizeof (CamelNNTPStoreInfo);
- s->version = CAMEL_NNTP_STORE_SUMMARY_VERSION;
- memset (&s->last_newslist, 0, sizeof (s->last_newslist));
-}
-
-static void
-camel_nntp_store_summary_finalise (CamelObject *obj)
-{
- /*struct _CamelNNTPStoreSummaryPrivate *p;*/
- /*CamelNNTPStoreSummary *s = (CamelNNTPStoreSummary *)obj;*/
-
- /*p = _PRIVATE(obj);
- g_free(p);*/
-}
-
-CamelType
-camel_nntp_store_summary_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- camel_nntp_store_summary_parent = (CamelStoreSummaryClass *)camel_store_summary_get_type();
- type = camel_type_register((CamelType)camel_nntp_store_summary_parent, "CamelNNTPStoreSummary",
- sizeof (CamelNNTPStoreSummary),
- sizeof (CamelNNTPStoreSummaryClass),
- (CamelObjectClassInitFunc) camel_nntp_store_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_nntp_store_summary_init,
- (CamelObjectFinalizeFunc) camel_nntp_store_summary_finalise);
- }
-
- return type;
-}
-
-/**
- * camel_nntp_store_summary_new:
- *
- * Create a new CamelNNTPStoreSummary object.
- *
- * Return value: A new CamelNNTPStoreSummary widget.
- **/
-CamelNNTPStoreSummary *
-camel_nntp_store_summary_new (void)
-{
- return (CamelNNTPStoreSummary *) camel_object_new (camel_nntp_store_summary_get_type ());
-}
-
-/**
- * camel_nntp_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().
- **/
-CamelNNTPStoreInfo *
-camel_nntp_store_summary_full_name(CamelNNTPStoreSummary *s, const char *full_name)
-{
- int count, i;
- CamelNNTPStoreInfo *info;
-
- count = camel_store_summary_count ((CamelStoreSummary *) s);
- for (i = 0; i < count; i++) {
- info = (CamelNNTPStoreInfo *)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_nntp_store_summary_full_to_path (CamelNNTPStoreSummary *s, const char *full_name, char dir_sep)
-{
- char *path, *p;
- int c;
- const char *f;
-
- if (dir_sep != '/') {
- p = path = g_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_nntp_store_summary_path_to_full (CamelNNTPStoreSummary *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;
-
- /* check to see if we have a subpath of path already defined */
- subpath = g_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_nntp_store_info_full_name (s, si));
- camel_store_summary_info_free ((CamelStoreSummary *) s, si);
- return f;
- }
-
- f = full = g_alloca (strlen (path)*2+1);
- if (si)
- p = path + strlen (subpath);
- 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_nntp_store_info_full_name (s, si), f);
- g_free (f);
- camel_store_summary_info_free ((CamelStoreSummary *) s, si);
- f = full;
- }
-
- return f;
-}
-
-CamelNNTPStoreInfo *
-camel_nntp_store_summary_add_from_full (CamelNNTPStoreSummary *s, const char *full, char dir_sep)
-{
- CamelNNTPStoreInfo *info;
- char *pathu8;
- int len;
- char *full_name;
-
- d(printf("adding full name '%s' '%c'\n", full, dir_sep));
-
- len = strlen (full);
- full_name = g_alloca (len+1);
- strcpy(full_name, full);
- if (full_name[len-1] == dir_sep)
- full_name[len-1] = 0;
-
- info = camel_nntp_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;
- }
-
- pathu8 = camel_nntp_store_summary_full_to_path (s, full_name, dir_sep);
-
- info = (CamelNNTPStoreInfo *) 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_NNTP_STORE_INFO_FULL_NAME, full_name);
- } else
- d(printf(" failed\n"));
-
- return info;
-}
-
-static int
-summary_header_load (CamelStoreSummary *s, FILE *in)
-{
- CamelNNTPStoreSummary *is = (CamelNNTPStoreSummary *) s;
- gint32 version, nil;
-
- if (camel_nntp_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_NNTP_STORE_SUMMARY_VERSION_0) {
- g_warning("Store summary header version too low");
- return -1;
- }
-
- if (fread (is->last_newslist, 1, NNTP_DATE_SIZE, in) < NNTP_DATE_SIZE)
- return -1;
-
- camel_file_util_decode_fixed_int32 (in, &nil);
-
- return 0;
-}
-
-static int
-summary_header_save (CamelStoreSummary *s, FILE *out)
-{
- CamelNNTPStoreSummary *is = (CamelNNTPStoreSummary *) s;
-
- /* always write as latest version */
- if (camel_nntp_store_summary_parent->summary_header_save ((CamelStoreSummary *) s, out) == -1
- || camel_file_util_encode_fixed_int32 (out, CAMEL_NNTP_STORE_SUMMARY_VERSION) == -1
- || fwrite (is->last_newslist, 1, NNTP_DATE_SIZE, out) < NNTP_DATE_SIZE
- || camel_file_util_encode_fixed_int32 (out, 0) == -1)
- return -1;
-
- return 0;
-}
-
-static CamelStoreInfo *
-store_info_load (CamelStoreSummary *s, FILE *in)
-{
- CamelNNTPStoreInfo *ni;
-
- ni = (CamelNNTPStoreInfo *) camel_nntp_store_summary_parent->store_info_load (s, in);
- if (ni) {
- if (camel_file_util_decode_string (in, &ni->full_name) == -1) {
- camel_store_summary_info_free (s, (CamelStoreInfo *) ni);
- return NULL;
- }
- if (((CamelNNTPStoreSummary *)s)->version >= CAMEL_NNTP_STORE_SUMMARY_VERSION_1) {
- if (camel_file_util_decode_uint32(in, &ni->first) == -1
- || camel_file_util_decode_uint32(in, &ni->last) == -1) {
- camel_store_summary_info_free (s, (CamelStoreInfo *) ni);
- return NULL;
- }
- }
- /* set the URL */
- }
-
- return (CamelStoreInfo *) ni;
-}
-
-static int
-store_info_save (CamelStoreSummary *s, FILE *out, CamelStoreInfo *mi)
-{
- CamelNNTPStoreInfo *isi = (CamelNNTPStoreInfo *)mi;
-
- if (camel_nntp_store_summary_parent->store_info_save (s, out, mi) == -1
- || camel_file_util_encode_string (out, isi->full_name) == -1
- || camel_file_util_encode_uint32(out, isi->first) == -1
- || camel_file_util_encode_uint32(out, isi->last) == -1)
- return -1;
-
- return 0;
-}
-
-static void
-store_info_free (CamelStoreSummary *s, CamelStoreInfo *mi)
-{
- CamelNNTPStoreInfo *nsi = (CamelNNTPStoreInfo *) mi;
-
- g_free (nsi->full_name);
- camel_nntp_store_summary_parent->store_info_free (s, mi);
-}
-
-static const char *
-store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, int type)
-{
- CamelNNTPStoreInfo *nsi = (CamelNNTPStoreInfo *)mi;
-
- /* FIXME: Locks? */
-
- g_assert (mi != NULL);
-
- switch (type) {
- case CAMEL_NNTP_STORE_INFO_FULL_NAME:
- return nsi->full_name;
- default:
- return camel_nntp_store_summary_parent->store_info_string(s, mi, type);
- }
-}
-
-static void
-store_info_set_string(CamelStoreSummary *s, CamelStoreInfo *mi, int type, const char *str)
-{
- CamelNNTPStoreInfo *nsi = (CamelNNTPStoreInfo *)mi;
-
- g_assert(mi != NULL);
-
- switch (type) {
- case CAMEL_NNTP_STORE_INFO_FULL_NAME:
- d(printf("Set full name %s -> %s\n", nsi->full_name, str));
- CAMEL_STORE_SUMMARY_LOCK(s, summary_lock);
- g_free (nsi->full_name);
- nsi->full_name = g_strdup (str);
- CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock);
- break;
- default:
- camel_nntp_store_summary_parent->store_info_set_string (s, mi, type, str);
- break;
- }
-}
diff --git a/camel/providers/nntp/camel-nntp-store-summary.h b/camel/providers/nntp/camel-nntp-store-summary.h
deleted file mode 100644
index 2e442a8166..0000000000
--- a/camel/providers/nntp/camel-nntp-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.
- */
-
-/* currently, this is just a straigt s/imap/nntp from the IMAP file*/
-
-
-#ifndef _CAMEL_NNTP_STORE_SUMMARY_H
-#define _CAMEL_NNTP_STORE_SUMMARY_H
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#include <camel/camel-object.h>
-#include <camel/camel-store-summary.h>
-
-#define CAMEL_NNTP_STORE_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_nntp_store_summary_get_type (), CamelNNTPStoreSummary)
-#define CAMEL_NNTP_STORE_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_nntp_store_summary_get_type (), CamelNNTPStoreSummaryClass)
-#define CAMEL_IS_NNTP_STORE_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_nntp_store_summary_get_type ())
-
-typedef struct _CamelNNTPStoreSummary CamelNNTPStoreSummary;
-typedef struct _CamelNNTPStoreSummaryClass CamelNNTPStoreSummaryClass;
-
-typedef struct _CamelNNTPStoreInfo CamelNNTPStoreInfo;
-
-enum {
- CAMEL_NNTP_STORE_INFO_FULL_NAME = CAMEL_STORE_INFO_LAST,
- CAMEL_NNTP_STORE_INFO_LAST,
-};
-
-struct _CamelNNTPStoreInfo {
- CamelStoreInfo info;
- char *full_name;
- guint32 first; /* from LIST or NEWGROUPS return */
- guint32 last;
-};
-
-#define NNTP_DATE_SIZE 14
-
-struct _CamelNNTPStoreSummary {
- CamelStoreSummary summary;
-
- struct _CamelNNTPStoreSummaryPrivate *priv;
-
- /* header info */
- guint32 version; /* version of base part of file */
- char last_newslist[NNTP_DATE_SIZE];
-};
-
-struct _CamelNNTPStoreSummaryClass {
- CamelStoreSummaryClass summary_class;
-};
-
-CamelType camel_nntp_store_summary_get_type (void);
-CamelNNTPStoreSummary *camel_nntp_store_summary_new (void);
-
-/* TODO: this api needs some more work, needs to support lists */
-/*CamelNNTPStoreNamespace *camel_nntp_store_summary_namespace_new(CamelNNTPStoreSummary *s, const char *full_name, char dir_sep);*/
-/*void camel_nntp_store_summary_namespace_set(CamelNNTPStoreSummary *s, CamelNNTPStoreNamespace *ns);*/
-/*CamelNNTPStoreNamespace *camel_nntp_store_summary_namespace_find_path(CamelNNTPStoreSummary *s, const char *path);*/
-/*CamelNNTPStoreNamespace *camel_nntp_store_summary_namespace_find_full(CamelNNTPStoreSummary *s, const char *full_name);*/
-
-/* helper macro's */
-#define camel_nntp_store_info_full_name(s, i) (camel_store_info_string((CamelStoreSummary *)s, (const CamelStoreInfo *)i, CAMEL_NNTP_STORE_INFO_FULL_NAME))
-
-/* converts to/from utf8 canonical nasmes */
-char *camel_nntp_store_summary_full_to_path(CamelNNTPStoreSummary *s, const char *full_name, char dir_sep);
-
-char *camel_nntp_store_summary_path_to_full(CamelNNTPStoreSummary *s, const char *path, char dir_sep);
-char *camel_nntp_store_summary_dotted_to_full(CamelNNTPStoreSummary *s, const char *dotted, char dir_sep);
-
-CamelNNTPStoreInfo *camel_nntp_store_summary_full_name(CamelNNTPStoreSummary *s, const char *full_name);
-CamelNNTPStoreInfo *camel_nntp_store_summary_add_from_full(CamelNNTPStoreSummary *s, const char *full_name, char dir_sep);
-
-/* a convenience lookup function. always use this if path known */
-char *camel_nntp_store_summary_full_from_path(CamelNNTPStoreSummary *s, const char *path);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* ! _CAMEL_NNTP_STORE_SUMMARY_H */
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
deleted file mode 100644
index f9daad8515..0000000000
--- a/camel/providers/nntp/camel-nntp-store.c
+++ /dev/null
@@ -1,1391 +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/camel-stream-mem.h>
-#include <camel/camel-data-cache.h>
-
-#include <camel/camel-disco-store.h>
-#include <camel/camel-disco-diary.h>
-#include "camel/camel-private.h"
-#include <camel/camel-debug.h>
-
-#include "camel-nntp-summary.h"
-#include "camel-nntp-store.h"
-#include "camel-nntp-store-summary.h"
-#include "camel-nntp-folder.h"
-#include "camel-nntp-private.h"
-#include "camel-nntp-resp-codes.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
-
-#define w(x)
-#define dd(x) (camel_debug("nntp")?(x):0)
-
-#define NNTP_PORT "119"
-#define NNTPS_PORT "563"
-
-#define DUMP_EXTENSIONS
-
-static CamelDiscoStoreClass *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))
-
-static int camel_nntp_try_authenticate (CamelNNTPStore *store, CamelException *ex);
-
-static void nntp_construct (CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- CamelException *ex);
-
-
-static gboolean
-nntp_can_work_offline(CamelDiscoStore *store)
-{
- return TRUE;
-}
-
-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(CamelNNTPStore *store, CamelException *ex)
-{
- int ret, i;
- char *line;
- unsigned int len;
- unsigned char c, *p;
- struct _xover_header *xover, *last;
-
- /* manual override */
- if (store->xover || getenv("CAMEL_NNTP_DISABLE_XOVER") != NULL)
- return 0;
-
- ret = camel_nntp_raw_command_auth(store, ex, &line, "list overview.fmt");
- if (ret == -1) {
- return -1;
- } else if (ret != 215)
- /* unsupported command? ignore */
- return 0;
-
- last = (struct _xover_header *)&store->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] = camel_tolower(c);
- }
- }
- }
-
- return ret;
-}
-
-enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
-#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, struct addrinfo *ai, int ssl_mode, CamelException *ex)
-{
- CamelNNTPStore *store = (CamelNNTPStore *) service;
- CamelDiscoStore *disco_store = (CamelDiscoStore*) service;
- CamelStream *tcp_stream;
- gboolean retval = FALSE;
- unsigned char *buf;
- unsigned int len;
- int ret;
- char *path;
-
- CAMEL_SERVICE_LOCK(store, connect_lock);
-
- /* setup store-wide cache */
- if (store->cache == NULL) {
- if (store->storage_path == NULL)
- goto fail;
-
- store->cache = camel_data_cache_new (store->storage_path, 0, ex);
- 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);
- }
-
- if (ssl_mode != MODE_CLEAR) {
-#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
-
- goto fail;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -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: %s"),
- service->url->host,
- g_strerror (errno));
-
- camel_object_unref (tcp_stream);
-
- goto fail;
- }
-
- store->stream = (CamelNNTPStream *) camel_nntp_stream_new (tcp_stream);
- camel_object_unref (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 (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 (store->stream);
- store->stream = NULL;
-
- goto fail;
- }
-
- /* if we have username, try it here */
- if (service->url->user != NULL
- && camel_nntp_try_authenticate(store, ex) != NNTP_AUTH_ACCEPTED)
- goto fail;
-
- /* set 'reader' mode & ignore return code, also ping the server, inn goes offline very quickly otherwise */
- if (camel_nntp_raw_command_auth (store, ex, (char **) &buf, "mode reader") == -1
- || camel_nntp_raw_command_auth (store, ex, (char **) &buf, "date") == -1)
- goto fail;
-
- if (xover_setup(store, ex) == -1)
- goto fail;
-
- path = g_build_filename (store->storage_path, ".ev-journal", NULL);
- disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
- g_free (path);
-
- retval = TRUE;
-
- g_free(store->current_folder);
- store->current_folder = NULL;
-
- fail:
- CAMEL_SERVICE_UNLOCK(store, connect_lock);
- return retval;
-}
-
-static struct {
- char *value;
- char *serv;
- char *port;
- int mode;
-} ssl_options[] = {
- { "", "nntps", NNTPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "nntps", NNTPS_PORT, MODE_SSL },
- { "when-possible", "nntp", NNTP_PORT, MODE_TLS },
- { "never", "nntp", NNTP_PORT, MODE_CLEAR },
- { NULL, "nntp", NNTP_PORT, MODE_CLEAR },
-};
-
-static gboolean
-nntp_connect_online (CamelService *service, CamelException *ex)
-{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
- break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
- } else {
- mode = MODE_CLEAR;
- serv = "nntp";
- port = NNTP_PORT;
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- ret = connect_to_server (service, ai, mode, ex);
-
- camel_freeaddrinfo (ai);
-
- return ret;
-}
-
-static gboolean
-nntp_connect_offline (CamelService *service, CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE(service);
- CamelDiscoStore *disco_store = (CamelDiscoStore *) nntp_store;
- char *path;
-
- if (nntp_store->storage_path == NULL)
- return FALSE;
-
- /* setup store-wide cache */
- if (nntp_store->cache == NULL) {
- nntp_store->cache = camel_data_cache_new (nntp_store->storage_path, 0, ex);
- if (nntp_store->cache == NULL)
- return FALSE;
-
- /* Default cache expiry - 2 weeks old, or not visited in 5 days */
- camel_data_cache_set_expire_age (nntp_store->cache, 60*60*24*14);
- camel_data_cache_set_expire_access (nntp_store->cache, 60*60*24*5);
- }
-
- path = g_build_filename (nntp_store->storage_path, ".ev-journal", NULL);
- disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
- g_free (path);
-
- if (!disco_store->diary)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-nntp_disconnect_online (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
- char *line;
-
- CAMEL_SERVICE_LOCK(store, connect_lock);
-
- if (clean) {
- camel_nntp_raw_command (store, ex, &line, "quit");
- camel_exception_clear(ex);
- }
-
- if (!service_class->disconnect (service, clean, ex)) {
- CAMEL_SERVICE_UNLOCK(store, connect_lock);
- return FALSE;
- }
-
- camel_object_unref (store->stream);
- store->stream = NULL;
- g_free(store->current_folder);
- store->current_folder = NULL;
-
- CAMEL_SERVICE_UNLOCK(store, connect_lock);
-
- return TRUE;
-}
-
-static gboolean
-nntp_disconnect_offline (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelDiscoStore *disco = CAMEL_DISCO_STORE(service);
-
- if (!service_class->disconnect (service, clean, ex))
- return FALSE;
-
- if (disco->diary) {
- camel_object_unref (disco->diary);
- disco->diary = NULL;
- }
-
- 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);
-
-}
-
-extern CamelServiceAuthType camel_nntp_password_authtype;
-
-static GList *
-nntp_store_query_auth_types (CamelService *service, CamelException *ex)
-{
- return g_list_append (NULL, &camel_nntp_password_authtype);
-}
-
-static CamelFolder *
-nntp_get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
- CamelFolder *folder;
-
- CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
-
- folder = camel_nntp_folder_new(store, folder_name, ex);
-
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
-
- return folder;
-}
-
-/*
- * Converts a fully-fledged newsgroup name to a name in short dotted notation,
- * e.g. nl.comp.os.linux.programmeren becomes n.c.o.l.programmeren
- */
-
-static char *
-nntp_newsgroup_name_short (const char *name)
-{
- char *resptr, *tmp;
- const char *ptr2;
-
- resptr = tmp = g_malloc0 (strlen (name) + 1);
-
- while ((ptr2 = strchr (name, '.'))) {
- if (ptr2 == name) {
- name++;
- continue;
- }
-
- *resptr++ = *name;
- *resptr++ = '.';
- name = ptr2 + 1;
- }
-
- strcpy (resptr, name);
- return tmp;
-}
-
-/*
- * This function converts a NNTPStoreSummary item to a FolderInfo item that
- * can be returned by the get_folders() call to the store. Both structs have
- * essentially the same fields.
- */
-
-static CamelFolderInfo *
-nntp_folder_info_from_store_info (CamelNNTPStore *store, gboolean short_notation, CamelStoreInfo *si)
-{
- CamelURL *base_url = ((CamelService *) store)->url;
- CamelFolderInfo *fi = g_malloc0(sizeof(*fi));
- CamelURL *url;
- char *path;
-
- fi->full_name = g_strdup (si->path);
-
- if (short_notation)
- fi->name = nntp_newsgroup_name_short (si->path);
- else
- fi->name = g_strdup (si->path);
-
- fi->unread = si->unread;
- fi->total = si->total;
- path = alloca(strlen(fi->full_name)+2);
- sprintf(path, "/%s", fi->full_name);
- url = camel_url_new_with_base (base_url, path);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
-
- return fi;
-}
-
-static CamelFolderInfo *
-nntp_folder_info_from_name (CamelNNTPStore *store, gboolean short_notation, const char *name)
-{
- CamelFolderInfo *fi = g_malloc0(sizeof(*fi));
- CamelURL *base_url = ((CamelService *)store)->url;
- CamelURL *url;
- char *path;
-
- fi->full_name = g_strdup (name);
-
- if (short_notation)
- fi->name = nntp_newsgroup_name_short (name);
- else
- fi->name = g_strdup (name);
-
- fi->unread = -1;
-
- path = alloca(strlen(fi->full_name)+2);
- sprintf(path, "/%s", fi->full_name);
- url = camel_url_new_with_base (base_url, path);
- fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
-
- return fi;
-}
-
-/* handle list/newgroups response */
-static CamelNNTPStoreInfo *
-nntp_store_info_update(CamelNNTPStore *store, char *line)
-{
- CamelStoreSummary *summ = (CamelStoreSummary *)store->summary;
- CamelURL *base_url = ((CamelService *)store)->url;
- CamelNNTPStoreInfo *si, *fsi;
- CamelURL *url;
- char *relpath, *tmp;
- guint32 last = 0, first = 0, new = 0;
-
- tmp = strchr(line, ' ');
- if (tmp)
- *tmp++ = 0;
-
- fsi = si = (CamelNNTPStoreInfo *)camel_store_summary_path((CamelStoreSummary *)store->summary, line);
- if (si == NULL) {
- si = (CamelNNTPStoreInfo*)camel_store_summary_info_new(summ);
-
- relpath = g_alloca(strlen(line)+2);
- sprintf(relpath, "/%s", line);
- url = camel_url_new_with_base (base_url, relpath);
- si->info.uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
- camel_url_free (url);
-
- si->info.path = g_strdup (line);
- si->full_name = g_strdup (line); /* why do we keep this? */
- camel_store_summary_add((CamelStoreSummary *)store->summary, &si->info);
- } else {
- first = si->first;
- last = si->last;
- }
-
- if (tmp && *tmp >= '0' && *tmp <= '9') {
- last = strtoul(tmp, &tmp, 10);
- if (*tmp == ' ' && tmp[1] >= '0' && tmp[1] <= '9') {
- first = strtoul(tmp+1, &tmp, 10);
- if (*tmp == ' ' && tmp[1] != 'y')
- si->info.flags |= CAMEL_STORE_INFO_FOLDER_READONLY;
- }
- }
-
- printf("store info update '%s' first '%d' last '%d'\n", line, first, last);
-
- if (si->last) {
- if (last > si->last)
- new = last-si->last;
- } else {
- if (last > first)
- new = last - first;
- }
-
- si->info.total = last > first?last-first:0;
- si->info.unread += new; /* this is a _guess_ */
- si->last = last;
- si->first = first;
-
- if (fsi)
- camel_store_summary_info_free((CamelStoreSummary *)store->summary, &fsi->info);
- else /* TODO see if we really did touch it */
- camel_store_summary_touch ((CamelStoreSummary *)store->summary);
-
- return si;
-}
-
-static CamelFolderInfo *
-nntp_store_get_subscribed_folder_info (CamelNNTPStore *store, const char *top, guint flags, CamelException *ex)
-{
- int i;
- CamelStoreInfo *si;
- CamelFolderInfo *first = NULL, *last = NULL, *fi = NULL;
-
- /* since we do not do a tree, any request that is not for root is sure to give no results */
- if (top != NULL && top[0] != 0)
- return NULL;
-
- for (i=0;(si = camel_store_summary_index ((CamelStoreSummary *) store->summary, i));i++) {
- if (si == NULL)
- continue;
-
- if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
- /* slow mode? open and update the folder, always! this will implictly update
- our storeinfo too; in a very round-about way */
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) {
- CamelNNTPFolder *folder;
- char *line;
-
- folder = (CamelNNTPFolder *)camel_store_get_folder((CamelStore *)store, si->path, 0, ex);
- if (folder) {
- CAMEL_SERVICE_LOCK(store, connect_lock);
- camel_nntp_command(store, ex, folder, &line, NULL);
- CAMEL_SERVICE_UNLOCK(store, connect_lock);
- camel_object_unref(folder);
- }
- camel_exception_clear(ex);
- }
- fi = nntp_folder_info_from_store_info (store, store->do_short_folder_notation, si);
- fi->flags |= CAMEL_FOLDER_NOINFERIORS | CAMEL_FOLDER_NOCHILDREN | CAMEL_FOLDER_SYSTEM;
- if (last)
- last->next = fi;
- else
- first = fi;
- last = fi;
- }
- camel_store_summary_info_free ((CamelStoreSummary *) store->summary, si);
- }
-
- return first;
-}
-
-/*
- * get folder info, using the information in our StoreSummary
- */
-static CamelFolderInfo *
-nntp_store_get_cached_folder_info (CamelNNTPStore *store, const char *orig_top, guint flags, CamelException *ex)
-{
- int i;
- int subscribed_or_flag = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) ? 0 : 1,
- root_or_flag = (orig_top == NULL || orig_top[0] == '\0') ? 1 : 0,
- recursive_flag = flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE;
- CamelStoreInfo *si;
- CamelFolderInfo *first = NULL, *last = NULL, *fi = NULL;
- char *tmpname;
- char *top = g_strconcat(orig_top?orig_top:"", ".", NULL);
- int toplen = strlen(top);
-
- for (i = 0; (si = camel_store_summary_index ((CamelStoreSummary *) store->summary, i)); i++) {
- if ((subscribed_or_flag || (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))
- && (root_or_flag || strncmp (si->path, top, toplen) == 0)) {
- if (recursive_flag || strchr (si->path + toplen, '.') == NULL) {
- /* add the item */
- fi = nntp_folder_info_from_store_info(store, FALSE, si);
- if (!fi)
- continue;
- if (store->folder_hierarchy_relative) {
- g_free (fi->name);
- fi->name = g_strdup (si->path + ((toplen == 1) ? 0 : toplen));
- }
- } else {
- /* apparently, this is an indirect subitem. if it's not a subitem of
- the item we added last, we need to add a portion of this item to
- the list as a placeholder */
- if (!last ||
- strncmp(si->path, last->full_name, strlen(last->full_name)) != 0 ||
- si->path[strlen(last->full_name)] != '.') {
- tmpname = g_strdup(si->path);
- *(strchr(tmpname + toplen, '.')) = '\0';
- fi = nntp_folder_info_from_name(store, FALSE, tmpname);
- fi->flags |= CAMEL_FOLDER_NOSELECT;
- if (store->folder_hierarchy_relative) {
- g_free(fi->name);
- fi->name = g_strdup(tmpname + ((toplen==1) ? 0 : toplen));
- }
- g_free(tmpname);
- } else {
- continue;
- }
- }
- if (last)
- last->next = fi;
- else
- first = fi;
- last = fi;
- } else if (subscribed_or_flag && first) {
- /* we have already added subitems, but this item is no longer a subitem */
- camel_store_summary_info_free((CamelStoreSummary *)store->summary, si);
- break;
- }
- camel_store_summary_info_free((CamelStoreSummary *)store->summary, si);
- }
-
- g_free(top);
- return first;
-}
-
-/* retrieves the date from the NNTP server */
-static gboolean
-nntp_get_date(CamelNNTPStore *nntp_store, CamelException *ex)
-{
- unsigned char *line;
- int ret = camel_nntp_command(nntp_store, ex, NULL, (char **)&line, "date");
- char *ptr;
-
- nntp_store->summary->last_newslist[0] = 0;
-
- if (ret == 111) {
- ptr = line + 3;
- while (*ptr == ' ' || *ptr == '\t')
- ptr++;
-
- if (strlen (ptr) == NNTP_DATE_SIZE) {
- memcpy (nntp_store->summary->last_newslist, ptr, NNTP_DATE_SIZE);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static void
-store_info_remove(void *key, void *value, void *data)
-{
- CamelStoreSummary *summary = data;
- CamelStoreInfo *si = value;
-
- camel_store_summary_remove(summary, si);
-}
-
-static gint
-store_info_sort (gconstpointer a, gconstpointer b)
-{
- return strcmp ((*(CamelNNTPStoreInfo**) a)->full_name, (*(CamelNNTPStoreInfo**) b)->full_name);
-}
-
-static CamelFolderInfo *
-nntp_store_get_folder_info_all(CamelNNTPStore *nntp_store, const char *top, guint32 flags, gboolean online, CamelException *ex)
-{
- CamelNNTPStoreSummary *summary = nntp_store->summary;
- CamelNNTPStoreInfo *si;
- unsigned int len;
- unsigned char *line;
- int ret = -1;
- CamelFolderInfo *fi = NULL;
-
- CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
-
- if (top == NULL)
- top = "";
-
- if (online && (top == NULL || top[0] == 0)) {
- /* we may need to update */
- if (summary->last_newslist[0] != 0) {
- char date[14];
- memcpy(date, summary->last_newslist + 2, 6); /* YYMMDDD */
- date[6] = ' ';
- memcpy(date + 7, summary->last_newslist + 8, 6); /* HHMMSS */
- date[13] = '\0';
-
- if (!nntp_get_date (nntp_store, ex))
- goto error;
-
- ret = camel_nntp_command (nntp_store, ex, NULL, (char **) &line, "newgroups %s", date);
- if (ret == -1)
- goto error;
- else if (ret != 231) {
- /* newgroups not supported :S so reload the complete list */
- summary->last_newslist[0] = 0;
- goto do_complete_list;
- }
-
- while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len)) > 0)
- nntp_store_info_update(nntp_store, line);
- } else {
- GHashTable *all;
- int i;
-
- do_complete_list:
- /* seems we do need a complete list */
- /* at first, we do a DATE to find out the last load occasion */
- if (!nntp_get_date (nntp_store, ex))
- goto error;
-
- ret = camel_nntp_command (nntp_store, ex, NULL, (char **)&line, "list");
- if (ret == -1)
- goto error;
- else if (ret != 215) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_INVALID,
- _("Error retrieving newsgroups:\n\n%s"), line);
- goto error;
- }
-
- all = g_hash_table_new(g_str_hash, g_str_equal);
- for (i = 0; (si = (CamelNNTPStoreInfo *)camel_store_summary_index ((CamelStoreSummary *)nntp_store->summary, i)); i++)
- g_hash_table_insert(all, si->info.path, si);
-
- while ((ret = camel_nntp_stream_line(nntp_store->stream, &line, &len)) > 0) {
- si = nntp_store_info_update(nntp_store, line);
- g_hash_table_remove(all, si->info.path);
- }
-
- g_hash_table_foreach(all, store_info_remove, nntp_store->summary);
- g_hash_table_destroy(all);
- }
-
- /* sort the list */
- g_ptr_array_sort (CAMEL_STORE_SUMMARY (nntp_store->summary)->folders, store_info_sort);
- if (ret < 0)
- goto error;
-
- camel_store_summary_save ((CamelStoreSummary *) nntp_store->summary);
- }
-
- fi = nntp_store_get_cached_folder_info (nntp_store, top, flags, ex);
- error:
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
-
- return fi;
-}
-
-static CamelFolderInfo *
-nntp_get_folder_info (CamelStore *store, const char *top, guint32 flags, gboolean online, CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE(store);
- CamelFolderInfo *first = NULL;
-
- dd(printf("g_f_i: fast %d subscr %d recursive %d online %d top \"%s\"\n",
- flags & CAMEL_STORE_FOLDER_INFO_FAST,
- flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
- flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE,
- online,
- top?top:""));
-
- if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
- first = nntp_store_get_subscribed_folder_info (nntp_store, top, flags, ex);
- else
- first = nntp_store_get_folder_info_all (nntp_store, top, flags, online, ex);
-
- return first;
-}
-
-static CamelFolderInfo *
-nntp_get_folder_info_online (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- return nntp_get_folder_info (store, top, flags, TRUE, ex);
-}
-
-static CamelFolderInfo *
-nntp_get_folder_info_offline(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- return nntp_get_folder_info (store, top, flags, FALSE, ex);
-}
-
-static gboolean
-nntp_store_folder_subscribed (CamelStore *store, const char *folder_name)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
- CamelStoreInfo *si;
- int truth = FALSE;
-
- si = camel_store_summary_path ((CamelStoreSummary *) nntp_store->summary, folder_name);
- if (si) {
- truth = (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0;
- camel_store_summary_info_free ((CamelStoreSummary *) nntp_store->summary, si);
- }
-
- return truth;
-}
-
-static void
-nntp_store_subscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE(store);
- CamelStoreInfo *si;
- CamelFolderInfo *fi;
-
- CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
-
- si = camel_store_summary_path(CAMEL_STORE_SUMMARY(nntp_store->summary), folder_name);
- if (!si) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
- _("You cannot subscribe to this newsgroup:\n\n"
- "No such newsgroup. The selected item is a probably a parent folder."));
- } else {
- if (!(si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)) {
- si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- fi = nntp_folder_info_from_store_info(nntp_store, nntp_store->do_short_folder_notation, si);
- fi->flags |= CAMEL_FOLDER_NOINFERIORS | CAMEL_FOLDER_NOCHILDREN;
- camel_store_summary_touch ((CamelStoreSummary *) nntp_store->summary);
- camel_store_summary_save ((CamelStoreSummary *) nntp_store->summary);
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
- camel_object_trigger_event ((CamelObject *) nntp_store, "folder_subscribed", fi);
- camel_folder_info_free (fi);
- return;
- }
- }
-
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
-}
-
-static void
-nntp_store_unsubscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE(store);
- CamelFolderInfo *fi;
- CamelStoreInfo *fitem;
- CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
-
- fitem = camel_store_summary_path(CAMEL_STORE_SUMMARY(nntp_store->summary), folder_name);
-
- if (!fitem) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
- _("You cannot unsubscribe to this newsgroup:\n\n"
- "newsgroup does not exist!"));
- } else {
- if (fitem->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
- fitem->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
- fi = nntp_folder_info_from_store_info (nntp_store, nntp_store->do_short_folder_notation, fitem);
- camel_store_summary_touch ((CamelStoreSummary *) nntp_store->summary);
- camel_store_summary_save ((CamelStoreSummary *) nntp_store->summary);
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
- camel_object_trigger_event ((CamelObject *) nntp_store, "folder_unsubscribed", fi);
- camel_folder_info_free (fi);
- return;
- }
- }
-
- CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
-}
-
-/* stubs for various folder operations we're not implementing */
-
-static CamelFolderInfo *
-nntp_create_folder (CamelStore *store, const char *parent_name,
- const char *folder_name, CamelException *ex)
-{
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
- _("You cannot create a folder in a News store: subscribe instead."));
- return NULL;
-}
-
-static void
-nntp_rename_folder (CamelStore *store, const char *old_name, const char *new_name_in, CamelException *ex)
-{
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
- _("You cannot rename a folder in a News store."));
-}
-
-static void
-nntp_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- nntp_store_subscribe_folder (store, folder_name, ex);
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
- _("You cannot remove a folder in a News store: unsubscribe instead."));
- return;
-}
-
-static void
-nntp_store_finalize (CamelObject *object)
-{
- /* call base finalize */
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (object);
- struct _CamelNNTPStorePrivate *p = nntp_store->priv;
- struct _xover_header *xover, *xn;
-
- camel_service_disconnect ((CamelService *)object, TRUE, NULL);
-
- if (nntp_store->summary) {
- camel_store_summary_save ((CamelStoreSummary *) nntp_store->summary);
- camel_object_unref (nntp_store->summary);
- }
-
- camel_object_unref (nntp_store->mem);
- nntp_store->mem = NULL;
- if (nntp_store->stream)
- camel_object_unref (nntp_store->stream);
-
- if (nntp_store->base_url)
- g_free (nntp_store->base_url);
- if (nntp_store->storage_path)
- g_free (nntp_store->storage_path);
-
- xover = nntp_store->xover;
- while (xover) {
- xn = xover->next;
- g_free(xover);
- xover = xn;
- }
-
- g_free(p);
-}
-
-static void
-nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class)
-{
- CamelDiscoStoreClass *camel_disco_store_class = CAMEL_DISCO_STORE_CLASS (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_DISCO_STORE_CLASS (camel_type_get_global_classfuncs (camel_disco_store_get_type ()));
- service_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ()));
-
- /* virtual method overload */
- camel_service_class->construct = nntp_construct;
- camel_service_class->query_auth_types = nntp_store_query_auth_types;
- camel_service_class->get_name = nntp_store_get_name;
-
- camel_disco_store_class->can_work_offline = nntp_can_work_offline;
- camel_disco_store_class->connect_online = nntp_connect_online;
- camel_disco_store_class->connect_offline = nntp_connect_offline;
- camel_disco_store_class->disconnect_online = nntp_disconnect_online;
- camel_disco_store_class->disconnect_offline = nntp_disconnect_offline;
- camel_disco_store_class->get_folder_online = nntp_get_folder;
- camel_disco_store_class->get_folder_resyncing = nntp_get_folder;
- camel_disco_store_class->get_folder_offline = nntp_get_folder;
-
- camel_disco_store_class->get_folder_info_online = nntp_get_folder_info_online;
- camel_disco_store_class->get_folder_info_resyncing = nntp_get_folder_info_online;
- camel_disco_store_class->get_folder_info_offline = nntp_get_folder_info_offline;
-
- 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;
-
- camel_store_class->create_folder = nntp_create_folder;
- camel_store_class->delete_folder = nntp_delete_folder;
- camel_store_class->rename_folder = nntp_rename_folder;
-}
-
-/* construction function in which we set some basic store properties */
-static void
-nntp_construct (CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- CamelException *ex)
-{
- CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE(service);
- CamelURL *summary_url;
- char *tmp;
-
- /* construct the parent first */
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
- if (camel_exception_is_set (ex))
- return;
-
- /* find out the storage path, base url */
- nntp_store->storage_path = camel_session_get_storage_path (session, service, ex);
- if (!nntp_store->storage_path)
- return;
-
- /* FIXME */
- nntp_store->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
- CAMEL_URL_HIDE_PARAMS |
- CAMEL_URL_HIDE_AUTH));
-
- tmp = g_build_filename (nntp_store->storage_path, ".ev-store-summary", NULL);
- nntp_store->summary = camel_nntp_store_summary_new ();
- camel_store_summary_set_filename ((CamelStoreSummary *) nntp_store->summary, tmp);
- summary_url = camel_url_new (nntp_store->base_url, NULL);
- camel_store_summary_set_uri_base ((CamelStoreSummary *) nntp_store->summary, summary_url);
- g_free (tmp);
-
- camel_url_free (summary_url);
- if (camel_store_summary_load ((CamelStoreSummary *)nntp_store->summary) == 0)
- ;
-
- /* get options */
- if (camel_url_get_param (url, "show_short_notation"))
- nntp_store->do_short_folder_notation = TRUE;
- else
- nntp_store->do_short_folder_notation = FALSE;
- if (camel_url_get_param (url, "folder_hierarchy_relative"))
- nntp_store->folder_hierarchy_relative = TRUE;
- else
- nntp_store->folder_hierarchy_relative = FALSE;
-}
-
-
-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));
-}
-
-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_DISCO_STORE_TYPE,
- "CamelNNTPStore",
- sizeof (CamelNNTPStore),
- sizeof (CamelNNTPStoreClass),
- (CamelObjectClassInitFunc) nntp_store_class_init,
- NULL,
- (CamelObjectInitFunc) nntp_store_init,
- (CamelObjectFinalizeFunc) nntp_store_finalize);
- }
-
- return camel_nntp_store_type;
-}
-
-static int
-camel_nntp_try_authenticate (CamelNNTPStore *store, CamelException *ex)
-{
- CamelService *service = (CamelService *) store;
- CamelSession *session = camel_service_get_session (service);
- int ret;
- char *line = NULL;
-
- if (!service->url->user) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_INVALID_PARAM,
- _("Authentication requested but no username provided"));
- return -1;
- }
-
- /* if nessecary, prompt for the password */
- if (!service->url->passwd) {
- char *prompt, *base;
- retry:
- base = g_strdup_printf (_("Please enter the NNTP password for %s@%s"),
- service->url->user,
- service->url->host);
- if (line) {
- char *top = g_strdup_printf(_("Cannot authenticate to server: %s"), line);
-
- prompt = g_strdup_printf("%s\n\n%s", top, base);
- g_free(top);
- } else {
- prompt = base;
- base = NULL;
- }
-
- service->url->passwd =
- camel_session_get_password (session, service, NULL,
- prompt, "password", CAMEL_SESSION_PASSWORD_SECRET, ex);
- g_free(prompt);
- g_free(base);
-
- if (!service->url->passwd)
- return -1;
- }
-
- /* now, send auth info (currently, only authinfo user/pass is supported) */
- ret = camel_nntp_raw_command(store, ex, &line, "authinfo user %s", service->url->user);
- if (ret == NNTP_AUTH_CONTINUE)
- ret = camel_nntp_raw_command(store, ex, &line, "authinfo pass %s", service->url->passwd);
-
- if (ret != NNTP_AUTH_ACCEPTED) {
- if (ret != -1) {
- /* Need to forget the password here since we have no context on it */
- camel_session_forget_password(session, service, NULL, "password", ex);
- goto retry;
- }
- return -1;
- }
-
- return ret;
-}
-
-/* Enter owning lock */
-int
-camel_nntp_raw_commandv (CamelNNTPStore *store, CamelException *ex, char **line, const char *fmt, va_list ap)
-{
- const unsigned char *p, *ps;
- unsigned char c;
- char *s;
- int d;
- unsigned int u, u2;
-
- e_mutex_assert_locked(((CamelService *)store)->priv->connect_lock);
- g_assert(store->stream->mode != CAMEL_NNTP_STREAM_DATA);
-
- camel_nntp_stream_set_mode(store->stream, CAMEL_NNTP_STREAM_LINE);
-
- 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);
-
- if (camel_stream_write((CamelStream *) store->stream, store->mem->buffer->data, store->mem->buffer->len) == -1)
- goto ioerror;
-
- /* FIXME: hack */
- camel_stream_reset ((CamelStream *) store->mem);
- g_byte_array_set_size (store->mem->buffer, 0);
-
- if (camel_nntp_stream_line (store->stream, (unsigned char **) line, &u) == -1)
- goto ioerror;
-
- 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;
-
-ioerror:
- if (errno == EINTR)
- camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled."));
- else
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("NNTP Command failed: %s"), g_strerror(errno));
- return -1;
-}
-
-int
-camel_nntp_raw_command(CamelNNTPStore *store, CamelException *ex, char **line, const char *fmt, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = camel_nntp_raw_commandv(store, ex, line, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-/* use this where you also need auth to be handled, i.e. most cases where you'd try raw command */
-int
-camel_nntp_raw_command_auth(CamelNNTPStore *store, CamelException *ex, char **line, const char *fmt, ...)
-{
- int ret, retry, go;
- va_list ap;
-
- retry = 0;
-
- do {
- go = FALSE;
- retry++;
-
- va_start(ap, fmt);
- ret = camel_nntp_raw_commandv(store, ex, line, fmt, ap);
- va_end(ap);
-
- if (ret == NNTP_AUTH_REQUIRED) {
- if (camel_nntp_try_authenticate(store, ex) != NNTP_AUTH_ACCEPTED)
- return -1;
- go = TRUE;
- }
- } while (retry < 3 && go);
-
- return ret;
-}
-
-int
-camel_nntp_command (CamelNNTPStore *store, CamelException *ex, CamelNNTPFolder *folder, char **line, const char *fmt, ...)
-{
- const unsigned char *p;
- va_list ap;
- int ret, retry;
- unsigned int u;
-
- e_mutex_assert_locked(((CamelService *)store)->priv->connect_lock);
-
- if (((CamelDiscoStore *)store)->status == CAMEL_DISCO_STORE_OFFLINE) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SERVICE_NOT_CONNECTED,
- _("Not connected."));
- return -1;
- }
-
- retry = 0;
- do {
- retry ++;
-
- if (store->stream == NULL
- && !camel_service_connect (CAMEL_SERVICE (store), ex))
- 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);
-
- if (folder != NULL
- && (store->current_folder == NULL || strcmp(store->current_folder, ((CamelFolder *)folder)->full_name) != 0)) {
- ret = camel_nntp_raw_command_auth(store, ex, line, "group %s", ((CamelFolder *)folder)->full_name);
- if (ret == 211) {
- g_free(store->current_folder);
- store->current_folder = g_strdup(((CamelFolder *)folder)->full_name);
- camel_nntp_folder_selected(folder, *line, ex);
- if (camel_exception_is_set(ex)) {
- ret = -1;
- goto error;
- }
- } else {
- goto error;
- }
- }
-
- /* dummy fmt, we just wanted to select the folder */
- if (fmt == NULL)
- return 0;
-
- va_start(ap, fmt);
- ret = camel_nntp_raw_commandv(store, ex, line, fmt, ap);
- va_end(ap);
- error:
- switch (ret) {
- case NNTP_AUTH_REQUIRED:
- if (camel_nntp_try_authenticate(store, ex) != NNTP_AUTH_ACCEPTED)
- return -1;
- retry--;
- ret = -1;
- continue;
- case 411: /* no such group */
- camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID,
- _("No such folder: %s"), line);
- return -1;
- case 400: /* service discontinued */
- case 401: /* wrong client state - this should quit but this is what the old code did */
- case 503: /* information not available - this should quit but this is what the old code did (?) */
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- ret = -1;
- continue;
- case -1: /* i/o error */
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- if (camel_exception_get_id(ex) == CAMEL_EXCEPTION_USER_CANCEL || retry >= 3)
- return -1;
- camel_exception_clear(ex);
- break;
- }
- } while (ret == -1 && retry < 3);
-
- return ret;
-}
diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h
deleted file mode 100644
index a9bd682cbd..0000000000
--- a/camel/providers/nntp/camel-nntp-store.h
+++ /dev/null
@@ -1,114 +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-disco-store.h>
-
-#include "camel-nntp-stream.h"
-#include "camel-nntp-store-summary.h"
-
-struct _CamelNNTPFolder;
-struct _CamelException;
-
-#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;
-
-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 _CamelNNTPStore {
- CamelDiscoStore parent_object;
-
- struct _CamelNNTPStorePrivate *priv;
-
- guint32 extensions;
-
- unsigned int posting_allowed:1;
- unsigned int do_short_folder_notation:1;
- unsigned int folder_hierarchy_relative:1;
-
- struct _CamelNNTPStoreSummary *summary;
-
- struct _CamelNNTPStream *stream;
- struct _CamelStreamMem *mem;
-
- struct _CamelDataCache *cache;
-
- char *current_folder, *storage_path, *base_url;
-
- struct _xover_header *xover;
-};
-
-struct _CamelNNTPStoreClass {
- CamelDiscoStoreClass parent_class;
-
-};
-
-/* Standard Camel function */
-CamelType camel_nntp_store_get_type (void);
-
-int camel_nntp_raw_commandv (CamelNNTPStore *store, struct _CamelException *ex, char **line, const char *fmt, va_list ap);
-int camel_nntp_raw_command(CamelNNTPStore *store, struct _CamelException *ex, char **line, const char *fmt, ...);
-int camel_nntp_raw_command_auth(CamelNNTPStore *store, struct _CamelException *ex, char **line, const char *fmt, ...);
-int camel_nntp_command (CamelNNTPStore *store, struct _CamelException *ex, struct _CamelNNTPFolder *folder, char **line, const char *fmt, ...);
-
-#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 244b67acb1..0000000000
--- a/camel/providers/nntp/camel-nntp-stream.c
+++ /dev/null
@@ -1,464 +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"
-#include "camel-debug.h"
-
-#define dd(x) (camel_debug("nntp:stream")?(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_SIZE (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 {
- if (left == 0)
- errno = ECONNRESET;
- dd(printf("NNTP_STREAM_FILL(ERROR): %d - '%s'\n", left, 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_SIZE+1);
- is->lineend = is->linebuf + CAMEL_NNTP_STREAM_LINE_SIZE;
-
- /* 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 e6c02b95af..0000000000
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ /dev/null
@@ -1,507 +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/camel-i18n.h"
-#include "camel/camel-debug.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))*/
-#define dd(x) (camel_debug("nntp")?(x):0)
-
-#define CAMEL_NNTP_SUMMARY_VERSION (1)
-
-struct _CamelNNTPSummaryPrivate {
- char *uid;
-
- struct _xover_header *xover; /* xoverview format */
- int xover_setup;
-};
-
-#define _PRIVATE(o) (((CamelNNTPSummary *)(o))->priv)
-
-static CamelMessageInfo * message_info_new_from_header (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_from_header = message_info_new_from_header;
- 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(CamelMessageInfoBase);
- 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);
-
- g_free(cns->priv);
-}
-
-CamelNNTPSummary *
-camel_nntp_summary_new(struct _CamelFolder *folder, const char *path)
-{
- CamelNNTPSummary *cns = (CamelNNTPSummary *)camel_object_new(camel_nntp_summary_get_type());
-
- ((CamelFolderSummary *)cns)->folder = folder;
-
- camel_folder_summary_set_filename((CamelFolderSummary *)cns, path);
- camel_folder_summary_set_build_content((CamelFolderSummary *)cns, FALSE);
-
- return cns;
-}
-
-static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
-{
- CamelMessageInfoBase *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 = (CamelMessageInfoBase *)((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new_from_header(s, h);
- if (mi) {
- mi->uid = g_strdup(cns->priv->uid);
- cns->priv->uid = NULL;
- }
-
- return (CamelMessageInfo *)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)
- return -1;
-
- /* Legacy version */
- if (s->version == 0x20c) {
- camel_file_util_decode_fixed_int32(in, &cns->high);
- return camel_file_util_decode_fixed_int32(in, &cns->low);
- }
-
- if (camel_file_util_decode_fixed_int32(in, &cns->version) == -1)
- return -1;
-
- if (cns->version > CAMEL_NNTP_SUMMARY_VERSION) {
- g_warning("Unknown NNTP summary version");
- errno = EINVAL;
- return -1;
- }
-
- if (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, CAMEL_NNTP_SUMMARY_VERSION) == -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;
-}
-
-/* ********************************************************************** */
-
-/* Note: This will be called from camel_nntp_command, so only use camel_nntp_raw_command */
-static int
-add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelFolderSummary *s;
- CamelMessageInfoBase *mi;
- struct _camel_header_raw *headers = NULL;
- char *line, *tab;
- int len, ret;
- unsigned int n, count, total, size;
- struct _xover_header *xover;
-
- s = (CamelFolderSummary *)cns;
-
- camel_operation_start(NULL, _("%s: Scanning new messages"), ((CamelService *)store)->url->host);
-
- ret = camel_nntp_raw_command_auth(store, ex, &line, "xover %r", low, high);
- if (ret != 224) {
- camel_operation_end(NULL);
- if (ret != -1)
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unexpected server response from xover: %s"), line);
- return -1;
- }
-
- 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 = store->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;
- }
- }
- }
- }
-
- /* skip headers we don't care about, incase the server doesn't actually send some it said it would. */
- while (xover && xover->name == NULL)
- xover = xover->next;
-
- /* truncated line? ignore? */
- if (xover == NULL) {
- mi = (CamelMessageInfoBase *)camel_folder_summary_uid(s, cns->priv->uid);
- if (mi == NULL) {
- mi = (CamelMessageInfoBase *)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_message_info_free(mi);
- }
- }
-
- if (cns->priv->uid) {
- g_free(cns->priv->uid);
- cns->priv->uid = NULL;
- }
-
- camel_header_raw_clear(&headers);
- }
-
- camel_operation_end(NULL);
-
- return ret;
-}
-
-/* Note: This will be called from camel_nntp_command, so only use camel_nntp_raw_command */
-static int
-add_range_head(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelFolderSummary *s;
- int i, ret = -1;
- char *line, *msgid;
- unsigned int n, count, total;
- CamelMessageInfo *mi;
- CamelMimeParser *mp;
-
- s = (CamelFolderSummary *)cns;
-
- mp = camel_mime_parser_new();
-
- camel_operation_start(NULL, _("%s: Scanning new messages"), ((CamelService *)store)->url->host);
-
- count = 0;
- total = high-low+1;
- for (i=low;i<high+1;i++) {
- camel_operation_progress(NULL, (count * 100) / total);
- count++;
- ret = camel_nntp_raw_command_auth(store, ex, &line, "head %u", i);
- /* unknown article, ignore */
- if (ret == 423)
- continue;
- else if (ret == -1)
- goto ioerror;
- else if (ret != 221) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Unexpected server response from head: %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);
-
- /* FIXME: use camel-mime-utils.c function for parsing msgid? */
- 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_message_info_free(mi);
- }
- if (cns->priv->uid) {
- g_free(cns->priv->uid);
- cns->priv->uid = NULL;
- }
- }
- }
-
- 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;
-}
-
-/* Assumes we have the stream */
-/* Note: This will be called from camel_nntp_command, so only use camel_nntp_raw_command */
-int
-camel_nntp_summary_check(CamelNNTPSummary *cns, CamelNNTPStore *store, char *line, CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelFolderSummary *s;
- int ret = 0, i;
- unsigned int n, f, l;
- int count;
- char *folder = NULL;
- CamelNNTPStoreInfo *si;
-
- s = (CamelFolderSummary *)cns;
-
- line +=3;
- n = strtoul(line, &line, 10);
- f = strtoul(line, &line, 10);
- l = strtoul(line, &line, 10);
- if (line[0] == ' ') {
- char *tmp;
-
- folder = line+1;
- tmp = strchr(folder, ' ');
- if (tmp)
- *tmp = 0;
- tmp = g_alloca(strlen(folder)+1);
- strcpy(tmp, folder);
- folder = tmp;
- }
-
- if (cns->low == f && cns->high == l) {
- dd(printf("nntp_summary: no work to do!\n"));
- goto update;
- }
-
- /* 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_message_info_free(mi);
- }
- }
- cns->low = f;
- }
-
- if (cns->high < l) {
- if (cns->high < f)
- cns->high = f-1;
-
- if (store->xover) {
- ret = add_range_xover(cns, store, l, cns->high+1, changes, ex);
- } else {
- ret = add_range_head(cns, store, l, cns->high+1, changes, ex);
- }
- }
-
- /* TODO: not from here */
- camel_folder_summary_touch(s);
- camel_folder_summary_save(s);
-update:
- /* update store summary if we have it */
- if (folder
- && (si = (CamelNNTPStoreInfo *)camel_store_summary_path((CamelStoreSummary *)store->summary, folder))) {
- int unread = 0;
-
- count = camel_folder_summary_count(s);
- for (i = 0; i < count; i++) {
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)camel_folder_summary_index(s, i);
-
- if (mi) {
- if ((mi->flags & CAMEL_MESSAGE_SEEN) == 0)
- unread++;
- camel_message_info_free(mi);
- }
- }
-
- if (si->info.unread != unread
- || si->info.total != count
- || si->first != f
- || si->last != l) {
- si->info.unread = unread;
- si->info.total = count;
- si->first = f;
- si->last = l;
- camel_store_summary_touch((CamelStoreSummary *)store->summary);
- camel_store_summary_save((CamelStoreSummary *)store->summary);
- }
- camel_store_summary_info_free ((CamelStoreSummary *)store->summary, (CamelStoreInfo *)si);
- } else {
- if (folder)
- g_warning("Group '%s' not present in summary", folder);
- else
- g_warning("Missing group from group response");
- }
-
- 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 2aff4319e1..0000000000
--- a/camel/providers/nntp/camel-nntp-summary.h
+++ /dev/null
@@ -1,56 +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>
-
-struct _CamelNNTPStore;
-struct _CamelFolderChangeInfo;
-struct _CamelException;
-
-#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;
-
- guint32 version;
- guint32 high, low;
-};
-
-struct _CamelNNTPSummaryClass {
- CamelFolderSummaryClass parent_class;
-};
-
-CamelType camel_nntp_summary_get_type (void);
-CamelNNTPSummary *camel_nntp_summary_new(struct _CamelFolder *folder, const char *path);
-
-int camel_nntp_summary_check(CamelNNTPSummary *cns, struct _CamelNNTPStore *store, char *line, struct _CamelFolderChangeInfo *changes, struct _CamelException *ex);
-
-#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 43cbb0eedb..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 "libedataserver/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 49df41e230..0000000000
--- a/camel/providers/pop3/Makefile.am
+++ /dev/null
@@ -1,31 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-camel_provider_LTLIBRARIES = libcamelpop3.la
-camel_provider_DATA = libcamelpop3.urls
-
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/camel \
- $(CAMEL_CFLAGS) \
- -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
-
-noinst_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)/libedataserver/libedataserver-${BASE_VERSION}.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 e79a382359..0000000000
--- a/camel/providers/pop3/camel-pop3-engine.c
+++ /dev/null
@@ -1,412 +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-service.h"
-#include "camel-sasl.h"
-#include "camel-i18n.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);
-
-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(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;
-}
-
-static int
-read_greeting (CamelPOP3Engine *pe)
-{
- extern CamelServiceAuthType camel_pop3_password_authtype;
- extern CamelServiceAuthType camel_pop3_apop_authtype;
- unsigned char *line, *apop, *apopend;
- unsigned int len;
-
- /* first, read the greeting */
- if (camel_pop3_stream_line (pe->stream, &line, &len) == -1
- || strncmp (line, "+OK", 3) != 0)
- return -1;
-
- 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);
-
- return 0;
-}
-
-/**
- * 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;
-
- if (read_greeting (pe) == -1) {
- camel_object_unref (pe);
- return NULL;
- }
-
- get_capabilities (pe);
-
- 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);
-}
-
-
-/* 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)
-{
- CamelPOP3Command *pc;
-
- 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)
- goto ioerror;
-
- 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)
- goto ioerror;
-
- 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;
-ioerror:
- /* we assume all outstanding commands are gunna fail now */
- while ( (pw = (CamelPOP3Command*)e_dlist_remhead(&pe->active)) ) {
- pw->state = CAMEL_POP3_COMMAND_ERR;
- e_dlist_addtail(&pe->done, (EDListNode *)pw);
- }
-
- while ( (pw = (CamelPOP3Command*)e_dlist_remhead(&pe->queue)) ) {
- pw->state = CAMEL_POP3_COMMAND_ERR;
- e_dlist_addtail(&pe->done, (EDListNode *)pw);
- }
-
- if (pe->current) {
- pe->current->state = CAMEL_POP3_COMMAND_ERR;
- e_dlist_addtail(&pe->done, (EDListNode *)pe->current);
- pe->current = NULL;
- }
-
- return -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 48938bbf48..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 "libedataserver/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 e0d91f1eff..0000000000
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ /dev/null
@@ -1,568 +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 "camel-i18n.h"
-
-#include <libedataserver/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 gboolean 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_SYSTEM,
- _("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 gboolean
-pop3_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
-{
- CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
- CamelPOP3FolderInfo *fi;
- gboolean res = FALSE;
-
- fi = g_hash_table_lookup(pop3_folder->uids_uid, uid);
- if (fi) {
- guint32 new = (fi->flags & ~flags) | (set & flags);
-
- if (fi->flags != new) {
- fi->flags = new;
- res = TRUE;
- }
- }
-
- return res;
-}
-
-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 7253edfbf4..0000000000
--- a/camel/providers/pop3/camel-pop3-provider.c
+++ /dev/null
@@ -1,109 +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"
-#include "camel-i18n.h"
-
-CamelProviderConfEntry pop3_conf_entries[] = {
- { CAMEL_PROVIDER_CONF_SECTION_START, "storage", 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(void)
-{
- 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_provider_register(&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 46a1fd3fe6..0000000000
--- a/camel/providers/pop3/camel-pop3-store.c
+++ /dev/null
@@ -1,646 +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 "libedataserver/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
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
-
-/* Specified in RFC 1939 */
-#define POP3_PORT "110"
-#define POP3S_PORT "995"
-
-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 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->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 {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
-#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, struct addrinfo *ai, int ssl_mode, CamelException *ex)
-{
- CamelPOP3Store *store = CAMEL_POP3_STORE (service);
- CamelStream *tcp_stream;
- CamelPOP3Command *pc;
- guint32 flags = 0;
- int clean_quit;
- int ret;
-
- if (ssl_mode != MODE_CLEAR) {
-#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
-
- return FALSE;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -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: %s"),
- service->url->host,
- g_strerror (errno));
-
- camel_object_unref (tcp_stream);
-
- return FALSE;
- }
-
- /* parent class connect initialization */
- if (CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex) == FALSE) {
- camel_object_unref (tcp_stream);
- return FALSE;
- }
-
- if (camel_url_get_param (service->url, "disable_extensions"))
- flags |= CAMEL_POP3_ENGINE_DISABLE_EXTENSIONS;
-
- if (!(store->engine = camel_pop3_engine_new (tcp_stream, flags))) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to read a valid greeting from POP server %s"),
- service->url->host);
- camel_object_unref (tcp_stream);
- return FALSE;
- }
-
- if (ssl_mode != MODE_TLS) {
- camel_object_unref (tcp_stream);
- return TRUE;
- }
-
- if (!(store->engine->capa & CAMEL_POP3_CAP_STLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to POP server %s in secure mode: %s"),
- service->url->host, _("STLS not supported"));
- goto stls_exception;
- }
-
- /* 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));
-
- 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;
- }
-
- camel_object_unref (tcp_stream);
-
- /* 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;
-}
-
-static struct {
- char *value;
- char *serv;
- char *port;
- int mode;
-} ssl_options[] = {
- { "", "pop3s", POP3S_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "pop3s", POP3S_PORT, MODE_SSL },
- { "when-possible", "pop3", POP3_PORT, MODE_TLS },
- { "never", "pop3", POP3_PORT, MODE_CLEAR },
- { NULL, "pop3", POP3_PORT, MODE_CLEAR },
-};
-
-static gboolean
-connect_to_server_wrapper (CamelService *service, CamelException *ex)
-{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
- break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
- } else {
- mode = MODE_CLEAR;
- serv = "pop3";
- port = POP3S_PORT;
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
- }
-
- camel_freeaddrinfo (ai);
-
- return ret;
-}
-
-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;
- guint32 flags = CAMEL_SESSION_PASSWORD_SECRET;
-
- if (reprompt)
- flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
-
- prompt = g_strdup_printf (_("%sPlease enter the POP password for %s on host %s"),
- errmsg ? errmsg : "",
- service->url->user,
- service->url->host);
- service->url->passwd = camel_session_get_password (camel_service_get_session (service), service, NULL,
- prompt, "password", flags, 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 (pcu && pcu->state != CAMEL_POP3_COMMAND_OK) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Unable to connect to POP server %s.\n"
- "Error sending username: %s"),
- CAMEL_SERVICE (store)->url->host,
- store->engine->line ? (char *)store->engine->line : _("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 {
- 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;
- camel_exception_clear (ex);
- }
- } 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 (g_ascii_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 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 46e3613081..0000000000
--- a/camel/providers/sendmail/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-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
-
-noinst_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 0aeb367cf3..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"
-#include "camel-i18n.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(void)
-{
- 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_provider_register(&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 a776b9729e..0000000000
--- a/camel/providers/sendmail/camel-sendmail-transport.c
+++ /dev/null
@@ -1,263 +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"
-#include "camel-i18n.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 29dc3dc44d..0000000000
--- a/camel/providers/smtp/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-camel_provider_LTLIBRARIES = libcamelsmtp.la
-camel_provider_DATA = libcamelsmtp.urls
-
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/camel \
- $(CAMEL_CFLAGS) \
- -DG_LOG_DOMAIN=\"camel-smtp-provider\"
-
-libcamelsmtp_la_SOURCES = \
- camel-smtp-provider.c \
- camel-smtp-transport.c
-
-noinst_HEADERS = \
- camel-smtp-transport.h
-
-libcamelsmtp_la_LDFLAGS = -avoid-version -module
-
-libcamelsmtp_la_LIBADD = \
- $(top_builddir)/libedataserver/libedataserver-${BASE_VERSION}.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 bff1d847d0..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"
-#include "camel-i18n.h"
-
-static CamelProvider smtp_provider = {
- "smtp",
- N_("SMTP"),
-
- N_("For delivering mail by connecting to a remote mailhub "
- "using SMTP."),
-
- "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(void)
-{
- 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_provider_register(&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 065d79fdac..0000000000
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ /dev/null
@@ -1,1397 +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"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
-
-extern int camel_verbose_debug;
-#define d(x) (camel_verbose_debug ? (x) : 0)
-
-/* Specified in RFC 821 */
-#define SMTP_PORT "25"
-#define SMTPS_PORT "465"
-
-/* 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, gboolean disconnect, 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)
-{
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
-}
-
-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");
- }
-}
-
-enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
-#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, struct addrinfo *ai, int ssl_mode, CamelException *ex)
-{
- CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
- CamelStream *tcp_stream;
- char *respbuf = NULL;
- int ret;
-
- if (!CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex))
- return FALSE;
-
- /* set some smtp transport defaults */
- transport->flags = 0;
- transport->authtypes = NULL;
-
- if (ssl_mode != MODE_CLEAR) {
-#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
-
- return FALSE;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -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: %s"),
- service->url->host, 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->localaddrlen);
-
- 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, FALSE, 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);
-
- if (ssl_mode != MODE_TLS) {
- /* we're done */
- return TRUE;
- }
-
- if (!(transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to SMTP server %s in secure mode: %s"),
- service->url->host, _("STARTTLS not supported"));
-
- goto exception_cleanup;
- }
-
- d(fprintf (stderr, "sending : STARTTLS\r\n"));
- if (camel_stream_write (tcp_stream, "STARTTLS\r\n", 10) == -1) {
- camel_exception_setv (ex, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("STARTTLS command failed: %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, FALSE, respbuf, _("STARTTLS command failed"), 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;
-}
-
-static struct {
- char *value;
- char *serv;
- char *port;
- int mode;
-} ssl_options[] = {
- { "", "smtps", SMTPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "smtps", SMTPS_PORT, MODE_SSL },
- { "when-possible", "smtp", SMTP_PORT, MODE_TLS },
- { "never", "smtp", SMTP_PORT, MODE_CLEAR },
- { NULL, "smtp", SMTP_PORT, MODE_CLEAR },
-};
-
-static gboolean
-connect_to_server_wrapper (CamelService *service, CamelException *ex)
-{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
- break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
- } else {
- mode = MODE_CLEAR;
- serv = "smtp";
- port = SMTP_PORT;
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL)
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- else if (!ret && mode == MODE_TLS)
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
-
- camel_freeaddrinfo (ai);
-
- return ret;
-}
-
-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, NULL, "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 on host %s"),
- errbuf ? errbuf : "", service->url->user,
- service->url->host);
-
- service->url->passwd = camel_session_get_password (session, service, NULL,
- prompt, "password", CAMEL_SESSION_PASSWORD_SECRET, 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);
- }
- }
- }
-
- 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;
- }
-
- g_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 (!smtp_transport->connected) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_NOT_CONNECTED,
- _("Cannot send message: service not connected."));
- return FALSE;
- }
-
- 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 */
- if (!smtp_rset (smtp_transport, ex))
- camel_exception_clear (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, gboolean disconnect, 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, error == 0 && errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : 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 */
- if (disconnect)
- camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
- else
- transport->connected = FALSE;
- }
-}
-
-static gboolean
-smtp_helo (CamelSmtpTransport *transport, CamelException *ex)
-{
- /* say hello to the server */
- char *name = NULL, *cmdbuf = NULL, *respbuf = NULL;
- const char *token, *numeric = NULL;
-
- /* 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"));
-
- /* force name resolution first, fallback to numerical, we need to know when it falls back */
- if (camel_getnameinfo(transport->localaddr, transport->localaddrlen, &name, NULL, NI_NAMEREQD, NULL) != 0) {
- if (camel_getnameinfo(transport->localaddr, transport->localaddrlen, &name, NULL, NI_NUMERICHOST, NULL) != 0)
- name = g_strdup("localhost.localdomain");
- else {
- if (transport->localaddr->sa_family == AF_INET6)
- numeric = "IPv6:";
- else
- numeric = "";
- }
- }
-
- /* hiya server! how are you today? */
- token = (transport->flags & CAMEL_SMTP_TRANSPORT_IS_ESMTP) ? "EHLO" : "HELO";
- if (numeric)
- cmdbuf = g_strdup_printf("%s [%s%s]\r\n", token, numeric, name);
- else
- cmdbuf = g_strdup_printf("%s %s\r\n", token, 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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("HELO command failed: %s"), g_strerror (errno));
- camel_operation_end (NULL);
-
- camel_service_disconnect ((CamelService *) transport, FALSE, 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, FALSE, respbuf, _("HELO command failed"), 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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("AUTH command failed: %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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("AUTH command failed: %s"), g_strerror (errno));
- goto lose;
- }
-
- /* the server challenge/response should follow a 334 code */
- if (strncmp (respbuf, "334", 3) != 0) {
- smtp_set_exception (transport, FALSE, respbuf, _("AUTH command failed"), ex);
- g_free (respbuf);
- 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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("MAIL FROM command failed: %s: mail not sent"),
- g_strerror (errno));
-
- camel_service_disconnect ((CamelService *) transport, FALSE, 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, TRUE, respbuf, _("MAIL FROM command failed"), 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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("RCPT TO command failed: %s: mail not sent"),
- g_strerror (errno));
-
- camel_service_disconnect ((CamelService *) transport, FALSE, 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, TRUE, 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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
-
- camel_service_disconnect ((CamelService *) transport, FALSE, 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, TRUE, respbuf, _("DATA command failed"), 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 (!g_ascii_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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
-
- camel_object_unref (filtered_stream);
-
- camel_service_disconnect ((CamelService *) transport, FALSE, 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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("DATA command failed: %s: mail not sent"),
- g_strerror (errno));
-
- camel_service_disconnect ((CamelService *) transport, FALSE, 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, TRUE, respbuf, _("DATA command failed"), 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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("RSET command failed: %s"), g_strerror (errno));
-
- camel_service_disconnect ((CamelService *) transport, FALSE, 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, TRUE, respbuf, _("RSET command failed"), 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, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
- _("QUIT command failed: %s"), g_strerror (errno));
-
- return FALSE;
- }
- g_free (cmdbuf);
-
- do {
- /* Check for "221" */
- g_free (respbuf);
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
-
- d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
- if (!respbuf || strncmp (respbuf, "221", 3)) {
- smtp_set_exception (transport, FALSE, respbuf, _("QUIT command failed"), 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 7b5ad88f12..0000000000
--- a/camel/providers/smtp/camel-smtp-transport.h
+++ /dev/null
@@ -1,74 +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_AUTH_EQUAL (1 << 4) /* set if we are using authtypes from a broken AUTH= */
-
-typedef struct {
- CamelTransport parent_object;
-
- CamelStream *istream, *ostream;
-
- guint32 flags;
-
- gboolean connected;
- struct sockaddr *localaddr;
- socklen_t localaddrlen;
-
- 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