aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap
diff options
context:
space:
mode:
authornobody <nobody@localhost>2001-03-02 09:33:29 +0800
committernobody <nobody@localhost>2001-03-02 09:33:29 +0800
commit33d0bbdc0ce1b25a612c2583c0bfcc3705866ebc (patch)
treecda39502324bf50b451e5c7f58e5dee7c7476bad /camel/providers/imap
parent50ef074887b43f43dad3edb120d9abf30092c681 (diff)
downloadgsoc2013-evolution-PONG_0_11.tar
gsoc2013-evolution-PONG_0_11.tar.gz
gsoc2013-evolution-PONG_0_11.tar.bz2
gsoc2013-evolution-PONG_0_11.tar.lz
gsoc2013-evolution-PONG_0_11.tar.xz
gsoc2013-evolution-PONG_0_11.tar.zst
gsoc2013-evolution-PONG_0_11.zip
This commit was manufactured by cvs2svn to create tag 'PONG_0_11'.PONG_0_11
svn path=/tags/PONG_0_11/; revision=8498
Diffstat (limited to 'camel/providers/imap')
-rw-r--r--camel/providers/imap/.cvsignore11
-rw-r--r--camel/providers/imap/Makefile.am52
-rw-r--r--camel/providers/imap/camel-imap-command.c578
-rw-r--r--camel/providers/imap/camel-imap-command.h59
-rw-r--r--camel/providers/imap/camel-imap-folder.c1152
-rw-r--r--camel/providers/imap/camel-imap-folder.h83
-rw-r--r--camel/providers/imap/camel-imap-private.h88
-rw-r--r--camel/providers/imap/camel-imap-provider.c113
-rw-r--r--camel/providers/imap/camel-imap-search.c151
-rw-r--r--camel/providers/imap/camel-imap-search.h51
-rw-r--r--camel/providers/imap/camel-imap-store.c1135
-rw-r--r--camel/providers/imap/camel-imap-store.h90
-rw-r--r--camel/providers/imap/camel-imap-summary.c215
-rw-r--r--camel/providers/imap/camel-imap-summary.h70
-rw-r--r--camel/providers/imap/camel-imap-types.h39
-rw-r--r--camel/providers/imap/camel-imap-utils.c568
-rw-r--r--camel/providers/imap/camel-imap-utils.h62
-rw-r--r--camel/providers/imap/camel-imap-wrapper.c234
-rw-r--r--camel/providers/imap/camel-imap-wrapper.h70
-rw-r--r--camel/providers/imap/libcamelimap.urls1
20 files changed, 0 insertions, 4822 deletions
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 39e160c879..0000000000
--- a/camel/providers/imap/Makefile.am
+++ /dev/null
@@ -1,52 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelimapincludedir = $(includedir)/camel
-
-
-providerdir = $(pkglibdir)/camel-providers/$(VERSION)
-
-provider_LTLIBRARIES = libcamelimap.la
-provider_DATA = libcamelimap.urls
-
-INCLUDES = -I.. \
- -I$(srcdir)/.. \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/libibex \
- -I$(top_srcdir)/e-util \
- -I$(top_srcdir) \
- -I$(includedir) \
- $(GTK_INCLUDEDIR) \
- -DG_LOG_DOMAIN=\"camel-imap-provider\"
-
-libcamelimap_la_SOURCES = \
- camel-imap-command.c \
- camel-imap-folder.c \
- camel-imap-provider.c \
- camel-imap-search.c \
- camel-imap-store.c \
- camel-imap-summary.c \
- camel-imap-utils.c \
- camel-imap-wrapper.c
-
-libcamelimapinclude_HEADERS = \
- camel-imap-command.h \
- camel-imap-folder.h \
- camel-imap-search.h \
- camel-imap-store.h \
- camel-imap-summary.h \
- camel-imap-types.h \
- camel-imap-utils.h \
- camel-imap-wrapper.h
-
-libcamelimap_la_LDFLAGS = -version-info 0:0:0
-
-noinst_HEADERS = \
- camel-imap-private.h
-
-EXTRA_DIST = libcamelimap.urls
-
-
-
-
-
diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c
deleted file mode 100644
index 8a713cde8b..0000000000
--- a/camel/providers/imap/camel-imap-command.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-command.c: IMAP command sending/parsing routines */
-
-/*
- * Authors:
- * Dan Winship <danw@helixcode.com>
- * Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#include <config.h>
-
-#include <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/camel-exception.h>
-
-static char *imap_read_untagged (CamelImapStore *store, char *line,
- CamelException *ex);
-static CamelImapResponse *imap_read_response (CamelImapStore *store,
- CamelException *ex);
-static char *imap_command_strdup_vprintf (CamelImapStore *store,
- const char *fmt, va_list ap);
-
-/**
- * camel_imap_command: Send a command to a IMAP server and get a response
- * @store: the IMAP store
- * @folder: The folder to perform the operation in (or %NULL if not
- * relevant).
- * @ex: a CamelException
- * @fmt: an 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. It then reads the
- * server's response(s) and parses the final result.
- *
- * As a special case, if @fmt is %NULL, it will just select @folder
- * and return the response from doing so.
- *
- * @fmt can include the following %-escapes ONLY:
- * %s, %d, %%: as with printf
- * %S: an IMAP "string" (quoted string or literal)
- *
- * %S strings will be passed as literals if the server supports LITERAL+
- * and quoted strings otherwise. (%S does not support strings that
- * contain newlines.)
- *
- * This function assumes you have an exclusive lock on the command
- * channel/stream.
- *
- * Return value: %NULL if an error occurred (in which case @ex will
- * be set). Otherwise, a CamelImapResponse describing the server's
- * response, which the caller must free with camel_imap_response_free().
- **/
-CamelImapResponse *
-camel_imap_command (CamelImapStore *store, CamelFolder *folder,
- CamelException *ex, const char *fmt, ...)
-{
- gchar *cmdbuf;
- va_list ap;
-
- /* Check for current folder */
- if (folder && (!fmt || folder != store->current_folder)) {
- CamelImapResponse *response;
-
- store->current_folder = NULL;
- response = camel_imap_command (store, NULL, ex, "SELECT %S",
- folder->full_name);
- if (!response)
- return NULL;
- store->current_folder = folder;
-
- if (!fmt)
- return response;
-
- camel_imap_folder_selected (folder, response, ex);
- camel_imap_response_free (response);
- }
-
- /* Send the command */
- va_start (ap, fmt);
- cmdbuf = imap_command_strdup_vprintf (store, fmt, ap);
- va_end (ap);
-
- camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex,
- "A%.5d %s\r\n", store->command++,
- cmdbuf);
- g_free (cmdbuf);
- if (camel_exception_is_set (ex))
- return NULL;
-
- /* Read the response. */
- return imap_read_response (store, ex);
-}
-
-/**
- * camel_imap_command_continuation: Send more command data to the IMAP server
- * @store: the IMAP store
- * @ex: a CamelException
- * @cmdbuf: buffer containing the response/request data
- *
- * This method is for sending continuing responses to the IMAP server
- * after camel_imap_command returns a CAMEL_IMAP_PLUS response.
- *
- * This function assumes you have an exclusive lock on the remote stream.
- *
- * Return value: as for camel_imap_command()
- **/
-CamelImapResponse *
-camel_imap_command_continuation (CamelImapStore *store, CamelException *ex,
- const char *cmdbuf)
-{
- if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex,
- "%s\r\n", cmdbuf) < 0)
- return NULL;
-
- return imap_read_response (store, ex);
-}
-
-/* Read the response to an IMAP command. */
-static CamelImapResponse *
-imap_read_response (CamelImapStore *store, CamelException *ex)
-{
- CamelImapResponse *response;
- int number, exists = 0;
- GArray *expunged = NULL;
- char *respbuf, *retcode, *word, *p;
-
- /* Read first line */
- if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store),
- &respbuf, ex) < 0)
- return NULL;
-
- response = g_new0 (CamelImapResponse, 1);
- response->untagged = g_ptr_array_new ();
-
- /* Check for untagged data */
- while (!strncmp (respbuf, "* ", 2)) {
- /* Read the rest of the response if it is multi-line. */
- respbuf = imap_read_untagged (store, respbuf, ex);
- if (camel_exception_is_set (ex))
- break;
-
- /* If it starts with a number, we might deal with
- * it ourselves.
- */
- word = imap_next_word (respbuf);
- number = strtoul (word, &p, 10);
- if (p != word && store->current_folder) {
- word = imap_next_word (p);
- if (!g_strcasecmp (word, "EXISTS")) {
- exists = number;
- g_free (respbuf);
- goto next;
- } else if (!g_strcasecmp (word, "EXPUNGE")) {
- if (!expunged) {
- expunged = g_array_new (FALSE, FALSE,
- sizeof (int));
- }
- g_array_append_val (expunged, number);
- g_free (respbuf);
- goto next;
- }
- } else {
- if (!g_strncasecmp (word, "BYE", 3)) {
- /* connection was lost, no more data to fetch */
- store->connected = FALSE;
- g_free (respbuf);
- respbuf = NULL;
- break;
- }
- }
-
- g_ptr_array_add (response->untagged, respbuf);
- next:
- if (camel_remote_store_recv_line (
- CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0)
- break;
- }
-
- /* Update the summary */
- if (store->current_folder && (exists > 0 || expunged)) {
- camel_imap_folder_changed (store->current_folder, exists,
- expunged, NULL);
- }
- if (expunged)
- g_array_free (expunged, TRUE);
-
- if (!respbuf || camel_exception_is_set (ex)) {
- camel_imap_response_free (response);
- return NULL;
- }
-
- response->status = respbuf;
-
- /* Check for OK or continuation response. */
- if (!strncmp (respbuf, "+ ", 2))
- return response;
- retcode = imap_next_word (respbuf);
- if (!strncmp (retcode, "OK", 2))
- return response;
-
- /* We should never get BAD, or anything else but +, OK, or NO
- * for that matter.
- */
- if (strncmp (retcode, "NO", 2) != 0) {
- g_warning ("Unexpected response from IMAP server: %s",
- respbuf);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Unexpected response from IMAP "
- "server: %s"), respbuf);
- camel_imap_response_free (response);
- return NULL;
- }
-
- retcode = imap_next_word (retcode);
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("IMAP command failed: %s"),
- retcode ? retcode : _("Unknown error"));
- camel_imap_response_free (response);
- return NULL;
-}
-
-/* Given a line that is the start of an untagged response, read and
- * return the complete response, which may include an arbitrary number
- * of literals.
- */
-static char *
-imap_read_untagged (CamelImapStore *store, char *line, CamelException *ex)
-{
- int fulllen, length, ldigits, nread, i;
- 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)
- break;
- ldigits = end - (p + 1);
-
- /* Read the literal */
- str = g_string_sized_new (length + 2);
- str->str[0] = '\n';
- nread = camel_stream_read (CAMEL_REMOTE_STORE (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, strerror(errno));
- camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
- goto lose;
- }
- if (nread < length) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Server response ended too soon."));
- camel_service_disconnect (CAMEL_SERVICE (store),
- FALSE, NULL);
- 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
- * - The only cause of embedded NULs we've seen is an
- * Evolution base64-encoder bug that sometimes
- * inserts a NUL into the last line when it
- * shouldn't.
- */
-
- 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_remote_store_recv_line (CAMEL_REMOTE_STORE (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:
- * response: a CamelImapResponse:
- *
- * Frees all of the data in @response.
- **/
-void
-camel_imap_response_free (CamelImapResponse *response)
-{
- int i;
-
- if (!response)
- return;
- for (i = 0; i < response->untagged->len; i++)
- g_free (response->untagged->pdata[i]);
- g_ptr_array_free (response->untagged, TRUE);
- g_free (response->status);
- g_free (response);
-}
-
-/**
- * camel_imap_response_extract:
- * @response: the response data returned from camel_imap_command
- * @type: the response type to extract
- * @ex: a CamelException
- *
- * This checks that @response contains a single untagged response of
- * type @type and returns just that response data. If @response
- * doesn't contain the right information, the function will set @ex and
- * return %NULL. Either way, @response will be freed.
- *
- * Return value: the desired response string, which the caller must free.
- **/
-char *
-camel_imap_response_extract (CamelImapResponse *response, const char *type,
- CamelException *ex)
-{
- int len = strlen (type), i;
- char *resp;
-
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i];
- /* Skip "* ", and initial sequence number, if present */
- strtoul (resp + 2, &resp, 10);
- if (*resp == ' ')
- resp = imap_next_word (resp);
-
- if (!g_strncasecmp (resp, type, len))
- break;
-
- g_free (response->untagged->pdata[i]);
- }
-
- if (i < response->untagged->len) {
- resp = response->untagged->pdata[i];
- for (i++; i < response->untagged->len; i++)
- g_free (response->untagged->pdata[i]);
- } else {
- resp = NULL;
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("IMAP server response did not contain "
- "%s information"), type);
- }
-
- g_ptr_array_free (response->untagged, TRUE);
- g_free (response->status);
- g_free (response);
- return resp;
-}
-
-/**
- * camel_imap_response_extract_continuation:
- * @response: the response data returned from camel_imap_command
- * @ex: a CamelException
- *
- * This checks that @response contains a continuation response, and
- * returns just that data. If @response doesn't contain a continuation
- * response, the function will set @ex and return %NULL. Either way,
- * @response will be freed.
- *
- * Return value: the desired response string, which the caller must free.
- **/
-char *
-camel_imap_response_extract_continuation (CamelImapResponse *response,
- CamelException *ex)
-{
- char *status;
-
- if (response->status && !strncmp (response->status, "+ ", 2)) {
- status = response->status;
- response->status = NULL;
- camel_imap_response_free (response);
- return status;
- }
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Unexpected OK response from IMAP server: %s"),
- response->status);
- camel_imap_response_free (response);
- return NULL;
-}
-
-
-static char *
-imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt,
- va_list ap)
-{
- GPtrArray *args;
- const char *p, *start;
- char *out, *op, *string;
- int num, len, i;
-
- 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':
- string = va_arg (ap, char *);
- g_ptr_array_add (args, string);
- if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS)
- len += strlen (string) + 15;
- else
- len += strlen (string) * 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 */
- op = out = g_malloc (len + 1);
- p = start = fmt;
- i = 0;
- while (*p) {
- p = strchr (start, '%');
- if (!p) {
- strcpy (op, start);
- break;
- } else {
- strncpy (op, start, p - start);
- op += p - start;
- }
-
- switch (*++p) {
- case 'd':
- num = GPOINTER_TO_INT (args->pdata[i++]);
- op += sprintf (op, "%d", num);
- break;
-
- case 's':
- string = args->pdata[i++];
- op += sprintf (op, "%s", string);
- break;
-
- case 'S':
- string = args->pdata[i++];
- if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) {
- op += sprintf (op, "{%d+}\r\n%s",
- strlen (string), string);
- } else {
- char *quoted = imap_quote_string (string);
- op += sprintf (op, "%s", quoted);
- g_free (quoted);
- }
- break;
-
- default:
- *op++ = '%';
- *op++ = *p;
- }
-
- start = *p ? p + 1 : p;
- }
-
- return out;
-}
diff --git a/camel/providers/imap/camel-imap-command.h b/camel/providers/imap/camel-imap-command.h
deleted file mode 100644
index a7d3c3eae9..0000000000
--- a/camel/providers/imap/camel-imap-command.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-command.h: IMAP command sending/parsing routines */
-
-/*
- * Authors:
- * Dan Winship <danw@helixcode.com>
- * Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright (C) 2000 Helix Code, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_COMMAND_H
-#define CAMEL_IMAP_COMMAND_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-imap-types.h"
-#include <glib.h>
-
-struct _CamelImapResponse {
- GPtrArray *untagged;
- char *status;
-};
-
-CamelImapResponse *camel_imap_command (CamelImapStore *store,
- CamelFolder *folder,
- CamelException *ex,
- const char *fmt, ...);
-CamelImapResponse *camel_imap_command_continuation (CamelImapStore *store,
- CamelException *ex,
- const char *cmdbuf);
-
-void camel_imap_response_free (CamelImapResponse *response);
-char *camel_imap_response_extract (CamelImapResponse *response,
- const char *type,
- CamelException *ex);
-char *camel_imap_response_extract_continuation (CamelImapResponse *response,
- CamelException *ex);
-
-#endif /* CAMEL_IMAP_COMMAND_H */
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
deleted file mode 100644
index cf91bceb12..0000000000
--- a/camel/providers/imap/camel-imap-folder.c
+++ /dev/null
@@ -1,1152 +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: Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright (C) 2000 Helix Code, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-#include <gal/util/e-util.h>
-
-#include "camel-imap-folder.h"
-#include "camel-imap-command.h"
-#include "camel-imap-search.h"
-#include "camel-imap-store.h"
-#include "camel-imap-summary.h"
-#include "camel-imap-utils.h"
-#include "camel-imap-wrapper.h"
-#include "string-utils.h"
-#include "camel-stream.h"
-#include "camel-stream-fs.h"
-#include "camel-stream-mem.h"
-#include "camel-stream-buffer.h"
-#include "camel-data-wrapper.h"
-#include "camel-mime-message.h"
-#include "camel-stream-filter.h"
-#include "camel-mime-filter-from.h"
-#include "camel-mime-filter-crlf.h"
-#include "camel-exception.h"
-#include "camel-mime-utils.h"
-#include "camel-imap-private.h"
-#include "camel-multipart.h"
-#include "camel-operation.h"
-
-#define d(x) x
-
-#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(o)))
-
-static CamelFolderClass *parent_class = NULL;
-
-static void imap_finalize (CamelObject *object);
-static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex);
-static void imap_refresh_info (CamelFolder *folder, CamelException *ex);
-static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
-static const char *imap_get_full_name (CamelFolder *folder);
-static void imap_expunge (CamelFolder *folder, CamelException *ex);
-
-/* message manipulation */
-static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid,
- CamelException *ex);
-static void imap_append_message (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, CamelException *ex);
-static void imap_copy_message_to (CamelFolder *source, const char *uid,
- CamelFolder *destination, CamelException *ex);
-static void imap_move_message_to (CamelFolder *source, const char *uid,
- CamelFolder *destination, CamelException *ex);
-
-/* summary info */
-static void imap_update_summary (CamelFolder *folder, int first, int last,
- CamelFolderChangeInfo *changes,
- CamelException *ex);
-
-/* searching */
-static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex);
-static void imap_search_free (CamelFolder *folder, GPtrArray *uids);
-
-static void
-camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_imap_folder_class);
-
- parent_class = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ()));
-
- /* virtual method definition */
-
- /* virtual method overload */
- camel_folder_class->refresh_info = imap_refresh_info;
- camel_folder_class->sync = imap_sync;
- camel_folder_class->expunge = imap_expunge;
- camel_folder_class->get_full_name = imap_get_full_name;
-
- camel_folder_class->get_message = imap_get_message;
- camel_folder_class->append_message = imap_append_message;
- camel_folder_class->copy_message_to = imap_copy_message_to;
- camel_folder_class->move_message_to = imap_move_message_to;
-
- camel_folder_class->search_by_expression = imap_search_by_expression;
- camel_folder_class->search_free = imap_search_free;
-}
-
-static void
-camel_imap_folder_init (gpointer object, gpointer klass)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
- CamelFolder *folder = CAMEL_FOLDER (object);
-
- folder->has_summary_capability = TRUE;
- folder->has_search_capability = TRUE;
-
- imap_folder->priv = g_malloc0(sizeof(*imap_folder->priv));
-#ifdef ENABLE_THREADS
- imap_folder->priv->search_lock = g_mutex_new();
-#endif
-}
-
-CamelType
-camel_imap_folder_get_type (void)
-{
- static CamelType camel_imap_folder_type = CAMEL_INVALID_TYPE;
-
- if (camel_imap_folder_type == CAMEL_INVALID_TYPE) {
- camel_imap_folder_type =
- camel_type_register (CAMEL_FOLDER_TYPE, "CamelImapFolder",
- sizeof (CamelImapFolder),
- sizeof (CamelImapFolderClass),
- (CamelObjectClassInitFunc) camel_imap_folder_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_folder_init,
- (CamelObjectFinalizeFunc) imap_finalize);
- }
-
- return camel_imap_folder_type;
-}
-
-CamelFolder *
-camel_imap_folder_new (CamelStore *parent, const char *folder_name,
- const char *short_name, const char *summary_file,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (parent);
- CamelFolder *folder = CAMEL_FOLDER (camel_object_new (camel_imap_folder_get_type ()));
- CamelImapResponse *response;
- char *resp;
- guint32 validity = 0;
- int i, exists = 0;
-
- camel_folder_construct (folder, parent, folder_name, short_name);
-
- CAMEL_IMAP_STORE_LOCK(imap_store, command_lock);
- response = camel_imap_command (imap_store, folder, ex, NULL);
- CAMEL_IMAP_STORE_UNLOCK(imap_store, command_lock);
-
- if (!response) {
- camel_object_unref ((CamelObject *)folder);
- return NULL;
- }
-
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i] + 2;
- if (!g_strncasecmp (resp, "FLAGS ", 6)) {
- resp += 6;
- folder->permanent_flags = imap_parse_flag_list (&resp);
- } else if (!g_strncasecmp (resp, "OK [PERMANENTFLAGS ", 19)) {
- resp += 19;
- folder->permanent_flags = imap_parse_flag_list (&resp);
- } else if (!g_strncasecmp (resp, "OK [UIDVALIDITY ", 16)) {
- validity = strtoul (resp + 16, NULL, 10);
- } else if (isdigit ((unsigned char)*resp)) {
- unsigned long num = strtoul (resp, &resp, 10);
-
- if (!g_strncasecmp (resp, " EXISTS", 7))
- exists = num;
- }
- }
- camel_imap_response_free (response);
-
- folder->summary = camel_imap_summary_new (summary_file, validity);
- 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;
- }
-
- CAMEL_IMAP_STORE_LOCK(imap_store, command_lock);
- imap_rescan (folder, exists, ex);
- CAMEL_IMAP_STORE_UNLOCK(imap_store, command_lock);
- if (camel_exception_is_set (ex)) {
- camel_object_unref (CAMEL_OBJECT (folder));
- return NULL;
- }
-
- return folder;
-}
-
-/* Called with the store's command_lock locked */
-void
-camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response,
- CamelException *ex)
-{
- unsigned long exists = 0, val, uid;
- CamelMessageInfo *info;
- int i, count;
- char *resp;
-
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i] + 2;
-
- exists = strtoul (resp, &resp, 10);
- if (!g_strncasecmp (resp, " EXISTS", 7))
- break;
- }
- if (i == response->untagged->len) {
- g_warning ("Server response did not include EXISTS info");
- return;
- }
-
- count = camel_folder_summary_count (folder->summary);
-
- /* If we've lost messages, we have to rescan everything */
- if (exists < count) {
- imap_rescan (folder, exists, ex);
- return;
- }
-
- if (count != 0) {
- /* 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 (CAMEL_IMAP_STORE (folder->parent_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 != count || g_strncasecmp (resp, " FETCH (", 8) != 0)
- continue;
- resp = e_strstrcase (resp, "UID ");
- if (!resp)
- continue;
- uid = strtoul (resp + 4, NULL, 10);
- break;
- }
- camel_imap_response_free (response);
-
- info = camel_folder_summary_index (folder->summary, count - 1);
- val = strtoul (camel_message_info_uid (info), NULL, 10);
- camel_folder_summary_info_free (folder->summary, info);
- if (uid == 0 || uid != val) {
- imap_rescan (folder, exists, ex);
- return;
- }
- }
-
- /* OK. So now we know that no messages have been expunged. Whew.
- * Now see if messages have been added.
- */
- 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 ((CamelObject *)imap_folder->search);
-
-#ifdef ENABLE_THREADS
- g_mutex_free(imap_folder->priv->search_lock);
-#endif
- g_free(imap_folder->priv);
-}
-
-static void
-imap_refresh_info (CamelFolder *folder, CamelException *ex)
-{
- CAMEL_IMAP_STORE_LOCK (folder->parent_store, command_lock);
- imap_rescan (folder, camel_folder_summary_count (folder->summary), ex);
- CAMEL_IMAP_STORE_UNLOCK (folder->parent_store, command_lock);
-}
-
-/* Called with the store's command_lock locked */
-static void
-imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- struct {
- char *uid;
- guint32 flags;
- } *new = NULL;
- char *resp, *p, *flags;
- const char *uid;
- int i, j, seq, summary_len;
- CamelMessageInfo *info;
- CamelImapMessageInfo *iinfo;
- GArray *removed;
-
- camel_operation_start(NULL, _("Scanning IMAP folder"));
-
- /* Get UIDs and flags of all messages. */
- if (exists > 0) {
- response = camel_imap_command (store, folder, ex,
- "FETCH 1:%d (UID FLAGS)",
- exists);
- if (!response)
- return;
-
- new = g_malloc0 (exists * sizeof (*new));
- for (i = 0; i < response->untagged->len; i++) {
- resp = response->untagged->pdata[i];
-
- seq = strtoul (resp + 2, &resp, 10);
- if (g_strncasecmp (resp, " FETCH ", 7) != 0)
- continue;
-
- uid = e_strstrcase (resp, "UID ");
- if (uid) {
- uid += 4;
- strtoul (uid, &p, 10);
- new[seq - 1].uid = g_strndup (uid, p - uid);
- }
-
- flags = e_strstrcase (resp, "FLAGS ");
- if (flags) {
- flags += 6;
- new[seq - 1].flags = imap_parse_flag_list (&flags);
- }
- }
- camel_imap_response_free (response);
- }
-
- /* If we find a UID in the summary that doesn't correspond to
- * the UID in the folder, that it means the message was
- * deleted on the server, so we remove it from the summary.
- */
- removed = g_array_new (FALSE, FALSE, sizeof (int));
- summary_len = camel_folder_summary_count (folder->summary);
- for (i = 0; i < summary_len && i < exists; i++) {
- int pc = (i*100)/MIN(summary_len, exists);
-
- camel_operation_progress(NULL, pc);
-
- /* Shouldn't happen, but... */
- if (!new[i].uid)
- continue;
-
- info = camel_folder_summary_index (folder->summary, i);
- iinfo = (CamelImapMessageInfo *)info;
-
- if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
- seq = i + 1;
- g_array_append_val (removed, seq);
- i--;
- summary_len--;
- continue;
- }
-
- /* Update summary flags */
- if (new[i].flags != iinfo->server_flags) {
- guint32 server_set, server_cleared;
-
- server_set = new[i].flags & ~iinfo->server_flags;
- server_cleared = iinfo->server_flags & ~new[i].flags;
-
- info->flags = (info->flags | server_set) & ~server_cleared;
- iinfo->server_flags = new[i].flags;
-
- camel_object_trigger_event (CAMEL_OBJECT (folder),
- "message_changed",
- g_strdup (new[i].uid));
- }
-
- camel_folder_summary_info_free(folder->summary, info);
-
- g_free (new[i].uid);
- }
-
- /* Remove any leftover cached summary messages. */
- for (j = i + 1; j < summary_len; j++) {
- seq = j - removed->len;
- g_array_append_val (removed, seq);
- }
-
- /* Free remaining memory. */
- while (i < exists)
- g_free (new[i++].uid);
- g_free (new);
-
- /* And finally update the summary. */
- camel_imap_folder_changed (folder, exists, removed, ex);
- g_array_free (removed, TRUE);
-
- camel_operation_end(NULL);
-}
-
-/* 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. The caller must free the infos, the
- * array, and the set string.
- */
-static GPtrArray *
-get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
-{
- GPtrArray *matches;
- CamelMessageInfo *info;
- int i, max, range;
- GString *gset;
-
- matches = g_ptr_array_new ();
- gset = g_string_new ("");
- max = camel_folder_summary_count (folder->summary);
- range = -1;
- for (i = 0; i < max; i++) {
- info = camel_folder_summary_index (folder->summary, i);
- if (!info)
- continue;
- if ((info->flags & mask) != flags) {
- camel_folder_summary_info_free (folder->summary, info);
- if (range != -1) {
- if (range != i - 1) {
- info = matches->pdata[matches->len - 1];
- g_string_sprintfa (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_sprintfa (gset, "%s", camel_message_info_uid (info));
- }
- if (range != -1 && range != max - 1) {
- info = matches->pdata[matches->len - 1];
- g_string_sprintfa (gset, ":%s", camel_message_info_uid (info));
- }
-
- if (matches->len) {
- *set = gset->str;
- g_string_free (gset, FALSE);
- return matches;
- } else {
- g_string_free (gset, TRUE);
- g_ptr_array_free (matches, TRUE);
- return NULL;
- }
-}
-
-static void
-imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- CamelMessageInfo *info;
- GPtrArray *matches;
- char *set, *flaglist;
- int i, j, max;
-
- max = camel_folder_summary_count (folder->summary);
-
- /* If we're expunging then we don't need to be precise about the
- * flags of deleted messages. Just add \Deleted to anything that
- * should have it.
- */
- if (expunge && (matches = get_matching (folder, CAMEL_MESSAGE_DELETED,
- CAMEL_MESSAGE_DELETED, &set))) {
- for (i = 0; i < matches->len; i++) {
- info = matches->pdata[i];
- info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- camel_folder_summary_info_free (folder->summary, info);
- }
- g_ptr_array_free (matches, TRUE);
- camel_folder_summary_touch (folder->summary);
-
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- response = camel_imap_command (store, folder, ex,
- "UID STORE %s +FLAGS.SILENT \\Deleted",
- set);
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- g_free (set);
- if (response)
- camel_imap_response_free (response);
- if (camel_exception_is_set (ex))
- return;
- }
-
- /* OK, now, 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.
- */
- for (i = 0; i < max; i++) {
- info = camel_folder_summary_index (folder->summary, i);
- if (!info)
- continue;
- if (!(info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- camel_folder_summary_info_free (folder->summary, info);
- continue;
- }
-
- flaglist = imap_create_flag_list (info->flags);
- matches = get_matching (folder, info->flags & (CAMEL_IMAP_SERVER_FLAGS | CAMEL_MESSAGE_FOLDER_FLAGGED),
- CAMEL_IMAP_SERVER_FLAGS | CAMEL_MESSAGE_FOLDER_FLAGGED, &set);
- camel_folder_summary_info_free (folder->summary, info);
-
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- response = camel_imap_command (store, folder, ex,
- "UID STORE %s FLAGS.SILENT %s",
- set, flaglist);
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- g_free (set);
- g_free (flaglist);
- if (response)
- camel_imap_response_free (response);
- if (!camel_exception_is_set (ex)) {
- for (j = 0; j < matches->len; j++) {
- info = matches->pdata[j];
- info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- ((CamelImapMessageInfo*)info)->server_flags =
- info->flags & CAMEL_IMAP_SERVER_FLAGS;
- }
- camel_folder_summary_touch (folder->summary);
- }
- for (j = 0; j < matches->len; j++) {
- info = matches->pdata[j];
- camel_folder_summary_info_free (folder->summary, info);
- }
- g_ptr_array_free (matches, TRUE);
-
- if (camel_exception_is_set (ex))
- return;
- }
-
- if (expunge) {
- CAMEL_IMAP_STORE_LOCK(store, command_lock);
- response = camel_imap_command (store, folder, ex, "EXPUNGE");
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
- camel_imap_response_free (response);
- }
-
- camel_folder_summary_save (folder->summary);
-
- camel_operation_end(NULL);
-}
-
-static void
-imap_expunge (CamelFolder *folder, CamelException *ex)
-{
- imap_sync (folder, TRUE, ex);
-}
-
-static const char *
-imap_get_full_name (CamelFolder *folder)
-{
- CamelURL *url = ((CamelService *)folder->parent_store)->url;
- int len;
-
- if (!url->path || !*url->path || !strcmp (url->path, "/"))
- return folder->full_name;
- len = strlen (url->path + 1);
- if (!strncmp (url->path + 1, folder->full_name, len) &&
- strlen (folder->full_name) > len + 1)
- return folder->full_name + len + 1;
- return folder->full_name;
-}
-
-static void
-imap_append_message (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- CamelStream *memstream;
- CamelMimeFilter *crlf_filter;
- CamelStreamFilter *streamfilter;
- GByteArray *ba;
- char *flagstr, *result;
-
- /* create flag string param */
- if (info && info->flags)
- flagstr = imap_create_flag_list (info->flags);
- else
- flagstr = NULL;
-
- /* FIXME: We could avoid this if we knew how big the message was. */
- memstream = camel_stream_mem_new ();
- ba = g_byte_array_new ();
- camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (memstream), ba);
-
- streamfilter = camel_stream_filter_new_with_stream (memstream);
- crlf_filter = camel_mime_filter_crlf_new (
- CAMEL_MIME_FILTER_CRLF_ENCODE,
- CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- camel_stream_filter_add (streamfilter, crlf_filter);
- camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message),
- CAMEL_STREAM (streamfilter));
- camel_object_unref (CAMEL_OBJECT (streamfilter));
- camel_object_unref (CAMEL_OBJECT (crlf_filter));
- camel_object_unref (CAMEL_OBJECT (memstream));
-
- CAMEL_IMAP_STORE_LOCK(store, command_lock);
- response = camel_imap_command (store, NULL, ex, "APPEND %S%s%s {%d}",
- folder->full_name, flagstr ? " " : "",
- flagstr ? flagstr : "", ba->len);
- g_free (flagstr);
-
- if (!response) {
- g_byte_array_free (ba, TRUE);
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
- return;
- }
- result = camel_imap_response_extract_continuation (response, ex);
- if (!result) {
- g_byte_array_free (ba, TRUE);
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
- return;
- }
- g_free (result);
-
- /* send the rest of our data - the mime message */
- g_byte_array_append (ba, "\0", 3);
- response = camel_imap_command_continuation (store, ex, ba->data);
- g_byte_array_free (ba, TRUE);
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
- if (!response)
- return;
- camel_imap_response_free (response);
-}
-
-static void
-imap_copy_message_to (CamelFolder *source, const char *uid,
- CamelFolder *destination, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store);
- CamelImapResponse *response;
- CamelMessageInfo *mi;
-
- mi = camel_folder_summary_uid (source->summary, uid);
- g_return_if_fail (mi != NULL);
-
- /* Sync message flags if needed. */
- if (mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) {
- char *flaglist;
-
- flaglist = imap_create_flag_list (mi->flags);
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- response = camel_imap_command (store, source, ex,
- "UID STORE %s FLAGS.SILENT %s",
- camel_message_info_uid (mi),
- flaglist);
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- g_free (flaglist);
- if (camel_exception_is_set (ex)) {
- camel_folder_summary_info_free (source->summary, mi);
- return;
- }
- camel_imap_response_free (response);
-
- mi->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- ((CamelImapMessageInfo *)mi)->server_flags =
- mi->flags & CAMEL_IMAP_SERVER_FLAGS;
- }
- camel_folder_summary_info_free (source->summary, mi);
-
- if (camel_exception_is_set (ex))
- return;
-
- /* Now copy it */
- CAMEL_IMAP_STORE_LOCK(store, command_lock);
- response = camel_imap_command (store, source, ex, "UID COPY %s %S",
- uid, destination->full_name);
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
-
- if (camel_exception_is_set (ex))
- return;
-
- camel_imap_response_free (response);
-
- /* Force the destination folder to notice its new messages. */
- response = camel_imap_command (store, destination, NULL, "NOOP");
- camel_imap_response_free (response);
- }
-
-static void
-imap_move_message_to (CamelFolder *source, const char *uid,
- CamelFolder *destination, CamelException *ex)
-{
- imap_copy_message_to (source, uid, destination, ex);
- if (camel_exception_is_set (ex))
- return;
-
- camel_folder_delete_message (source, uid);
-}
-
-static GPtrArray *
-imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- GPtrArray *matches, *summary;
-
- /* we could get around this by creating a new search object each time,
- but i doubt its worth it since any long operation would lock the
- command channel too */
- CAMEL_IMAP_FOLDER_LOCK(folder, search_lock);
-
- if (!imap_folder->search)
- imap_folder->search = camel_imap_search_new ();
-
- camel_folder_search_set_folder (imap_folder->search, folder);
- summary = camel_folder_get_summary(folder);
- camel_folder_search_set_summary(imap_folder->search, summary);
- matches = camel_folder_search_execute_expression (imap_folder->search, expression, ex);
-
- CAMEL_IMAP_FOLDER_UNLOCK(folder, search_lock);
-
- camel_folder_free_summary(folder, summary);
-
- return matches;
-}
-
-static 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);
-}
-
-/* parse a header response (starting after the first ' ' after
- * *@headers_p) and construct a content-free CamelMedium from it.
- */
-static CamelMedium *
-parse_headers (char **headers_p, CamelType medium_type)
-{
- CamelMedium *medium;
- CamelStream *stream;
- char *headers;
- int len;
-
- *headers_p = strchr (*headers_p, ' ');
- if (!*headers_p)
- return FALSE;
- (*headers_p)++;
-
- headers = imap_parse_nstring (headers_p, &len);
- if (!headers)
- return FALSE;
- stream = camel_stream_mem_new_with_buffer (headers, len);
- g_free (headers);
-
- medium = CAMEL_MEDIUM (camel_object_new (medium_type));
- camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (medium), stream);
- camel_object_unref (CAMEL_OBJECT (stream));
-
- return medium;
-}
-
-static CamelMedium *
-fetch_medium (CamelFolder *folder, const char *uid, const char *section_text,
- CamelType type, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- CamelMedium *medium;
- char *result, *p;
-
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- 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);
- }
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- if (!response)
- return NULL;
-
- /* FIXME: there could be multiple lines of FETCH response. */
- result = camel_imap_response_extract (response, "FETCH", ex);
- if (!result)
- return NULL;
-
-
- if (store->server_level < IMAP_LEVEL_IMAP4REV1 && !*section_text)
- p = e_strstrcase (result, "RFC822");
- else
- p = e_strstrcase (result, "BODY");
-
- if (p)
- medium = parse_headers (&p, type);
- else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not find message body in FETCH "
- "response."));
- medium = NULL;
- }
- g_free (result);
-
- return medium;
-}
-
-static CamelMimeMessage *get_message (CamelFolder *folder, const char *uid,
- const char *part_specifier,
- CamelMessageContentInfo *ci,
- CamelException *ex);
-
-/* Fetch the contents of the MIME part indicated by @ci, which is part
- * of message @uid in @folder.
- */
-static CamelDataWrapper *
-get_content (CamelFolder *folder, const char *uid, const char *part_spec,
- CamelMimePart *part, CamelMessageContentInfo *ci,
- CamelException *ex)
-{
- char *child_spec;
-
- /* There are three cases: multipart, message/rfc822, and "other" */
-
- if (header_content_type_is (ci->type, "multipart", "*")) {
- CamelMultipart *body_mp;
- CamelDataWrapper *content;
- int speclen, num;
-
- body_mp = camel_multipart_new ();
- camel_data_wrapper_set_mime_type_field (
- CAMEL_DATA_WRAPPER (body_mp), ci->type);
- camel_multipart_set_boundary (body_mp, NULL);
-
- speclen = strlen (part_spec);
- child_spec = g_malloc (speclen + 15);
- memcpy (child_spec, part_spec, speclen);
- if (speclen > 0)
- child_spec[speclen++] = '.';
-
- ci = ci->childs;
- num = 1;
- while (ci) {
- sprintf (child_spec + speclen, "%d.MIME", num++);
- part = (CamelMimePart *)fetch_medium (folder, uid, child_spec, CAMEL_MIME_PART_TYPE, ex);
- *(strchr (child_spec + speclen, '.')) = '\0';
- if (part)
- content = get_content (folder, uid, child_spec, part, ci, ex);
- if (!part || !content) {
- g_free (child_spec);
- camel_object_unref (CAMEL_OBJECT (part));
- camel_object_unref (CAMEL_OBJECT (body_mp));
- return NULL;
- }
- camel_medium_set_content_object (CAMEL_MEDIUM (part),
- content);
- camel_object_unref (CAMEL_OBJECT (content));
- camel_multipart_add_part (body_mp, part);
- camel_object_unref (CAMEL_OBJECT (part));
-
- ci = ci->next;
- }
- g_free (child_spec);
-
- return (CamelDataWrapper *)body_mp;
- } else if (header_content_type_is (ci->type, "message", "rfc822")) {
- return (CamelDataWrapper *)
- get_message (folder, uid, part_spec, ci->childs, ex);
- } else {
- CamelDataWrapper *content;
-
- if (!ci->parent || header_content_type_is (ci->parent->type, "message", "rfc822"))
- child_spec = g_strdup_printf ("%s%s1", part_spec, *part_spec ? "." : "");
- else
- child_spec = g_strdup (part_spec);
- content = camel_imap_wrapper_new (folder, ci->type, uid, child_spec, part);
- g_free (child_spec);
- return content;
- }
-}
-
-static CamelMimeMessage *
-get_message (CamelFolder *folder, const char *uid, const char *part_spec,
- CamelMessageContentInfo *ci, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelDataWrapper *content;
- CamelMimeMessage *msg;
- char *section_text;
-
- section_text = g_strdup_printf ("%s%s%s", part_spec, *part_spec ? "." : "",
- store->server_level >= IMAP_LEVEL_IMAP4REV1 ? "HEADER" : "0");
- msg = (CamelMimeMessage *)fetch_medium (folder, uid, section_text, CAMEL_MIME_MESSAGE_TYPE, ex);
- g_free (section_text);
- if (!msg)
- return NULL;
-
- content = get_content (folder, uid, part_spec, CAMEL_MIME_PART (msg), ci, ex);
- if (!content) {
- camel_object_unref (CAMEL_OBJECT (msg));
- return NULL;
- }
-
- camel_medium_set_content_object (CAMEL_MEDIUM (msg), content);
- camel_object_unref (CAMEL_OBJECT (content));
-
- return msg;
-}
-
-/* FIXME: I pulled this number out of my butt. */
-#define IMAP_SMALL_BODY_SIZE 5120
-
-static CamelMimeMessage *
-imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
-{
- CamelMessageInfo *mi;
- CamelMimeMessage *msg;
-
- mi = camel_folder_summary_uid (folder->summary, uid);
- g_return_val_if_fail (mi != NULL, NULL);
-
- /* Fetch small messages directly. */
- if (mi->size < IMAP_SMALL_BODY_SIZE) {
- camel_folder_summary_info_free (folder->summary, mi);
- return (CamelMimeMessage *)fetch_medium (folder, uid, "", CAMEL_MIME_MESSAGE_TYPE, ex);
- }
-
- /* For larger messages, fetch the structure and build a message
- * with offline parts. (We check mi->content->type rather than
- * mi->content because camel_folder_summary_info_new always creates
- * an empty content struct.)
- */
- if (!mi->content->type) {
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- char *result, *p;
-
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- response = camel_imap_command (store, folder, ex,
- "UID FETCH %s BODY", uid);
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- if (!response) {
- camel_folder_summary_info_free (folder->summary, mi);
- return NULL;
- }
- /* FIXME, wrong */
- result = camel_imap_response_extract (response, "FETCH", ex);
- if (!result) {
- camel_folder_summary_info_free (folder->summary, mi);
- return NULL;
- }
-
- p = e_strstrcase (result, "BODY ");
- if (p) {
- p += 5;
- imap_parse_body (&p, folder, mi->content);
- }
- g_free (result);
- if (!mi->content->type) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not find message body in FETCH response."));
- camel_folder_summary_info_free (folder->summary, mi);
- return NULL;
- }
- }
-
- msg = get_message (folder, uid, "", mi->content, ex);
- camel_folder_summary_info_free (folder->summary, mi);
-
- return msg;
-}
-
-static const char *
-imap_protocol_get_summary_specifier (CamelImapStore *store)
-{
- if (store->server_level >= IMAP_LEVEL_IMAP4REV1)
- return "UID FLAGS RFC822.SIZE BODY.PEEK[HEADER]";
- else
- return "UID FLAGS RFC822.SIZE RFC822.HEADER";
-}
-
-static void
-imap_update_summary (CamelFolder *folder, int first, int last,
- CamelFolderChangeInfo *changes, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapResponse *response;
- GPtrArray *headers, *messages;
- const char *summary_specifier;
- char *p, *uid;
- int i, seq, count;
- CamelMimeMessage *msg;
- CamelMessageInfo *mi;
- guint32 flags, size;
-
- summary_specifier = imap_protocol_get_summary_specifier (store);
- /* We already have the command lock */
- if (first == last) {
- response = camel_imap_command (store, folder, ex,
- "FETCH %d (%s)", first,
- summary_specifier);
- } else {
- response = camel_imap_command (store, folder, ex,
- "FETCH %d:%d (%s)", first,
- last, summary_specifier);
- }
-
- if (!response)
- return;
-
- count = camel_folder_summary_count (folder->summary);
- messages = g_ptr_array_new ();
- g_ptr_array_set_size (messages, last - first + 1);
- headers = response->untagged;
- for (i = 0; i < headers->len; i++) {
- p = headers->pdata[i];
- if (*p++ != '*' || *p++ != ' ')
- continue;
- seq = strtoul (p, &p, 10);
- if (!seq || seq < count)
- continue;
- if (g_strncasecmp (p, " FETCH (", 8) != 0)
- continue;
- p += 8;
-
- mi = messages->pdata[seq - first];
- flags = size = 0;
- uid = NULL;
- while (p && *p != ')') {
- if (*p == ' ')
- p++;
- if (!g_strncasecmp (p, "FLAGS ", 6)) {
- p += 6;
- /* FIXME user flags */
- flags = imap_parse_flag_list (&p);
- } else if (!g_strncasecmp (p, "RFC822.SIZE ", 12)) {
- size = strtoul (p + 12, &p, 10);
- } else if (!g_strncasecmp (p, "UID ", 4)) {
- uid = p + 4;
- strtoul (uid, &p, 10);
- uid = g_strndup (uid, p - uid);
- } else if (!g_strncasecmp (p, "BODY[HEADER", 11) ||
- !g_strncasecmp (p, "RFC822.HEADER", 13)) {
- msg = (CamelMimeMessage *) parse_headers (&p, CAMEL_MIME_MESSAGE_TYPE);
- mi = camel_folder_summary_info_new_from_message (folder->summary, msg);
- camel_object_unref (CAMEL_OBJECT (msg));
- } else {
- g_warning ("Waiter, I did not order this %.*s",
- (int)strcspn (p, " \n"), p);
- p = NULL;
- }
- }
-
- /* Ideally we got everything on one line, but if we
- * we didn't, and we didn't get the body yet, then we
- * have to postpone this line for later.
- */
- if (mi == NULL) {
- p = headers->pdata[i];
- g_ptr_array_remove_index (headers, i);
- g_ptr_array_add (headers, p);
- continue;
- }
-
- messages->pdata[seq - first] = mi;
- if (uid)
- camel_message_info_set_uid (mi, uid);
- if (flags)
- mi->flags = flags;
- if (size)
- mi->size = size;
- }
- camel_imap_response_free (response);
-
- for (i = 0; i < messages->len; i++) {
- mi = messages->pdata[i];
- camel_folder_summary_add (folder->summary, mi);
- camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
- }
- g_ptr_array_free (messages, TRUE);
-}
-
-/* Called with the store's command_lock locked */
-void
-camel_imap_folder_changed (CamelFolder *folder, int exists,
- GArray *expunged, CamelException *ex)
-{
- CamelFolderChangeInfo *changes;
- CamelMessageInfo *info;
- int len;
-
- 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);
- camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
- camel_folder_summary_remove (folder->summary, info);
- camel_folder_summary_info_free(folder->summary, info);
- }
- }
-
- len = camel_folder_summary_count (folder->summary);
- if (exists > len)
- imap_update_summary (folder, len + 1, 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);
-}
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
deleted file mode 100644
index a943189f5a..0000000000
--- a/camel/providers/imap/camel-imap-folder.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-folder.h : Abstract class for an imap folder */
-
-/*
- * Author:
- * Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_FOLDER_H
-#define CAMEL_IMAP_FOLDER_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-imap-types.h"
-#include "camel-folder.h"
-#include <camel/camel-folder-search.h>
-
-#define CAMEL_IMAP_FOLDER_TYPE (camel_imap_folder_get_type ())
-#define CAMEL_IMAP_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_FOLDER_TYPE, CamelImapFolder))
-#define CAMEL_IMAP_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAP_FOLDER_TYPE, CamelImapFolderClass))
-#define CAMEL_IS_IMAP_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_FOLDER_TYPE))
-
-struct _CamelImapFolder {
- CamelFolder parent_object;
-
- struct _CamelImapFolderPrivate *priv;
-
- CamelFolderSearch *search;
-};
-
-
-typedef struct {
- CamelFolderClass parent_class;
-
- /* Virtual methods */
-
-} CamelImapFolderClass;
-
-
-/* public methods */
-CamelFolder *camel_imap_folder_new (CamelStore *parent,
- const char *folder_name,
- const char *short_name,
- const char *summary_file,
- CamelException *ex);
-
-void camel_imap_folder_selected (CamelFolder *folder,
- CamelImapResponse *response,
- CamelException *ex);
-
-void camel_imap_folder_changed (CamelFolder *folder, int exists,
- GArray *expunged, CamelException *ex);
-
-/* Standard Camel function */
-CamelType camel_imap_folder_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAP_FOLDER_H */
diff --git a/camel/providers/imap/camel-imap-private.h b/camel/providers/imap/camel-imap-private.h
deleted file mode 100644
index c7af3ee5e6..0000000000
--- a/camel/providers/imap/camel-imap-private.h
+++ /dev/null
@@ -1,88 +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@helixcode.com>
- *
- * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_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 */
-
-#include "config.h"
-
-#ifdef ENABLE_THREADS
-#include "e-util/e-msgport.h"
-#endif
-
-struct _CamelImapStorePrivate {
-#ifdef ENABLE_THREADS
- EMutex *command_lock; /* for locking the command stream for a complete operation */
-#endif
-};
-
-#ifdef ENABLE_THREADS
-#define CAMEL_IMAP_STORE_LOCK(f, l) (e_mutex_lock(((CamelImapStore *)f)->priv->l))
-#define CAMEL_IMAP_STORE_UNLOCK(f, l) (e_mutex_unlock(((CamelImapStore *)f)->priv->l))
-#else
-#define CAMEL_IMAP_STORE_LOCK(f, l)
-#define CAMEL_IMAP_STORE_UNLOCK(f, l)
-#endif
-
-struct _CamelImapFolderPrivate {
-#ifdef ENABLE_THREADS
- GMutex *search_lock; /* for locking the search object */
-#endif
-};
-
-#ifdef ENABLE_THREADS
-#define CAMEL_IMAP_FOLDER_LOCK(f, l) (g_mutex_lock(((CamelImapFolder *)f)->priv->l))
-#define CAMEL_IMAP_FOLDER_UNLOCK(f, l) (g_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 9b962df5f4..0000000000
--- a/camel/providers/imap/camel-imap-provider.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-provider.c: imap provider registration code */
-
-/*
- * Authors: Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#include "config.h"
-#include "camel-imap-store.h"
-#include "camel-provider.h"
-#include "camel-session.h"
-#include "camel-url.h"
-
-static void add_hash (guint *hash, char *s);
-static guint imap_url_hash (gconstpointer key);
-static gint check_equal (char *s1, char *s2);
-static gint imap_url_equal (gconstpointer a, gconstpointer b);
-
-static CamelProvider imap_provider = {
- "imap",
- N_("IMAPv4"),
-
- N_("For reading and storing mail on IMAP servers."),
-
- "mail",
-
- CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
- CAMEL_PROVIDER_IS_STORAGE,
-
- CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST |
- CAMEL_URL_ALLOW_PATH | CAMEL_URL_ALLOW_AUTH,
-
- { 0, 0 },
-
- NULL
-};
-
-void
-camel_provider_module_init (CamelSession *session)
-{
- imap_provider.object_types[CAMEL_PROVIDER_STORE] =
- camel_imap_store_get_type();
-
- imap_provider.service_cache = g_hash_table_new (imap_url_hash, imap_url_equal);
-
- camel_session_register_provider (session, &imap_provider);
-}
-
-static void
-add_hash (guint *hash, char *s)
-{
- if (s)
- *hash ^= g_str_hash(s);
-}
-
-static guint
-imap_url_hash (gconstpointer key)
-{
- const CamelURL *u = (CamelURL *)key;
- guint hash = 0;
-
- add_hash (&hash, u->user);
- add_hash (&hash, u->authmech);
- add_hash (&hash, u->host);
- hash ^= u->port;
-
- return hash;
-}
-
-static gint
-check_equal (char *s1, char *s2)
-{
- if (s1 == NULL) {
- if (s2 == NULL)
- return TRUE;
- else
- return FALSE;
- }
-
- if (s2 == NULL)
- return FALSE;
-
- return strcmp (s1, s2) == 0;
-}
-
-static gint
-imap_url_equal (gconstpointer a, gconstpointer b)
-{
- const CamelURL *u1 = a, *u2 = b;
-
- return check_equal (u1->user, u2->user)
- && check_equal (u1->authmech, u2->authmech)
- && check_equal (u1->host, u2->host)
- && u1->port == u2->port;
-}
diff --git a/camel/providers/imap/camel-imap-search.c b/camel/providers/imap/camel-imap-search.c
deleted file mode 100644
index 06cf4a8d30..0000000000
--- a/camel/providers/imap/camel-imap-search.c
+++ /dev/null
@@ -1,151 +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@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#include <config.h>
-
-#include <string.h>
-
-#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"
-
-static ESExpResult *
-imap_body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv,
- CamelFolderSearch *s);
-
-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);
-
- /* virtual method overload */
- camel_folder_search_class->body_contains = imap_body_contains;
-}
-
-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, NULL, NULL);
- }
-
- return camel_imap_search_type;
-}
-
-static ESExpResult *
-imap_body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv,
- CamelFolderSearch *s)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (s->folder->parent_store);
- char *value = argv[0]->value.string;
- CamelImapResponse *response;
- char *result, *p, *lasts = NULL, *real_uid;
- const char *uid = "";
- ESExpResult *r;
- CamelMessageInfo *info;
- GHashTable *uid_hash = NULL;
-
- CAMEL_IMAP_STORE_LOCK(store, command_lock);
-
- if (s->current) {
- uid = camel_message_info_uid (s->current);
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
- response = camel_imap_command (store, s->folder, NULL,
- "UID SEARCH UID %s BODY \"%s\"",
- uid, value);
- } else {
- r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
- r->value.ptrarray = g_ptr_array_new ();
- response = camel_imap_command (store, s->folder, NULL,
- "UID SEARCH BODY \"%s\"",
- value);
- }
-
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
-
- if (!response)
- return r;
- result = camel_imap_response_extract (response, "SEARCH", NULL);
- if (!result)
- return r;
-
- p = result + sizeof ("* SEARCH");
- for (p = strtok_r (p, " ", &lasts); p; p = strtok_r (NULL, " ", &lasts)) {
- if (s->current) {
- if (!strcmp (uid, p)) {
- r->value.bool = TRUE;
- break;
- }
- } else {
- /* if we need to setup a hash of summary items, this way we get
- access to the summary memory which is locked for the duration of
- the search, and wont vanish on us */
- if (uid_hash == NULL) {
- int i;
-
- uid_hash = g_hash_table_new(g_str_hash, g_str_equal);
- for (i=0;i<s->summary->len;i++) {
- info = s->summary->pdata[i];
- g_hash_table_insert(uid_hash, (char *)camel_message_info_uid(info), info);
- }
- }
- if (g_hash_table_lookup_extended(uid_hash, p, (void *)&real_uid, (void *)&info))
- g_ptr_array_add (r->value.ptrarray, real_uid);
- }
- }
-
- /* we could probably cache this globally, but its probably not worth it */
- if (uid_hash)
- g_hash_table_destroy(uid_hash);
-
- return r;
-}
-
-/**
- * camel_imap_search_new:
- *
- * Return value: A new CamelImapSearch widget.
- **/
-CamelFolderSearch *
-camel_imap_search_new (void)
-{
- CamelFolderSearch *new = CAMEL_FOLDER_SEARCH (camel_object_new (camel_imap_search_get_type ()));
-
- camel_folder_search_construct (new);
- return new;
-}
diff --git a/camel/providers/imap/camel-imap-search.h b/camel/providers/imap/camel-imap-search.h
deleted file mode 100644
index 97fd6cd6c4..0000000000
--- a/camel/providers/imap/camel-imap-search.h
+++ /dev/null
@@ -1,51 +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@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef _CAMEL_IMAP_SEARCH_H
-#define _CAMEL_IMAP_SEARCH_H
-
-#include <camel/camel-folder-search.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;
-
-};
-
-struct _CamelImapSearchClass {
- CamelFolderSearchClass parent_class;
-
-};
-
-guint camel_imap_search_get_type (void);
-CamelFolderSearch *camel_imap_search_new (void);
-
-#endif /* ! _CAMEL_IMAP_SEARCH_H */
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
deleted file mode 100644
index a924c4dab7..0000000000
--- a/camel/providers/imap/camel-imap-store.c
+++ /dev/null
@@ -1,1135 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-store.c : class for an imap store */
-
-/*
- * Authors: Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <gal/util/e-util.h>
-
-#include "camel-imap-store.h"
-#include "camel-imap-folder.h"
-#include "camel-imap-utils.h"
-#include "camel-imap-command.h"
-#include "camel-folder.h"
-#include "camel-exception.h"
-#include "camel-session.h"
-#include "camel-stream.h"
-#include "camel-stream-buffer.h"
-#include "camel-stream-fs.h"
-#include "camel-url.h"
-#include "camel-sasl.h"
-#include "string-utils.h"
-
-#include "camel-imap-private.h"
-#include "camel-private.h"
-
-#define d(x) x
-
-/* Specified in RFC 2060 */
-#define IMAP_PORT 143
-
-static CamelRemoteStoreClass *remote_store_class = NULL;
-
-static gboolean imap_connect (CamelService *service, CamelException *ex);
-static gboolean imap_disconnect (CamelService *service, gboolean clean, CamelException *ex);
-static GList *query_auth_types (CamelService *service, gboolean connect, CamelException *ex);
-static guint hash_folder_name (gconstpointer key);
-static gint compare_folder_name (gconstpointer a, gconstpointer b);
-static CamelFolder *get_folder (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 CamelFolderInfo *get_folder_info (CamelStore *store, const char *top,
- gboolean fast, gboolean recursive,
- gboolean subscribed_only,
- CamelException *ex);
-static gboolean folder_subscribed (CamelStore *store, const char *folder_name);
-static void subscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex);
-static void unsubscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex);
-static void imap_keepalive (CamelRemoteStore *store);
-
-static void
-camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class)
-{
- /* virtual method overload */
- CamelServiceClass *camel_service_class =
- CAMEL_SERVICE_CLASS (camel_imap_store_class);
- CamelStoreClass *camel_store_class =
- CAMEL_STORE_CLASS (camel_imap_store_class);
- CamelRemoteStoreClass *camel_remote_store_class =
- CAMEL_REMOTE_STORE_CLASS (camel_imap_store_class);
-
- remote_store_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs
- (camel_remote_store_get_type ()));
-
- /* virtual method overload */
- camel_service_class->query_auth_types = query_auth_types;
- camel_service_class->connect = imap_connect;
- camel_service_class->disconnect = imap_disconnect;
-
- camel_store_class->hash_folder_name = hash_folder_name;
- camel_store_class->compare_folder_name = compare_folder_name;
- camel_store_class->get_folder = get_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;
-
- camel_store_class->folder_subscribed = folder_subscribed;
- camel_store_class->subscribe_folder = subscribe_folder;
- camel_store_class->unsubscribe_folder = unsubscribe_folder;
-
- camel_remote_store_class->keepalive = imap_keepalive;
-}
-
-static gboolean
-free_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);
-
- if (imap_store->subscribed_folders) {
- g_hash_table_foreach_remove (imap_store->subscribed_folders,
- free_key, NULL);
- g_hash_table_destroy (imap_store->subscribed_folders);
- }
- if (imap_store->authtypes) {
- g_hash_table_foreach_remove (imap_store->authtypes,
- free_key, NULL);
- g_hash_table_destroy (imap_store->authtypes);
- }
- if (imap_store->namespace)
- g_free (imap_store->namespace);
-#ifdef ENABLE_THREADS
- e_mutex_destroy(imap_store->priv->command_lock);
-#endif
- g_free(imap_store->priv);
-}
-
-static void
-camel_imap_store_init (gpointer object, gpointer klass)
-{
- CamelRemoteStore *remote_store = CAMEL_REMOTE_STORE (object);
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
- CamelStore *store = CAMEL_STORE (object);
-
- remote_store->default_port = 143;
-
- imap_store->dir_sep = '\0';
- imap_store->current_folder = NULL;
-
- store->flags = CAMEL_STORE_SUBSCRIPTIONS;
-
- imap_store->connected = FALSE;
- imap_store->subscribed_folders = NULL;
-
- imap_store->priv = g_malloc0(sizeof(*imap_store->priv));
-#ifdef ENABLE_THREADS
- imap_store->priv->command_lock = e_mutex_new(E_MUTEX_REC);
-#endif
-}
-
-CamelType
-camel_imap_store_get_type (void)
-{
- static CamelType camel_imap_store_type = CAMEL_INVALID_TYPE;
-
- if (camel_imap_store_type == CAMEL_INVALID_TYPE) {
- camel_imap_store_type =
- camel_type_register (CAMEL_REMOTE_STORE_TYPE, "CamelImapStore",
- sizeof (CamelImapStore),
- sizeof (CamelImapStoreClass),
- (CamelObjectClassInitFunc) camel_imap_store_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_store_init,
- (CamelObjectFinalizeFunc) camel_imap_store_finalize);
- }
-
- return camel_imap_store_type;
-}
-
-static struct {
- const char *name;
- guint32 flag;
-} capabilities[] = {
- { "IMAP4", IMAP_CAPABILITY_IMAP4 },
- { "IMAP4REV1", IMAP_CAPABILITY_IMAP4REV1 },
- { "STATUS", IMAP_CAPABILITY_STATUS },
- { "NAMESPACE", IMAP_CAPABILITY_NAMESPACE },
- { "UIDPLUS", IMAP_CAPABILITY_UIDPLUS },
- { "LITERAL+", IMAP_CAPABILITY_LITERALPLUS },
- { NULL, 0 }
-};
-
-/* we have remote-store:connect_lock by now */
-static gboolean
-connect_to_server (CamelService *service, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelImapResponse *response;
- char *result, *buf, *capa, *lasts;
- int i;
-
- if (!CAMEL_SERVICE_CLASS (remote_store_class)->connect (service, ex))
- return FALSE;
-
- store->command = 0;
-
- /* Read the greeting, if any. FIXME: deal with PREAUTH */
- if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (service),
- &buf, ex) < 0) {
- return FALSE;
- }
- g_free (buf);
- store->connected = TRUE;
-
- /* Find out the IMAP capabilities */
- store->capabilities = 0;
- 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 (response, "CAPABILITY", ex);
- if (!result)
- return FALSE;
-
- /* Skip over "* CAPABILITY". */
- capa = imap_next_word (result + 2);
-
- for (capa = strtok_r (capa, " ", &lasts); capa;
- capa = strtok_r (NULL, " ", &lasts)) {
- 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_strcasecmp (capa, capabilities[i].name) == 0) {
- store->capabilities |= capabilities[i].flag;
- break;
- }
- }
- }
- g_free (result);
-
- if (store->capabilities & IMAP_CAPABILITY_IMAP4REV1) {
- store->server_level = IMAP_LEVEL_IMAP4REV1;
- store->capabilities |= IMAP_CAPABILITY_STATUS;
- } else if (store->capabilities & IMAP_CAPABILITY_IMAP4)
- store->server_level = IMAP_LEVEL_IMAP4;
- else
- store->server_level = IMAP_LEVEL_UNKNOWN;
-
- return TRUE;
-}
-
-static CamelServiceAuthType password_authtype = {
- N_("Password"),
-
- N_("This option will connect to the IMAP server using a "
- "plaintext password."),
-
- "",
- TRUE
-};
-
-static GList *
-query_auth_types (CamelService *service, gboolean connect, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelServiceAuthType *authtype;
- GList *types, *sasl_types, *t;
-
- if (connect && !connect_to_server (service, ex))
- return NULL;
-
- types = CAMEL_SERVICE_CLASS (remote_store_class)->query_auth_types (service, connect, ex);
-
- sasl_types = camel_sasl_authtype_list ();
- if (connect) {
- for (t = types; t; t = t->next) {
- authtype = t->data;
-
- if (!g_hash_table_lookup (store->authtypes, authtype->authproto)) {
- g_list_remove_link (types, t);
- g_list_free_1 (t);
- }
- }
- }
- types = g_list_concat (types, sasl_types);
-
- return g_list_prepend (types, &password_authtype);
-}
-
-/* call refresh folder directly, bypassing the folder lock */
-static void
-refresh_folder_info (gpointer key, gpointer value, gpointer data)
-{
- CamelFolder *folder = CAMEL_FOLDER (value);
-
- CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->refresh_info(folder, data);
-}
-
-/* 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 */
-/* 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 */
-static void
-imap_store_refresh_folders (CamelRemoteStore *store, CamelException *ex)
-{
- CAMEL_STORE_LOCK(store, cache_lock);
-
- g_hash_table_foreach (CAMEL_STORE (store)->folders, refresh_folder_info, ex);
-
- CAMEL_STORE_UNLOCK(store, cache_lock);
-}
-
-static gboolean
-try_auth (CamelImapStore *store, const char *mech, CamelException *ex)
-{
- CamelSasl *sasl;
- CamelImapResponse *response;
- char *resp;
- char *sasl_resp;
-
- sasl = camel_sasl_new ("imap", mech, CAMEL_SERVICE (store));
-
- sasl_resp = camel_sasl_challenge_base64 (sasl, NULL, ex);
-
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- response = camel_imap_command (store, NULL, ex, "AUTHENTICATE %s%s%s",
- mech, sasl_resp ? " " : "",
- sasl_resp ? sasl_resp : "");
- if (!response)
- goto lose;
-
- while (!camel_sasl_authenticated (sasl)) {
- resp = camel_imap_response_extract_continuation (response, ex);
- if (!resp)
- goto lose;
-
- sasl_resp = camel_sasl_challenge_base64 (sasl, resp + 2, ex);
- g_free (resp);
- if (camel_exception_is_set (ex))
- goto break_and_lose;
-
- response = camel_imap_command_continuation (store, ex, sasl_resp);
- g_free (sasl_resp);
- if (!response)
- goto lose;
- }
-
- resp = camel_imap_response_extract_continuation (response, NULL);
- if (resp) {
- /* Oops. SASL claims we're done, but the IMAP server
- * doesn't think so...
- */
- g_free (resp);
- goto lose;
- }
-
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- return TRUE;
-
- break_and_lose:
- /* Get the server out of "waiting for continuation data" mode. */
- response = camel_imap_command_continuation (store, NULL, "*");
- if (response)
- camel_imap_response_free (response);
-
- lose:
- if (!camel_exception_is_set (ex)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Bad authentication response from server."));
- }
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- return FALSE;
-}
-
-static gboolean
-imap_connect (CamelService *service, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelSession *session = camel_service_get_session (service);
- char *result, *errbuf = NULL, *name;
- CamelImapResponse *response;
- gboolean authenticated = FALSE;
- int len, i, flags;
- CamelServiceAuthType *authtype = NULL;
-
- if (connect_to_server (service, ex) == 0)
- return FALSE;
-
- 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);
- 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) {
- authenticated = try_auth (store, authtype->authproto, ex);
- if (!authenticated) {
- camel_service_disconnect (service, TRUE, NULL);
- return FALSE;
- }
- }
- }
-
- while (!authenticated) {
- if (errbuf) {
- /* We need to un-cache the password before prompting again */
- camel_session_query_authenticator (
- session, CAMEL_AUTHENTICATOR_TELL, NULL,
- TRUE, service, "password", ex);
- g_free (service->url->passwd);
- service->url->passwd = NULL;
- }
-
- if (!service->url->passwd) {
- char *prompt;
-
- prompt = g_strdup_printf (_("%sPlease enter the IMAP "
- "password for %s@%s"),
- errbuf ? errbuf : "",
- service->url->user,
- service->url->host);
- service->url->passwd =
- camel_session_query_authenticator (
- session, CAMEL_AUTHENTICATOR_ASK,
- prompt, TRUE, service, "password", ex);
- g_free (prompt);
- g_free (errbuf);
- errbuf = NULL;
-
- if (!service->url->passwd) {
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- "You didn\'t enter a password.");
- camel_service_disconnect (service, TRUE, NULL);
- return FALSE;
- }
- }
-
- if (authtype)
- authenticated = try_auth (store, authtype->authproto, ex);
- else {
- CAMEL_IMAP_STORE_LOCK(store, command_lock);
- response = camel_imap_command (store, NULL, ex,
- "LOGIN %S %S",
- service->url->user,
- service->url->passwd);
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
- if (response) {
- camel_imap_response_free (response);
- authenticated = TRUE;
- }
- }
- if (!authenticated) {
- errbuf = g_strdup_printf (_("Unable to authenticate "
- "to IMAP server.\n%s\n\n"),
- camel_exception_get_description (ex));
- camel_exception_clear (ex);
- }
- }
-
- /* Get subscribed folders */
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- response = camel_imap_command (store, NULL, ex, "LSUB \"\" \"*\"");
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- if (!response)
- return FALSE;
- store->subscribed_folders = g_hash_table_new (g_str_hash, g_str_equal);
- for (i = 0; i < response->untagged->len; i++) {
- result = response->untagged->pdata[i];
- if (!imap_parse_list_response (result, &flags, NULL, &name))
- continue;
- if (flags & (IMAP_LIST_FLAG_MARKED | IMAP_LIST_FLAG_UNMARKED))
- store->useful_lsub = TRUE;
- if (flags & IMAP_LIST_FLAG_NOSELECT) {
- g_free (name);
- continue;
- }
- g_hash_table_insert (store->subscribed_folders, name,
- GINT_TO_POINTER (1));
- }
- camel_imap_response_free (response);
-
- /* Get namespace and hierarchy separator */
- if (service->url->path && strlen (service->url->path) > 1)
- store->namespace = g_strdup (service->url->path + 1);
- else if (store->capabilities & IMAP_CAPABILITY_NAMESPACE) {
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- response = camel_imap_command (store, NULL, ex, "NAMESPACE");
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- if (!response)
- return FALSE;
-
- result = camel_imap_response_extract (response, "NAMESPACE", ex);
- if (!result)
- return FALSE;
-
- name = e_strstrcase (result, "NAMESPACE ((");
- if (name) {
- char *sep;
-
- name += 12;
- store->namespace = imap_parse_string (&name, &len);
- if (name && *name++ == ' ') {
- sep = imap_parse_string (&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) {
- CAMEL_IMAP_STORE_LOCK(store, command_lock);
- 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);
- }
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
-
- if (!response)
- return FALSE;
-
- result = camel_imap_response_extract (response, "LIST", NULL);
- if (result) {
- imap_parse_list_response (result, NULL, &store->dir_sep, NULL);
- g_free (result);
- }
- if (!store->dir_sep)
- store->dir_sep = '/'; /* Guess */
- }
-
- /* Generate base URL */
- store->base_url = camel_url_to_string (service->url, FALSE);
- len = strlen (store->base_url);
- if (service->url->path)
- store->base_url[len - strlen (service->url->path) + 1] = '\0';
- else {
- store->base_url = g_realloc (store->base_url, len + 2);
- store->base_url[len] = '/';
- store->base_url[len + 1] = '\0';
- }
-
- /* Find our storage path. */
- if (!store->storage_path) {
- store->storage_path =
- camel_session_get_storage_path (session, service, ex);
- if (camel_exception_is_set (ex))
- return FALSE;
- }
-
- imap_store_refresh_folders (CAMEL_REMOTE_STORE (store), ex);
-
- return !camel_exception_is_set (ex);
-}
-
-static gboolean
-imap_disconnect (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelImapResponse *response;
-
- if (store->connected && clean) {
- /* send the logout command */
-
- /* NB: this lock probably isn't required */
- CAMEL_IMAP_STORE_LOCK(store, command_lock);
- response = camel_imap_command (store, NULL, ex, "LOGOUT");
- CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
- camel_imap_response_free (response);
- }
- store->connected = FALSE;
- store->current_folder = NULL;
-
- if (store->subscribed_folders) {
- g_hash_table_foreach_remove (store->subscribed_folders,
- free_key, NULL);
- g_hash_table_destroy (store->subscribed_folders);
- store->subscribed_folders = NULL;
- }
-
- if (store->namespace) {
- g_free (store->namespace);
- store->namespace = NULL;
- }
-
- return CAMEL_SERVICE_CLASS (remote_store_class)->disconnect (service, clean, ex);
-}
-
-/* NOTE: Must have imap_store::command_lock before calling this */
-static gboolean
-imap_folder_exists (CamelImapStore *store, const char *folder_name,
- gboolean *selectable, char **short_name,
- CamelException *ex)
-{
- CamelImapResponse *response;
- char *result, sep;
- int flags;
-
- if (!g_strcasecmp (folder_name, "INBOX")) {
- if (selectable)
- *selectable = TRUE;
- if (short_name)
- *short_name = g_strdup ("INBOX");
- return TRUE;
- }
-
- response = camel_imap_command (store, NULL, ex, "LIST \"\" %S",
- folder_name);
- if (!response)
- return FALSE;
- result = camel_imap_response_extract (response, "LIST", ex);
- if (!result)
- return FALSE;
-
- if (!imap_parse_list_response (result, &flags, &sep, NULL))
- return FALSE;
-
- if (selectable)
- *selectable = !(flags & IMAP_LIST_FLAG_NOSELECT);
- if (short_name) {
- *short_name = strrchr (folder_name, sep);
- if (*short_name)
- *short_name = g_strdup (*short_name + 1);
- else
- *short_name = g_strdup (folder_name);
- }
-
- return TRUE;
-}
-
-/* NOTE: Must have imap_store::command_lock before calling this */
-static gboolean
-imap_create (CamelImapStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelImapResponse *response;
-
- response = camel_imap_command (store, NULL, ex, "CREATE %S",
- folder_name);
- camel_imap_response_free (response);
-
- return !camel_exception_is_set (ex);
-}
-
-static guint
-hash_folder_name (gconstpointer key)
-{
- if (g_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_strcasecmp (a, "INBOX") == 0)
- aname = "INBOX";
- if (g_strcasecmp (b, "INBOX") == 0)
- bname = "INBOX";
- return g_str_equal (aname, bname);
-}
-
-static CamelFolder *
-get_folder (CamelStore *store, const char *folder_name, guint32 flags,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelFolder *new_folder = NULL;
- char *short_name, *summary_file, *p;
- gboolean selectable;
-
- if (!camel_remote_store_connected (CAMEL_REMOTE_STORE (store), ex))
- return NULL;
-
- /* lock around the whole lot to check/create atomically */
- CAMEL_IMAP_STORE_LOCK(imap_store, command_lock);
- if (!imap_folder_exists (imap_store, folder_name,
- &selectable, &short_name, ex)) {
- if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0
- || (!imap_create (imap_store, folder_name, ex))
- || (!imap_folder_exists (imap_store, folder_name,
- &selectable, &short_name, ex))) {
- CAMEL_IMAP_STORE_UNLOCK(imap_store, command_lock);
- return NULL;
- }
- }
- CAMEL_IMAP_STORE_UNLOCK(imap_store, command_lock);
-
- if (!selectable) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
- "%s is not a selectable folder",
- folder_name);
- g_free (short_name);
- return NULL;
- }
-
- summary_file = g_strdup_printf ("%s/%s/#summary",
- imap_store->storage_path,
- folder_name);
- p = strrchr (summary_file, '/');
- *p = '\0';
- if (e_mkdir_hier (summary_file, S_IRWXU) == 0) {
- *p = '/';
- new_folder = camel_imap_folder_new (store, folder_name,
- short_name, summary_file,
- ex);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create directory %s: %s"),
- summary_file, g_strerror (errno));
- }
- g_free (summary_file);
- g_free (short_name);
-
- if (camel_exception_is_set (ex))
- return NULL;
-
- return new_folder;
-}
-
-static char *
-imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix)
-{
- int 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);
-}
-
-static CamelFolderInfo *
-create_folder (CamelStore *store, const char *parent_name,
- const char *folder_name, CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelFolderInfo *fi;
- char *full_name;
-
- if (!parent_name)
- parent_name = imap_store->namespace;
- full_name = imap_concat (imap_store, parent_name, folder_name);
-
- imap_create (imap_store, full_name, ex);
- if (camel_exception_is_set (ex)) {
- g_free (full_name);
- return NULL;
- }
-
- fi = get_folder_info (store, full_name, FALSE, FALSE, FALSE, ex);
- g_free (full_name);
-
- return fi;
-}
-
-static CamelFolderInfo *
-parse_list_response_as_folder_info (CamelImapStore *imap_store,
- const char *response)
-{
- CamelFolderInfo *fi;
- int flags;
- char sep, *dir, *name = NULL;
-
- if (!imap_parse_list_response (response, &flags, &sep, &dir))
- return NULL;
-
- if (sep) {
- name = strrchr (dir, sep);
- if (name && !*++name) {
- g_free (dir);
- return NULL;
- }
- }
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = dir;
- if (sep && name)
- fi->name = g_strdup (name);
- else
- fi->name = g_strdup (dir);
- if (!(flags & IMAP_LIST_FLAG_NOSELECT))
- fi->url = g_strdup_printf ("%s%s", imap_store->base_url, dir);
- if (!(flags & IMAP_LIST_FLAG_UNMARKED))
- fi->unread_message_count = -1;
-
- return fi;
-}
-
-static void
-copy_folder_name (gpointer name, gpointer key, gpointer array)
-{
- g_ptr_array_add (array, name);
-}
-
-static void
-get_subscribed_folders_by_hand (CamelImapStore *imap_store, const char *top,
- GPtrArray *folders, CamelException *ex)
-{
- GPtrArray *names;
- CamelImapResponse *response;
- CamelFolderInfo *fi;
- char *result;
- int i, toplen = strlen (top);
-
- names = g_ptr_array_new ();
- g_hash_table_foreach (imap_store->subscribed_folders,
- copy_folder_name, names);
-
- for (i = 0; i < names->len; i++) {
- CAMEL_IMAP_STORE_LOCK (imap_store, command_lock);
- response = camel_imap_command (imap_store, NULL, ex,
- "LIST \"\" %S",
- names->pdata[i]);
- CAMEL_IMAP_STORE_UNLOCK (imap_store, command_lock);
-
- if (!response) {
- g_ptr_array_free (names, TRUE);
- return;
- }
- result = camel_imap_response_extract (response, "LIST", NULL);
- if (!result) {
- g_hash_table_remove (imap_store->subscribed_folders,
- names->pdata[i]);
- g_free (names->pdata[i]);
- g_ptr_array_remove_index_fast (names, i--);
- continue;
- }
-
- fi = parse_list_response_as_folder_info (imap_store, result);
- if (!fi)
- continue;
-
- if (strncmp (top, fi->full_name, toplen) != 0) {
- camel_folder_info_free (fi);
- continue;
- }
-
- g_ptr_array_add (folders, fi);
- }
- g_ptr_array_free (names, TRUE);
-}
-
-static void
-get_folders (CamelImapStore *imap_store, const char *pattern,
- GPtrArray *folders, gboolean lsub, CamelException *ex)
-{
- CamelImapResponse *response;
- CamelFolderInfo *fi;
- char *list;
- int i;
-
- CAMEL_IMAP_STORE_LOCK (imap_store, command_lock);
- response = camel_imap_command (imap_store, NULL, ex,
- "%s \"\" %S", lsub ? "LSUB" : "LIST",
- pattern);
- CAMEL_IMAP_STORE_UNLOCK (imap_store, command_lock);
- if (!response)
- return;
-
- for (i = 0; i < response->untagged->len; i++) {
- list = response->untagged->pdata[i];
- fi = parse_list_response_as_folder_info (imap_store, list);
- if (!fi)
- continue;
- g_ptr_array_add (folders, fi);
- }
- camel_imap_response_free (response);
-}
-
-static CamelFolderInfo *
-get_folder_info (CamelStore *store, const char *top, gboolean fast,
- gboolean recursive, gboolean subscribed_only,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- gboolean need_inbox = FALSE;
- CamelImapResponse *response;
- GPtrArray *folders;
- const char *name, *p;
- char *pattern, *status;
- CamelFolderInfo *fi;
- int i;
-
- if (!camel_remote_store_connected (CAMEL_REMOTE_STORE (store), ex))
- return NULL;
-
- /* Sync flag changes to the server so it has the same ideas about
- * read/unread as we do.
- */
- camel_store_sync (store, ex);
- if (camel_exception_is_set (ex))
- return NULL;
-
- name = top;
- if (!name) {
- need_inbox = TRUE;
- name = imap_store->namespace;
- }
-
- folders = g_ptr_array_new ();
-
- get_folders (imap_store, name, folders, FALSE, ex);
- if (camel_exception_is_set (ex))
- return NULL;
- if (folders->len) {
- fi = folders->pdata[0];
- if (!fi->url)
- g_ptr_array_remove_index (folders, 0);
- }
-
- if (subscribed_only && !imap_store->useful_lsub)
- get_subscribed_folders_by_hand (imap_store, name, folders, ex);
- else {
- pattern = imap_concat (imap_store, name, recursive ? "*" : "%");
- get_folders (imap_store, pattern, folders, subscribed_only, ex);
- g_free (pattern);
- }
- if (camel_exception_is_set (ex)) {
- for (i = 0; i < folders->len; i++)
- camel_folder_info_free (folders->pdata[i]);
- g_ptr_array_free (folders, TRUE);
- return NULL;
- }
-
- /* Add INBOX, if necessary */
- if (need_inbox) {
- for (i = 0; i < folders->len; i++) {
- fi = folders->pdata[i];
- if (!g_strcasecmp (fi->full_name, "INBOX")) {
- need_inbox = FALSE;
- break;
- }
- }
- }
- if (need_inbox) {
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = g_strdup ("INBOX");
- fi->name = g_strdup ("INBOX");
- fi->url = g_strdup_printf ("%sINBOX", imap_store->base_url);
- fi->unread_message_count = -1;
-
- g_ptr_array_add (folders, fi);
- }
-
- if (!fast) {
- /* Get unread counts */
- for (i = 0; i < folders->len; i++) {
- fi = folders->pdata[i];
- if (!fi->url || fi->unread_message_count != -1)
- continue;
-
- /* UW will give cached data for the currently
- * selected folder. Grr. Well, I guess this
- * also potentially saves us one IMAP command.
- */
- if (imap_store->current_folder &&
- !strcmp (imap_store->current_folder->full_name,
- fi->full_name)) {
- fi->unread_message_count = camel_folder_get_unread_message_count (imap_store->current_folder);
- continue;
- }
-
- CAMEL_IMAP_STORE_LOCK (imap_store, command_lock);
- response = camel_imap_command (imap_store, NULL, NULL,
- "STATUS %S (UNSEEN)",
- fi->full_name);
- CAMEL_IMAP_STORE_UNLOCK (imap_store, command_lock);
- if (!response)
- continue;
- status = camel_imap_response_extract (response, "STATUS", NULL);
- if (!status)
- continue;
-
- p = e_strstrcase (status, "UNSEEN");
- if (p)
- fi->unread_message_count = strtoul (p + 6, NULL, 10);
- g_free (status);
- }
- }
-
- /* And assemble. */
- fi = camel_folder_info_build (folders, name, imap_store->dir_sep, TRUE);
- 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);
-
- g_return_val_if_fail (imap_store->subscribed_folders != NULL, FALSE);
-
- return g_hash_table_lookup (imap_store->subscribed_folders,
- folder_name) != NULL;
-}
-
-static void
-subscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelImapResponse *response;
-
- if (!camel_remote_store_connected (CAMEL_REMOTE_STORE (store), ex))
- return;
-
- CAMEL_IMAP_STORE_LOCK(imap_store, command_lock);
- response = camel_imap_command (imap_store, NULL, ex,
- "SUBSCRIBE %S", folder_name);
- CAMEL_IMAP_STORE_UNLOCK(imap_store, command_lock);
- if (response) {
- CamelFolderInfo *fi;
- char *name;
-
- g_hash_table_insert (imap_store->subscribed_folders,
- g_strdup (folder_name),
- GUINT_TO_POINTER (1));
-
- name = strrchr (folder_name, imap_store->dir_sep);
- if (name)
- name++;
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = g_strdup (folder_name);
- fi->name = g_strdup (name);
- fi->url = g_strdup_printf ("%s%s", imap_store->base_url, folder_name);
- fi->unread_message_count = -1;
-
- camel_object_trigger_event (CAMEL_OBJECT (store),
- "folder_created", fi);
-
- camel_folder_info_free (fi);
- }
- camel_imap_response_free (response);
-}
-
-static void
-unsubscribe_folder (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelImapResponse *response;
- gpointer key, value;
-
- if (!camel_remote_store_connected (CAMEL_REMOTE_STORE (store), ex))
- return;
-
- CAMEL_IMAP_STORE_LOCK(imap_store, command_lock);
- response = camel_imap_command (imap_store, NULL, ex,
- "UNSUBSCRIBE %S", folder_name);
- CAMEL_IMAP_STORE_UNLOCK(imap_store, command_lock);
- if (response) {
- CamelFolderInfo *fi;
- char *name;
-
- g_hash_table_lookup_extended (imap_store->subscribed_folders,
- folder_name, &key, &value);
- g_hash_table_remove (imap_store->subscribed_folders,
- folder_name);
- g_free (key);
-
- name = strrchr (folder_name, imap_store->dir_sep);
- if (name)
- name++;
-
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = g_strdup (folder_name);
- fi->name = g_strdup (name);
- fi->url = g_strdup_printf ("%s%s", imap_store->base_url, folder_name);
- fi->unread_message_count = -1;
-
- camel_object_trigger_event (CAMEL_OBJECT (store),
- "folder_deleted", fi);
-
- camel_folder_info_free (fi);
- }
- camel_imap_response_free (response);
-}
-
-static void
-imap_keepalive (CamelRemoteStore *store)
-{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- CamelImapResponse *response;
-
- CAMEL_IMAP_STORE_LOCK(imap_store, command_lock);
- response = camel_imap_command (imap_store, NULL, NULL, "NOOP");
- CAMEL_IMAP_STORE_UNLOCK(imap_store, command_lock);
- camel_imap_response_free (response);
-}
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
deleted file mode 100644
index 3792e92872..0000000000
--- a/camel/providers/imap/camel-imap-store.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-store.h : class for an imap store */
-
-/*
- * Authors: Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright (C) 2000 Helix Code, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_STORE_H
-#define CAMEL_IMAP_STORE_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-imap-types.h"
-#include "camel-remote-store.h"
-
-#define CAMEL_IMAP_STORE_TYPE (camel_imap_store_get_type ())
-#define CAMEL_IMAP_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_STORE_TYPE, CamelImapStore))
-#define CAMEL_IMAP_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAP_STORE_TYPE, CamelImapStoreClass))
-#define CAMEL_IS_IMAP_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_STORE_TYPE))
-
-typedef enum {
- IMAP_LEVEL_UNKNOWN,
- IMAP_LEVEL_IMAP4,
- IMAP_LEVEL_IMAP4REV1
-} CamelImapServerLevel;
-
-#define IMAP_CAPABILITY_IMAP4 (1 << 0)
-#define IMAP_CAPABILITY_IMAP4REV1 (1 << 1)
-#define IMAP_CAPABILITY_STATUS (1 << 2)
-#define IMAP_CAPABILITY_NAMESPACE (1 << 3)
-#define IMAP_CAPABILITY_UIDPLUS (1 << 4)
-#define IMAP_CAPABILITY_LITERALPLUS (1 << 5)
-
-struct _CamelImapStore {
- CamelRemoteStore parent_object;
- struct _CamelImapStorePrivate *priv;
-
- CamelFolder *current_folder;
-
- guint32 command;
-
- CamelImapServerLevel server_level;
- guint32 capabilities;
- GHashTable *authtypes;
-
- char *namespace, dir_sep, *storage_path, *base_url;
-
- gboolean connected;
-
- GHashTable *subscribed_folders;
- gboolean useful_lsub;
-};
-
-
-typedef struct {
- CamelRemoteStoreClass parent_class;
-
-} CamelImapStoreClass;
-
-
-/* Standard Camel function */
-CamelType camel_imap_store_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAP_STORE_H */
diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c
deleted file mode 100644
index 66228649bc..0000000000
--- a/camel/providers/imap/camel-imap-summary.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2000 Helix Code Inc.
- *
- * Authors:
- * Michael Zucchi <notzed@helixcode.com>
- * Dan Winship <danw@helixcode.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include "camel-imap-summary.h"
-#include <camel/camel-mime-message.h>
-
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define CAMEL_IMAP_SUMMARY_VERSION (0x300)
-
-static int summary_header_load (CamelFolderSummary *, FILE *);
-static int summary_header_save (CamelFolderSummary *, FILE *);
-
-static CamelMessageInfo *message_info_load (CamelFolderSummary *s, FILE *in);
-static int message_info_save (CamelFolderSummary *s, FILE *out,
- CamelMessageInfo *info);
-static CamelMessageContentInfo *content_info_load (CamelFolderSummary *s, FILE *in);
-static int content_info_save (CamelFolderSummary *s, FILE *out,
- CamelMessageContentInfo *info);
-
-static void camel_imap_summary_class_init (CamelImapSummaryClass *klass);
-static void camel_imap_summary_init (CamelImapSummary *obj);
-
-static CamelFolderSummaryClass *camel_imap_summary_parent;
-
-CamelType
-camel_imap_summary_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register(
- camel_folder_summary_get_type(), "CamelImapSummary",
- sizeof (CamelImapSummary),
- sizeof (CamelImapSummaryClass),
- (CamelObjectClassInitFunc) camel_imap_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_summary_init,
- NULL);
- }
-
- return type;
-}
-
-static void
-camel_imap_summary_class_init (CamelImapSummaryClass *klass)
-{
- CamelFolderSummaryClass *cfs_class = (CamelFolderSummaryClass *) klass;
-
- camel_imap_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs (camel_folder_summary_get_type()));
-
- cfs_class->summary_header_load = summary_header_load;
- cfs_class->summary_header_save = summary_header_save;
- cfs_class->message_info_load = message_info_load;
- cfs_class->message_info_save = message_info_save;
- cfs_class->content_info_load = content_info_load;
- cfs_class->content_info_save = content_info_save;
-}
-
-static void
-camel_imap_summary_init (CamelImapSummary *obj)
-{
- CamelFolderSummary *s = (CamelFolderSummary *)obj;
-
- /* subclasses need to set the right instance data sizes */
- s->message_info_size = sizeof(CamelImapMessageInfo);
- s->content_info_size = sizeof(CamelImapMessageContentInfo);
-
- /* and a unique file version */
- s->version += CAMEL_IMAP_SUMMARY_VERSION;
-}
-
-/**
- * camel_imap_summary_new:
- * @filename: the file to store the summary in.
- * @validity: the current UIDVALIDITY value of the folder
- *
- * This will create a new CamelImapSummary object and read in the
- * summary data from disk, if it exists and has the right UIDVALIDITY
- * value.
- *
- * Return value: A new CamelImapSummary object.
- **/
-CamelFolderSummary *
-camel_imap_summary_new (const char *filename, guint32 validity)
-{
- CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (
- camel_object_new (camel_imap_summary_get_type ()));
- CamelImapSummary *imap_summary = (CamelImapSummary *)summary;
-
- camel_folder_summary_set_build_content (summary, TRUE);
- camel_folder_summary_set_filename (summary, filename);
-
- if (camel_folder_summary_load (summary) == -1) {
- if (errno == ENOENT) {
- imap_summary->validity = validity;
- return summary;
- } else {
- /* FIXME: are there error conditions where this won't work? */
- camel_folder_summary_clear (summary);
- camel_folder_summary_touch (summary);
-
- return summary;
- }
- }
-
- if (imap_summary->validity != validity) {
- camel_folder_summary_clear (summary);
- imap_summary->validity = validity;
- }
-
- return summary;
-}
-
-
-static int
-summary_header_load (CamelFolderSummary *s, FILE *in)
-{
- CamelImapSummary *ims = CAMEL_IMAP_SUMMARY (s);
-
- if (camel_imap_summary_parent->summary_header_load (s, in) == -1)
- return -1;
-
- return camel_folder_summary_decode_uint32 (in, &ims->validity);
-}
-
-static int
-summary_header_save (CamelFolderSummary *s, FILE *out)
-{
- CamelImapSummary *ims = CAMEL_IMAP_SUMMARY(s);
-
- if (camel_imap_summary_parent->summary_header_save (s, out) == -1)
- return -1;
-
- return camel_folder_summary_encode_uint32 (out, ims->validity);
-}
-
-
-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_folder_summary_decode_uint32 (in, &iinfo->server_flags) == -1)
- goto error;
- }
-
- return info;
-error:
- camel_folder_summary_info_free (s, info);
- return NULL;
-}
-
-static int
-message_info_save (CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
-{
- CamelImapMessageInfo *iinfo = (CamelImapMessageInfo *)info;
-
- if (camel_imap_summary_parent->message_info_save (s, out, info) == -1)
- return -1;
-
- return camel_folder_summary_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);
-}
diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h
deleted file mode 100644
index 7ad1e3f4e8..0000000000
--- a/camel/providers/imap/camel-imap-summary.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2000 Helix Code Inc.
- *
- * Authors:
- * Michael Zucchi <notzed@helixcode.com>
- * Dan Winship <danw@helixcode.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef _CAMEL_IMAP_SUMMARY_H
-#define _CAMEL_IMAP_SUMMARY_H
-
-#include "camel-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)
-
-typedef struct _CamelImapSummaryClass CamelImapSummaryClass;
-
-typedef struct _CamelImapMessageContentInfo {
- CamelMessageContentInfo info;
-
-} CamelImapMessageContentInfo;
-
-typedef struct _CamelImapMessageInfo {
- CamelMessageInfo info;
-
- guint32 server_flags;
-} CamelImapMessageInfo;
-
-struct _CamelImapSummary {
- CamelFolderSummary parent;
-
- guint32 validity;
-};
-
-struct _CamelImapSummaryClass {
- CamelFolderSummaryClass parent_class;
-
-};
-
-guint camel_imap_summary_get_type (void);
-CamelFolderSummary *camel_imap_summary_new (const char *filename,
- guint32 validity);
-
-#endif /* ! _CAMEL_IMAP_SUMMARY_H */
-
diff --git a/camel/providers/imap/camel-imap-types.h b/camel/providers/imap/camel-imap-types.h
deleted file mode 100644
index af5d8b8c77..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 Helix Code, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef CAMEL_IMAP_TYPES_H
-#define CAMEL_IMAP_TYPES_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-types.h"
-
-typedef struct _CamelImapResponse CamelImapResponse;
-typedef struct _CamelImapFolder CamelImapFolder;
-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 8116f12386..0000000000
--- a/camel/providers/imap/camel-imap-utils.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-#include "camel-imap-utils.h"
-#include "camel-imap-summary.h"
-#include "camel-folder.h"
-
-#define d(x) x
-
-char *
-imap_next_word (const char *buf)
-{
- char *word;
-
- /* skip over current word */
- for (word = (char *)buf; *word && *word != ' '; word++);
-
- /* skip over white space */
- for ( ; *word && *word == ' '; word++);
-
- return word;
-}
-
-/**
- * imap_parse_list_response:
- * @buf: the LIST or LSUB response
- * @flags: a pointer to a variable to store the flags in, or %NULL
- * @sep: a pointer to a variable to store the hierarchy separator in, or %NULL
- * @folder: a pointer to a variable to store the folder name in, or %NULL
- *
- * Parses a LIST or LSUB response and returns the desired parts of it.
- * If @folder is non-%NULL, its value must be freed by the caller.
- *
- * Return value: whether or not the response was successfully parsed.
- **/
-gboolean
-imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder)
-{
- char *word;
- int len;
-
- if (*buf != '*')
- return FALSE;
-
- word = imap_next_word (buf);
- if (g_strncasecmp (word, "LIST", 4) && g_strncasecmp (word, "LSUB", 4))
- return FALSE;
-
- /* get the flags */
- word = imap_next_word (word);
- if (*word != '(')
- return FALSE;
-
- if (flags)
- *flags = 0;
-
- word++;
- while (*word != ')') {
- len = strcspn (word, " )");
- if (flags) {
- if (!g_strncasecmp (word, "\\Noinferiors", len))
- *flags |= IMAP_LIST_FLAG_NOINFERIORS;
- else if (!g_strncasecmp (word, "\\Noselect", len))
- *flags |= IMAP_LIST_FLAG_NOSELECT;
- else if (!g_strncasecmp (word, "\\Marked", len))
- *flags |= IMAP_LIST_FLAG_MARKED;
- else if (!g_strncasecmp (word, "\\Unmarked", len))
- *flags |= IMAP_LIST_FLAG_UNMARKED;
- }
-
- word += len;
- while (*word == ' ')
- word++;
- }
-
- /* get the directory separator */
- word = imap_next_word (word);
- if (!strncmp (word, "NIL", 3)) {
- if (sep)
- *sep = '\0';
- } else if (*word++ == '"') {
- if (*word == '\\')
- word++;
- if (sep)
- *sep = *word;
- word++;
- if (*word++ != '"')
- return FALSE;
- } else
- return FALSE;
-
- if (folder) {
- /* get the folder name */
- word = imap_next_word (word);
- *folder = imap_parse_astring (&word, &len);
- return *folder != NULL;
- }
-
- return TRUE;
-}
-
-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_strncasecmp (flag_list, "\\Answered", len))
- flags |= CAMEL_MESSAGE_ANSWERED;
- else if (!g_strncasecmp (flag_list, "\\Deleted", len))
- flags |= CAMEL_MESSAGE_DELETED;
- else if (!g_strncasecmp (flag_list, "\\Draft", len))
- flags |= CAMEL_MESSAGE_DRAFT;
- else if (!g_strncasecmp (flag_list, "\\Flagged", len))
- flags |= CAMEL_MESSAGE_FLAGGED;
- else if (!g_strncasecmp (flag_list, "\\Seen", len))
- flags |= CAMEL_MESSAGE_SEEN;
-
- flag_list += len;
- if (*flag_list == ' ')
- flag_list++;
- }
-
- if (*flag_list++ != ')') {
- *flag_list_p = NULL;
- return 0;
- }
-
- *flag_list_p = flag_list;
- return flags;
-}
-
-static char imap_atom_specials[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 1, 0, 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, 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, 1, 0, 0, 0, 0,
-};
-#define imap_is_atom_char(ch) (isascii (ch) && !imap_atom_specials[ch])
-
-/**
- * imap_parse_string_generic:
- * @str_p: a pointer to a string
- * @len: a pointer to an int 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 (char **str_p, int *len, int type)
-{
- char *str = *str_p;
- char *out;
-
- if (!str)
- return NULL;
- else if (*str == '"') {
- char *p;
- int size;
-
- str++;
- size = strcspn (str, "\"") + 1;
- p = out = g_malloc (size);
-
- while (*str && *str != '"') {
- if (*str == '\\')
- str++;
- *p++ = *str++;
- if (p - out == size) {
- out = g_realloc (out, size * 2);
- p = out + size;
- size *= 2;
- }
- }
- if (*str != '"') {
- *str_p = NULL;
- g_free (out);
- return NULL;
- }
- *p = '\0';
- *str_p = str + 1;
- *len = strlen (out);
- return out;
- } else if (*str == '{') {
- *len = strtoul (str + 1, (char **)&str, 10);
- if (*str++ != '}' || *str++ != '\n' || strlen (str) < *len) {
- *str_p = NULL;
- return NULL;
- }
-
- out = g_strndup (str, *len);
- *str_p = str + *len;
- return out;
- } else if (type == IMAP_NSTRING && !g_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;
- str = g_strndup (*str_p, *len);
- *str_p += *len;
- return str;
- } else {
- *str_p = NULL;
- return NULL;
- }
-}
-
-static inline void
-skip_char (char **str_p, char ch)
-{
- if (*str_p && **str_p == ch)
- *str_p = *str_p + 1;
- else
- *str_p = NULL;
-}
-
-/* Skip atom, string, or number */
-static void
-skip_asn (char **str_p)
-{
- 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, &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;
- }
-}
-
-static void
-skip_list (char **str_p)
-{
- skip_char (str_p, '(');
- while (*str_p && **str_p != ')') {
- if (**str_p == '(')
- skip_list (str_p);
- else
- skip_asn (str_p);
- if (*str_p && **str_p == ' ')
- skip_char (str_p, ' ');
- }
- skip_char (str_p, ')');
-}
-
-static void
-parse_params (char **parms_p, CamelContentType *type)
-{
- char *parms = *parms_p, *name, *value;
- int len;
-
- if (!g_strncasecmp (parms, "nil", 3)) {
- *parms_p += 3;
- return;
- }
-
- if (*parms++ != '(') {
- *parms_p = NULL;
- return;
- }
-
- while (parms && *parms != ')') {
- name = imap_parse_nstring (&parms, &len);
- skip_char (&parms, ' ');
- value = imap_parse_nstring (&parms, &len);
-
- if (name && value)
- header_content_type_set_param (type, name, value);
- g_free (name);
- g_free (value);
-
- if (parms && *parms == ' ')
- parms++;
- }
-
- if (!parms || *parms++ != ')') {
- *parms_p = NULL;
- return;
- }
- *parms_p = parms;
-}
-
-/**
- * imap_parse_body:
- * @body_p: pointer to the start of an IMAP "body"
- * @folder: an imap folder
- * @ci: a CamelMessageContentInfo to fill in
- *
- * This filles 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 (char **body_p, CamelFolder *folder,
- CamelMessageContentInfo *ci)
-{
- char *body = *body_p;
- CamelMessageContentInfo *child;
- CamelContentType *type;
- int len;
-
- if (*body++ != '(') {
- *body_p = NULL;
- return;
- }
-
- if (*body == '(') {
- /* multipart */
- GPtrArray *children;
- char *subtype;
- int i;
-
- /* Parse the child body parts */
- children = g_ptr_array_new ();
- i = 0;
- while (body && *body == '(') {
- child = camel_folder_summary_content_info_new (folder->summary);
- g_ptr_array_add (children, child);
- imap_parse_body (&body, folder, child);
- if (!body)
- break;
- child->parent = ci;
- }
- skip_char (&body, ' ');
-
- /* Parse the multipart subtype */
- subtype = imap_parse_string (&body, &len);
-
- /* If there is a parse error, abort. */
- if (!body) {
- for (i = 0; i < children->len; i++) {
- child = children->pdata[i];
- camel_folder_summary_content_info_free (folder->summary, child);
- }
- g_ptr_array_free (children, TRUE);
- *body_p = NULL;
- return;
- }
-
- g_strdown (subtype);
- ci->type = header_content_type_new ("multipart", subtype);
- g_free (subtype);
-
- /* Chain the children. */
- ci->childs = children->pdata[0];
- ci->size = 0;
- for (i = 0; i < children->len - 1; i++) {
- child = children->pdata[i];
- child->next = children->pdata[i + 1];
- ci->size += child->size;
- }
- g_ptr_array_free (children, TRUE);
- } else {
- /* single part */
- char *main_type, *subtype;
- char *id, *description, *encoding;
- guint32 size;
-
- main_type = imap_parse_string (&body, &len);
- skip_char (&body, ' ');
- subtype = imap_parse_string (&body, &len);
- skip_char (&body, ' ');
- if (!body) {
- g_free (main_type);
- g_free (subtype);
- *body_p = NULL;
- return;
- }
- g_strdown (main_type);
- g_strdown (subtype);
- type = header_content_type_new (main_type, subtype);
- g_free (main_type);
- g_free (subtype);
- parse_params (&body, type);
- skip_char (&body, ' ');
-
- id = imap_parse_nstring (&body, &len);
- skip_char (&body, ' ');
- description = imap_parse_nstring (&body, &len);
- skip_char (&body, ' ');
- encoding = imap_parse_string (&body, &len);
- skip_char (&body, ' ');
- if (body)
- size = strtoul (body, &body, 10);
-
- child = NULL;
- if (header_content_type_is (type, "message", "rfc822")) {
- skip_char (&body, ' ');
- skip_list (&body); /* envelope */
- skip_char (&body, ' ');
- child = camel_folder_summary_content_info_new (folder->summary);
- imap_parse_body (&body, folder, child);
- if (!body)
- camel_folder_summary_content_info_free (folder->summary, child);
- skip_char (&body, ' ');
- if (body)
- strtoul (body, &body, 10);
- } else if (header_content_type_is (type, "text", "*")) {
- if (body)
- strtoul (body, &body, 10);
- }
-
- if (body) {
- ci->type = type;
- ci->id = id;
- ci->description = description;
- ci->encoding = encoding;
- ci->size = size;
- ci->childs = child;
- } else {
- header_content_type_unref (type);
- g_free (id);
- g_free (description);
- g_free (encoding);
- }
- }
-
- if (!body || *body++ != ')') {
- *body_p = NULL;
- return;
- }
-
- *body_p = body;
-}
-
-/**
- * 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;
-
- len = strlen (str);
- p = str;
- while ((p = strpbrk (p, "\"\\"))) {
- len++;
- p++;
- }
-
- quoted = q = g_malloc (len + 3);
- *q++ = '"';
- while ((p = strpbrk (str, "\"\\"))) {
- memcpy (q, str, p - str);
- q += p - str;
- *q++ = '\\';
- *q++ = *p++;
- str = p;
- }
- sprintf (q, "%s\"", str);
-
- return quoted;
-}
diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h
deleted file mode 100644
index 985f177b3a..0000000000
--- a/camel/providers/imap/camel-imap-utils.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef CAMEL_IMAP_UTILS_H
-#define CAMEL_IMAP_UTILS_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include "camel-folder-summary.h"
-
-char *imap_next_word (const char *buf);
-
-#define IMAP_LIST_FLAG_NOINFERIORS (1 << 0)
-#define IMAP_LIST_FLAG_NOSELECT (1 << 1)
-#define IMAP_LIST_FLAG_MARKED (1 << 2)
-#define IMAP_LIST_FLAG_UNMARKED (1 << 3)
-gboolean imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder);
-
-char *imap_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 (char **str_p, int *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 (char **body_p, CamelFolder *folder,
- CamelMessageContentInfo *ci);
-
-char *imap_quote_string (const char *str);
-
-#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 e4d06a009b..0000000000
--- a/camel/providers/imap/camel-imap-wrapper.c
+++ /dev/null
@@ -1,234 +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@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include <config.h>
-
-#include "camel-imap-wrapper.h"
-#include "camel-imap-command.h"
-#include "camel-imap-store.h"
-#include "camel-imap-utils.h"
-#include "camel-imap-private.h"
-#include "camel-exception.h"
-#include "camel-folder.h"
-#include "camel-stream-mem.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"
-
-#include <errno.h>
-#include <string.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 int 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 camel_imap_wrapper_type = CAMEL_INVALID_TYPE;
-
- if (camel_imap_wrapper_type == CAMEL_INVALID_TYPE) {
- camel_imap_wrapper_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 camel_imap_wrapper_type;
-}
-
-
-static int
-write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
-{
- CamelImapWrapper *imap_wrapper = CAMEL_IMAP_WRAPPER (data_wrapper);
- CamelImapStore *store;
- CamelImapResponse *response;
- CamelStream *memstream;
- CamelStreamFilter *filterstream;
- CamelMimeFilter *filter;
- CamelContentType *ct;
- char *result, *p, *body;
- int len;
-
- CAMEL_IMAP_WRAPPER_LOCK (imap_wrapper, lock);
- if (!data_wrapper->offline) {
- CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
- return parent_class->write_to_stream (data_wrapper, stream);
- }
-
- store = CAMEL_IMAP_STORE (imap_wrapper->folder->parent_store);
- CAMEL_IMAP_STORE_LOCK (store, command_lock);
- response = camel_imap_command (store, imap_wrapper->folder, NULL,
- "UID FETCH %s BODY.PEEK[%s]",
- imap_wrapper->uid,
- imap_wrapper->part_spec);
- CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
- if (!response)
- goto lose;
-
- result = camel_imap_response_extract (response, "FETCH", NULL);
- if (!result)
- goto lose;
-
- p = strchr (result, ']');
- if (!p) {
- g_free (result);
- goto lose;
- }
- p += 2;
-
- body = imap_parse_nstring (&p, &len);
- g_free (result);
- if (!body)
- goto lose;
-
- memstream = camel_stream_mem_new_with_buffer (body, len);
- g_free (body);
- filterstream = camel_stream_filter_new_with_stream (memstream);
-
- if (camel_mime_part_get_encoding (imap_wrapper->part) ==
- CAMEL_MIME_PART_ENCODING_BASE64) {
- filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type (CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
- camel_stream_filter_add (filterstream, filter);
- } else if (camel_mime_part_get_encoding (imap_wrapper->part) ==
- CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE) {
- filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type (CAMEL_MIME_FILTER_BASIC_QP_DEC);
- camel_stream_filter_add (filterstream, filter);
- } else
- filter = NULL;
-
- ct = camel_mime_part_get_content_type (imap_wrapper->part);
- if (header_content_type_is (ct, "text", "*")) {
- const char *charset;
-
- /* If we just did B64/QP, need to also do CRLF->LF */
- if (filter) {
- filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE,
- CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- camel_stream_filter_add (filterstream, filter);
- }
-
- charset = header_content_type_param (ct, "charset");
- if (charset && !(strcasecmp (charset, "us-ascii") == 0
- || strcasecmp (charset, "utf-8") == 0)) {
- filter = (CamelMimeFilter *)camel_mime_filter_charset_new_convert (charset, "UTF-8");
- if (filter)
- camel_stream_filter_add (filterstream, filter);
- }
- }
-
- data_wrapper->stream = CAMEL_STREAM (filterstream);
- data_wrapper->offline = FALSE;
-
- camel_object_unref (CAMEL_OBJECT (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;
-
- CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
-
- return parent_class->write_to_stream (data_wrapper, stream);
-
- lose:
- CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
- errno = ENETUNREACH;
- return -1;
-}
-
-
-CamelDataWrapper *
-camel_imap_wrapper_new (CamelFolder *folder, CamelContentType *type,
- const char *uid, const char *part_spec,
- CamelMimePart *part)
-{
- CamelImapWrapper *imap_wrapper;
-
- imap_wrapper = (CamelImapWrapper *)camel_object_new(camel_imap_wrapper_get_type());
-
- camel_data_wrapper_set_mime_type_field (CAMEL_DATA_WRAPPER (imap_wrapper), type);
- ((CamelDataWrapper *)imap_wrapper)->offline = TRUE;
-
- imap_wrapper->folder = folder;
- camel_object_ref (CAMEL_OBJECT (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;
-
- 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 8eb9d0969a..0000000000
--- a/camel/providers/imap/camel-imap-wrapper.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-imap-wrapper.h: data wrapper for offline IMAP data */
-
-/*
- * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-#ifndef CAMEL_IMAP_WRAPPER_H
-#define CAMEL_IMAP_WRAPPER_H 1
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <camel/camel-data-wrapper.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;
-
- CamelFolder *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 (CamelFolder *folder,
- CamelContentType *type,
- const char *uid,
- const char *part_spec,
- CamelMimePart *part);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_DATA_WRAPPER_H */
diff --git a/camel/providers/imap/libcamelimap.urls b/camel/providers/imap/libcamelimap.urls
deleted file mode 100644
index c301c0ffac..0000000000
--- a/camel/providers/imap/libcamelimap.urls
+++ /dev/null
@@ -1 +0,0 @@
-imap