summaryrefslogtreecommitdiff
path: root/camel/providers/imap4
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/imap4')
-rw-r--r--camel/providers/imap4/.cvsignore7
-rw-r--r--camel/providers/imap4/Makefile.am40
-rw-r--r--camel/providers/imap4/camel-imap4-command.c674
-rw-r--r--camel/providers/imap4/camel-imap4-command.h144
-rw-r--r--camel/providers/imap4/camel-imap4-engine.c1673
-rw-r--r--camel/providers/imap4/camel-imap4-engine.h222
-rw-r--r--camel/providers/imap4/camel-imap4-folder.c888
-rw-r--r--camel/providers/imap4/camel-imap4-folder.h65
-rw-r--r--camel/providers/imap4/camel-imap4-provider.c139
-rw-r--r--camel/providers/imap4/camel-imap4-specials.c100
-rw-r--r--camel/providers/imap4/camel-imap4-specials.h53
-rw-r--r--camel/providers/imap4/camel-imap4-store.c1178
-rw-r--r--camel/providers/imap4/camel-imap4-store.h61
-rw-r--r--camel/providers/imap4/camel-imap4-stream.c708
-rw-r--r--camel/providers/imap4/camel-imap4-stream.h124
-rw-r--r--camel/providers/imap4/camel-imap4-summary.c1107
-rw-r--r--camel/providers/imap4/camel-imap4-summary.h91
-rw-r--r--camel/providers/imap4/camel-imap4-utils.c315
-rw-r--r--camel/providers/imap4/camel-imap4-utils.h67
-rw-r--r--camel/providers/imap4/libcamelimap4.urls1
20 files changed, 0 insertions, 7657 deletions
diff --git a/camel/providers/imap4/.cvsignore b/camel/providers/imap4/.cvsignore
deleted file mode 100644
index 08f5ed37d..000000000
--- a/camel/providers/imap4/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-Makefile
-Makefile.in
-*.o
-*.lo
-*.la
-.deps
-.libs
diff --git a/camel/providers/imap4/Makefile.am b/camel/providers/imap4/Makefile.am
deleted file mode 100644
index d1bb57e15..000000000
--- a/camel/providers/imap4/Makefile.am
+++ /dev/null
@@ -1,40 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-libcamelimap4includedir = $(privincludedir)/camel
-
-camel_provider_LTLIBRARIES = libcamelimap4.la
-camel_provider_DATA = libcamelimap4.urls
-
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/camel \
- -I$(top_srcdir)/intl \
- -I$(top_srcdir)/e-util \
- -I$(top_srcdir) \
- $(CAMEL_CFLAGS) \
- $(GNOME_INCLUDEDIR) \
- $(GTK_INCLUDEDIR) \
- -DG_LOG_DOMAIN=\"camel-imap4-provider\"
-
-libcamelimap4_la_SOURCES = \
- camel-imap4-command.c \
- camel-imap4-command.h \
- camel-imap4-engine.c \
- camel-imap4-engine.h \
- camel-imap4-folder.c \
- camel-imap4-folder.h \
- camel-imap4-provider.c \
- camel-imap4-specials.c \
- camel-imap4-specials.h \
- camel-imap4-store.c \
- camel-imap4-store.h \
- camel-imap4-stream.c \
- camel-imap4-stream.h \
- camel-imap4-summary.c \
- camel-imap4-summary.h \
- camel-imap4-utils.c \
- camel-imap4-utils.h
-
-libcamelimap4_la_LDFLAGS = -avoid-version -module
-
-EXTRA_DIST = libcamelimap4.urls
diff --git a/camel/providers/imap4/camel-imap4-command.c b/camel/providers/imap4/camel-imap4-command.c
deleted file mode 100644
index c1ff3a289..000000000
--- a/camel/providers/imap4/camel-imap4-command.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <camel/camel-stream-null.h>
-#include <camel/camel-stream-filter.h>
-#include <camel/camel-mime-filter-crlf.h>
-
-#include "camel-imap4-stream.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-specials.h"
-
-#include "camel-imap4-command.h"
-
-
-#define d(x) x
-
-
-enum {
- IMAP4_STRING_ATOM,
- IMAP4_STRING_QSTRING,
- IMAP4_STRING_LITERAL,
-};
-
-static int
-imap4_string_get_type (const char *str)
-{
- int type = 0;
-
- while (*str) {
- if (!is_atom (*str)) {
- if (is_qsafe (*str))
- type = IMAP4_STRING_QSTRING;
- else
- return IMAP4_STRING_LITERAL;
- }
- str++;
- }
-
- return type;
-}
-
-#if 0
-static gboolean
-imap4_string_is_atom_safe (const char *str)
-{
- while (is_atom (*str))
- str++;
-
- return *str == '\0';
-}
-
-static gboolean
-imap4_string_is_quote_safe (const char *str)
-{
- while (is_qsafe (*str))
- str++;
-
- return *str == '\0';
-}
-#endif
-
-static size_t
-camel_imap4_literal_length (CamelIMAP4Literal *literal)
-{
- CamelStream *stream, *null;
- CamelMimeFilter *crlf;
- size_t len;
-
- if (literal->type == CAMEL_IMAP4_LITERAL_STRING)
- return strlen (literal->literal.string);
-
- null = camel_stream_null_new ();
- crlf = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- stream = (CamelStream *) camel_stream_filter_new_with_stream (null);
- camel_stream_filter_add ((CamelStreamFilter *) stream, crlf);
- camel_object_unref (crlf);
-
- switch (literal->type) {
- case CAMEL_IMAP4_LITERAL_STREAM:
- camel_stream_write_to_stream (literal->literal.stream, stream);
- camel_stream_reset (literal->literal.stream);
- break;
- case CAMEL_IMAP4_LITERAL_WRAPPER:
- camel_data_wrapper_write_to_stream (literal->literal.wrapper, stream);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- len = ((CamelStreamNull *) null)->written;
-
- camel_object_unref (stream);
- camel_object_unref (null);
-
- return len;
-}
-
-static CamelIMAP4CommandPart *
-command_part_new (void)
-{
- CamelIMAP4CommandPart *part;
-
- part = g_new (CamelIMAP4CommandPart, 1);
- part->next = NULL;
- part->buffer = NULL;
- part->buflen = 0;
- part->literal = NULL;
-
- return part;
-}
-
-static void
-imap4_command_append_string (CamelIMAP4Engine *engine, CamelIMAP4CommandPart **tail, GString *str, const char *string)
-{
- CamelIMAP4CommandPart *part;
- CamelIMAP4Literal *literal;
-
- switch (imap4_string_get_type (string)) {
- case IMAP4_STRING_ATOM:
- /* string is safe as it is... */
- g_string_append (str, string);
- break;
- case IMAP4_STRING_QSTRING:
- /* we need to quote the string */
- /* FIXME: need to escape stuff */
- g_string_append_printf (str, "\"%s\"", string);
- break;
- case IMAP4_STRING_LITERAL:
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_LITERALPLUS) {
- /* we have to send a literal, but the server supports LITERAL+ so use that */
- g_string_append_printf (str, "{%u+}\r\n%s", strlen (string), string);
- } else {
- /* we have to make it a literal */
- literal = g_new (CamelIMAP4Literal, 1);
- literal->type = CAMEL_IMAP4_LITERAL_STRING;
- literal->literal.string = g_strdup (string);
-
- g_string_append_printf (str, "{%u}\r\n", strlen (string));
-
- (*tail)->buffer = g_strdup (str->str);
- (*tail)->buflen = str->len;
- (*tail)->literal = literal;
-
- part = command_part_new ();
- (*tail)->next = part;
- (*tail) = part;
-
- g_string_truncate (str, 0);
- }
- break;
- }
-}
-
-CamelIMAP4Command *
-camel_imap4_command_newv (CamelIMAP4Engine *engine, CamelIMAP4Folder *imap4_folder, const char *format, va_list args)
-{
- CamelIMAP4CommandPart *parts, *part, *tail;
- CamelIMAP4Command *ic;
- const char *start;
- GString *str;
-
- tail = parts = command_part_new ();
-
- str = g_string_new ("");
- start = format;
-
- while (*format) {
- register char ch = *format++;
-
- if (ch == '%') {
- CamelIMAP4Literal *literal;
- CamelIMAP4Folder *folder;
- unsigned int u;
- char *string;
- size_t len;
- void *obj;
- int c, d;
-
- g_string_append_len (str, start, format - start - 1);
-
- switch (*format) {
- case '%':
- /* literal % */
- g_string_append_c (str, '%');
- break;
- case 'c':
- /* character */
- c = va_arg (args, int);
- g_string_append_c (str, c);
- break;
- case 'd':
- /* integer */
- d = va_arg (args, int);
- g_string_append_printf (str, "%d", d);
- break;
- case 'u':
- /* unsigned integer */
- u = va_arg (args, unsigned int);
- g_string_append_printf (str, "%u", u);
- break;
- case 'F':
- /* CamelIMAP4Folder */
- folder = va_arg (args, CamelIMAP4Folder *);
- string = (char *) camel_imap4_folder_utf7_name (folder);
- imap4_command_append_string (engine, &tail, str, string);
- break;
- case 'L':
- /* Literal */
- obj = va_arg (args, void *);
-
- literal = g_new (CamelIMAP4Literal, 1);
- if (CAMEL_IS_DATA_WRAPPER (obj)) {
- literal->type = CAMEL_IMAP4_LITERAL_WRAPPER;
- literal->literal.wrapper = obj;
- } else if (CAMEL_IS_STREAM (obj)) {
- literal->type = CAMEL_IMAP4_LITERAL_STREAM;
- literal->literal.stream = obj;
- } else {
- g_assert_not_reached ();
- }
-
- camel_object_ref (obj);
-
- /* FIXME: take advantage of LITERAL+? */
- len = camel_imap4_literal_length (literal);
- g_string_append_printf (str, "{%u}\r\n", len);
-
- tail->buffer = g_strdup (str->str);
- tail->buflen = str->len;
- tail->literal = literal;
-
- part = command_part_new ();
- tail->next = part;
- tail = part;
-
- g_string_truncate (str, 0);
-
- break;
- case 'S':
- /* string which may need to be quoted or made into a literal */
- string = va_arg (args, char *);
- imap4_command_append_string (engine, &tail, str, string);
- break;
- case 's':
- /* safe atom string */
- string = va_arg (args, char *);
- g_string_append (str, string);
- break;
- default:
- g_warning ("unknown formatter %%%c", *format);
- g_string_append_c (str, '%');
- g_string_append_c (str, *format);
- break;
- }
-
- format++;
-
- start = format;
- }
- }
-
- g_string_append (str, start);
- tail->buffer = str->str;
- tail->buflen = str->len;
- tail->literal = NULL;
- g_string_free (str, FALSE);
-
- ic = g_new0 (CamelIMAP4Command, 1);
- ((EDListNode *) ic)->next = NULL;
- ((EDListNode *) ic)->prev = NULL;
- ic->untagged = g_hash_table_new (g_str_hash, g_str_equal);
- ic->status = CAMEL_IMAP4_COMMAND_QUEUED;
- ic->resp_codes = g_ptr_array_new ();
- ic->engine = engine;
- ic->ref_count = 1;
- ic->parts = parts;
- ic->part = parts;
-
- camel_exception_init (&ic->ex);
-
- if (imap4_folder) {
- camel_object_ref (imap4_folder);
- ic->folder = imap4_folder;
- } else
- ic->folder = NULL;
-
- return ic;
-}
-
-CamelIMAP4Command *
-camel_imap4_command_new (CamelIMAP4Engine *engine, CamelIMAP4Folder *folder, const char *format, ...)
-{
- CamelIMAP4Command *command;
- va_list args;
-
- va_start (args, format);
- command = camel_imap4_command_newv (engine, folder, format, args);
- va_end (args);
-
- return command;
-}
-
-void
-camel_imap4_command_register_untagged (CamelIMAP4Command *ic, const char *atom, CamelIMAP4UntaggedCallback untagged)
-{
- g_hash_table_insert (ic->untagged, g_strdup (atom), untagged);
-}
-
-void
-camel_imap4_command_ref (CamelIMAP4Command *ic)
-{
- ic->ref_count++;
-}
-
-void
-camel_imap4_command_unref (CamelIMAP4Command *ic)
-{
- CamelIMAP4CommandPart *part, *next;
- int i;
-
- if (ic == NULL)
- return;
-
- ic->ref_count--;
- if (ic->ref_count == 0) {
- if (ic->folder)
- camel_object_unref (ic->folder);
-
- g_free (ic->tag);
-
- for (i = 0; i < ic->resp_codes->len; i++) {
- CamelIMAP4RespCode *resp_code;
-
- resp_code = ic->resp_codes->pdata[i];
- camel_imap4_resp_code_free (resp_code);
- }
- g_ptr_array_free (ic->resp_codes, TRUE);
-
- g_hash_table_foreach (ic->untagged, (GHFunc) g_free, NULL);
- g_hash_table_destroy (ic->untagged);
-
- camel_exception_clear (&ic->ex);
-
- part = ic->parts;
- while (part != NULL) {
- g_free (part->buffer);
- if (part->literal) {
- switch (part->literal->type) {
- case CAMEL_IMAP4_LITERAL_STRING:
- g_free (part->literal->literal.string);
- break;
- case CAMEL_IMAP4_LITERAL_STREAM:
- camel_object_unref (part->literal->literal.stream);
- break;
- case CAMEL_IMAP4_LITERAL_WRAPPER:
- camel_object_unref (part->literal->literal.wrapper);
- break;
- }
-
- g_free (part->literal);
- }
-
- next = part->next;
- g_free (part);
- part = next;
- }
-
- g_free (ic);
- }
-}
-
-
-static int
-imap4_literal_write_to_stream (CamelIMAP4Literal *literal, CamelStream *stream)
-{
- CamelStream *istream, *ostream = NULL;
- CamelDataWrapper *wrapper;
- CamelMimeFilter *crlf;
- char *string;
-
- if (literal->type == CAMEL_IMAP4_LITERAL_STRING) {
- string = literal->literal.string;
- if (camel_stream_write (stream, string, strlen (string)) == -1)
- return -1;
-
- return 0;
- }
-
- crlf = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- ostream = (CamelStream *) camel_stream_filter_new_with_stream (stream);
- camel_stream_filter_add ((CamelStreamFilter *) ostream, crlf);
- camel_object_unref (crlf);
-
- /* write the literal */
- switch (literal->type) {
- case CAMEL_IMAP4_LITERAL_STREAM:
- istream = literal->literal.stream;
- if (camel_stream_write_to_stream (istream, ostream) == -1)
- goto exception;
- break;
- case CAMEL_IMAP4_LITERAL_WRAPPER:
- wrapper = literal->literal.wrapper;
- if (camel_data_wrapper_write_to_stream (wrapper, ostream) == -1)
- goto exception;
- break;
- }
-
- camel_object_unref (ostream);
- ostream = NULL;
-
-#if 0
- if (camel_stream_write (stream, "\r\n", 2) == -1)
- return -1;
-#endif
-
- return 0;
-
- exception:
-
- camel_object_unref (ostream);
-
- return -1;
-}
-
-
-static void
-unexpected_token (camel_imap4_token_t *token)
-{
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_NO_DATA:
- fprintf (stderr, "*** NO DATA ***");
- break;
- case CAMEL_IMAP4_TOKEN_ERROR:
- fprintf (stderr, "*** ERROR ***");
- break;
- case CAMEL_IMAP4_TOKEN_NIL:
- fprintf (stderr, "NIL");
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- fprintf (stderr, "%s", token->v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- fprintf (stderr, "\"%s\"", token->v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- fprintf (stderr, "{%u}", token->v.literal);
- break;
- default:
- fprintf (stderr, "%c", (unsigned char) (token->token & 0xff));
- break;
- }
-}
-
-int
-camel_imap4_command_step (CamelIMAP4Command *ic)
-{
- CamelIMAP4Engine *engine = ic->engine;
- int result = CAMEL_IMAP4_RESULT_NONE;
- CamelIMAP4Literal *literal;
- camel_imap4_token_t token;
- unsigned char *linebuf;
- ssize_t nwritten;
- size_t len;
-
- g_assert (ic->part != NULL);
-
- if (ic->part == ic->parts) {
- ic->tag = g_strdup_printf ("%c%.5u", engine->tagprefix, engine->tag++);
- camel_stream_printf (engine->ostream, "%s ", ic->tag);
- d(fprintf (stderr, "sending : %s ", ic->tag));
- }
-
-#if d(!)0
- {
- int sending = ic->part != ic->parts;
- unsigned char *eoln, *eob;
-
- linebuf = ic->part->buffer;
- eob = linebuf + ic->part->buflen;
-
- do {
- eoln = linebuf;
- while (eoln < eob && *eoln != '\n')
- eoln++;
-
- if (eoln < eob)
- eoln++;
-
- if (sending)
- fwrite ("sending : ", 1, 10, stderr);
- fwrite (linebuf, 1, eoln - linebuf, stderr);
-
- linebuf = eoln + 1;
- sending = 1;
- } while (linebuf < eob);
- }
-#endif
-
- linebuf = ic->part->buffer;
- len = ic->part->buflen;
-
- if ((nwritten = camel_stream_write (engine->ostream, linebuf, len)) == -1)
- goto exception;
-
- if (camel_stream_flush (engine->ostream) == -1)
- goto exception;
-
- /* now we need to read the response(s) from the IMAP4 server */
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, &ic->ex) == -1)
- goto exception;
-
- if (token.token == '+') {
- /* we got a continuation response from the server */
- literal = ic->part->literal;
-
- if (camel_imap4_engine_line (engine, &linebuf, &len, &ic->ex) == -1)
- goto exception;
-
- if (literal) {
- if (imap4_literal_write_to_stream (literal, engine->ostream) == -1)
- goto exception;
-
- g_free (linebuf);
- linebuf = NULL;
-
- break;
- } else if (ic->plus) {
- /* command expected a '+' response - probably AUTHENTICATE? */
- if (ic->plus (engine, ic, linebuf, len, &ic->ex) == -1) {
- g_free (linebuf);
- return -1;
- }
-
- /* now we need to wait for a "<tag> OK/NO/BAD" response */
- } else {
- /* FIXME: error?? */
- g_assert_not_reached ();
- }
-
- g_free (linebuf);
- linebuf = NULL;
- } else if (token.token == '*') {
- /* we got an untagged response, let the engine handle this */
- if (camel_imap4_engine_handle_untagged_1 (engine, &token, &ic->ex) == -1)
- goto exception;
- } else if (token.token == CAMEL_IMAP4_TOKEN_ATOM && !strcmp (token.v.atom, ic->tag)) {
- /* we got "<tag> OK/NO/BAD" */
- fprintf (stderr, "got %s response\n", token.v.atom);
-
- if (camel_imap4_engine_next_token (engine, &token, &ic->ex) == -1)
- goto exception;
-
- if (token.token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!strcmp (token.v.atom, "OK"))
- result = CAMEL_IMAP4_RESULT_OK;
- else if (!strcmp (token.v.atom, "NO"))
- result = CAMEL_IMAP4_RESULT_NO;
- else if (!strcmp (token.v.atom, "BAD"))
- result = CAMEL_IMAP4_RESULT_BAD;
-
- if (result == CAMEL_IMAP4_RESULT_NONE) {
- fprintf (stderr, "expected OK/NO/BAD but got %s\n", token.v.atom);
- goto unexpected;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, &ic->ex) == -1)
- goto exception;
-
- if (token.token == '[') {
- /* we have a response code */
- camel_imap4_stream_unget_token (engine->istream, &token);
- if (camel_imap4_engine_parse_resp_code (engine, &ic->ex) == -1)
- goto exception;
- } else if (token.token != '\n') {
- /* just gobble up the rest of the line */
- if (camel_imap4_engine_line (engine, NULL, NULL, &ic->ex) == -1)
- goto exception;
- }
- } else {
- fprintf (stderr, "expected anything but this: ");
- unexpected_token (&token);
- fprintf (stderr, "\n");
-
- goto unexpected;
- }
-
- break;
- } else {
- fprintf (stderr, "wtf is this: ");
- unexpected_token (&token);
- fprintf (stderr, "\n");
-
- unexpected:
-
- /* no fucking clue what we got... */
- if (camel_imap4_engine_line (engine, &linebuf, &len, &ic->ex) == -1)
- goto exception;
-
- camel_exception_setv (&ic->ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unexpected response from IMAP4 server %s: %s"),
- engine->url->host, linebuf);
-
- g_free (linebuf);
-
- goto exception;
- }
- } while (1);
-
- /* status should always be ACTIVE here... */
- if (ic->status == CAMEL_IMAP4_COMMAND_ACTIVE) {
- ic->part = ic->part->next;
- if (ic->part == NULL || result) {
- ic->status = CAMEL_IMAP4_COMMAND_COMPLETE;
- ic->result = result;
- return 1;
- }
- }
-
- return 0;
-
- exception:
-
- ic->status = CAMEL_IMAP4_COMMAND_ERROR;
-
- return -1;
-}
-
-
-void
-camel_imap4_command_reset (CamelIMAP4Command *ic)
-{
- int i;
-
- for (i = 0; i < ic->resp_codes->len; i++)
- camel_imap4_resp_code_free (ic->resp_codes->pdata[i]);
- g_ptr_array_set_size (ic->resp_codes, 0);
-
- ic->status = CAMEL_IMAP4_COMMAND_QUEUED;
- ic->result = CAMEL_IMAP4_RESULT_NONE;
- ic->part = ic->parts;
- g_free (ic->tag);
- ic->tag = NULL;
-
- camel_exception_clear (&ic->ex);
-}
diff --git a/camel/providers/imap4/camel-imap4-command.h b/camel/providers/imap4/camel-imap4-command.h
deleted file mode 100644
index 49487b1b2..000000000
--- a/camel/providers/imap4/camel-imap4-command.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __CAMEL_IMAP4_COMMAND_H__
-#define __CAMEL_IMAP4_COMMAND_H__
-
-#include <stdarg.h>
-
-#include <glib.h>
-
-#include <e-util/e-msgport.h>
-
-#include <camel/camel-stream.h>
-#include <camel/camel-exception.h>
-#include <camel/camel-data-wrapper.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-struct _CamelIMAP4Engine;
-struct _CamelIMAP4Folder;
-struct _camel_imap4_token_t;
-
-typedef struct _CamelIMAP4Command CamelIMAP4Command;
-typedef struct _CamelIMAP4Literal CamelIMAP4Literal;
-
-typedef int (* CamelIMAP4PlusCallback) (struct _CamelIMAP4Engine *engine,
- CamelIMAP4Command *ic,
- const unsigned char *linebuf,
- size_t linelen, CamelException *ex);
-
-typedef int (* CamelIMAP4UntaggedCallback) (struct _CamelIMAP4Engine *engine,
- CamelIMAP4Command *ic,
- guint32 index,
- struct _camel_imap4_token_t *token,
- CamelException *ex);
-
-enum {
- CAMEL_IMAP4_LITERAL_STRING,
- CAMEL_IMAP4_LITERAL_STREAM,
- CAMEL_IMAP4_LITERAL_WRAPPER,
-};
-
-struct _CamelIMAP4Literal {
- int type;
- union {
- char *string;
- CamelStream *stream;
- CamelDataWrapper *wrapper;
- } literal;
-};
-
-typedef struct _CamelIMAP4CommandPart {
- struct _CamelIMAP4CommandPart *next;
- unsigned char *buffer;
- size_t buflen;
-
- CamelIMAP4Literal *literal;
-} CamelIMAP4CommandPart;
-
-enum {
- CAMEL_IMAP4_COMMAND_QUEUED,
- CAMEL_IMAP4_COMMAND_ACTIVE,
- CAMEL_IMAP4_COMMAND_COMPLETE,
- CAMEL_IMAP4_COMMAND_ERROR,
-};
-
-enum {
- CAMEL_IMAP4_RESULT_NONE,
- CAMEL_IMAP4_RESULT_OK,
- CAMEL_IMAP4_RESULT_NO,
- CAMEL_IMAP4_RESULT_BAD,
-};
-
-struct _CamelIMAP4Command {
- EDListNode node;
-
- struct _CamelIMAP4Engine *engine;
-
- unsigned int ref_count:26;
- unsigned int status:3;
- unsigned int result:3;
- int id;
-
- char *tag;
-
- GPtrArray *resp_codes;
-
- struct _CamelIMAP4Folder *folder;
- CamelException ex;
-
- /* command parts - logical breaks in the overall command based on literals */
- CamelIMAP4CommandPart *parts;
-
- /* current part */
- CamelIMAP4CommandPart *part;
-
- /* untagged handlers */
- GHashTable *untagged;
-
- /* '+' callback/data */
- CamelIMAP4PlusCallback plus;
- void *user_data;
-};
-
-CamelIMAP4Command *camel_imap4_command_new (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Folder *folder,
- const char *format, ...);
-CamelIMAP4Command *camel_imap4_command_newv (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Folder *folder,
- const char *format, va_list args);
-
-void camel_imap4_command_register_untagged (CamelIMAP4Command *ic, const char *atom, CamelIMAP4UntaggedCallback untagged);
-
-void camel_imap4_command_ref (CamelIMAP4Command *ic);
-void camel_imap4_command_unref (CamelIMAP4Command *ic);
-
-/* returns 1 when complete, 0 if there is more to do, or -1 on error */
-int camel_imap4_command_step (CamelIMAP4Command *ic);
-
-void camel_imap4_command_reset (CamelIMAP4Command *ic);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_COMMAND_H__ */
diff --git a/camel/providers/imap4/camel-imap4-engine.c b/camel/providers/imap4/camel-imap4-engine.c
deleted file mode 100644
index a84ac1dfb..000000000
--- a/camel/providers/imap4/camel-imap4-engine.c
+++ /dev/null
@@ -1,1673 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <camel/camel-sasl.h>
-#include <camel/camel-stream-buffer.h>
-
-#include "camel-imap4-summary.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-utils.h"
-
-#include "camel-imap4-engine.h"
-
-#define d(x) x
-
-
-static void camel_imap4_engine_class_init (CamelIMAP4EngineClass *klass);
-static void camel_imap4_engine_init (CamelIMAP4Engine *engine, CamelIMAP4EngineClass *klass);
-static void camel_imap4_engine_finalize (CamelObject *object);
-
-
-static CamelObjectClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_engine_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (camel_object_get_type (),
- "CamelIMAP4Engine",
- sizeof (CamelIMAP4Engine),
- sizeof (CamelIMAP4EngineClass),
- (CamelObjectClassInitFunc) camel_imap4_engine_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_engine_init,
- (CamelObjectFinalizeFunc) camel_imap4_engine_finalize);
- }
-
- return type;
-}
-
-static void
-camel_imap4_engine_class_init (CamelIMAP4EngineClass *klass)
-{
- parent_class = camel_type_get_global_classfuncs (CAMEL_OBJECT_TYPE);
-
- klass->tagprefix = 'A';
-}
-
-static void
-camel_imap4_engine_init (CamelIMAP4Engine *engine, CamelIMAP4EngineClass *klass)
-{
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
- engine->level = CAMEL_IMAP4_LEVEL_UNKNOWN;
-
- engine->session = NULL;
- engine->url = NULL;
-
- engine->istream = NULL;
- engine->ostream = NULL;
-
- engine->authtypes = g_hash_table_new (g_str_hash, g_str_equal);
-
- engine->capa = 0;
-
- /* this is the suggested default, impacts the max command line length we'll send */
- engine->maxlentype = CAMEL_IMAP4_ENGINE_MAXLEN_LINE;
- engine->maxlen = 1000;
-
- engine->namespaces.personal = NULL;
- engine->namespaces.other = NULL;
- engine->namespaces.shared = NULL;
-
- if (klass->tagprefix > 'Z')
- klass->tagprefix = 'A';
-
- engine->tagprefix = klass->tagprefix++;
- engine->tag = 0;
-
- engine->nextid = 1;
-
- engine->folder = NULL;
-
- e_dlist_init (&engine->queue);
-}
-
-static void
-imap4_namespace_clear (CamelIMAP4Namespace **namespace)
-{
- CamelIMAP4Namespace *node, *next;
-
- node = *namespace;
- while (node != NULL) {
- next = node->next;
- g_free (node->path);
- g_free (node);
- node = next;
- }
-
- *namespace = NULL;
-}
-
-static void
-camel_imap4_engine_finalize (CamelObject *object)
-{
- CamelIMAP4Engine *engine = (CamelIMAP4Engine *) object;
- EDListNode *node;
-
- if (engine->session)
- camel_object_unref (engine->session);
-
- if (engine->istream)
- camel_object_unref (engine->istream);
-
- if (engine->ostream)
- camel_object_unref (engine->ostream);
-
- g_hash_table_foreach (engine->authtypes, (GHFunc) g_free, NULL);
- g_hash_table_destroy (engine->authtypes);
-
- imap4_namespace_clear (&engine->namespaces.personal);
- imap4_namespace_clear (&engine->namespaces.other);
- imap4_namespace_clear (&engine->namespaces.shared);
-
- if (engine->folder)
- camel_object_unref (engine->folder);
-
- while ((node = e_dlist_remhead (&engine->queue))) {
- node->next = NULL;
- node->prev = NULL;
-
- camel_imap4_command_unref ((CamelIMAP4Command *) node);
- }
-}
-
-
-/**
- * camel_imap4_engine_new:
- * @session: session
- * @url: service url
- *
- * Returns a new imap4 engine
- **/
-CamelIMAP4Engine *
-camel_imap4_engine_new (CamelSession *session, CamelURL *url)
-{
- CamelIMAP4Engine *engine;
-
- g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL);
-
- engine = (CamelIMAP4Engine *) camel_object_new (CAMEL_TYPE_IMAP4_ENGINE);
- camel_object_ref (session);
- engine->session = session;
- engine->url = url;
-
- return engine;
-}
-
-
-/**
- * camel_imap4_engine_take_stream:
- * @engine: imap4 engine
- * @stream: tcp stream
- * @ex: exception
- *
- * Gives ownership of @stream to @engine and reads the greeting from
- * the stream.
- *
- * Returns 0 on success or -1 on fail.
- *
- * Note: on error, @stream will be unref'd.
- **/
-int
-camel_imap4_engine_take_stream (CamelIMAP4Engine *engine, CamelStream *stream, CamelException *ex)
-{
- camel_imap4_token_t token;
- int code;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_ENGINE (engine), -1);
- g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
-
- if (engine->istream)
- camel_object_unref (engine->istream);
-
- if (engine->ostream)
- camel_object_unref (engine->ostream);
-
- engine->istream = (CamelIMAP4Stream *) camel_imap4_stream_new (stream);
- engine->ostream = camel_stream_buffer_new (stream, CAMEL_STREAM_BUFFER_WRITE);
- engine->state = CAMEL_IMAP4_ENGINE_CONNECTED;
- camel_object_unref (stream);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != '*') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if ((code = camel_imap4_engine_handle_untagged_1 (engine, &token, ex)) == -1) {
- goto exception;
- } else if (code != CAMEL_IMAP4_UNTAGGED_OK && code != CAMEL_IMAP4_UNTAGGED_PREAUTH) {
- /* FIXME: set an error? */
- goto exception;
- }
-
- return 0;
-
- exception:
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-
- camel_object_unref (engine->istream);
- engine->istream = NULL;
- camel_object_unref (engine->ostream);
- engine->ostream = NULL;
-
- return -1;
-}
-
-
-/**
- * camel_imap4_engine_capability:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Forces the IMAP4 engine to query the IMAP4 server for a list of capabilities.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_capability (CamelIMAP4Engine *engine, CamelException *ex)
-{
- CamelIMAP4Command *ic;
- int id, retval = 0;
-
- ic = camel_imap4_engine_queue (engine, NULL, "CAPABILITY\r\n");
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- retval = -1;
- }
-
- camel_imap4_command_unref (ic);
-
- return retval;
-}
-
-
-/**
- * camel_imap4_engine_namespace:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Forces the IMAP4 engine to query the IMAP4 server for a list of namespaces.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_list_t *list;
- GPtrArray *array = NULL;
- CamelIMAP4Command *ic;
- int id, i;
-
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_NAMESPACE) {
- ic = camel_imap4_engine_queue (engine, NULL, "NAMESPACE\r\n");
- } else {
- ic = camel_imap4_engine_queue (engine, NULL, "LIST \"\" \"\"\r\n");
- camel_imap4_command_register_untagged (ic, "LIST", camel_imap4_untagged_list);
- ic->user_data = array = g_ptr_array_new ();
- }
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
-
- if (array != NULL)
- g_ptr_array_free (array, TRUE);
-
- return -1;
- }
-
- if (array != NULL) {
- if (ic->result == CAMEL_IMAP4_RESULT_OK) {
- CamelIMAP4Namespace *namespace;
-
- g_assert (array->len == 1);
- list = array->pdata[0];
-
- namespace = g_new (CamelIMAP4Namespace, 1);
- namespace->next = NULL;
- namespace->path = g_strdup ("");
- namespace->sep = list->delim;
-
- engine->namespaces.personal = namespace;
- } else {
- /* should never *ever* happen */
- }
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- g_free (list->name);
- g_free (list);
- }
-
- g_ptr_array_free (array, TRUE);
- }
-
- camel_imap4_command_unref (ic);
-
- return 0;
-}
-
-
-int
-camel_imap4_engine_select_folder (CamelIMAP4Engine *engine, CamelFolder *folder, CamelException *ex)
-{
- CamelIMAP4RespCode *resp;
- CamelIMAP4Command *ic;
- int id, retval = 0;
- int i;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_ENGINE (engine), -1);
- g_return_val_if_fail (CAMEL_IS_IMAP4_FOLDER (folder), -1);
-
- /* POSSIBLE FIXME: if the folder to be selected will already
- * be selected by the time the queue is emptied, simply
- * no-op? */
-
- ic = camel_imap4_engine_queue (engine, folder, "SELECT %F\r\n", folder);
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- return -1;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /*folder->mode = 0;*/
- for (i = 0; i < ic->resp_codes->len; i++) {
- resp = ic->resp_codes->pdata[i];
- switch (resp->code) {
- case CAMEL_IMAP4_RESP_CODE_PERM_FLAGS:
- folder->permanent_flags = resp->v.flags;
- break;
- case CAMEL_IMAP4_RESP_CODE_READONLY:
- /*folder->mode = CAMEL_FOLDER_MODE_READ_ONLY;*/
- break;
- case CAMEL_IMAP4_RESP_CODE_READWRITE:
- /*folder->mode = CAMEL_FOLDER_MODE_READ_WRITE;*/
- break;
- case CAMEL_IMAP4_RESP_CODE_UIDNEXT:
- camel_imap4_summary_set_uidnext (folder->summary, resp->v.uidnext);
- break;
- case CAMEL_IMAP4_RESP_CODE_UIDVALIDITY:
- camel_imap4_summary_set_uidvalidity (folder->summary, resp->v.uidvalidity);
- break;
- case CAMEL_IMAP4_RESP_CODE_UNSEEN:
- camel_imap4_summary_set_unseen (folder->summary, resp->v.unseen);
- break;
- default:
- break;
- }
- }
-
- /*if (folder->mode == 0) {
- folder->mode = CAMEL_FOLDER_MODE_READ_ONLY;
- g_warning ("Expected to find [READ-ONLY] or [READ-WRITE] in SELECT response");
- }*/
-
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot select folder `%s': Invalid mailbox name"),
- folder->full_name);
- retval = -1;
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot select folder `%s': Bad command"),
- folder->full_name);
- retval = -1;
- break;
- default:
- g_assert_not_reached ();
- retval = -1;
- }
-
- camel_imap4_command_unref (ic);
-
- return retval;
-}
-
-
-static struct {
- const char *name;
- guint32 flag;
-} imap4_capabilities[] = {
- { "IMAP44", CAMEL_IMAP4_CAPABILITY_IMAP44 },
- { "IMAP44REV1", CAMEL_IMAP4_CAPABILITY_IMAP44REV1 },
- { "STATUS", CAMEL_IMAP4_CAPABILITY_STATUS },
- { "NAMESPACE", CAMEL_IMAP4_CAPABILITY_NAMESPACE },
- { "UIDPLUS", CAMEL_IMAP4_CAPABILITY_UIDPLUS },
- { "LITERAL+", CAMEL_IMAP4_CAPABILITY_LITERALPLUS },
- { "LOGINDISABLED", CAMEL_IMAP4_CAPABILITY_LOGINDISABLED },
- { "STARTTLS", CAMEL_IMAP4_CAPABILITY_STARTTLS },
- { NULL, 0 }
-};
-
-static gboolean
-auth_free (gpointer key, gpointer value, gpointer user_data)
-{
- g_free (key);
- return TRUE;
-}
-
-static int
-engine_parse_capability (CamelIMAP4Engine *engine, int sentinel, CamelException *ex)
-{
- camel_imap4_token_t token;
- int i;
-
- engine->capa = CAMEL_IMAP4_CAPABILITY_utf8_search;
- engine->level = 0;
-
- g_hash_table_foreach_remove (engine->authtypes, (GHRFunc) auth_free, NULL);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- while (token.token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!strncasecmp ("AUTH=", token.v.atom, 5)) {
- CamelServiceAuthType *auth;
-
- if ((auth = camel_sasl_authtype (token.v.atom + 5)) != NULL)
- g_hash_table_insert (engine->authtypes, g_strdup (token.v.atom + 5), auth);
- } else {
- for (i = 0; imap4_capabilities[i].name; i++) {
- if (!strcasecmp (imap4_capabilities[i].name, token.v.atom))
- engine->capa |= imap4_capabilities[i].flag;
- }
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
- }
-
- if (token.token != sentinel) {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- /* unget our sentinel token */
- camel_imap4_stream_unget_token (engine->istream, &token);
-
- /* figure out which version of IMAP4 we are dealing with */
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_IMAP44REV1) {
- engine->level = CAMEL_IMAP4_LEVEL_IMAP44REV1;
- engine->capa |= CAMEL_IMAP4_CAPABILITY_STATUS;
- } else if (engine->capa & CAMEL_IMAP4_CAPABILITY_IMAP44) {
- engine->level = CAMEL_IMAP4_LEVEL_IMAP44;
- } else {
- engine->level = CAMEL_IMAP4_LEVEL_UNKNOWN;
- }
-
- return 0;
-}
-
-static int
-engine_parse_flags_list (CamelIMAP4Engine *engine, CamelIMAP4RespCode *resp, int perm, CamelException *ex)
-{
- guint32 flags = 0;
-
- if (camel_imap4_parse_flags_list (engine, &flags, ex) == -1)
- return-1;
-
- if (resp != NULL)
- resp->v.flags = flags;
-
- if (engine->current && engine->current->folder) {
- if (perm)
- ((CamelFolder *) engine->current->folder)->permanent_flags = flags;
- /*else
- ((CamelFolder *) engine->current->folder)->folder_flags = flags;*/
- } else if (engine->folder) {
- if (perm)
- ((CamelFolder *) engine->folder)->permanent_flags = flags;
- /*else
- ((CamelFolder *) engine->folder)->folder_flags = flags;*/
- } else {
- fprintf (stderr, "We seem to be in a bit of a pickle. we've just parsed an untagged %s\n"
- "response for a folder, yet we do not currently have a folder selected?\n",
- perm ? "PERMANENTFLAGS" : "FLAGS");
- }
-
- return 0;
-}
-
-static int
-engine_parse_flags (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_token_t token;
-
- if (engine_parse_flags_list (engine, NULL, FALSE, ex) == -1)
- return -1;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != '\n') {
- d(fprintf (stderr, "Expected to find a '\\n' token after the FLAGS response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-
-enum {
- IMAP4_STATUS_MESSAGES,
- IMAP4_STATUS_RECENT,
- IMAP4_STATUS_UIDNEXT,
- IMAP4_STATUS_UIDVALIDITY,
- IMAP4_STATUS_UNSEEN,
- IMAP4_STATUS_UNKNOWN
-};
-
-static struct {
- const char *name;
- int type;
-} imap4_status[] = {
- { "MESSAGES", IMAP4_STATUS_MESSAGES },
- { "RECENT", IMAP4_STATUS_RECENT },
- { "UIDNEXT", IMAP4_STATUS_UIDNEXT },
- { "UIDVALIDITY", IMAP4_STATUS_UIDVALIDITY },
- { "UNSEEN", IMAP4_STATUS_UNSEEN },
- { NULL, IMAP4_STATUS_UNKNOWN },
-};
-
-static int
-engine_parse_status (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_token_t token;
- char *mailbox;
- size_t len;
- int type;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_ATOM:
- mailbox = g_strdup (token.v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- mailbox = g_strdup (token.v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, (unsigned char **) &mailbox, &len, ex) == -1)
- return -1;
- break;
- default:
- fprintf (stderr, "Unexpected token in IMAP4 untagged STATUS response: %s%c\n",
- token.token == CAMEL_IMAP4_TOKEN_NIL ? "NIL" : "",
- (unsigned char) (token.token & 0xff));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1) {
- g_free (mailbox);
- return -1;
- }
-
- if (token.token != '(') {
- d(fprintf (stderr, "Expected to find a '(' token after the mailbox token in the STATUS response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- g_free (mailbox);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1) {
- g_free (mailbox);
- return -1;
- }
-
- while (token.token == CAMEL_IMAP4_TOKEN_ATOM) {
- const unsigned char *inptr;
- unsigned int v = 0;
-
- /* parse the status messages list */
- for (type = 0; imap4_status[type].name; type++) {
- if (!strcasecmp (imap4_status[type].name, token.v.atom))
- break;
- }
-
- if (type == IMAP4_STATUS_UNKNOWN)
- fprintf (stderr, "unrecognized token in STATUS list: %s\n", token.v.atom);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1) {
- g_free (mailbox);
- return -1;
- }
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM)
- break;
-
- if (type == IMAP4_STATUS_UIDNEXT || type == IMAP4_STATUS_UIDVALIDITY) {
- /* these tokens should be numeric, but we
- * treat them as strings internally so we are
- * special-casing them here */
-
- /* FIXME: save the UIDNEXT/UIDVALIDITY value */
- } else {
- inptr = (const unsigned char *) token.v.atom;
- while (*inptr && isdigit ((int) *inptr) && v < (UINT_MAX / 10))
- v = (v * 10) + (*inptr++ - '0');
-
- if (*inptr != '\0') {
- if (type == IMAP4_STATUS_UNKNOWN) {
- /* we'll let it slide... unget this token and continue */
- camel_imap4_stream_unget_token (engine->istream, &token);
- goto loop;
- }
-
- d(fprintf (stderr, "Encountered non-numeric token after %s in untagged STATUS response: %s\n",
- imap4_status[type].name, token.v.atom));
- goto loop;
- }
-
- switch (type) {
- case IMAP4_STATUS_MESSAGES:
- /* FIXME: save value */
- break;
- case IMAP4_STATUS_RECENT:
- /* FIXME: save value */
- break;
- case IMAP4_STATUS_UNSEEN:
- /* FIXME: save value */
- break;
- default:
- g_assert_not_reached ();
- }
- }
-
- loop:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1) {
- g_free (mailbox);
- return -1;
- }
- }
-
- /* don't need this anymore... */
- g_free (mailbox);
-
- if (token.token != ')') {
- d(fprintf (stderr, "Expected to find a ')' token terminating the untagged STATUS response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != '\n') {
- d(fprintf (stderr, "Expected to find a '\\n' token after the STATUS response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-static int
-engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
-{
- CamelIMAP4Namespace *namespaces[3], *node, *tail;
- camel_imap4_token_t token;
- int i, n = 0;
-
- imap4_namespace_clear (&engine->namespaces.personal);
- imap4_namespace_clear (&engine->namespaces.other);
- imap4_namespace_clear (&engine->namespaces.shared);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- do {
- namespaces[n] = NULL;
- tail = (CamelIMAP4Namespace *) &namespaces[n];
-
- if (token.token == '(') {
- /* decode the list of namespace pairs */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- while (token.token == '(') {
- /* decode a namespace pair */
-
- /* get the path name token */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != CAMEL_IMAP4_TOKEN_QSTRING) {
- d(fprintf (stderr, "Expected to find a qstring token as first element in NAMESPACE pair\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- node = g_new (CamelIMAP4Namespace, 1);
- node->next = NULL;
- node->path = g_strdup (token.v.qstring);
-
- /* get the path delimiter token */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1) {
- g_free (node->path);
- g_free (node);
-
- goto exception;
- }
-
- if (token.token != CAMEL_IMAP4_TOKEN_QSTRING || strlen (token.v.qstring) > 1) {
- d(fprintf (stderr, "Expected to find a qstring token as second element in NAMESPACE pair\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- g_free (node->path);
- g_free (node);
-
- goto exception;
- }
-
- node->sep = *token.v.qstring;
- tail->next = node;
- tail = node;
-
- /* canonicalise the namespace path */
- if (node->path[strlen (node->path) - 1] == node->sep)
- node->path[strlen (node->path) - 1] = '\0';
-
- /* canonicalise if this is an INBOX namespace */
- if (!g_ascii_strncasecmp (node->path, "INBOX", 5) &&
- (node->path[6] == '\0' || node->path[6] == node->sep))
- memcpy (node->path, "INBOX", 5);
-
- /* get the closing ')' for this namespace pair */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != ')') {
- d(fprintf (stderr, "Expected to find a ')' token to close the current namespace pair\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
-
- goto exception;
- }
-
- /* get the next token (should be either '(' or ')') */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
- }
-
- if (token.token != ')') {
- d(fprintf (stderr, "Expected to find a ')' to close the current namespace list\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
- } else if (token.token == CAMEL_IMAP4_TOKEN_NIL) {
- /* namespace list is NIL */
- namespaces[n] = NULL;
- } else {
- d(fprintf (stderr, "Expected to find either NIL or '(' token in untagged NAMESPACE response\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- /* get the next token (should be either '(', NIL, or '\n') */
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- n++;
- } while (n < 3);
-
- engine->namespaces.personal = namespaces[0];
- engine->namespaces.other = namespaces[1];
- engine->namespaces.shared = namespaces[2];
-
- return 0;
-
- exception:
-
- for (i = 0; i <= n; i++)
- imap4_namespace_clear (&namespaces[i]);
-
- return -1;
-}
-
-
-/**
- *
- * resp-text-code = "ALERT" /
- * "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
- * capability-data / "PARSE" /
- * "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
- * "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
- * "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
- * "UNSEEN" SP nz-number /
- * atom [SP 1*<any TEXT-CHAR except "]">]
- **/
-
-static struct {
- const char *name;
- camel_imap4_resp_code_t code;
- int save;
-} imap4_resp_codes[] = {
- { "ALERT", CAMEL_IMAP4_RESP_CODE_ALERT, 0 },
- { "BADCHARSET", CAMEL_IMAP4_RESP_CODE_BADCHARSET, 0 },
- { "CAPABILITY", CAMEL_IMAP4_RESP_CODE_CAPABILITY, 0 },
- { "PARSE", CAMEL_IMAP4_RESP_CODE_PARSE, 1 },
- { "PERMANENTFLAGS", CAMEL_IMAP4_RESP_CODE_PERM_FLAGS, 1 },
- { "READ-ONLY", CAMEL_IMAP4_RESP_CODE_READONLY, 1 },
- { "READ-WRITE", CAMEL_IMAP4_RESP_CODE_READWRITE, 1 },
- { "TRYCREATE", CAMEL_IMAP4_RESP_CODE_TRYCREATE, 1 },
- { "UIDNEXT", CAMEL_IMAP4_RESP_CODE_UIDNEXT, 1 },
- { "UIDVALIDITY", CAMEL_IMAP4_RESP_CODE_UIDVALIDITY, 1 },
- { "UNSEEN", CAMEL_IMAP4_RESP_CODE_UNSEEN, 1 },
- { "NEWNAME", CAMEL_IMAP4_RESP_CODE_NEWNAME, 1 },
- { "APPENDUID", CAMEL_IMAP4_RESP_CODE_APPENDUID, 1 },
- { "COPYUID", CAMEL_IMAP4_RESP_CODE_COPYUID, 1 },
- { NULL, CAMEL_IMAP4_RESP_CODE_UNKNOWN, 0 }
-};
-
-
-int
-camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex)
-{
- CamelIMAP4RespCode *resp = NULL;
- camel_imap4_resp_code_t code;
- camel_imap4_token_t token;
- unsigned char *linebuf;
- size_t len;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != '[') {
- d(fprintf (stderr, "Expected a '[' token (followed by a RESP-CODE)\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM) {
- d(fprintf (stderr, "Expected an atom token containing a RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- for (code = 0; imap4_resp_codes[code].name; code++) {
- if (!strcmp (imap4_resp_codes[code].name, token.v.atom)) {
- if (engine->current && imap4_resp_codes[code].save) {
- resp = g_new0 (CamelIMAP4RespCode, 1);
- resp->code = code;
- }
- break;
- }
- }
-
- switch (code) {
- case CAMEL_IMAP4_RESP_CODE_BADCHARSET:
- /* apparently we don't support UTF-8 afterall */
- engine->capa &= ~CAMEL_IMAP4_CAPABILITY_utf8_search;
- break;
- case CAMEL_IMAP4_RESP_CODE_CAPABILITY:
- /* capability list follows */
- if (engine_parse_capability (engine, ']', ex) == -1)
- goto exception;
- break;
- case CAMEL_IMAP4_RESP_CODE_PERM_FLAGS:
- /* flag list follows */
- if (engine_parse_flags_list (engine, resp, TRUE, ex) == -1)
- goto exception;
- break;
- case CAMEL_IMAP4_RESP_CODE_READONLY:
- break;
- case CAMEL_IMAP4_RESP_CODE_READWRITE:
- break;
- case CAMEL_IMAP4_RESP_CODE_TRYCREATE:
- break;
- case CAMEL_IMAP4_RESP_CODE_UIDNEXT:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as an argument to the UIDNEXT RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.uidnext = token.v.number;
-
- break;
- case CAMEL_IMAP4_RESP_CODE_UIDVALIDITY:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as an argument to the UIDVALIDITY RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.uidvalidity = token.v.number;
-
- break;
- case CAMEL_IMAP4_RESP_CODE_UNSEEN:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as an argument to the UNSEEN RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.unseen = token.v.number;
-
- break;
- case CAMEL_IMAP4_RESP_CODE_NEWNAME:
- /* this RESP-CODE may actually be removed - see here:
- * http://www.washington.edu/imap4/listarch/2001/msg00058.html */
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_QSTRING) {
- d(fprintf (stderr, "Expected an atom or qstring token as the first argument to the NEWNAME RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.newname[0] = g_strdup (token.v.atom);
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_QSTRING) {
- d(fprintf (stderr, "Expected an atom or qstring token as the second argument to the NEWNAME RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.newname[1] = g_strdup (token.v.atom);
-
- break;
- case CAMEL_IMAP4_RESP_CODE_APPENDUID:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as the first argument to the APPENDUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.appenduid.uidvalidity = token.v.number;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as the second argument to the APPENDUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.appenduid.uid = token.v.number;
-
- break;
- case CAMEL_IMAP4_RESP_CODE_COPYUID:
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an nz_number token as the first argument to the COPYUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.copyuid.uidvalidity = token.v.number;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM) {
- d(fprintf (stderr, "Expected an atom token as the second argument to the COPYUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.copyuid.srcset = g_strdup (token.v.atom);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM) {
- d(fprintf (stderr, "Expected an atom token as the third argument to the APPENDUID RESP-CODE\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- goto exception;
- }
-
- if (resp != NULL)
- resp->v.copyuid.destset = g_strdup (token.v.atom);
-
- break;
- default:
- d(fprintf (stderr, "Unknown RESP-CODE encountered: %s\n", token.v.atom));
-
- /* extensions are of the form: "[" atom [SPACE 1*<any TEXT_CHAR except "]">] "]" */
-
- /* eat up the TEXT_CHARs */
- while (token.token != ']' && token.token != '\n') {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
- }
-
- break;
- }
-
- while (token.token != ']' && token.token != '\n') {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
- }
-
- if (token.token != ']') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- d(fprintf (stderr, "Expected to find a ']' token after the RESP-CODE\n"));
- return -1;
- }
-
- if (code == CAMEL_IMAP4_RESP_CODE_ALERT) {
- if (camel_imap4_engine_line (engine, &linebuf, &len, ex) == -1)
- goto exception;
-
- camel_session_alert_user (engine->session, CAMEL_SESSION_ALERT_INFO, linebuf, FALSE);
- g_free (linebuf);
- } else if (resp != NULL && code == CAMEL_IMAP4_RESP_CODE_PARSE) {
- if (camel_imap4_engine_line (engine, &linebuf, &len, ex) == -1)
- goto exception;
-
- resp->v.parse = linebuf;
- } else {
- /* eat up the rest of the response */
- if (camel_imap4_engine_line (engine, NULL, NULL, ex) == -1)
- goto exception;
- }
-
- if (resp != NULL)
- g_ptr_array_add (engine->current->resp_codes, resp);
-
- return 0;
-
- exception:
-
- if (resp != NULL)
- camel_imap4_resp_code_free (resp);
-
- return -1;
-}
-
-
-
-/* returns -1 on error, or one of CAMEL_IMAP4_UNTAGGED_[OK,NO,BAD,PREAUTH,HANDLED] on success */
-int
-camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
-{
- int code = CAMEL_IMAP4_UNTAGGED_HANDLED;
- CamelIMAP4Command *ic = engine->current;
- CamelIMAP4UntaggedCallback untagged;
- CamelFolder *folder;
- unsigned int v;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!strcmp ("BYE", token->v.atom)) {
- /* we don't care if we fail here, either way we've been disconnected */
- camel_imap4_engine_parse_resp_code (engine, NULL);
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-
- /* FIXME: emit a "disconnected" signal for our Store?
- * The Store could then initiate a reconnect if
- * desirable. */
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, _("Got BYE response"));
-
- return -1;
- } else if (!strcmp ("CAPABILITY", token->v.atom)) {
- /* capability tokens follow */
- if (engine_parse_capability (engine, '\n', ex) == -1)
- return -1;
-
- /* find the eoln token */
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != '\n') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
- } else if (!strcmp ("FLAGS", token->v.atom)) {
- /* flags list follows */
- if (engine_parse_flags (engine, ex) == -1)
- return -1;
- } else if (!strcmp ("NAMESPACE", token->v.atom)) {
- if (engine_parse_namespace (engine, ex) == -1)
- return -1;
- } else if (!strcmp ("NO", token->v.atom) || !strcmp ("BAD", token->v.atom)) {
- code = !strcmp ("NO", token->v.atom) ? CAMEL_IMAP4_UNTAGGED_NO : CAMEL_IMAP4_UNTAGGED_BAD;
-
- /* our command has been rejected */
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token == '[') {
- /* we have a resp code */
- camel_imap4_stream_unget_token (engine->istream, token);
- if (camel_imap4_engine_parse_resp_code (engine, ex) == -1)
- return -1;
- } else if (token->token != '\n') {
- /* we just have resp text */
- if (camel_imap4_engine_line (engine, NULL, NULL, ex) == -1)
- return -1;
- }
- } else if (!strcmp ("OK", token->v.atom)) {
- code = CAMEL_IMAP4_UNTAGGED_OK;
-
- if (engine->state == CAMEL_IMAP4_ENGINE_CONNECTED) {
- /* initial server greeting */
- engine->state = CAMEL_IMAP4_ENGINE_PREAUTH;
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token == '[') {
- /* we have a resp code */
- camel_imap4_stream_unget_token (engine->istream, token);
- if (camel_imap4_engine_parse_resp_code (engine, ex) == -1)
- return -1;
- } else {
- /* we just have resp text */
- if (camel_imap4_engine_line (engine, NULL, NULL, ex) == -1)
- return -1;
- }
- } else if (!strcmp ("PREAUTH", token->v.atom)) {
- code = CAMEL_IMAP4_UNTAGGED_PREAUTH;
-
- if (engine->state == CAMEL_IMAP4_ENGINE_CONNECTED)
- engine->state = CAMEL_IMAP4_ENGINE_AUTHENTICATED;
-
- if (camel_imap4_engine_parse_resp_code (engine, ex) == -1)
- return -1;
- } else if (!strcmp ("STATUS", token->v.atom)) {
- /* FIXME: This should probably be removed... leave it
- * up to the caller that sent the STATUS command to
- * register an untagged response handler for this */
-
- /* next token must be the mailbox name followed by a paren list */
- if (engine_parse_status (engine, ex) == -1)
- return -1;
- } else if (ic && (untagged = g_hash_table_lookup (ic->untagged, token->v.atom))) {
- /* registered untagged handler for imap4 command */
- if (untagged (engine, ic, 0, token, ex) == -1)
- return -1;
- } else {
- d(fprintf (stderr, "Unhandled atom token in untagged response: %s", token->v.atom));
-
- if (camel_imap4_engine_eat_line (engine, ex) == -1)
- return -1;
- }
- } else if (token->token == CAMEL_IMAP4_TOKEN_NUMBER) {
- /* we probably have something like "* 1 EXISTS" */
- v = token->v.number;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != CAMEL_IMAP4_TOKEN_ATOM) {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- return -1;
- }
-
- /* which folder is this EXISTS/EXPUNGE/RECENT acting on? */
- if (engine->current && engine->current->folder)
- folder = (CamelFolder *) engine->current->folder;
- else if (engine->folder)
- folder = (CamelFolder *) engine->folder;
- else
- folder = NULL;
-
- /* NOTE: these can be over-ridden by a registered untagged response handler */
- if (!strcmp ("EXISTS", token->v.atom)) {
- camel_imap4_summary_set_exists (folder->summary, v);
- } else if (!strcmp ("EXPUNGE", token->v.atom)) {
- camel_imap4_summary_expunge (folder->summary, (int) v);
- } else if (!strcmp ("RECENT", token->v.atom)) {
- camel_imap4_summary_set_recent (folder->summary, v);
- } else if (ic && (untagged = g_hash_table_lookup (ic->untagged, token->v.atom))) {
- /* registered untagged handler for imap4 command */
- if (untagged (engine, ic, v, token, ex) == -1)
- return -1;
- } else {
- d(fprintf (stderr, "Unrecognized untagged response: * %u %s\n", v, token->v.atom));
- }
-
- /* find the eoln token */
- if (camel_imap4_engine_eat_line (engine, ex) == -1)
- return -1;
- } else {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- return -1;
- }
-
- return code;
-}
-
-
-void
-camel_imap4_engine_handle_untagged (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_token_t token;
-
- g_return_if_fail (CAMEL_IS_IMAP4_ENGINE (engine));
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- goto exception;
-
- if (token.token != '*')
- break;
-
- if (camel_imap4_engine_handle_untagged_1 (engine, &token, ex) == -1)
- goto exception;
- } while (1);
-
- camel_imap4_stream_unget_token (engine->istream, &token);
-
- return;
-
- exception:
-
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
-}
-
-
-static int
-imap4_process_command (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
-{
- int retval;
-
- while ((retval = camel_imap4_command_step (ic)) == 0)
- ;
-
- if (retval == -1) {
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
- return -1;
- }
-
- return 0;
-}
-
-
-static void
-engine_prequeue_folder_select (CamelIMAP4Engine *engine)
-{
- CamelIMAP4Command *ic;
- const char *cmd;
-
- ic = (CamelIMAP4Command *) engine->queue.head;
- cmd = (const char *) ic->parts->buffer;
-
- if (!ic->folder || ic->folder == engine->folder ||
- !strncmp (cmd, "SELECT ", 7) || !strncmp (cmd, "EXAMINE ", 8)) {
- /* no need to pre-queue a SELECT */
- return;
- }
-
- /* we need to pre-queue a SELECT */
- ic = camel_imap4_command_new (engine, ic->folder, "SELECT %F\r\n", ic->folder);
- camel_imap4_engine_prequeue (engine, ic);
- ic->user_data = engine;
-
- camel_imap4_command_unref (ic);
-}
-
-
-static int
-engine_state_change (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
-{
- const char *cmd;
- int retval = 0;
-
- cmd = ic->parts->buffer;
- if (!strncmp (cmd, "SELECT ", 7) || !strncmp (cmd, "EXAMINE ", 8)) {
- if (ic->result == CAMEL_IMAP4_RESULT_OK) {
- /* Update the selected folder */
- camel_object_ref (ic->folder);
- if (engine->folder)
- camel_object_unref (engine->folder);
- engine->folder = ic->folder;
-
- engine->state = CAMEL_IMAP4_ENGINE_SELECTED;
- } else if (ic->user_data == engine) {
- /* the engine pre-queued this SELECT command */
- retval = -1;
- }
- } else if (!strncmp (cmd, "CLOSE", 5)) {
- if (ic->result == CAMEL_IMAP4_RESULT_OK)
- engine->state = CAMEL_IMAP4_ENGINE_AUTHENTICATED;
- } else if (!strncmp (cmd, "LOGOUT", 6)) {
- engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED;
- }
-
- return retval;
-}
-
-/**
- * camel_imap4_engine_iterate:
- * @engine: IMAP4 engine
- *
- * Processes the first command in the queue.
- *
- * Returns the id of the processed command, 0 if there were no
- * commands to process, or -1 on error.
- *
- * Note: more details on the error will be held on the
- * CamelIMAP4Command that failed.
- **/
-int
-camel_imap4_engine_iterate (CamelIMAP4Engine *engine)
-{
- CamelIMAP4Command *ic, *nic;
- GPtrArray *resp_codes;
- int retval = -1;
-
- if (e_dlist_empty (&engine->queue))
- return 0;
-
- /* check to see if we need to pre-queue a SELECT, if so do it */
- engine_prequeue_folder_select (engine);
-
- engine->current = ic = (CamelIMAP4Command *) e_dlist_remhead (&engine->queue);
- ic->status = CAMEL_IMAP4_COMMAND_ACTIVE;
-
- if (imap4_process_command (engine, ic) != -1) {
- if (engine_state_change (engine, ic) == -1) {
- /* This can ONLY happen if @ic was the pre-queued SELECT command
- * and it got a NO or BAD response.
- *
- * We have to pop the next imap4 command or we'll get into an
- * infinite loop. In order to provide @nic's owner with as much
- * information as possible, we move all @ic status information
- * over to @nic and pretend we just processed @nic.
- **/
-
- nic = (CamelIMAP4Command *) e_dlist_remhead (&engine->queue);
-
- nic->status = ic->status;
- nic->result = ic->result;
- resp_codes = nic->resp_codes;
- nic->resp_codes = ic->resp_codes;
- ic->resp_codes = resp_codes;
-
- camel_exception_xfer (&nic->ex, &ic->ex);
-
- camel_imap4_command_unref (ic);
- ic = nic;
- }
-
- retval = ic->id;
- }
-
- camel_imap4_command_unref (ic);
-
- return retval;
-}
-
-
-/**
- * camel_imap4_engine_queue:
- * @engine: IMAP4 engine
- * @folder: IMAP4 folder that the command will affect (or %NULL if it doesn't matter)
- * @format: command format
- * @Varargs: arguments
- *
- * Basically the same as #camel_imap4_command_new() except that this
- * function also places the command in the engine queue.
- *
- * Returns the CamelIMAP4Command.
- **/
-CamelIMAP4Command *
-camel_imap4_engine_queue (CamelIMAP4Engine *engine, CamelFolder *folder, const char *format, ...)
-{
- CamelIMAP4Command *ic;
- va_list args;
-
- va_start (args, format);
- ic = camel_imap4_command_newv (engine, (CamelIMAP4Folder *) folder, format, args);
- va_end (args);
-
- ic->id = engine->nextid++;
- e_dlist_addtail (&engine->queue, (EDListNode *) ic);
- camel_imap4_command_ref (ic);
-
- return ic;
-}
-
-
-/**
- * camel_imap4_engine_prequeue:
- * @engine: IMAP4 engine
- * @ic: IMAP4 command to pre-queue
- *
- * Places @ic at the head of the queue of pending IMAP4 commands.
- **/
-void
-camel_imap4_engine_prequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
-{
- g_return_if_fail (CAMEL_IS_IMAP4_ENGINE (engine));
- g_return_if_fail (ic != NULL);
-
- camel_imap4_command_ref (ic);
-
- if (e_dlist_empty (&engine->queue)) {
- e_dlist_addtail (&engine->queue, (EDListNode *) ic);
- ic->id = engine->nextid++;
- } else {
- CamelIMAP4Command *nic;
- EDListNode *node;
-
- node = (EDListNode *) ic;
- e_dlist_addhead (&engine->queue, node);
- nic = (CamelIMAP4Command *) node->next;
- ic->id = nic->id - 1;
-
- if (ic->id == 0) {
- /* increment all command ids */
- node = engine->queue.head;
- while (node->next) {
- nic = (CamelIMAP4Command *) node;
- node = node->next;
- nic->id++;
- }
- }
- }
-}
-
-
-void
-camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
-{
- EDListNode *node = (EDListNode *) ic;
-
- if (node->next == NULL && node->prev == NULL)
- return;
-
- e_dlist_remove (node);
- node->next = NULL;
- node->prev = NULL;
-
- camel_imap4_command_unref (ic);
-}
-
-
-int
-camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
-{
- if (camel_imap4_stream_next_token (engine->istream, token) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
- return -1;
- }
-
- return 0;
-}
-
-
-int
-camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex)
-{
- camel_imap4_token_t token;
- unsigned char *literal;
- int retval;
- size_t n;
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token == CAMEL_IMAP4_TOKEN_LITERAL) {
- while ((retval = camel_imap4_stream_literal (engine->istream, &literal, &n)) == 1)
- ;
-
- if (retval == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
-
- return -1;
- }
- }
- } while (token.token != '\n');
-
- return 0;
-}
-
-
-int
-camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t *len, CamelException *ex)
-{
- GByteArray *linebuf = NULL;
- unsigned char *buf;
- size_t buflen;
- int retval;
-
- if (line != NULL)
- linebuf = g_byte_array_new ();
-
- while ((retval = camel_imap4_stream_line (engine->istream, &buf, &buflen)) > 0) {
- if (linebuf != NULL)
- g_byte_array_append (linebuf, buf, buflen);
- }
-
- if (retval == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
-
- if (linebuf != NULL)
- g_byte_array_free (linebuf, TRUE);
-
- return -1;
- }
-
- if (linebuf != NULL) {
- g_byte_array_append (linebuf, buf, buflen);
-
- *line = linebuf->data;
- *len = linebuf->len;
-
- g_byte_array_free (linebuf, FALSE);
- }
-
- return 0;
-}
-
-
-int
-camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, size_t *len, CamelException *ex)
-{
- GByteArray *literalbuf = NULL;
- unsigned char *buf;
- size_t buflen;
- int retval;
-
- if (literal != NULL)
- literalbuf = g_byte_array_new ();
-
- while ((retval = camel_imap4_stream_literal (engine->istream, &buf, &buflen)) > 0) {
- if (literalbuf != NULL)
- g_byte_array_append (literalbuf, buf, buflen);
- }
-
- if (retval == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP4 server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
-
- if (literalbuf != NULL)
- g_byte_array_free (literalbuf, TRUE);
-
- return -1;
- }
-
- if (literalbuf != NULL) {
- g_byte_array_append (literalbuf, buf, buflen);
- g_byte_array_append (literalbuf, "", 1);
-
- *literal = literalbuf->data;
- *len = literalbuf->len - 1;
-
- g_byte_array_free (literalbuf, FALSE);
- }
-
- return 0;
-}
-
-
-void
-camel_imap4_resp_code_free (CamelIMAP4RespCode *rcode)
-{
- switch (rcode->code) {
- case CAMEL_IMAP4_RESP_CODE_PARSE:
- g_free (rcode->v.parse);
- break;
- case CAMEL_IMAP4_RESP_CODE_NEWNAME:
- g_free (rcode->v.newname[0]);
- g_free (rcode->v.newname[1]);
- break;
- case CAMEL_IMAP4_RESP_CODE_COPYUID:
- g_free (rcode->v.copyuid.srcset);
- g_free (rcode->v.copyuid.destset);
- break;
- default:
- break;
- }
-
- g_free (rcode);
-}
diff --git a/camel/providers/imap4/camel-imap4-engine.h b/camel/providers/imap4/camel-imap4-engine.h
deleted file mode 100644
index 25ae7ed11..000000000
--- a/camel/providers/imap4/camel-imap4-engine.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __CAMEL_IMAP4_ENGINE_H__
-#define __CAMEL_IMAP4_ENGINE_H__
-
-#include <stdarg.h>
-
-#include <glib.h>
-
-#include <e-util/e-msgport.h>
-
-#include <camel/camel-stream.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-session.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_ENGINE (camel_imap4_engine_get_type ())
-#define CAMEL_IMAP4_ENGINE(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_ENGINE, CamelIMAP4Engine))
-#define CAMEL_IMAP4_ENGINE_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP4_ENGINE, CamelIMAP4EngineClass))
-#define CAMEL_IS_IMAP4_ENGINE(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP4_ENGINE))
-#define CAMEL_IS_IMAP4_ENGINE_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP4_ENGINE))
-#define CAMEL_IMAP4_ENGINE_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_IMAP4_ENGINE, CamelIMAP4EngineClass))
-
-typedef struct _CamelIMAP4Engine CamelIMAP4Engine;
-typedef struct _CamelIMAP4EngineClass CamelIMAP4EngineClass;
-
-struct _camel_imap4_token_t;
-struct _CamelIMAP4Command;
-struct _CamelIMAP4Folder;
-struct _CamelIMAP4Stream;
-
-typedef enum {
- CAMEL_IMAP4_ENGINE_DISCONNECTED,
- CAMEL_IMAP4_ENGINE_CONNECTED,
- CAMEL_IMAP4_ENGINE_PREAUTH,
- CAMEL_IMAP4_ENGINE_AUTHENTICATED,
- CAMEL_IMAP4_ENGINE_SELECTED,
-} camel_imap4_engine_t;
-
-typedef enum {
- CAMEL_IMAP4_LEVEL_UNKNOWN,
- CAMEL_IMAP4_LEVEL_IMAP44,
- CAMEL_IMAP4_LEVEL_IMAP44REV1
-} camel_imap4_level_t;
-
-enum {
- CAMEL_IMAP4_CAPABILITY_IMAP44 = (1 << 0),
- CAMEL_IMAP4_CAPABILITY_IMAP44REV1 = (1 << 1),
- CAMEL_IMAP4_CAPABILITY_STATUS = (1 << 2),
- CAMEL_IMAP4_CAPABILITY_NAMESPACE = (1 << 3),
- CAMEL_IMAP4_CAPABILITY_UIDPLUS = (1 << 4),
- CAMEL_IMAP4_CAPABILITY_LITERALPLUS = (1 << 5),
- CAMEL_IMAP4_CAPABILITY_LOGINDISABLED = (1 << 6),
- CAMEL_IMAP4_CAPABILITY_STARTTLS = (1 << 7),
- CAMEL_IMAP4_CAPABILITY_useful_lsub = (1 << 8),
- CAMEL_IMAP4_CAPABILITY_utf8_search = (1 << 9),
-};
-
-typedef enum {
- CAMEL_IMAP4_RESP_CODE_ALERT,
- CAMEL_IMAP4_RESP_CODE_BADCHARSET,
- CAMEL_IMAP4_RESP_CODE_CAPABILITY,
- CAMEL_IMAP4_RESP_CODE_PARSE,
- CAMEL_IMAP4_RESP_CODE_PERM_FLAGS,
- CAMEL_IMAP4_RESP_CODE_READONLY,
- CAMEL_IMAP4_RESP_CODE_READWRITE,
- CAMEL_IMAP4_RESP_CODE_TRYCREATE,
- CAMEL_IMAP4_RESP_CODE_UIDNEXT,
- CAMEL_IMAP4_RESP_CODE_UIDVALIDITY,
- CAMEL_IMAP4_RESP_CODE_UNSEEN,
- CAMEL_IMAP4_RESP_CODE_NEWNAME,
- CAMEL_IMAP4_RESP_CODE_APPENDUID,
- CAMEL_IMAP4_RESP_CODE_COPYUID,
- CAMEL_IMAP4_RESP_CODE_UNKNOWN,
-} camel_imap4_resp_code_t;
-
-typedef struct _CamelIMAP4RespCode {
- camel_imap4_resp_code_t code;
- union {
- guint32 flags;
- char *parse;
- guint32 uidnext;
- guint32 uidvalidity;
- guint32 unseen;
- char *newname[2];
- struct {
- guint32 uidvalidity;
- guint32 uid;
- } appenduid;
- struct {
- guint32 uidvalidity;
- char *srcset;
- char *destset;
- } copyuid;
- } v;
-} CamelIMAP4RespCode;
-
-enum {
- CAMEL_IMAP4_UNTAGGED_ERROR = -1,
- CAMEL_IMAP4_UNTAGGED_OK,
- CAMEL_IMAP4_UNTAGGED_NO,
- CAMEL_IMAP4_UNTAGGED_BAD,
- CAMEL_IMAP4_UNTAGGED_PREAUTH,
- CAMEL_IMAP4_UNTAGGED_HANDLED,
-};
-
-typedef struct _CamelIMAP4Namespace {
- struct _CamelIMAP4Namespace *next;
- char *path;
- char sep;
-} CamelIMAP4Namespace;
-
-typedef struct _CamelIMAP4NamespaceList {
- CamelIMAP4Namespace *personal;
- CamelIMAP4Namespace *other;
- CamelIMAP4Namespace *shared;
-} CamelIMAP4NamespaceList;
-
-enum {
- CAMEL_IMAP4_ENGINE_MAXLEN_LINE,
- CAMEL_IMAP4_ENGINE_MAXLEN_TOKEN
-};
-
-struct _CamelIMAP4Engine {
- CamelObject parent_object;
-
- CamelSession *session;
- CamelURL *url;
-
- camel_imap4_engine_t state;
- camel_imap4_level_t level;
- guint32 capa;
-
- guint32 maxlen:31;
- guint32 maxlentype:1;
-
- CamelIMAP4NamespaceList namespaces;
- GHashTable *authtypes; /* supported authtypes */
-
- struct _CamelIMAP4Stream *istream;
- CamelStream *ostream;
-
- unsigned char tagprefix; /* 'A'..'Z' */
- unsigned int tag; /* next command tag */
- int nextid;
-
- struct _CamelIMAP4Folder *folder; /* currently selected folder */
-
- EDList queue; /* queue of waiting commands */
- struct _CamelIMAP4Command *current;
-};
-
-struct _CamelIMAP4EngineClass {
- CamelObjectClass parent_class;
-
- unsigned char tagprefix;
-};
-
-
-CamelType camel_imap4_engine_get_type (void);
-
-CamelIMAP4Engine *camel_imap4_engine_new (CamelSession *session, CamelURL *url);
-
-/* returns 0 on success or -1 on error */
-int camel_imap4_engine_take_stream (CamelIMAP4Engine *engine, CamelStream *stream, CamelException *ex);
-
-int camel_imap4_engine_capability (CamelIMAP4Engine *engine, CamelException *ex);
-int camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex);
-
-int camel_imap4_engine_select_folder (CamelIMAP4Engine *engine, CamelFolder *folder, CamelException *ex);
-
-struct _CamelIMAP4Command *camel_imap4_engine_queue (CamelIMAP4Engine *engine, CamelFolder *folder,
- const char *format, ...);
-void camel_imap4_engine_prequeue (CamelIMAP4Engine *engine, struct _CamelIMAP4Command *ic);
-
-void camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, struct _CamelIMAP4Command *ic);
-
-int camel_imap4_engine_iterate (CamelIMAP4Engine *engine);
-
-
-/* untagged response utility functions */
-int camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, struct _camel_imap4_token_t *token, CamelException *ex);
-void camel_imap4_engine_handle_untagged (CamelIMAP4Engine *engine, CamelException *ex);
-
-/* stream wrapper utility functions */
-int camel_imap4_engine_next_token (CamelIMAP4Engine *engine, struct _camel_imap4_token_t *token, CamelException *ex);
-int camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t *len, CamelException *ex);
-int camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, size_t *len, CamelException *ex);
-int camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex);
-
-
-/* response code stuff */
-int camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex);
-void camel_imap4_resp_code_free (CamelIMAP4RespCode *rcode);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_ENGINE_H__ */
diff --git a/camel/providers/imap4/camel-imap4-folder.c b/camel/providers/imap4/camel-imap4-folder.c
deleted file mode 100644
index a88ca7185..000000000
--- a/camel/providers/imap4/camel-imap4-folder.c
+++ /dev/null
@@ -1,888 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-
-#include <camel/camel-utf8.h>
-#include <camel/camel-private.h>
-#include <camel/camel-file-utils.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-stream-filter.h>
-#include <camel/camel-mime-filter-crlf.h>
-
-#include "camel-imap4-utils.h"
-#include "camel-imap4-store.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-summary.h"
-
-#define d(x) x
-
-static void camel_imap4_folder_class_init (CamelIMAP4FolderClass *klass);
-static void camel_imap4_folder_init (CamelIMAP4Folder *folder, CamelIMAP4FolderClass *klass);
-static void camel_imap4_folder_finalize (CamelObject *object);
-
-static void imap4_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
-static void imap4_expunge (CamelFolder *folder, CamelException *ex);
-static CamelMimeMessage *imap4_get_message (CamelFolder *folder, const char *uid, CamelException *ex);
-static void imap4_append_message (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid, CamelException *ex);
-static void imap4_transfer_messages_to (CamelFolder *src, GPtrArray *uids, CamelFolder *dest,
- GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex);
-
-
-static CamelFolderClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_folder_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (CAMEL_FOLDER_TYPE,
- "CamelIMAP4Folder",
- sizeof (CamelIMAP4Folder),
- sizeof (CamelIMAP4FolderClass),
- (CamelObjectClassInitFunc) camel_imap4_folder_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_folder_init,
- (CamelObjectFinalizeFunc) camel_imap4_folder_finalize);
- }
-
- return type;
-}
-
-static void
-camel_imap4_folder_class_init (CamelIMAP4FolderClass *klass)
-{
- CamelFolderClass *folder_class = (CamelFolderClass *) klass;
-
- parent_class = (CamelFolderClass *) camel_type_get_global_classfuncs (CAMEL_FOLDER_TYPE);
-
- folder_class->sync = imap4_sync;
- folder_class->expunge = imap4_expunge;
- folder_class->get_message = imap4_get_message;
- folder_class->append_message = imap4_append_message;
- folder_class->transfer_messages_to = imap4_transfer_messages_to;
-}
-
-static void
-camel_imap4_folder_init (CamelIMAP4Folder *folder, CamelIMAP4FolderClass *klass)
-{
- folder->utf7_name = NULL;
-}
-
-static void
-camel_imap4_folder_finalize (CamelObject *object)
-{
- CamelIMAP4Folder *folder = (CamelIMAP4Folder *) object;
-
- g_free (folder->utf7_name);
-}
-
-static char
-imap4_get_path_delim (CamelIMAP4Engine *engine, const char *full_name)
-{
- CamelIMAP4Namespace *namespace;
- const char *slash;
- size_t len;
- char *top;
-
- if ((slash = strchr (full_name, '/')))
- len = (slash - full_name);
- else
- len = strlen (full_name);
-
- top = g_alloca (len + 1);
- memcpy (top, full_name, len);
- top[len] = '\0';
-
- if (!g_ascii_strcasecmp (top, "INBOX"))
- top = "INBOX";
-
- retry:
- namespace = engine->namespaces.personal;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- namespace = engine->namespaces.other;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- namespace = engine->namespaces.shared;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- if (top[0] != '\0') {
- /* look for a default namespace? */
- top[0] = '\0';
- goto retry;
- }
-
- return '/';
-}
-
-CamelFolder *
-camel_imap4_folder_new (CamelStore *store, const char *full_name, CamelException *ex)
-{
- CamelIMAP4Folder *imap_folder;
- char *utf7_name, *name, *p;
- char sep;
-
- if (!(p = strrchr (full_name, '/')))
- p = (char *) full_name;
- else
- p++;
-
- name = g_alloca (strlen (p) + 1);
- strcpy (name, p);
-
- utf7_name = g_alloca (strlen (full_name) + 1);
- strcpy (utf7_name, full_name);
-
- sep = imap4_get_path_delim (((CamelIMAP4Store *) store)->engine, full_name);
- if (sep != '/') {
- p = utf7_name;
- while (*p != '\0') {
- if (*p == '/')
- *p = sep;
- p++;
- }
- }
-
- utf7_name = camel_utf8_utf7 (utf7_name);
-
- imap_folder = (CamelIMAP4Folder *) camel_object_new (CAMEL_TYPE_IMAP4_FOLDER);
- camel_folder_construct ((CamelFolder *) imap_folder, store, full_name, name);
- imap_folder->utf7_name = utf7_name;
-
- return (CamelFolder *) imap_folder;
-}
-
-
-const char *
-camel_imap4_folder_utf7_name (CamelIMAP4Folder *folder)
-{
- return folder->utf7_name;
-}
-
-
-static struct {
- const char *name;
- guint32 flag;
-} imap4_flags[] = {
- { "\\Answered", CAMEL_MESSAGE_ANSWERED },
- { "\\Deleted", CAMEL_MESSAGE_DELETED },
- { "\\Draft", CAMEL_MESSAGE_DRAFT },
- { "\\Flagged", CAMEL_MESSAGE_FLAGGED },
- /*{ "Forwarded", CAMEL_MESSAGE_FORWARDED },*/
- { "\\Seen", CAMEL_MESSAGE_SEEN },
-};
-
-static int
-imap4_get_uid_set (CamelIMAP4Engine *engine, CamelFolderSummary *summary, GPtrArray *infos, int cur, size_t linelen, char **set)
-{
- CamelMessageInfo *info;
- guint32 this, prev, next;
- gboolean range = FALSE;
- GString *uidset;
- int scount, i;
- size_t len;
-
- if (engine->maxlentype == CAMEL_IMAP4_ENGINE_MAXLEN_LINE)
- len = engine->maxlen - linelen;
- else
- len = engine->maxlen;
-
- i = cur + 1;
- info = (CamelMessageInfo *) infos->pdata[cur];
- fflush (stdout);
- uidset = g_string_new ("");
- g_string_append (uidset, camel_message_info_uid (info));
-
- if (!(i < infos->len))
- goto done;
-
- scount = summary->messages->len;
-
- /* init this info */
- for (this = 0; this < scount; this++) {
- if (info == summary->messages->pdata[this])
- break;
- }
-
- /* init next info */
- info = (CamelMessageInfo *) infos->pdata[i];
- for (next = this; next < scount; next++) {
- if (info == summary->messages->pdata[next])
- break;
- }
-
- for ( ; i < infos->len && uidset->len < len; i++) {
- prev = this;
- this = next;
-
- if (i + 1 < infos->len) {
- info = infos->pdata[i + 1];
- for (next = this; next < scount; next++) {
- if (info == summary->messages->pdata[next])
- break;
- }
- } else {
- next = scount;
- }
-
- if (this == (next - 1) || this == (prev + 1)) {
- range = TRUE;
- } else {
- if (range) {
- info = (CamelMessageInfo *) summary->messages->pdata[prev];
- g_string_append_printf (uidset, ":%s", camel_message_info_uid (info));
- range = FALSE;
- }
-
- info = infos->pdata[i];
- g_string_append_printf (uidset, ",%s", camel_message_info_uid (info));
- }
- }
-
- if (range) {
- info = (CamelMessageInfo *) summary->messages->pdata[this];
- g_string_append_printf (uidset, ":%s", camel_message_info_uid (info));
- }
-
- done:
-
- *set = uidset->str;
- g_string_free (uidset, FALSE);
-
- return (i - cur);
-}
-
-static int
-imap4_sync_flag (CamelFolder *folder, GPtrArray *infos, char onoff, const char *flag, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelIMAP4Command *ic;
- int i, id, retval = 0;
- char *set = NULL;
-
- for (i = 0; i < infos->len; ) {
- i += imap4_get_uid_set (engine, folder->summary, infos, i, 30 + strlen (flag), &set);
-
- ic = camel_imap4_engine_queue (engine, folder, "UID STORE %s %cFLAGS.SILENT (%s)\r\n", set, onoff, flag);
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- g_free (set);
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
-
- return -1;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot sync flags to folder `%s': Unknown"),
- folder->full_name);
- retval = -1;
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot sync flags to folder `%s': Bad command"),
- folder->full_name);
- retval = -1;
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- if (retval == -1)
- return -1;
- }
-
- return 0;
-}
-
-static int
-imap4_sync_changes (CamelFolder *folder, GPtrArray *sync, CamelException *ex)
-{
- CamelIMAP4MessageInfo *iinfo;
- GPtrArray *on_set, *off_set;
- CamelMessageInfo *info;
- flags_diff_t diff;
- int retval = 0;
- int i, j;
-
- on_set = g_ptr_array_new ();
- off_set = g_ptr_array_new ();
-
- /* construct commands to sync system and user flags */
- for (i = 0; i < G_N_ELEMENTS (imap4_flags); i++) {
- if (!(imap4_flags[i].flag & folder->permanent_flags))
- continue;
-
- for (j = 0; j < sync->len; j++) {
- iinfo = (CamelIMAP4MessageInfo *) info = sync->pdata[j];
- camel_imap4_flags_diff (&diff, iinfo->server_flags, info->flags);
- if (diff.changed & imap4_flags[i].flag) {
- if (diff.bits & imap4_flags[i].flag) {
- g_ptr_array_add (on_set, info);
- } else {
- g_ptr_array_add (off_set, info);
- }
- }
- }
-
- if (on_set->len > 0) {
- if ((retval = imap4_sync_flag (folder, on_set, '+', imap4_flags[i].name, ex)) == -1)
- break;
-
- g_ptr_array_set_size (on_set, 0);
- }
-
- if (off_set->len > 0) {
- if ((retval = imap4_sync_flag (folder, off_set, '-', imap4_flags[i].name, ex)) == -1)
- break;
-
- g_ptr_array_set_size (off_set, 0);
- }
- }
-
- g_ptr_array_free (on_set, TRUE);
- g_ptr_array_free (off_set, TRUE);
-
- if (retval == -1)
- return-1;
-
- for (i = 0; i < sync->len; i++) {
- iinfo = (CamelIMAP4MessageInfo *) info = sync->pdata[i];
- info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- iinfo->server_flags = info->flags & folder->permanent_flags;
- }
-
- return 0;
-}
-
-static void
-imap4_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelIMAP4MessageInfo *iinfo;
- CamelMessageInfo *info;
- CamelIMAP4Command *ic;
- flags_diff_t diff;
- GPtrArray *sync;
- int id, max, i;
- int retval;
-
- CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
-
- /* gather a list of changes to sync to the server */
- sync = g_ptr_array_new ();
- max = camel_folder_summary_count (folder->summary);
- for (i = 0; i < max; i++) {
- iinfo = (CamelIMAP4MessageInfo *) info = camel_folder_summary_index (folder->summary, i);
- expunge = expunge && (info->flags & CAMEL_MESSAGE_DELETED);
- if (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) {
- camel_imap4_flags_diff (&diff, iinfo->server_flags, info->flags);
- diff.changed &= folder->permanent_flags;
-
- /* weed out flag changes that we can't sync to the server */
- if (!diff.changed)
- camel_folder_summary_info_free (folder->summary, info);
- else
- g_ptr_array_add (sync, info);
- } else {
- camel_folder_summary_info_free (folder->summary, info);
- }
- }
-
- if (sync->len > 0) {
- retval = imap4_sync_changes (folder, sync, ex);
-
- for (i = 0; i < sync->len; i++)
- camel_folder_summary_info_free (folder->summary, sync->pdata[i]);
-
- g_ptr_array_free (sync, TRUE);
-
- if (retval == -1)
- goto done;
- } else {
- g_ptr_array_free (sync, TRUE);
- }
-
- if (expunge) {
- ic = camel_imap4_engine_queue (engine, folder, "EXPUNGE\r\n");
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot expunge folder `%s': Unknown"),
- folder->full_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot expunge folder `%s': Bad command"),
- folder->full_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
- }
-
- camel_folder_summary_save (folder->summary);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
-}
-
-static void
-imap4_expunge (CamelFolder *folder, CamelException *ex)
-{
- imap4_sync (folder, TRUE, ex);
-}
-
-
-static int
-untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
-{
- CamelStream *fstream, *stream = ic->user_data;
- CamelMimeFilter *crlf;
- int left = 2;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- /* parse the FETCH response list */
- if (token->token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- do {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_ATOM)
- goto unexpected;
-
- if (!strcmp (token->v.atom, "BODY[]")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_LITERAL)
- goto unexpected;
-
- fstream = (CamelStream *) camel_stream_filter_new_with_stream (stream);
- crlf = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- camel_stream_filter_add ((CamelStreamFilter *) fstream, crlf);
- camel_object_unref (crlf);
-
- camel_stream_write_to_stream ((CamelStream *) engine->istream, fstream);
- camel_stream_flush (fstream);
- camel_object_unref (fstream);
-
- left--;
- } else if (!strcmp (token->v.atom, "UID")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NUMBER || token->v.number == 0)
- goto unexpected;
-
- left--;
- } else {
- /* wtf? */
- fprintf (stderr, "huh? %s?...\n", token->v.atom);
- }
- } while (left);
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != ')') {
- fprintf (stderr, "expected ')' to close untagged FETCH response\n");
- goto unexpected;
- }
-
- return 0;
-
- unexpected:
-
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- exception:
-
- return -1;
-}
-
-static CamelMimeMessage *
-imap4_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelMimeMessage *message = NULL;
- CamelIMAP4Command *ic;
- CamelStream *stream;
- int id;
-
- CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
-
- ic = camel_imap4_engine_queue (engine, folder, "UID FETCH %s BODY.PEEK[]\r\n", uid);
- camel_imap4_command_register_untagged (ic, "FETCH", untagged_fetch);
- ic->user_data = stream = camel_stream_mem_new ();
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- camel_object_unref (stream);
- goto done;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- camel_stream_reset (stream);
- message = camel_mime_message_new ();
- camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream);
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get message %s from folder `%s': No such message"),
- uid, folder->full_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get message %s from folder `%s': Bad command"),
- uid, folder->full_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- camel_object_unref (stream);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
-
- return message;
-}
-
-static char *tm_months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static void
-imap4_append_message (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
- CamelIMAP4Summary *summary = (CamelIMAP4Summary *) folder->summary;
- CamelIMAP4RespCode *resp;
- CamelIMAP4Command *ic;
- CamelFolderInfo *fi;
- CamelException lex;
- char flags[100], *p;
- char date[50];
- struct tm tm;
- int id, i;
-
- CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
-
- /* construct the option flags list */
- if (info->flags & folder->permanent_flags) {
- p = g_stpcpy (flags, " (");
-
- for (i = 0; i < G_N_ELEMENTS (imap4_flags); i++) {
- if ((info->flags & imap4_flags[i].flag) & folder->permanent_flags) {
- p = g_stpcpy (p, imap4_flags[i].name);
- *p++ = ' ';
- }
- }
-
- p[-1] = ')';
- *p = '\0';
- } else {
- flags[0] = '\0';
- }
-
- /* construct the optional date_time string */
- if (info->date_received != (time_t) -1) {
- int tzone;
-
-#ifdef HAVE_LOCALTIME_R
- localtime_r (&info->date_received, &tm);
-#else
- memcpy (&tm, localtime (&info->date_received), sizeof (tm));
-#endif
-
-#if defined (HAVE_TM_GMTOFF)
- tzone = -tm.tm_gmtoff;
-#elif defined (HAVE_TIMEZONE)
- if (tm.tm_isdst > 0) {
-#if defined (HAVE_ALTZONE)
- tzone = altzone;
-#else /* !defined (HAVE_ALTZONE) */
- tzone = (timezone - 3600);
-#endif
- } else {
- tzone = timezone;
- }
-#else
-#error Neither HAVE_TIMEZONE nor HAVE_TM_GMTOFF defined. Rerun autoheader, autoconf, etc.
-#endif
-
- sprintf (date, " \"%02d-%s-%04d %02d:%02d:%02d %+05d\"",
- tm.tm_mday, tm_months[tm.tm_mon], tm.tm_year + 1900,
- tm.tm_hour, tm.tm_min, tm.tm_sec, tzone);
- } else {
- date[0] = '\0';
- }
-
- retry:
-
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_UIDPLUS)
- ic = camel_imap4_engine_queue (engine, NULL, "UID APPEND %F%s%s %L\r\n", flags, date, message);
- else
- ic = camel_imap4_engine_queue (engine, NULL, "APPEND %F%s%s %L\r\n", flags, date, message);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
- return;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- if (!(engine->capa & CAMEL_IMAP4_CAPABILITY_UIDPLUS))
- break;
-
- if (!appended_uid)
- break;
-
- for (i = 0; i < ic->resp_codes->len; i++) {
- resp = ic->resp_codes->pdata[i];
- if (resp->code == CAMEL_IMAP4_RESP_CODE_APPENDUID) {
- if (resp->v.appenduid.uidvalidity == summary->uidvalidity)
- *appended_uid = g_strdup_printf ("%u", resp->v.appenduid.uid);
- break;
- }
- }
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: can we give the user any more information? */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to folder `%s': Unknown error"),
- folder->full_name);
-
- for (i = 0; i < ic->resp_codes->len; i++) {
- resp = ic->resp_codes->pdata[i];
- if (resp->code == CAMEL_IMAP4_RESP_CODE_TRYCREATE) {
- char *parent_name, *p;
-
- parent_name = g_alloca (strlen (folder->full_name) + 1);
- if (!(p = strrchr (parent_name, '/')))
- *parent_name = '\0';
- else
- *p = '\0';
-
- if (!(fi = camel_store_create_folder (folder->parent_store, parent_name, folder->name, &lex))) {
- camel_exception_clear (&lex);
- break;
- }
-
- camel_store_free_folder_info (folder->parent_store, fi);
- camel_imap4_command_unref (ic);
- camel_exception_clear (ex);
- goto retry;
- }
- }
-
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot append message to folder `%s': Bad command"),
- folder->full_name);
-
- break;
- default:
- g_assert_not_reached ();
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
-}
-
-
-static int
-info_uid_sort (const CamelMessageInfo **info0, const CamelMessageInfo **info1)
-{
- guint32 uid0, uid1;
-
- uid0 = strtoul (camel_message_info_uid (*info0), NULL, 10);
- uid1 = strtoul (camel_message_info_uid (*info1), NULL, 10);
-
- if (uid0 == uid1)
- return 0;
-
- return uid0 < uid1 ? -1 : 1;
-}
-
-static void
-imap4_transfer_messages_to (CamelFolder *src, GPtrArray *uids, CamelFolder *dest,
- GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) src->parent_store)->engine;
- int i, j, n, id, dest_namelen;
- CamelMessageInfo *info;
- CamelIMAP4Command *ic;
- GPtrArray *infos;
- char *set;
-
- infos = g_ptr_array_new ();
- for (i = 0; i < uids->len; i++) {
- if (!(info = camel_folder_summary_uid (src->summary, uids->pdata[i])))
- continue;
-
- g_ptr_array_add (infos, info);
- }
-
- if (infos->len == 0) {
- g_ptr_array_free (infos, TRUE);
- return;
- }
-
- g_ptr_array_sort (infos, (GCompareFunc) info_uid_sort);
-
- CAMEL_SERVICE_LOCK (src->parent_store, connect_lock);
-
- dest_namelen = strlen (camel_imap4_folder_utf7_name ((CamelIMAP4Folder *) dest));
-
- for (i = 0; i < infos->len; i += n) {
- n = imap4_get_uid_set (engine, src->summary, infos, i, 10 + dest_namelen, &set);
-
- ic = camel_imap4_engine_queue (engine, src, "UID COPY %s %F\r\n", set, dest);
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- g_free (set);
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- g_free (set);
- goto done;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- if (delete_originals) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot move messages from folder `%s' to folder `%s': Unknown"),
- src->full_name, dest->full_name);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot copy messages from folder `%s' to folder `%s': Unknown"),
- src->full_name, dest->full_name);
- }
-
- goto done;
- case CAMEL_IMAP4_RESULT_BAD:
- if (delete_originals) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot move messages from folder `%s' to folder `%s': Bad command"),
- src->full_name, dest->full_name);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot copy messages from folder `%s' to folder `%s': Bad command"),
- src->full_name, dest->full_name);
- }
-
- goto done;
- }
-
- camel_imap4_command_unref (ic);
-
- if (delete_originals) {
- for (j = i; j < n; j++) {
- info = infos->pdata[j];
- camel_folder_set_message_flags (src, camel_message_info_uid (info),
- CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED);
- }
-
- camel_folder_summary_touch (src->summary);
- }
- }
-
- done:
-
- for (i = 0; i < infos->len; i++)
- camel_folder_summary_info_free (src->summary, infos->pdata[i]);
- g_ptr_array_free (infos, TRUE);
-
- CAMEL_SERVICE_LOCK (src->parent_store, connect_lock);
-}
diff --git a/camel/providers/imap4/camel-imap4-folder.h b/camel/providers/imap4/camel-imap4-folder.h
deleted file mode 100644
index 203c80074..000000000
--- a/camel/providers/imap4/camel-imap4-folder.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __CAMEL_IMAP4_FOLDER_H__
-#define __CAMEL_IMAP4_FOLDER_H__
-
-#include <camel/camel-store.h>
-#include <camel/camel-folder.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_FOLDER (camel_imap4_folder_get_type ())
-#define CAMEL_IMAP4_FOLDER(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_FOLDER, CamelIMAP4Folder))
-#define CAMEL_IMAP4_FOLDER_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP4_FOLDER, CamelIMAP4FolderClass))
-#define CAMEL_IS_IMAP4_FOLDER(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP4_FOLDER))
-#define CAMEL_IS_IMAP4_FOLDER_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP4_FOLDER))
-#define CAMEL_IMAP4_FOLDER_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_IMAP4_FOLDER, CamelIMAP4FolderClass))
-
-typedef struct _CamelIMAP4Folder CamelIMAP4Folder;
-typedef struct _CamelIMAP4FolderClass CamelIMAP4FolderClass;
-
-struct _CamelIMAP4Folder {
- CamelFolder parent_object;
-
- char *cachedir;
- char *utf7_name;
-};
-
-struct _CamelIMAP4FolderClass {
- CamelFolderClass parent_class;
-
-};
-
-
-CamelType camel_imap4_folder_get_type (void);
-
-CamelFolder *camel_imap4_folder_new (CamelStore *store, const char *full_name, CamelException *ex);
-
-const char *camel_imap4_folder_utf7_name (CamelIMAP4Folder *folder);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_FOLDER_H__ */
diff --git a/camel/providers/imap4/camel-imap4-provider.c b/camel/providers/imap4/camel-imap4-provider.c
deleted file mode 100644
index 185053f03..000000000
--- a/camel/providers/imap4/camel-imap4-provider.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include <camel/camel-sasl.h>
-#include <camel/camel-provider.h>
-
-#include "camel-imap4-store.h"
-
-
-CamelProviderConfEntry imap4_conf_entries[] = {
- { CAMEL_PROVIDER_CONF_SECTION_START, "mailcheck", NULL,
- N_("Checking for new mail") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "check_all", NULL,
- N_("Check for new messages in all folders"), "1" },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_SECTION_START, "folders", NULL,
- N_("Folders") },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "use_lsub", NULL,
- N_("Show only subscribed folders"), "1" },
- { CAMEL_PROVIDER_CONF_CHECKBOX, "override_namespace", NULL,
- N_("Override server-supplied folder namespace"), "0" },
- { CAMEL_PROVIDER_CONF_ENTRY, "namespace", "override_namespace",
- N_("Namespace") },
- { CAMEL_PROVIDER_CONF_SECTION_END },
- { CAMEL_PROVIDER_CONF_END }
-};
-
-static CamelProvider imap4_provider = {
- "imap4",
- N_("IMAPv4rev1"),
-
- N_("For reading and storing mail on IMAPv4rev1 servers. EXPERIMENTAL !!"),
-
- "mail",
-
- CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
- CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL,
-
- CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH,
-
- imap4_conf_entries,
-
- /* ... */
-};
-
-CamelServiceAuthType camel_imap4_password_authtype = {
- N_("Password"),
-
- N_("This option will connect to the IMAPv4rev1 server using a "
- "plaintext password."),
-
- "",
- TRUE
-};
-
-
-static void
-add_hash (guint *hash, char *s)
-{
- if (s)
- *hash ^= g_str_hash(s);
-}
-
-static guint
-imap4_url_hash (gconstpointer key)
-{
- const CamelURL *u = (CamelURL *)key;
- guint hash = 0;
-
- add_hash (&hash, u->user);
- add_hash (&hash, u->authmech);
- add_hash (&hash, u->host);
- hash ^= u->port;
-
- return hash;
-}
-
-static 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
-imap4_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;
-}
-
-
-void
-camel_provider_module_init (void)
-{
- imap4_provider.object_types[CAMEL_PROVIDER_STORE] = camel_imap4_store_get_type ();
- imap4_provider.url_hash = imap4_url_hash;
- imap4_provider.url_equal = imap4_url_equal;
- imap4_provider.authtypes = camel_sasl_authtype_list (FALSE);
- imap4_provider.authtypes = g_list_prepend (imap4_provider.authtypes, &camel_imap4_password_authtype);
-
- camel_provider_register (&imap4_provider);
-}
diff --git a/camel/providers/imap4/camel-imap4-specials.c b/camel/providers/imap4/camel-imap4-specials.c
deleted file mode 100644
index 4682a403e..000000000
--- a/camel/providers/imap4/camel-imap4-specials.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "camel-imap4-specials.h"
-
-#define CHARS_ATOM_SPECIALS "(){]"
-#define CHARS_LWSP " \t\r\n"
-#define CHARS_QUOTED_SPECIALS "\\\""
-#define CHARS_LIST_WILDCARDS "*%"
-
-unsigned char camel_imap4_specials[256] = {
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 6, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 20, 0, 8, 0, 0, 32, 0, 0, 1, 1, 32, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-};
-
-
-static void
-imap4_init_bits (unsigned short bit, unsigned short bitcopy, int remove, unsigned char *vals)
-{
- int i, len = strlen (vals);
-
- if (!remove) {
- for (i = 0; i < len; i++)
- camel_imap4_specials[vals[i]] |= bit;
- if (bitcopy) {
- for (i = 0; i < 256; i++) {
- if (camel_imap4_specials[i] & bitcopy)
- camel_imap4_specials[i] |= bit;
- }
- }
- } else {
- for (i = 0; i < 256; i++)
- camel_imap4_specials[i] |= bit;
- for (i = 0; i < len; i++)
- camel_imap4_specials[vals[i]] &= ~bit;
- if (bitcopy) {
- for (i = 0; i < 256; i++) {
- if (camel_imap4_specials[i] & bitcopy)
- camel_imap4_specials[i] &= ~bit;
- }
- }
- }
-}
-
-
-void
-camel_imap4_specials_init (void)
-{
- int i;
-
- for (i = 0; i < 256; i++) {
- camel_imap4_specials[i] = 0;
- if (i <= 0x1f || i >= 0x7f)
- camel_imap4_specials[i] |= IS_CTRL;
- }
-
- camel_imap4_specials[' '] |= IS_SPACE;
-
- imap4_init_bits (IS_LWSP, 0, 0, CHARS_LWSP);
- imap4_init_bits (IS_ASPECIAL, 0, 0, CHARS_ATOM_SPECIALS);
- imap4_init_bits (IS_QSPECIAL, 0, 0, CHARS_QUOTED_SPECIALS);
- imap4_init_bits (IS_WILDCARD, 0, 0, CHARS_LIST_WILDCARDS);
-}
diff --git a/camel/providers/imap4/camel-imap4-specials.h b/camel/providers/imap4/camel-imap4-specials.h
deleted file mode 100644
index 36765cdc6..000000000
--- a/camel/providers/imap4/camel-imap4-specials.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __CAMEL_IMAP4_SPECIALS_H__
-#define __CAMEL_IMAP4_SPECIALS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-enum {
- IS_ASPECIAL = (1 << 0),
- IS_CTRL = (1 << 1),
- IS_LWSP = (1 << 2),
- IS_QSPECIAL = (1 << 3),
- IS_SPACE = (1 << 4),
- IS_WILDCARD = (1 << 5),
-};
-
-extern unsigned char camel_imap4_specials[256];
-
-#define is_atom(x) ((camel_imap4_specials[(unsigned char)(x)] & (IS_ASPECIAL|IS_SPACE|IS_CTRL|IS_WILDCARD|IS_QSPECIAL)) == 0)
-#define is_ctrl(x) ((camel_imap4_specials[(unsigned char)(x)] & IS_CTRL) != 0)
-#define is_lwsp(x) ((camel_imap4_specials[(unsigned char)(x)] & IS_LWSP) != 0)
-#define is_type(x, t) ((camel_imap4_specials[(unsigned char)(x)] & (t)) != 0)
-#define is_qsafe(x) ((camel_imap4_specials[(unsigned char)(x)] & (IS_QSPECIAL|IS_CTRL)) == 0)
-#define is_wild(x) ((camel_imap4_specials[(unsigned char)(x)] & IS_WILDCARD) != 0)
-
-void camel_imap4_specials_init (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_SPECIALS_H__ */
diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c
deleted file mode 100644
index aa8dfc0c0..000000000
--- a/camel/providers/imap4/camel-imap4-store.c
+++ /dev/null
@@ -1,1178 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <camel/camel-sasl.h>
-#include <camel/camel-utf8.h>
-#include <camel/camel-tcp-stream-raw.h>
-#include <camel/camel-tcp-stream-ssl.h>
-
-#include <camel/camel-private.h>
-
-#include "camel-imap4-store.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-utils.h"
-
-
-static void camel_imap4_store_class_init (CamelIMAP4StoreClass *klass);
-static void camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass);
-static void camel_imap4_store_finalize (CamelObject *object);
-
-/* service methods */
-static void imap4_construct (CamelService *service, CamelSession *session,
- CamelProvider *provider, CamelURL *url,
- CamelException *ex);
-static char *imap4_get_name (CamelService *service, gboolean brief);
-static gboolean imap4_connect (CamelService *service, CamelException *ex);
-static gboolean imap4_disconnect (CamelService *service, gboolean clean, CamelException *ex);
-static GList *imap4_query_auth_types (CamelService *service, CamelException *ex);
-
-/* store methods */
-static CamelFolder *imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
-static CamelFolderInfo *imap4_create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex);
-static void imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex);
-static void imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
-static CamelFolderInfo *imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
-static void imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
-static void imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
-static void imap4_noop (CamelStore *store, CamelException *ex);
-
-
-static CamelStoreClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_store_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (CAMEL_STORE_TYPE,
- "CamelIMAP4Store",
- sizeof (CamelIMAP4Store),
- sizeof (CamelIMAP4StoreClass),
- (CamelObjectClassInitFunc) camel_imap4_store_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_store_init,
- (CamelObjectFinalizeFunc) camel_imap4_store_finalize);
- }
-
- return type;
-}
-
-static guint
-imap4_hash_folder_name (gconstpointer key)
-{
- if (g_ascii_strcasecmp (key, "INBOX") == 0)
- return g_str_hash ("INBOX");
- else
- return g_str_hash (key);
-}
-
-static gint
-imap4_compare_folder_name (gconstpointer a, gconstpointer b)
-{
- gconstpointer aname = a, bname = b;
-
- if (g_ascii_strcasecmp (a, "INBOX") == 0)
- aname = "INBOX";
- if (g_ascii_strcasecmp (b, "INBOX") == 0)
- bname = "INBOX";
- return g_str_equal (aname, bname);
-}
-
-static void
-camel_imap4_store_class_init (CamelIMAP4StoreClass *klass)
-{
- CamelServiceClass *service_class = (CamelServiceClass *) klass;
- CamelStoreClass *store_class = (CamelStoreClass *) klass;
-
- parent_class = (CamelStoreClass *) camel_type_get_global_classfuncs (CAMEL_STORE_TYPE);
-
- service_class->construct = imap4_construct;
- service_class->get_name = imap4_get_name;
- service_class->connect = imap4_connect;
- service_class->disconnect = imap4_disconnect;
- service_class->query_auth_types = imap4_query_auth_types;
-
- store_class->hash_folder_name = imap4_hash_folder_name;
- store_class->compare_folder_name = imap4_compare_folder_name;
-
- store_class->get_folder = imap4_get_folder;
- store_class->create_folder = imap4_create_folder;
- store_class->delete_folder = imap4_delete_folder;
- store_class->rename_folder = imap4_rename_folder;
- store_class->get_folder_info = imap4_get_folder_info;
- store_class->subscribe_folder = imap4_subscribe_folder;
- store_class->unsubscribe_folder = imap4_unsubscribe_folder;
- store_class->noop = imap4_noop;
-}
-
-static void
-camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass)
-{
- store->engine = NULL;
-}
-
-static void
-camel_imap4_store_finalize (CamelObject *object)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) object;
-
- if (store->engine)
- camel_object_unref (store->engine);
-}
-
-
-static void
-imap4_construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
-{
- CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
-}
-
-static char *
-imap4_get_name (CamelService *service, gboolean brief)
-{
- if (brief)
- return g_strdup_printf (_("IMAP server %s"), service->url->host);
- else
- return g_strdup_printf (_("IMAP service for %s on %s"),
- service->url->user, service->url->host);
-}
-
-enum {
- USE_SSL_NEVER,
- USE_SSL_ALWAYS,
- USE_SSL_WHEN_POSSIBLE
-};
-
-#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
-
-static gboolean
-connect_to_server (CamelService *service, struct hostent *host, int ssl_mode, int try_starttls, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- CamelIMAP4Engine *engine;
- CamelStream *tcp_stream;
- int port, ret;
-
- if (store->engine) {
- camel_object_unref (store->engine);
- store->engine = NULL;
- }
-
- port = service->url->port ? service->url->port : 143;
-
- if (ssl_mode) {
-#ifdef HAVE_SSL
- if (try_starttls) {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- port = service->url->port ? service->url->port : 993;
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
- }
-#else
- if (!try_starttls)
- port = service->url->port ? service->url->port : 993;
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port,
- _("SSL unavailable"));
-
- return FALSE;
-#endif /* HAVE_SSL */
- } else {
- tcp_stream = camel_tcp_stream_raw_new ();
- }
-
- fprintf (stderr, "connecting to %s:%d\n", service->url->host, port);
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, port)) == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Connection cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s (port %d): %s"),
- service->url->host, port,
- g_strerror (errno));
-
- camel_object_unref (tcp_stream);
-
- return FALSE;
- }
-
- engine = camel_imap4_engine_new (service->session, service->url);
- if (camel_imap4_engine_take_stream (engine, tcp_stream, ex) == -1) {
- camel_object_unref (engine);
-
- return FALSE;
- }
-
- if (camel_imap4_engine_capability (engine, ex) == -1) {
- camel_object_unref (engine);
-
- return FALSE;
- }
-
- store->engine = engine;
-
-#ifdef HAVE_SSL
- if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
- /* try_starttls is always TRUE here */
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_STARTTLS)
- goto starttls;
- } else if (ssl_mode == USE_SSL_ALWAYS) {
- if (try_starttls) {
- if (engine->capa & CAMEL_IMAP4_CAPABILITY_STARTTLS) {
- goto starttls;
- } else {
- /* server doesn't support STARTTLS, abort */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Failed to connect to IMAP server %s in secure mode: "
- "Server does not support STARTTLS"),
- service->url->host);
- goto exception;
- }
- }
- }
-#endif /* HAVE_SSL */
-
- return TRUE;
-
-#ifdef HAVE_SSL
- starttls:
-
- if (1) {
- CamelIMAP4Command *ic;
- int id;
-
- ic = camel_imap4_engine_queue (engine, NULL, "STARTTLS\r\n");
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->result != CAMEL_IMAP4_RESULT_OK) {
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to IMAP server %s in secure mode: %s"),
- service->url->host, _("Unknown error"));
- } else {
- camel_exception_xfer (ex, &ic->ex);
- }
-
- camel_imap4_command_unref (ic);
-
- goto exception;
- }
-
- camel_imap4_command_unref (ic);
- }
-
- return TRUE;
-
- exception:
-
- camel_object_unref (store->engine);
- store->engine = NULL;
-
- return FALSE;
-#endif /* HAVE_SSL */
-}
-
-static struct {
- char *value;
- int mode;
-} ssl_options[] = {
- { "", USE_SSL_ALWAYS },
- { "always", USE_SSL_ALWAYS },
- { "when-possible", USE_SSL_WHEN_POSSIBLE },
- { "never", USE_SSL_NEVER },
- { NULL, USE_SSL_NEVER },
-};
-
-static gboolean
-connect_to_server_wrapper (CamelService *service, CamelException *ex)
-{
- const char *use_ssl;
- struct hostent *h;
- int ssl_mode;
- int ret, i;
-
- if (!(h = camel_service_gethost (service, ex)))
- return FALSE;
-
- if ((use_ssl = camel_url_get_param (service->url, "use_ssl"))) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, use_ssl))
- break;
- ssl_mode = ssl_options[i].mode;
- } else {
- ssl_mode = USE_SSL_NEVER;
- }
-
- if (ssl_mode == USE_SSL_ALWAYS) {
- /* First try the ssl port */
- if (!(ret = connect_to_server (service, h, ssl_mode, FALSE, ex))) {
- if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
- /* The ssl port seems to be unavailable, lets try STARTTLS */
- camel_exception_clear (ex);
- ret = connect_to_server (service, h, ssl_mode, TRUE, ex);
- }
- }
- } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
- /* If the server supports STARTTLS, use it */
- ret = connect_to_server (service, h, ssl_mode, TRUE, ex);
- } else {
- /* User doesn't care about SSL */
- ret = connect_to_server (service, h, USE_SSL_ALWAYS, FALSE, ex);
- }
-
- camel_free_host (h);
-
- return ret;
-}
-
-static int
-sasl_auth (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, const unsigned char *linebuf, size_t linelen, CamelException *ex)
-{
- /* Perform a single challenge iteration */
- CamelSasl *sasl = ic->user_data;
- char *challenge;
-
- if (camel_sasl_authenticated (sasl)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Cannot authenticate to IMAP server %s using the %s authentication mechanism"),
- engine->url->host, engine->url->authmech);
- return -1;
- }
-
- while (isspace (*linebuf))
- linebuf++;
-
- if (*linebuf == '\0')
- linebuf = NULL;
-
- if (!(challenge = camel_sasl_challenge_base64 (sasl, (const char *) linebuf, ex)))
- return -1;
-
- fprintf (stderr, "sending : %s\r\n", challenge);
-
- if (camel_stream_printf (engine->ostream, "%s\r\n", challenge) == -1) {
- g_free (challenge);
- return -1;
- }
-
- g_free (challenge);
-
- if (camel_stream_flush (engine->ostream) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-imap4_try_authenticate (CamelService *service, gboolean reprompt, const char *errmsg, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- CamelSession *session = service->session;
- CamelSasl *sasl = NULL;
- CamelIMAP4Command *ic;
- int id;
-
- if (!service->url->passwd) {
- guint32 flags = CAMEL_SESSION_PASSWORD_SECRET;
- char *prompt;
-
- if (reprompt)
- flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
-
- prompt = g_strdup_printf (_("%sPlease enter the IMAP password for %s on host %s"),
- errmsg ? errmsg : "",
- service->url->user,
- service->url->host);
-
- service->url->passwd = camel_session_get_password (session, prompt, flags, service, "password", ex);
-
- g_free (prompt);
-
- if (!service->url->passwd)
- return FALSE;
- }
-
- if (service->url->authmech) {
- CamelServiceAuthType *mech;
-
- mech = g_hash_table_lookup (store->engine->authtypes, service->url->authmech);
- sasl = camel_sasl_new ("imap4", mech->authproto, service);
-
- ic = camel_imap4_engine_queue (store->engine, NULL, "AUTHENTICATE %s\r\n", service->url->authmech);
- ic->plus = sasl_auth;
- ic->user_data = sasl;
- } else {
- ic = camel_imap4_engine_queue (store->engine, NULL, "LOGIN %S %S\r\n",
- service->url->user, service->url->passwd);
- }
-
- while ((id = camel_imap4_engine_iterate (store->engine)) < ic->id && id != -1)
- ;
-
- if (sasl != NULL)
- camel_object_unref (sasl);
-
- if (id == -1 || ic->status == CAMEL_IMAP4_COMMAND_ERROR) {
- /* unrecoverable error */
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
-
- return FALSE;
- }
-
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_imap4_command_unref (ic);
-
- /* try again */
-
- return TRUE;
- }
-
- camel_imap4_command_unref (ic);
-
- return FALSE;
-}
-
-static gboolean
-imap4_connect (CamelService *service, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- CamelServiceAuthType *mech;
- gboolean reprompt = FALSE;
- char *errmsg = NULL;
- CamelException lex;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- if (!connect_to_server_wrapper (service, ex)) {
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return FALSE;
- }
-
-#define CANT_USE_AUTHMECH (!(mech = g_hash_table_lookup (store->engine->authtypes, service->url->authmech)))
- if (service->url->authmech && CANT_USE_AUTHMECH) {
- /* Oops. We can't AUTH using the requested mechanism */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
- _("Cannot authenticate to IMAP server %s using %s"),
- service->url->host, service->url->authmech);
-
- camel_object_unref (store->engine);
- store->engine = NULL;
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return FALSE;
- }
-
- camel_exception_init (&lex);
- while (imap4_try_authenticate (service, reprompt, errmsg, &lex)) {
- g_free (errmsg);
- errmsg = g_strdup (lex.desc);
- camel_exception_clear (&lex);
- reprompt = TRUE;
- }
- g_free (errmsg);
-
- if (camel_exception_is_set (&lex)) {
- camel_exception_xfer (ex, &lex);
- camel_object_unref (store->engine);
- store->engine = NULL;
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return FALSE;
- }
-
- if (camel_imap4_engine_namespace (store->engine, ex) == -1) {
- camel_object_unref (store->engine);
- store->engine = NULL;
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return FALSE;
- }
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return TRUE;
-}
-
-static gboolean
-imap4_disconnect (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- CamelIMAP4Command *ic;
- int id;
-
- if (clean && !store->engine->istream->disconnected) {
- ic = camel_imap4_engine_queue (store->engine, NULL, "LOGOUT\r\n");
- while ((id = camel_imap4_engine_iterate (store->engine)) < ic->id && id != -1)
- ;
-
- camel_imap4_command_unref (ic);
- }
-
- camel_object_unref (store->engine);
-
- return 0;
-}
-
-extern CamelServiceAuthType camel_imap4_password_authtype;
-
-static GList *
-imap4_query_auth_types (CamelService *service, CamelException *ex)
-{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- CamelServiceAuthType *authtype;
- GList *sasl_types, *t, *next;
- gboolean connected;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- connected = connect_to_server_wrapper (service, ex);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- if (!connected)
- return NULL;
-
- sasl_types = camel_sasl_authtype_list (FALSE);
- for (t = sasl_types; t; t = next) {
- authtype = t->data;
- next = t->next;
-
- if (!g_hash_table_lookup (store->engine->authtypes, authtype->authproto)) {
- sasl_types = g_list_remove_link (sasl_types, t);
- g_list_free_1 (t);
- }
- }
-
- return g_list_prepend (sasl_types, &camel_imap4_password_authtype);
-}
-
-
-static char
-imap4_get_path_delim (CamelIMAP4Engine *engine, const char *full_name)
-{
- /* FIXME: move this to utils so imap4-folder.c can share */
- CamelIMAP4Namespace *namespace;
- const char *slash;
- size_t len;
- char *top;
-
- if ((slash = strchr (full_name, '/')))
- len = (slash - full_name);
- else
- len = strlen (full_name);
-
- top = g_alloca (len + 1);
- memcpy (top, full_name, len);
- top[len] = '\0';
-
- if (!g_ascii_strcasecmp (top, "INBOX"))
- top = "INBOX";
-
- retry:
- namespace = engine->namespaces.personal;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- namespace = engine->namespaces.other;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- namespace = engine->namespaces.shared;
- while (namespace != NULL) {
- if (!strcmp (namespace->path, top))
- return namespace->sep;
- namespace = namespace->next;
- }
-
- if (top[0] != '\0') {
- /* look for a default namespace? */
- top[0] = '\0';
- goto retry;
- }
-
- return '/';
-}
-
-static char *
-imap4_folder_utf7_name (CamelStore *store, const char *folder_name, char wildcard)
-{
- char *real_name, *p;
- char sep;
- int len;
-
- sep = imap4_get_path_delim (((CamelIMAP4Store *) store)->engine, folder_name);
-
- if (sep != '/') {
- p = real_name = g_alloca (strlen (folder_name) + 1);
- strcpy (real_name, folder_name);
- while (*p != '\0') {
- if (*p == '/')
- *p = sep;
- p++;
- }
-
- folder_name = real_name;
- }
-
- if (*folder_name)
- real_name = camel_utf8_utf7 (folder_name);
- else
- real_name = g_strdup ("");
-
- if (wildcard) {
- len = strlen (real_name);
- real_name = g_realloc (real_name, len + 3);
-
- if (len > 0)
- real_name[len++] = sep;
-
- real_name[len++] = wildcard;
- real_name[len] = '\0';
- }
-
- return real_name;
-}
-
-static CamelFolder *
-imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelFolder *folder = NULL;
- camel_imap4_list_t *list;
- CamelIMAP4Command *ic;
- CamelFolderInfo *fi;
- GPtrArray *array;
- char *utf7_name;
- int create;
- int id, i;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- /* make sure the folder exists - try LISTing it? */
- utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "LIST "" %S\r\n", utf7_name);
- camel_imap4_command_register_untagged (ic, "LIST", camel_imap4_untagged_list);
- ic->user_data = array = g_ptr_array_new ();
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- g_ptr_array_free (array, TRUE);
- goto done;
- }
-
- create = array->len == 0;
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- g_free (list->name);
- g_free (list);
- }
-
- g_ptr_array_free (array, TRUE);
-
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get folder `%s' on IMAP server %s: Unknown"),
- folder_name, ((CamelService *) store)->url->host);
- camel_imap4_command_unref (ic);
- goto done;
- }
-
- camel_imap4_command_unref (ic);
-
- if (create) {
- const char *basename;
- char *parent;
- int len;
-
- if (!(flags & CAMEL_STORE_FOLDER_CREATE))
- goto done;
-
- if (!(basename = strrchr (folder_name, '/')))
- basename = folder_name;
- else
- basename++;
-
- len = basename > folder_name ? (basename - folder_name) - 1 : 0;
- parent = g_alloca (len + 1);
- memcpy (parent, folder_name, len);
- parent[len] = '\0';
-
- if (!(fi = imap4_create_folder (store, parent, basename, ex)))
- goto done;
-
- camel_store_free_folder_info (store, fi);
- }
-
- folder = camel_imap4_folder_new (store, folder_name, ex);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return folder;
-}
-
-static CamelFolderInfo *
-imap4_create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex)
-{
- /* FIXME: also need to deal with parent folders that can't
- * contain subfolders - delete them and re-create with the
- * proper hint */
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelFolderInfo *fi = NULL;
- CamelIMAP4Command *ic;
- char *utf7_name;
- const char *c;
- char *name;
- int id;
-
- c = folder_name;
- while (*c != '\0') {
- if (*c == store->dir_sep || strchr ("#%*", *c)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_PATH,
- _("The folder name \"%s\" is invalid because "
- "it containes the character \"%c\""),
- folder_name, *c);
- return NULL;
- }
-
- c++;
- }
-
- if (parent_name != NULL && *parent_name)
- name = g_strdup_printf ("%s/%s", parent_name, folder_name);
- else
- name = g_strdup (folder_name);
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- utf7_name = imap4_folder_utf7_name (store, name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "CREATE %S\r\n", utf7_name);
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- g_free (name);
- goto done;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- if (!(fi = imap4_get_folder_info (store, name, CAMEL_STORE_FOLDER_INFO_FAST, ex))) {
- camel_imap4_command_unref (ic);
- g_free (name);
-
- goto done;
- }
-
- camel_object_trigger_event (store, "folder_created", fi);
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder `%s': Invalid mailbox name"),
- name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot create folder `%s': Bad command"),
- name);
- break;
- default:
- g_assert_not_reached ();
- }
-
- camel_imap4_command_unref (ic);
-
- g_free (name);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return fi;
-}
-
-static void
-imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelIMAP4Command *ic;
- char *utf7_name;
- int id;
-
- if (!g_ascii_strcasecmp (folder_name, "INBOX")) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot delete folder `%s': Special folder"),
- folder_name);
-
- return;
- }
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "DELETE %S\r\n", utf7_name);
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /* deleted */
- /*fi = imap4_build_folder_info (store, folder_name);
- camel_object_trigger_event (store, "folder_deleted", fi);
- camel_folder_info_free (fi);*/
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot delete folder `%s': Invalid mailbox name"),
- folder_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot delete folder `%s': Bad command"),
- folder_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static void
-imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex)
-{
-
-}
-
-static int
-list_sort (const camel_imap4_list_t **list0, const camel_imap4_list_t **list1)
-{
- return strcmp ((*list0)->name, (*list1)->name);
-}
-
-static void
-list_remove_duplicates (GPtrArray *array)
-{
- camel_imap4_list_t *list, *last;
- int i;
-
- last = array->pdata[0];
- for (i = 1; i < array->len; i++) {
- list = array->pdata[i];
- if (!strcmp (list->name, last->name)) {
- g_ptr_array_remove_index (array, i--);
- last->flags |= list->flags;
- g_free (list->name);
- g_free (list);
- }
- }
-}
-
-static CamelFolderInfo *
-imap4_build_folder_info (CamelIMAP4Engine *engine, guint32 flags, GPtrArray *array, const char *top)
-{
- camel_imap4_list_t *list;
- CamelFolderInfo *fi;
- char *name, *p;
- CamelURL *url;
- int i;
-
- g_ptr_array_sort (array, (GCompareFunc) list_sort);
-
- list_remove_duplicates (array);
-
- url = camel_url_copy (engine->url);
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- fi = g_malloc0 (sizeof (CamelFolderInfo));
-
- p = name = camel_utf7_utf8 (list->name);
- while (*p != '\0') {
- if (*p == list->delim)
- *p = '/';
- p++;
- }
-
- camel_url_set_fragment (url, name);
-
- fi->full_name = name;
- p = strrchr (name, '/');
- fi->name = g_strdup (p ? p + 1: name);
- fi->path = g_strdup_printf ("/%s", name);
- fi->uri = camel_url_to_string (url, 0);
- fi->flags = list->flags;
-
- /* FIXME: use STATUS to get these values if requested */
- fi->unread = -1;
- fi->total = -1;
-
- g_free (list->name);
- g_free (list);
-
- array->pdata[i] = fi;
- }
-
- fi = camel_folder_info_build (array, top, '/', TRUE);
-
- camel_url_free (url);
-
- g_ptr_array_free (array, TRUE);
-
- return fi;
-}
-
-static CamelFolderInfo *
-imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelFolderInfo *fi = NULL;
- camel_imap4_list_t *list;
- CamelIMAP4Command *ic;
- GPtrArray *array;
- const char *cmd;
- char *pattern;
- int id, i;
-
- if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
- cmd = "LSUB";
- else
- cmd = "LIST";
-
- if (top == NULL)
- top = "";
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- pattern = imap4_folder_utf7_name (store, top, (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? '*' : '%');
- ic = camel_imap4_engine_queue (engine, NULL, "%s "" %S\r\n", cmd, pattern);
- camel_imap4_command_register_untagged (ic, cmd, camel_imap4_untagged_list);
- ic->user_data = array = g_ptr_array_new ();
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- g_ptr_array_free (array, TRUE);
- g_free (pattern);
- goto done;
- }
-
- if (ic->result != CAMEL_IMAP4_RESULT_OK) {
- camel_imap4_command_unref (ic);
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot get %s information for pattern `%s' on IMAP server %s: %s"),
- cmd, pattern, engine->url->host, ic->result == CAMEL_IMAP4_RESULT_BAD ?
- _("Bad command") : _("Unknown"));
-
- for (i = 0; i < array->len; i++) {
- list = array->pdata[i];
- g_free (list->name);
- g_free (list);
- }
-
- g_ptr_array_free (array, TRUE);
-
- g_free (pattern);
-
- goto done;
- }
-
- g_free (pattern);
-
- fi = imap4_build_folder_info (engine, flags, array, top);
-
- done:
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return fi;
-}
-
-static void
-imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelIMAP4Command *ic;
- char *utf7_name;
- int id;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "SUBSCRIBE %S\r\n", utf7_name);
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /* subscribed */
- /*fi = imap4_build_folder_info (store, folder_name);
- fi->flags |= CAMEL_FOLDER_NOCHILDREN;
- camel_object_trigger_event (store, "folder_subscribed", fi);
- camel_folder_info_free (fi);*/
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot subscribe to folder `%s': Invalid mailbox name"),
- folder_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot subscribe to folder `%s': Bad command"),
- folder_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static void
-imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelIMAP4Command *ic;
- char *utf7_name;
- int id;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
- ic = camel_imap4_engine_queue (engine, NULL, "UNSUBSCRIBE %S\r\n", utf7_name);
- g_free (utf7_name);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return;
- }
-
- switch (ic->result) {
- case CAMEL_IMAP4_RESULT_OK:
- /* unsubscribed */
- /*fi = imap4_build_folder_info (store, folder_name);
- camel_object_trigger_event (store, "folder_unsubscribed", fi);
- camel_folder_info_free (fi);*/
- break;
- case CAMEL_IMAP4_RESULT_NO:
- /* FIXME: would be good to save the NO reason into the err message */
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot unsubscribe from folder `%s': Invalid mailbox name"),
- folder_name);
- break;
- case CAMEL_IMAP4_RESULT_BAD:
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Cannot unsubscribe from folder `%s': Bad command"),
- folder_name);
- break;
- }
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
-
-static void
-imap4_noop (CamelStore *store, CamelException *ex)
-{
- CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelIMAP4Command *ic;
- int id;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
-
- ic = camel_imap4_engine_queue (engine, NULL, "NOOP\r\n");
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE)
- camel_exception_xfer (ex, &ic->ex);
-
- camel_imap4_command_unref (ic);
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-}
diff --git a/camel/providers/imap4/camel-imap4-store.h b/camel/providers/imap4/camel-imap4-store.h
deleted file mode 100644
index d8d758ab6..000000000
--- a/camel/providers/imap4/camel-imap4-store.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __CAMEL_IMAP4_STORE_H__
-#define __CAMEL_IMAP4_STORE_H__
-
-#include <camel/camel-store.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_STORE (camel_imap4_store_get_type ())
-#define CAMEL_IMAP4_STORE(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_STORE, CamelIMAP4Store))
-#define CAMEL_IMAP4_STORE_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP4_STORE, CamelIMAP4StoreClass))
-#define CAMEL_IS_IMAP4_STORE(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP4_STORE))
-#define CAMEL_IS_IMAP4_STORE_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP4_STORE))
-#define CAMEL_IMAP4_STORE_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_IMAP4_STORE, CamelIMAP4StoreClass))
-
-typedef struct _CamelIMAP4Store CamelIMAP4Store;
-typedef struct _CamelIMAP4StoreClass CamelIMAP4StoreClass;
-
-struct _CamelIMAP4Engine;
-
-struct _CamelIMAP4Store {
- CamelStore parent_object;
-
- struct _CamelIMAP4Engine *engine;
-};
-
-struct _CamelIMAP4StoreClass {
- CamelStoreClass parent_class;
-
-};
-
-
-CamelType camel_imap4_store_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_STORE_H__ */
diff --git a/camel/providers/imap4/camel-imap4-stream.c b/camel/providers/imap4/camel-imap4-stream.c
deleted file mode 100644
index de14f4e4e..000000000
--- a/camel/providers/imap4/camel-imap4-stream.c
+++ /dev/null
@@ -1,708 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "camel-imap4-specials.h"
-
-#include "camel-imap4-stream.h"
-
-#define d(x) x
-
-#define IMAP4_TOKEN_LEN 128
-
-static void camel_imap4_stream_class_init (CamelIMAP4StreamClass *klass);
-static void camel_imap4_stream_init (CamelIMAP4Stream *stream, CamelIMAP4StreamClass *klass);
-static void camel_imap4_stream_finalize (CamelObject *object);
-
-static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n);
-static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n);
-static int stream_flush (CamelStream *stream);
-static int stream_close (CamelStream *stream);
-static gboolean stream_eos (CamelStream *stream);
-
-
-static CamelStreamClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_stream_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (CAMEL_STREAM_TYPE,
- "CamelIMAP4Stream",
- sizeof (CamelIMAP4Stream),
- sizeof (CamelIMAP4StreamClass),
- (CamelObjectClassInitFunc) camel_imap4_stream_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_stream_init,
- (CamelObjectFinalizeFunc) camel_imap4_stream_finalize);
- }
-
- return type;
-}
-
-static void
-camel_imap4_stream_class_init (CamelIMAP4StreamClass *klass)
-{
- CamelStreamClass *stream_class = (CamelStreamClass *) klass;
-
- parent_class = (CamelStreamClass *) camel_type_get_global_classfuncs (CAMEL_STREAM_TYPE);
-
- /* virtual method overload */
- stream_class->read = stream_read;
- stream_class->write = stream_write;
- stream_class->flush = stream_flush;
- stream_class->close = stream_close;
- stream_class->eos = stream_eos;
-}
-
-static void
-camel_imap4_stream_init (CamelIMAP4Stream *imap4, CamelIMAP4StreamClass *klass)
-{
- imap4->stream = NULL;
-
- imap4->mode = CAMEL_IMAP4_STREAM_MODE_TOKEN;
- imap4->disconnected = FALSE;
- imap4->eol = FALSE;
-
- imap4->literal = 0;
-
- imap4->inbuf = imap4->realbuf + IMAP4_READ_PRELEN;
- imap4->inptr = imap4->inbuf;
- imap4->inend = imap4->inbuf;
-
- imap4->tokenbuf = g_malloc (IMAP4_TOKEN_LEN);
- imap4->tokenptr = imap4->tokenbuf;
- imap4->tokenleft = IMAP4_TOKEN_LEN;
-
- imap4->unget = NULL;
-}
-
-static void
-camel_imap4_stream_finalize (CamelObject *object)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) object;
-
- if (imap4->stream)
- camel_object_unref (imap4->stream);
-
- g_free (imap4->tokenbuf);
- g_free (imap4->unget);
-}
-
-
-static ssize_t
-imap4_fill (CamelIMAP4Stream *imap4)
-{
- unsigned char *inbuf, *inptr, *inend;
- ssize_t nread;
- size_t inlen;
-
- if (imap4->disconnected) {
- errno = EINVAL;
- return -1;
- }
-
- inbuf = imap4->inbuf;
- inptr = imap4->inptr;
- inend = imap4->inend;
- inlen = inend - inptr;
-
- g_assert (inptr <= inend);
-
- /* attempt to align 'inend' with realbuf + SCAN_HEAD */
- if (inptr >= inbuf) {
- inbuf -= inlen < IMAP4_READ_PRELEN ? inlen : IMAP4_READ_PRELEN;
- memmove (inbuf, inptr, inlen);
- inptr = inbuf;
- inbuf += inlen;
- } else if (inptr > imap4->realbuf) {
- size_t shift;
-
- shift = MIN (inptr - imap4->realbuf, inend - inbuf);
- memmove (inptr - shift, inptr, inlen);
- inptr -= shift;
- inbuf = inptr + inlen;
- } else {
- /* we can't shift... */
- inbuf = inend;
- }
-
- imap4->inptr = inptr;
- imap4->inend = inbuf;
- inend = imap4->realbuf + IMAP4_READ_PRELEN + IMAP4_READ_BUFLEN - 1;
-
- if ((nread = camel_stream_read (imap4->stream, inbuf, inend - inbuf)) == -1)
- return -1;
- else if (nread == 0)
- imap4->disconnected = TRUE;
-
- imap4->inend += nread;
-
- return imap4->inend - imap4->inptr;
-}
-
-static ssize_t
-stream_read (CamelStream *stream, char *buffer, size_t n)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
- ssize_t len, nread = 0;
-
- if (imap4->mode == CAMEL_IMAP4_STREAM_MODE_LITERAL) {
- /* don't let our caller read past the end of the literal */
- n = MIN (n, imap4->literal);
- }
-
- if (imap4->inptr < imap4->inend) {
- len = MIN (n, imap4->inend - imap4->inptr);
- memcpy (buffer, imap4->inptr, len);
- imap4->inptr += len;
- nread = len;
- }
-
- if (nread < n) {
- if ((len = camel_stream_read (imap4->stream, buffer + nread, n - nread)) == 0)
- imap4->disconnected = TRUE;
- else if (len == -1)
- return -1;
-
- nread += len;
- }
-
- if (imap4->mode == CAMEL_IMAP4_STREAM_MODE_LITERAL) {
- imap4->literal -= nread;
-
- if (imap4->literal == 0) {
- imap4->mode = CAMEL_IMAP4_STREAM_MODE_TOKEN;
- imap4->eol = TRUE;
- }
- }
-
- return nread;
-}
-
-static ssize_t
-stream_write (CamelStream *stream, const char *buffer, size_t n)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
- ssize_t nwritten;
-
- if (imap4->disconnected) {
- errno = EINVAL;
- return -1;
- }
-
- if ((nwritten = camel_stream_write (imap4->stream, buffer, n)) == 0)
- imap4->disconnected = TRUE;
-
- return nwritten;
-}
-
-static int
-stream_flush (CamelStream *stream)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
-
- return camel_stream_flush (imap4->stream);
-}
-
-static int
-stream_close (CamelStream *stream)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
-
- if (camel_stream_close (imap4->stream) == -1)
- return -1;
-
- camel_object_unref (imap4->stream);
- imap4->stream = NULL;
-
- imap4->disconnected = TRUE;
-
- return 0;
-}
-
-static gboolean
-stream_eos (CamelStream *stream)
-{
- CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;
-
- if (imap4->eol)
- return TRUE;
-
- if (imap4->disconnected && imap4->inptr == imap4->inend)
- return TRUE;
-
- if (camel_stream_eos (imap4->stream))
- return TRUE;
-
- return FALSE;
-}
-
-
-/**
- * camel_imap4_stream_new:
- * @stream: tcp stream
- *
- * Returns a new imap4 stream
- **/
-CamelStream *
-camel_imap4_stream_new (CamelStream *stream)
-{
- CamelIMAP4Stream *imap4;
-
- g_return_val_if_fail (CAMEL_IS_STREAM (stream), NULL);
-
- imap4 = (CamelIMAP4Stream *) camel_object_new (CAMEL_TYPE_IMAP4_STREAM);
- camel_object_ref (stream);
- imap4->stream = stream;
-
- return (CamelStream *) imap4;
-}
-
-
-
-#define token_save(imap4, start, len) G_STMT_START { \
- if (imap4->tokenleft <= len) { \
- unsigned int tlen, toff; \
- \
- tlen = toff = imap4->tokenptr - imap4->tokenbuf; \
- tlen = tlen ? tlen : 1; \
- \
- while (tlen < toff + len) \
- tlen <<= 1; \
- \
- imap4->tokenbuf = g_realloc (imap4->tokenbuf, tlen + 1); \
- imap4->tokenptr = imap4->tokenbuf + toff; \
- imap4->tokenleft = tlen - toff; \
- } \
- \
- memcpy (imap4->tokenptr, start, len); \
- imap4->tokenptr += len; \
- imap4->tokenleft -= len; \
-} G_STMT_END
-
-#define token_clear(imap4) G_STMT_START { \
- imap4->tokenleft += imap4->tokenptr - imap4->tokenbuf; \
- imap4->tokenptr = imap4->tokenbuf; \
- imap4->literal = 0; \
-} G_STMT_END
-
-
-/**
- * camel_imap4_stream_next_token:
- * @stream: imap4 stream
- * @token: imap4 token
- *
- * Reads the next token from the imap4 stream and saves it in @token.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_stream_next_token (CamelIMAP4Stream *stream, camel_imap4_token_t *token)
-{
- register unsigned char *inptr;
- unsigned char *inend, *start, *p;
- gboolean escaped = FALSE;
- size_t literal = 0;
- guint32 nz_number;
- int ret;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_STREAM (stream), -1);
- g_return_val_if_fail (stream->mode != CAMEL_IMAP4_STREAM_MODE_LITERAL, -1);
- g_return_val_if_fail (token != NULL, -1);
-
- if (stream->unget) {
- memcpy (token, stream->unget, sizeof (camel_imap4_token_t));
- g_free (stream->unget);
- stream->unget = NULL;
- return 0;
- }
-
- token_clear (stream);
-
- inptr = stream->inptr;
- inend = stream->inend;
- *inend = '\0';
-
- do {
- if (inptr == inend) {
- if ((ret = imap4_fill (stream)) < 0) {
- token->token = CAMEL_IMAP4_TOKEN_ERROR;
- return -1;
- } else if (ret == 0) {
- token->token = CAMEL_IMAP4_TOKEN_NO_DATA;
- return 0;
- }
-
- inptr = stream->inptr;
- inend = stream->inend;
- *inend = '\0';
- }
-
- while (*inptr == ' ' || *inptr == '\r')
- inptr++;
- } while (inptr == inend);
-
- do {
- if (inptr < inend) {
- if (*inptr == '"') {
- /* qstring token */
- escaped = FALSE;
- start = inptr;
-
- /* eat the beginning " */
- inptr++;
-
- p = inptr;
- while (inptr < inend) {
- if (*inptr == '"' && !escaped)
- break;
-
- if (*inptr == '\\' && !escaped) {
- token_save (stream, p, inptr - p);
- escaped = TRUE;
- inptr++;
- p = inptr;
- } else {
- inptr++;
- escaped = FALSE;
- }
- }
-
- token_save (stream, p, inptr - p);
-
- if (inptr == inend) {
- stream->inptr = start;
- goto refill;
- }
-
- /* eat the ending " */
- inptr++;
-
- /* nul-terminate the atom token */
- token_save (stream, "", 1);
-
- token->token = CAMEL_IMAP4_TOKEN_QSTRING;
- token->v.qstring = stream->tokenbuf;
-
- d(fprintf (stderr, "token: \"%s\"\n", token->v.qstring));
-
- break;
- } else if (strchr ("+*()[]\n", *inptr)) {
- /* special character token */
- token->token = *inptr++;
-#if d(!)0
- if (token->token != '\n')
- fprintf (stderr, "token: %c\n", token->token);
- else
- fprintf (stderr, "token: \\n\n");
-#endif
- break;
- } else if (*inptr == '{') {
- /* literal identifier token */
- if ((p = strchr (inptr, '}')) && strchr (p, '\n')) {
- inptr++;
-
- while (isdigit ((int) *inptr) && literal < UINT_MAX / 10)
- literal = (literal * 10) + (*inptr++ - '0');
-
- if (*inptr != '}') {
- if (isdigit ((int) *inptr))
- g_warning ("illegal literal identifier: literal too large");
- else if (*inptr != '+')
- g_warning ("illegal literal identifier: garbage following size");
-
- while (*inptr != '}')
- inptr++;
- }
-
- /* skip over '}' */
- inptr++;
-
- /* skip over any trailing whitespace */
- while (*inptr == ' ' || *inptr == '\r')
- inptr++;
-
- if (*inptr != '\n') {
- g_warning ("illegal token following literal identifier: %s", inptr);
-
- /* skip ahead to the eoln */
- inptr = strchr (inptr, '\n');
- }
-
- /* skip over '\n' */
- inptr++;
-
- token->token = CAMEL_IMAP4_TOKEN_LITERAL;
- token->v.literal = literal;
-
- d(fprintf (stderr, "token: {%u}\n", literal));
-
- stream->mode = CAMEL_IMAP4_STREAM_MODE_LITERAL;
- stream->literal = literal;
- stream->eol = FALSE;
-
- break;
- } else {
- stream->inptr = inptr;
- goto refill;
- }
- } else if (*inptr >= '0' && *inptr <= '9') {
- /* number token */
- *inend = '\0';
- nz_number = strtoul ((char *) inptr, (char **) &start, 10);
- if (start == inend)
- goto refill;
-
- if (*start == ':' || *start == ',') {
- /* workaround for 'set' tokens (APPENDUID / COPYUID) */
- goto atom_token;
- }
-
- inptr = start;
- token->token = CAMEL_IMAP4_TOKEN_NUMBER;
- token->v.number = nz_number;
-
- d(fprintf (stderr, "token: %u\n", nz_number));
-
- break;
- } else if (is_atom (*inptr)) {
- atom_token:
- /* simple atom token */
- start = inptr;
-
- while (inptr < inend && is_atom (*inptr))
- inptr++;
-
- if (inptr == inend) {
- stream->inptr = start;
- goto refill;
- }
-
- token_save (stream, start, inptr - start);
-
- /* nul-terminate the atom token */
- token_save (stream, "", 1);
-
- if (!strcmp (stream->tokenbuf, "NIL")) {
- /* special atom token */
- token->token = CAMEL_IMAP4_TOKEN_NIL;
- d(fprintf (stderr, "token: NIL\n"));
- } else {
- token->token = CAMEL_IMAP4_TOKEN_ATOM;
- token->v.atom = stream->tokenbuf;
- d(fprintf (stderr, "token: %s\n", token->v.atom));
- }
-
- break;
- } else if (*inptr == '\\') {
- /* possible flag token ("\" atom) */
- start = inptr++;
-
- while (inptr < inend && is_atom (*inptr))
- inptr++;
-
- if (inptr == inend) {
- stream->inptr = start;
- goto refill;
- }
-
- if ((inptr - start) > 1) {
- token_save (stream, start, inptr - start);
-
- /* nul-terminate the flag token */
- token_save (stream, "", 1);
-
- token->token = CAMEL_IMAP4_TOKEN_FLAG;
- token->v.atom = stream->tokenbuf;
- d(fprintf (stderr, "token: %s\n", token->v.atom));
- } else {
- token->token = '\\';
- d(fprintf (stderr, "token: %c\n", token->token));
- }
- break;
- } else if (is_lwsp (*inptr)) {
- inptr++;
- } else {
- /* unknown character token? */
- token->token = *inptr++;
- d(fprintf (stderr, "token: %c\n", token->token));
- break;
- }
- } else {
- refill:
- token_clear (stream);
-
- if (imap4_fill (stream) <= 0) {
- token->token = CAMEL_IMAP4_TOKEN_ERROR;
- return -1;
- }
-
- inptr = stream->inptr;
- inend = stream->inend;
- *inend = '\0';
- }
- } while (inptr < inend);
-
- stream->inptr = inptr;
-
- return 0;
-}
-
-
-/**
- * camel_imap4_stream_unget_token:
- * @stream: imap4 stream
- * @token: token to 'unget'
- *
- * Ungets an imap4 token (as in ungetc()).
- *
- * Note: you may *ONLY* unget a single token. Trying to unget another
- * token will fail.
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_stream_unget_token (CamelIMAP4Stream *stream, camel_imap4_token_t *token)
-{
- camel_imap4_token_t *unget;
-
- if (stream->unget)
- return -1;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NO_DATA) {
- stream->unget = unget = g_new (camel_imap4_token_t, 1);
- memcpy (unget, token, sizeof (camel_imap4_token_t));
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_stream_readline:
- * @stream: imap4 stream
- * @line: line pointer
- * @len: line length
- *
- * Reads a single line from the imap4 stream and points @line at an
- * internal buffer containing the line read and sets @len to the
- * length of the line buffer.
- *
- * Returns -1 on error, 0 if the line read is complete, or 1 if the
- * read is incomplete.
- **/
-int
-camel_imap4_stream_line (CamelIMAP4Stream *stream, unsigned char **line, size_t *len)
-{
- register unsigned char *inptr;
- unsigned char *inend;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_STREAM (stream), -1);
- g_return_val_if_fail (stream->mode != CAMEL_IMAP4_STREAM_MODE_LITERAL, -1);
- g_return_val_if_fail (line != NULL, -1);
- g_return_val_if_fail (len != NULL, -1);
-
- if ((stream->inend - stream->inptr) < 3) {
- /* keep our buffer full to the optimal size */
- if (imap4_fill (stream) == -1 && stream->inptr == stream->inend)
- return -1;
- }
-
- *line = stream->inptr;
- inptr = stream->inptr;
- inend = stream->inend;
- *inend = '\n';
-
- while (*inptr != '\n')
- inptr++;
-
- *len = (inptr - stream->inptr);
- if (inptr < inend) {
- /* got the eoln */
- if (inptr > stream->inptr && inptr[-1] == '\r')
- inptr[-1] = '\0';
- else
- inptr[0] = '\0';
-
- stream->inptr = inptr + 1;
- *len += 1;
-
- return 0;
- }
-
- stream->inptr = inptr;
-
- return 1;
-}
-
-
-int
-camel_imap4_stream_literal (CamelIMAP4Stream *stream, unsigned char **literal, size_t *len)
-{
- unsigned char *inptr, *inend;
- size_t nread;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_STREAM (stream), -1);
- g_return_val_if_fail (stream->mode == CAMEL_IMAP4_STREAM_MODE_LITERAL, -1);
- g_return_val_if_fail (literal != NULL, -1);
- g_return_val_if_fail (len != NULL, -1);
-
- if (stream->eol) {
- *len = 0;
- return 0;
- }
-
- if ((stream->inend - stream->inptr) < 1) {
- /* keep our buffer full to the optimal size */
- if (imap4_fill (stream) == -1 && stream->inptr == stream->inend)
- return -1;
- }
-
- *literal = inptr = stream->inptr;
- inend = stream->inend;
- if ((inend - inptr) > stream->literal)
- inend = inptr + stream->literal;
- else
- inend = stream->inend;
-
- *len = nread = inend - inptr;
-
- stream->literal -= nread;
- if (stream->literal == 0) {
- stream->mode = CAMEL_IMAP4_STREAM_MODE_TOKEN;
- stream->eol = TRUE;
- return 0;
- }
-
- return 1;
-}
diff --git a/camel/providers/imap4/camel-imap4-stream.h b/camel/providers/imap4/camel-imap4-stream.h
deleted file mode 100644
index 7ef842200..000000000
--- a/camel/providers/imap4/camel-imap4-stream.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __CAMEL_IMAP4_STREAM_H__
-#define __CAMEL_IMAP4_STREAM_H__
-
-#include <camel/camel-stream.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_STREAM (camel_imap4_stream_get_type ())
-#define CAMEL_IMAP4_STREAM(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_STREAM, CamelIMAP4Stream))
-#define CAMEL_IMAP4_STREAM_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_TYPE_IMAP4_STREAM, CamelIMAP4StreamClass))
-#define CAMEL_IS_IMAP4_STREAM(o) (CAMEL_CHECK_TYPE((o), CAMEL_TYPE_IMAP4_STREAM))
-
-typedef struct _CamelIMAP4Stream CamelIMAP4Stream;
-typedef struct _CamelIMAP4StreamClass CamelIMAP4StreamClass;
-
-#define IMAP4_READ_PRELEN 128
-#define IMAP4_READ_BUFLEN 4096
-
-enum {
- CAMEL_IMAP4_TOKEN_NO_DATA = -8,
- CAMEL_IMAP4_TOKEN_ERROR = -7,
- CAMEL_IMAP4_TOKEN_NIL = -6,
- CAMEL_IMAP4_TOKEN_ATOM = -5,
- CAMEL_IMAP4_TOKEN_FLAG = -4,
- CAMEL_IMAP4_TOKEN_NUMBER = -3,
- CAMEL_IMAP4_TOKEN_QSTRING = -2,
- CAMEL_IMAP4_TOKEN_LITERAL = -1,
- /* CAMEL_IMAP4_TOKEN_CHAR would just be the char we got */
- CAMEL_IMAP4_TOKEN_EOLN = '\n',
- CAMEL_IMAP4_TOKEN_LPAREN = '(',
- CAMEL_IMAP4_TOKEN_RPAREN = ')',
- CAMEL_IMAP4_TOKEN_ASTERISK = '*',
- CAMEL_IMAP4_TOKEN_PLUS = '+',
- CAMEL_IMAP4_TOKEN_LBRACKET = '[',
- CAMEL_IMAP4_TOKEN_RBRACKET = ']',
-};
-
-typedef struct _camel_imap4_token_t {
- int token;
- union {
- char *atom;
- char *flag;
- char *qstring;
- size_t literal;
- guint32 number;
- } v;
-} camel_imap4_token_t;
-
-enum {
- CAMEL_IMAP4_STREAM_MODE_TOKEN = 0,
- CAMEL_IMAP4_STREAM_MODE_LITERAL = 1,
-};
-
-struct _CamelIMAP4Stream {
- CamelStream parent_object;
-
- CamelStream *stream;
-
- guint disconnected:1; /* disconnected state */
- guint mode:1; /* TOKEN vs LITERAL */
- guint eol:1; /* end-of-literal */
-
- size_t literal;
-
- /* i/o buffers */
- unsigned char realbuf[IMAP4_READ_PRELEN + IMAP4_READ_BUFLEN + 1];
- unsigned char *inbuf;
- unsigned char *inptr;
- unsigned char *inend;
-
- /* token buffers */
- unsigned char *tokenbuf;
- unsigned char *tokenptr;
- unsigned int tokenleft;
-
- camel_imap4_token_t *unget;
-};
-
-struct _CamelIMAP4StreamClass {
- CamelStreamClass parent_class;
-
- /* Virtual methods */
-};
-
-
-/* Standard Camel function */
-CamelType camel_imap4_stream_get_type (void);
-
-CamelStream *camel_imap4_stream_new (CamelStream *stream);
-
-int camel_imap4_stream_next_token (CamelIMAP4Stream *stream, camel_imap4_token_t *token);
-int camel_imap4_stream_unget_token (CamelIMAP4Stream *stream, camel_imap4_token_t *token);
-
-int camel_imap4_stream_line (CamelIMAP4Stream *stream, unsigned char **line, size_t *len);
-int camel_imap4_stream_literal (CamelIMAP4Stream *stream, unsigned char **literal, size_t *len);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_STREAM_H__ */
diff --git a/camel/providers/imap4/camel-imap4-summary.c b/camel/providers/imap4/camel-imap4-summary.c
deleted file mode 100644
index 4c181c4ab..000000000
--- a/camel/providers/imap4/camel-imap4-summary.c
+++ /dev/null
@@ -1,1107 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <limits.h>
-#include <utime.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-#include <e-util/md5-utils.h>
-
-#include <camel/camel-file-utils.h>
-
-#include "camel-imap4-store.h"
-#include "camel-imap4-engine.h"
-#include "camel-imap4-folder.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-command.h"
-#include "camel-imap4-utils.h"
-
-#include "camel-imap4-summary.h"
-
-#define IMAP4_SUMMARY_VERSION 1
-
-static void camel_imap4_summary_class_init (CamelIMAP4SummaryClass *klass);
-static void camel_imap4_summary_init (CamelIMAP4Summary *summary, CamelIMAP4SummaryClass *klass);
-static void camel_imap4_summary_finalize (CamelObject *object);
-
-static int imap4_header_load (CamelFolderSummary *summary, FILE *fin);
-static int imap4_header_save (CamelFolderSummary *summary, FILE *fout);
-static CamelMessageInfo *imap4_message_info_new (CamelFolderSummary *summary, struct _camel_header_raw *header);
-static CamelMessageInfo *imap4_message_info_load (CamelFolderSummary *summary, FILE *fin);
-static int imap4_message_info_save (CamelFolderSummary *summary, FILE *fout, CamelMessageInfo *info);
-
-
-static CamelFolderSummaryClass *parent_class = NULL;
-
-
-CamelType
-camel_imap4_summary_get_type (void)
-{
- static CamelType type = 0;
-
- if (!type) {
- type = camel_type_register (CAMEL_FOLDER_SUMMARY_TYPE,
- "CamelIMAP4Summary",
- sizeof (CamelIMAP4Summary),
- sizeof (CamelIMAP4SummaryClass),
- (CamelObjectClassInitFunc) camel_imap4_summary_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap4_summary_init,
- (CamelObjectFinalizeFunc) camel_imap4_summary_finalize);
- }
-
- return type;
-}
-
-
-static void
-camel_imap4_summary_class_init (CamelIMAP4SummaryClass *klass)
-{
- CamelFolderSummaryClass *summary_class = (CamelFolderSummaryClass *) klass;
-
- parent_class = (CamelFolderSummaryClass *) camel_type_get_global_classfuncs (camel_folder_summary_get_type ());
-
- summary_class->summary_header_load = imap4_header_load;
- summary_class->summary_header_save = imap4_header_save;
- summary_class->message_info_new = imap4_message_info_new;
- summary_class->message_info_load = imap4_message_info_load;
- summary_class->message_info_save = imap4_message_info_save;
-}
-
-static void
-camel_imap4_summary_init (CamelIMAP4Summary *summary, CamelIMAP4SummaryClass *klass)
-{
- CamelFolderSummary *folder_summary = (CamelFolderSummary *) summary;
-
- folder_summary->version += IMAP4_SUMMARY_VERSION;
- folder_summary->flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED |
- CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN;
-
- folder_summary->message_info_size = sizeof (CamelIMAP4MessageInfo);
-}
-
-static void
-camel_imap4_summary_finalize (CamelObject *object)
-{
- ;
-}
-
-
-CamelFolderSummary *
-camel_imap4_summary_new (CamelFolder *folder)
-{
- CamelFolderSummary *summary;
-
- summary = (CamelFolderSummary *) camel_object_new (CAMEL_TYPE_IMAP4_SUMMARY);
- ((CamelIMAP4Summary *) summary)->folder = folder;
-
- return summary;
-}
-
-static int
-imap4_header_load (CamelFolderSummary *summary, FILE *fin)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- if (CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->summary_header_load (summary, fin) == -1)
- return -1;
-
- if (camel_file_util_decode_uint32 (fin, &imap4_summary->uidvalidity) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-imap4_header_save (CamelFolderSummary *summary, FILE *fout)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- if (CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->summary_header_save (summary, fout) == -1)
- return -1;
-
- if (camel_file_util_encode_uint32 (fout, imap4_summary->uidvalidity) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-envelope_decode_address (CamelIMAP4Engine *engine, GString *addrs, CamelException *ex)
-{
- camel_imap4_token_t token;
- gboolean had_name = FALSE;
- int part = 0;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token == CAMEL_IMAP4_TOKEN_NIL) {
- return 0;
- } else if (token.token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- if (addrs->len > 0)
- g_string_append (addrs, ", ");
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- case CAMEL_IMAP4_TOKEN_QSTRING:
- switch (part) {
- case 0:
- g_string_append_printf (addrs, "\"%s\" <", token.v.qstring);
- had_name = TRUE;
- break;
- case 2:
- g_string_append (addrs, token.v.qstring);
- break;
- case 3:
- g_string_append_printf (addrs, "@%s%s", token.v.qstring, had_name ? ">" : "");
- break;
- }
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- part++;
- } while (part < 4);
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != ')') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-static int
-envelope_decode_addresses (CamelIMAP4Engine *engine, char **addrlist, CamelException *ex)
-{
- camel_imap4_token_t token;
- GString *addrs;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token == CAMEL_IMAP4_TOKEN_NIL) {
- *addrlist = NULL;
- return 0;
- } else if (token.token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- addrs = g_string_new ("");
-
- do {
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1) {
- g_string_free (addrs, TRUE);
- return -1;
- }
-
- if (token.token == '(') {
- camel_imap4_stream_unget_token (engine->istream, &token);
-
- if (envelope_decode_address (engine, addrs, ex) == -1) {
- g_string_free (addrs, TRUE);
- return -1;
- }
- } else if (token.token == ')') {
- break;
- } else {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
- } while (1);
-
- *addrlist = addrs->str;
- g_string_free (addrs, FALSE);
-
- return 0;
-}
-
-static int
-envelope_decode_date (CamelIMAP4Engine *engine, time_t *date, CamelException *ex)
-{
- camel_imap4_token_t token;
- const char *nstring;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- *date = (time_t) -1;
- return 0;
- case CAMEL_IMAP4_TOKEN_ATOM:
- nstring = token.v.atom;
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- nstring = token.v.qstring;
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- *date = camel_header_decode_date (nstring, NULL);
-
- return 0;
-}
-
-static int
-envelope_decode_nstring (CamelIMAP4Engine *engine, char **nstring, CamelException *ex)
-{
- camel_imap4_token_t token;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- *nstring = NULL;
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- *nstring = g_strdup (token.v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- *nstring = g_strdup (token.v.qstring);
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-static CamelSummaryReferences *
-decode_references (const char *string)
-{
- struct _camel_header_references *refs, *r;
- CamelSummaryReferences *references;
- unsigned char md5sum[16];
- guint32 i, n = 0;
- MD5Context md5;
-
- if (!(r = refs = camel_header_references_inreplyto_decode (string)))
- return NULL;
-
- while (r != NULL) {
- r = r->next;
- n++;
- }
-
- references = g_malloc (sizeof (CamelSummaryReferences) + (sizeof (CamelSummaryMessageID) * (n - 1)));
- references->size = n;
-
- for (i = 0, r = refs; i < n; i++, r = r->next) {
- md5_init (&md5);
- md5_update (&md5, r->id, strlen (r->id));
- md5_final (&md5, md5sum);
- memcpy (references->references[i].id.hash, md5sum, sizeof (references->references[i].id.hash));
- }
-
- camel_header_references_list_clear (&refs);
-
- return references;
-}
-
-static int
-decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_token_t *token, CamelException *ex)
-{
- unsigned char md5sum[16];
- char *nstring;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- if (envelope_decode_date (engine, &info->date_sent, ex) == -1)
- goto exception;
-
- /* subject */
- if (envelope_decode_nstring (engine, &nstring, ex) == -1)
- goto exception;
- camel_message_info_set_subject (info, nstring);
-
- /* from */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- camel_message_info_set_from (info, nstring);
-
- /* sender */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- g_free (nstring);
-
- /* reply-to */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- g_free (nstring);
-
- /* to */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- camel_message_info_set_to (info, nstring);
-
- /* cc */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- camel_message_info_set_cc (info, nstring);
-
- /* bcc */
- if (envelope_decode_addresses (engine, &nstring, ex) == -1)
- goto exception;
- g_free (nstring);
-
- /* in-reply-to */
- if (envelope_decode_nstring (engine, &nstring, ex) == -1)
- goto exception;
-
- if (nstring != NULL) {
- info->references = decode_references (nstring);
- g_free (nstring);
- }
-
- /* message-id */
- if (envelope_decode_nstring (engine, &nstring, ex) == -1)
- goto exception;
-
- if (nstring != NULL) {
- md5_get_digest (nstring, strlen (nstring), md5sum);
- memcpy (info->message_id.id.hash, md5sum, sizeof (info->message_id.id.hash));
- g_free (nstring);
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- if (token->token != ')') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- goto exception;
- }
-
- return 0;
-
- exception:
-
- return -1;
-}
-
-static char *tm_months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static gboolean
-decode_time (const char **in, int *hour, int *min, int *sec)
-{
- register const unsigned char *inptr = (const unsigned char *) *in;
- int *val, colons = 0;
-
- *hour = *min = *sec = 0;
-
- val = hour;
- for ( ; *inptr && !isspace ((int) *inptr); inptr++) {
- if (*inptr == ':') {
- colons++;
- switch (colons) {
- case 1:
- val = min;
- break;
- case 2:
- val = sec;
- break;
- default:
- return FALSE;
- }
- } else if (!isdigit ((int) *inptr))
- return FALSE;
- else
- *val = (*val * 10) + (*inptr - '0');
- }
-
- *in = inptr;
-
- return TRUE;
-}
-
-static time_t
-mktime_utc (struct tm *tm)
-{
- time_t tt;
-
- tm->tm_isdst = -1;
- tt = mktime (tm);
-
-#if defined (HAVE_TM_GMTOFF)
- tt += tm->tm_gmtoff;
-#elif defined (HAVE_TIMEZONE)
- if (tm->tm_isdst > 0) {
-#if defined (HAVE_ALTZONE)
- tt -= altzone;
-#else /* !defined (HAVE_ALTZONE) */
- tt -= (timezone - 3600);
-#endif
- } else
- tt -= timezone;
-#endif
-
- return tt;
-}
-
-static time_t
-decode_internaldate (const char *in)
-{
- const char *inptr = in;
- int hour, min, sec, n;
- struct tm tm;
- time_t date;
- char *buf;
-
- memset ((void *) &tm, 0, sizeof (struct tm));
-
- tm.tm_mday = strtoul (inptr, &buf, 10);
- if (buf == inptr || *buf != '-')
- return (time_t) -1;
-
- inptr = buf + 1;
- if (inptr[3] != '-')
- return (time_t) -1;
-
- for (n = 0; n < 12; n++) {
- if (!strncasecmp (inptr, tm_months[n], 3))
- break;
- }
-
- if (n >= 12)
- return (time_t) -1;
-
- tm.tm_mon = n;
-
- inptr += 4;
-
- n = strtoul (inptr, &buf, 10);
- if (buf == inptr || *buf != ' ')
- return (time_t) -1;
-
- tm.tm_year = n - 1900;
-
- inptr = buf + 1;
- if (!decode_time (&inptr, &hour, &min, &sec))
- return (time_t) -1;
-
- tm.tm_hour = hour;
- tm.tm_min = min;
- tm.tm_sec = sec;
-
- n = strtol (inptr, NULL, 10);
-
- date = mktime_utc (&tm);
-
- /* date is now GMT of the time we want, but not offset by the timezone ... */
-
- /* this should convert the time to the GMT equiv time */
- date -= ((n / 100) * 60 * 60) + (n % 100) * 60;
-
- return date;
-}
-
-enum {
- IMAP4_FETCH_ENVELOPE = (1 << 1),
- IMAP4_FETCH_FLAGS = (1 << 2),
- IMAP4_FETCH_INTERNALDATE = (1 << 3),
- IMAP4_FETCH_RFC822SIZE = (1 << 4),
- IMAP4_FETCH_UID = (1 << 5),
-};
-
-#define IMAP4_FETCH_ALL (IMAP4_FETCH_ENVELOPE | IMAP4_FETCH_FLAGS | IMAP4_FETCH_INTERNALDATE | IMAP4_FETCH_RFC822SIZE | IMAP4_FETCH_UID)
-
-struct imap4_envelope_t {
- CamelMessageInfo *info;
- guint changed;
-};
-
-struct imap4_fetch_all_t {
- CamelFolderSummary *summary;
- GHashTable *uid_hash;
- GPtrArray *added;
-};
-
-static void
-imap4_fetch_all_free (struct imap4_fetch_all_t *fetch)
-{
- struct imap4_envelope_t *envelope;
- int i;
-
- for (i = 0; i < fetch->added->len; i++) {
- if (!(envelope = fetch->added->pdata[i]))
- continue;
-
- camel_folder_summary_info_free (fetch->summary, envelope->info);
- g_free (envelope);
- }
-
- g_ptr_array_free (fetch->added, TRUE);
- g_hash_table_destroy (fetch->uid_hash);
-
- g_free (fetch);
-}
-
-static void
-imap4_fetch_all_add (struct imap4_fetch_all_t *fetch)
-{
- struct imap4_envelope_t *envelope;
- CamelMessageInfo *info;
- int i;
-
- for (i = 0; i < fetch->added->len; i++) {
- if (!(envelope = fetch->added->pdata[i]))
- continue;
-
- if (envelope->changed != IMAP4_FETCH_ALL) {
- fprintf (stderr, "Hmmm, IMAP4 server didn't give us everything for message %d\n", i + 1);
- camel_folder_summary_info_free (fetch->summary, envelope->info);
- g_free (envelope);
- continue;
- }
-
- if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (envelope->info)))) {
- camel_folder_summary_info_free (fetch->summary, envelope->info);
- g_free (envelope);
- continue;
- }
-
- camel_folder_summary_add (fetch->summary, envelope->info);
- g_free (envelope);
- }
-
- g_ptr_array_free (fetch->added, TRUE);
- g_hash_table_destroy (fetch->uid_hash);
-
- g_free (fetch);
-}
-
-static guint32
-imap4_fetch_all_update (struct imap4_fetch_all_t *fetch)
-{
- CamelIMAP4MessageInfo *iinfo, *new_iinfo;
- struct imap4_envelope_t *envelope;
- CamelMessageInfo *info;
- guint32 first = 0;
- int scount, i;
-
- scount = camel_folder_summary_count (fetch->summary);
- for (i = 0; i < scount; i++) {
- info = camel_folder_summary_index (fetch->summary, i);
- if (!(envelope = g_hash_table_lookup (fetch->uid_hash, camel_message_info_uid (info)))) {
- /* remove it */
- camel_folder_summary_remove (fetch->summary, info);
- scount--;
- i--;
- } else if (envelope->changed & IMAP4_FETCH_FLAGS) {
- /* update it with the new flags */
- new_iinfo = (CamelIMAP4MessageInfo *) envelope->info;
- iinfo = (CamelIMAP4MessageInfo *) info;
-
- info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, new_iinfo->server_flags);
- iinfo->server_flags = new_iinfo->server_flags;
- }
-
- camel_folder_summary_info_free (fetch->summary, info);
- }
-
- for (i = 0; i < fetch->added->len; i++) {
- if (!(envelope = fetch->added->pdata[i]))
- continue;
-
- info = envelope->info;
- if (!first && camel_message_info_uid (info)) {
- if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (info)))) {
- camel_folder_summary_info_free (fetch->summary, info);
- } else {
- first = i + 1;
- }
- }
-
- camel_folder_summary_info_free (fetch->summary, envelope->info);
- g_free (envelope);
- }
-
- g_ptr_array_free (fetch->added, TRUE);
- g_hash_table_destroy (fetch->uid_hash);
-
- g_free (fetch);
-
- return first;
-}
-
-static int
-untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
-{
- struct imap4_fetch_all_t *fetch = ic->user_data;
- CamelFolderSummary *summary = fetch->summary;
- struct imap4_envelope_t *envelope;
- GPtrArray *added = fetch->added;
- CamelIMAP4MessageInfo *iinfo;
- CamelMessageInfo *info;
- char uid[12];
-
- if (index > added->len)
- g_ptr_array_set_size (added, index);
-
- if (!(envelope = added->pdata[index - 1])) {
- iinfo = (CamelIMAP4MessageInfo *) info = camel_folder_summary_info_new (summary);
- envelope = g_new (struct imap4_envelope_t, 1);
- added->pdata[index - 1] = envelope;
- envelope->info = info;
- envelope->changed = 0;
- } else {
- iinfo = (CamelIMAP4MessageInfo *) info = envelope->info;
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- /* parse the FETCH response list */
- if (token->token != '(') {
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
- return -1;
- }
-
- do {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token == ')' || token->token == '\n')
- break;
-
- if (token->token != CAMEL_IMAP4_TOKEN_ATOM)
- goto unexpected;
-
- if (!strcmp (token->v.atom, "ENVELOPE")) {
- if (decode_envelope (engine, info, token, ex) == -1)
- goto exception;
-
- envelope->changed |= IMAP4_FETCH_ENVELOPE;
- } else if (!strcmp (token->v.atom, "FLAGS")) {
- guint32 server_flags = 0;
-
- if (camel_imap4_parse_flags_list (engine, &server_flags, ex) == -1)
- return -1;
-
- info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, server_flags);
- iinfo->server_flags = server_flags;
-
- envelope->changed |= IMAP4_FETCH_FLAGS;
- } else if (!strcmp (token->v.atom, "INTERNALDATE")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- info->date_received = (time_t) -1;
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- case CAMEL_IMAP4_TOKEN_QSTRING:
- info->date_received = decode_internaldate (token->v.qstring);
- break;
- default:
- goto unexpected;
- }
-
- envelope->changed |= IMAP4_FETCH_INTERNALDATE;
- } else if (!strcmp (token->v.atom, "RFC822.SIZE")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NUMBER)
- goto unexpected;
-
- info->size = token->v.number;
-
- envelope->changed |= IMAP4_FETCH_RFC822SIZE;
- } else if (!strcmp (token->v.atom, "UID")) {
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- goto exception;
-
- if (token->token != CAMEL_IMAP4_TOKEN_NUMBER || token->v.number == 0)
- goto unexpected;
-
- sprintf (uid, "%u", token->v.number);
- if (camel_message_info_uid (info) != NULL) {
- if (strcmp (camel_message_info_uid (info), uid) != 0)
- fprintf (stderr, "Hmmm, UID mismatch for message %u\n", index);
- else
- fprintf (stderr, "Hmmm, got UID for messages %d again?\n", index);
-
- g_hash_table_remove (fetch->uid_hash, camel_message_info_uid (info));
- }
-
- camel_message_info_set_uid (info, g_strdup (uid));
- g_hash_table_insert (fetch->uid_hash, (void *) camel_message_info_uid (info), envelope);
-
- envelope->changed |= IMAP4_FETCH_UID;
- } else {
- /* wtf? */
- fprintf (stderr, "huh? %s?...\n", token->v.atom);
- }
- } while (1);
-
- if (token->token != ')')
- goto unexpected;
-
- return 0;
-
- unexpected:
-
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- exception:
-
- return -1;
-}
-
-static CamelIMAP4Command *
-imap4_summary_fetch_all (CamelFolderSummary *summary, guint32 first, guint32 last)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelFolder *folder = imap4_summary->folder;
- struct imap4_fetch_all_t *fetch;
- CamelIMAP4Engine *engine;
- CamelIMAP4Command *ic;
-
- engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
-
- fetch = g_new (struct imap4_fetch_all_t, 1);
- fetch->uid_hash = g_hash_table_new (g_str_hash, g_str_equal);
- fetch->added = g_ptr_array_new ();
- fetch->summary = summary;
-
- /* From rfc2060, Section 6.4.5:
- *
- * The currently defined data items that can be fetched are:
- *
- * ALL Macro equivalent to: (FLAGS INTERNALDATE
- * RFC822.SIZE ENVELOPE)
- **/
-
- if (last != 0)
- ic = camel_imap4_engine_queue (engine, folder, "FETCH %u:%u (UID ALL)\r\n", first, last);
- else
- ic = camel_imap4_engine_queue (engine, folder, "FETCH %u:* (UID ALL)\r\n", first);
-
- camel_imap4_command_register_untagged (ic, "FETCH", untagged_fetch_all);
- ic->user_data = fetch;
-
- return ic;
-}
-
-static CamelIMAP4Command *
-imap4_summary_fetch_flags (CamelFolderSummary *summary, guint32 first, guint32 last)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelFolder *folder = imap4_summary->folder;
- struct imap4_fetch_all_t *fetch;
- CamelIMAP4Engine *engine;
- CamelIMAP4Command *ic;
-
- engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
-
- fetch = g_new (struct imap4_fetch_all_t, 1);
- fetch->uid_hash = g_hash_table_new (g_str_hash, g_str_equal);
- fetch->added = g_ptr_array_new ();
- fetch->summary = summary;
-
- if (last != 0)
- ic = camel_imap4_engine_queue (engine, folder, "FETCH %u:%u (UID FLAGS)\r\n", first, last);
- else
- ic = camel_imap4_engine_queue (engine, folder, "FETCH %u:* (UID FLAGS)\r\n", first);
-
- camel_imap4_command_register_untagged (ic, "FETCH", untagged_fetch_all);
- ic->user_data = fetch;
-
- return ic;
-}
-
-#if 0
-static int
-imap4_build_summary (CamelFolderSummary *summary, guint32 first, guint32 last)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelFolder *folder = imap4_summary->folder;
- struct imap4_fetch_all_t *fetch;
- CamelIMAP4Engine *engine;
- CamelIMAP4Command *ic;
- int id;
-
- engine = ((CamelIMAP4Store *) folder->store)->engine;
-
- ic = imap4_summary_fetch_all (summary, first, last);
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- fetch = ic->user_data;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- camel_imap4_command_unref (ic);
- imap4_fetch_all_free (fetch);
- return -1;
- }
-
- imap4_fetch_all_add (fetch);
-
- camel_imap4_command_unref (ic);
-
- return 0;
-}
-#endif
-
-static CamelMessageInfo *
-imap4_message_info_new (CamelFolderSummary *summary, struct _camel_header_raw *header)
-{
- CamelMessageInfo *info;
-
- info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new (summary, header);
-
- ((CamelIMAP4MessageInfo *) info)->server_flags = 0;
-
- return info;
-}
-
-static CamelMessageInfo *
-imap4_message_info_load (CamelFolderSummary *summary, FILE *fin)
-{
- CamelIMAP4MessageInfo *minfo;
- CamelMessageInfo *info;
-
- if (!(info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_load (summary, fin)))
- return NULL;
-
- minfo = (CamelIMAP4MessageInfo *) info;
-
- if (camel_file_util_decode_uint32 (fin, &minfo->server_flags) == -1)
- goto exception;
-
- return info;
-
- exception:
-
- camel_folder_summary_info_free (summary, info);
-
- return NULL;
-}
-
-static int
-imap4_message_info_save (CamelFolderSummary *summary, FILE *fout, CamelMessageInfo *info)
-{
- CamelIMAP4MessageInfo *minfo = (CamelIMAP4MessageInfo *) info;
-
- if (CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_save (summary, fout, info) == -1)
- return -1;
-
- if (camel_file_util_encode_uint32 (fout, minfo->server_flags) == -1)
- return -1;
-
- return 0;
-}
-
-
-void
-camel_imap4_summary_set_exists (CamelFolderSummary *summary, guint32 exists)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- imap4_summary->exists = exists;
-
- imap4_summary->exists_changed = TRUE;
-}
-
-void
-camel_imap4_summary_set_recent (CamelFolderSummary *summary, guint32 recent)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- imap4_summary->recent = recent;
-}
-
-void
-camel_imap4_summary_set_unseen (CamelFolderSummary *summary, guint32 unseen)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- imap4_summary->unseen = unseen;
-}
-
-void
-camel_imap4_summary_set_uidnext (CamelFolderSummary *summary, guint32 uidnext)
-{
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- summary->nextuid = uidnext;
-}
-
-void
-camel_imap4_summary_set_uidvalidity (CamelFolderSummary *summary, guint32 uidvalidity)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- if (imap4_summary->uidvalidity == uidvalidity)
- return;
-
- /* FIXME: emit a signal or something first? */
- camel_folder_summary_clear (summary);
-
- imap4_summary->uidvalidity = uidvalidity;
-
- imap4_summary->uidvalidity_changed = TRUE;
-}
-
-void
-camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid)
-{
- CamelMessageInfo *info;
-
- g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
-
- if (!(info = camel_folder_summary_index (summary, seqid)))
- return;
-
- /* FIXME: emit a signal or something that our Folder can proxy
- * up to the app so that it can update its display and
- * whatnot? */
-
- /* emit signal */
-
- camel_folder_summary_info_free (summary, info);
- camel_folder_summary_remove_index (summary, seqid);
-}
-
-
-static int
-info_uid_sort (const CamelMessageInfo **info0, const CamelMessageInfo **info1)
-{
- guint32 uid0, uid1;
-
- uid0 = strtoul (camel_message_info_uid (*info0), NULL, 10);
- uid1 = strtoul (camel_message_info_uid (*info1), NULL, 10);
-
- if (uid0 == uid1)
- return 0;
-
- return uid0 < uid1 ? -1 : 1;
-}
-
-int
-camel_imap4_summary_flush_updates (CamelFolderSummary *summary, CamelException *ex)
-{
- CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
- CamelIMAP4Engine *engine;
- CamelIMAP4Command *ic;
- guint32 first = 0;
- int scount, id;
-
- g_return_val_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary), -1);
-
- engine = ((CamelIMAP4Store *) imap4_summary->folder->parent_store)->engine;
-
- if (imap4_summary->uidvalidity_changed) {
- first = 1;
- } else if (imap4_summary->exists_changed) {
- scount = camel_folder_summary_count (summary);
- ic = imap4_summary_fetch_flags (summary, 1, scount);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- imap4_fetch_all_free (ic->user_data);
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- return -1;
- }
-
- if (!(first = imap4_fetch_all_update (ic->user_data)) && imap4_summary->exists > scount)
- first = scount + 1;
-
- camel_imap4_command_unref (ic);
- }
-
- if (first != 0) {
- ic = imap4_summary_fetch_all (summary, first, 0);
-
- while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
- ;
-
- if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
- imap4_fetch_all_free (ic->user_data);
- camel_exception_xfer (ex, &ic->ex);
- camel_imap4_command_unref (ic);
- return -1;
- }
-
- imap4_fetch_all_add (ic->user_data);
- camel_imap4_command_unref (ic);
-
- /* it's important for these to be sorted sequentially for EXPUNGE events to work */
- g_ptr_array_sort (summary->messages, (GCompareFunc) info_uid_sort);
- }
-
- imap4_summary->exists_changed = FALSE;
- imap4_summary->uidvalidity_changed = FALSE;
-
- return 0;
-}
diff --git a/camel/providers/imap4/camel-imap4-summary.h b/camel/providers/imap4/camel-imap4-summary.h
deleted file mode 100644
index 6b5e90696..000000000
--- a/camel/providers/imap4/camel-imap4-summary.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __CAMEL_IMAP4_SUMMARY_H__
-#define __CAMEL_IMAP4_SUMMARY_H__
-
-#include <sys/types.h>
-
-#include <camel/camel-folder.h>
-#include <camel/camel-folder-summary.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CAMEL_TYPE_IMAP4_SUMMARY (camel_imap4_summary_get_type ())
-#define CAMEL_IMAP4_SUMMARY(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP4_SUMMARY, CamelIMAP4Summary))
-#define CAMEL_IMAP4_SUMMARY_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP4_SUMMARY, CamelIMAP4SummaryClass))
-#define CAMEL_IS_IMAP4_SUMMARY(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP4_SUMMARY))
-#define CAMEL_IS_IMAP4_SUMMARY_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP4_SUMMARY))
-#define CAMEL_IMAP4_SUMMARY_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_FOLDER_SUMMARY, CamelIMAP4SummaryClass))
-
-typedef struct _CamelIMAP4MessageInfo CamelIMAP4MessageInfo;
-typedef struct _CamelIMAP4Summary CamelIMAP4Summary;
-typedef struct _CamelIMAP4SummaryClass CamelIMAP4SummaryClass;
-
-struct _CamelIMAP4MessageInfo {
- CamelMessageInfo parent_info;
-
- guint32 server_flags;
-};
-
-struct _CamelIMAP4Summary {
- CamelFolderSummary parent_object;
-
- CamelFolder *folder;
-
- guint32 exists;
- guint32 recent;
- guint32 unseen;
-
- guint32 uidvalidity;
-
- guint uidvalidity_changed:1;
- guint exists_changed:1;
-};
-
-struct _CamelIMAP4SummaryClass {
- CamelFolderSummaryClass parent_class;
-
-};
-
-
-CamelType camel_imap4_summary_get_type (void);
-
-CamelFolderSummary *camel_imap4_summary_new (CamelFolder *folder);
-
-void camel_imap4_summary_set_exists (CamelFolderSummary *summary, guint32 exists);
-void camel_imap4_summary_set_recent (CamelFolderSummary *summary, guint32 recent);
-void camel_imap4_summary_set_unseen (CamelFolderSummary *summary, guint32 unseen);
-void camel_imap4_summary_set_uidnext (CamelFolderSummary *summary, guint32 uidnext);
-
-void camel_imap4_summary_set_uidvalidity (CamelFolderSummary *summary, guint32 uidvalidity);
-
-void camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid);
-
-int camel_imap4_summary_flush_updates (CamelFolderSummary *summary, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_SUMMARY_H__ */
diff --git a/camel/providers/imap4/camel-imap4-utils.c b/camel/providers/imap4/camel-imap4-utils.c
deleted file mode 100644
index 67dd82813..000000000
--- a/camel/providers/imap4/camel-imap4-utils.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <camel/camel-store.h>
-
-#include "camel-imap4-engine.h"
-#include "camel-imap4-stream.h"
-#include "camel-imap4-command.h"
-
-#include "camel-imap4-utils.h"
-
-#define d(x) x
-
-
-void
-camel_imap4_flags_diff (flags_diff_t *diff, guint32 old, guint32 new)
-{
- diff->changed = old ^ new;
- diff->bits = new & diff->changed;
-}
-
-
-guint32
-camel_imap4_flags_merge (flags_diff_t *diff, guint32 flags)
-{
- return (flags & ~diff->changed) | diff->bits;
-}
-
-
-/**
- * camel_imap4_merge_flags:
- * @original: original server flags
- * @local: local flags (after changes)
- * @server: new server flags (another client updated the server flags)
- *
- * Merge the local flag changes into the new server flags.
- *
- * Returns the merged flags.
- **/
-guint32
-camel_imap4_merge_flags (guint32 original, guint32 local, guint32 server)
-{
- flags_diff_t diff;
-
- camel_imap4_flags_diff (&diff, original, local);
-
- return camel_imap4_flags_merge (&diff, server);
-}
-
-
-void
-camel_imap4_utils_set_unexpected_token_error (CamelException *ex, CamelIMAP4Engine *engine, camel_imap4_token_t *token)
-{
- GString *errmsg;
-
- if (ex == NULL)
- return;
-
- errmsg = g_string_new ("");
- g_string_append_printf (errmsg, _("Unexpected token in response from IMAP server %s: "),
- engine->url->host);
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- g_string_append (errmsg, "NIL");
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- g_string_append (errmsg, token->v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_FLAG:
- g_string_append (errmsg, token->v.flag);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- g_string_append (errmsg, token->v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- g_string_append_printf (errmsg, "{%u}", token->v.literal);
- break;
- case CAMEL_IMAP4_TOKEN_NUMBER:
- g_string_append_printf (errmsg, "%u", token->v.number);
- break;
- case CAMEL_IMAP4_TOKEN_NO_DATA:
- g_string_append (errmsg, _("No data"));
- break;
- default:
- g_string_append_c (errmsg, (unsigned char) (token->token & 0xff));
- break;
- }
-
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, errmsg->str);
-
- g_string_free (errmsg, TRUE);
-}
-
-
-static struct {
- const char *name;
- guint32 flag;
-} imap4_flags[] = {
- { "\\Answered", CAMEL_MESSAGE_ANSWERED },
- { "\\Deleted", CAMEL_MESSAGE_DELETED },
- { "\\Draft", CAMEL_MESSAGE_DRAFT },
- { "\\Flagged", CAMEL_MESSAGE_FLAGGED },
- { "\\Seen", CAMEL_MESSAGE_SEEN },
- /*{ "\\Recent", CAMEL_MESSAGE_RECENT },*/
- { "\\*", CAMEL_MESSAGE_USER },
-};
-
-#if 0
-static struct {
- const char *name;
- guint32 flag;
-} imap4_user_flags[] = {
- { "Forwarded", CAMEL_MESSAGE_FORWARDED },
-};
-#endif
-
-
-int
-camel_imap4_parse_flags_list (CamelIMAP4Engine *engine, guint32 *flags, CamelException *ex)
-{
- camel_imap4_token_t token;
- guint32 new = 0;
- int i;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- if (token.token != '(') {
- d(fprintf (stderr, "Expected to find a '(' token starting the flags list\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- while (token.token == CAMEL_IMAP4_TOKEN_ATOM || token.token == CAMEL_IMAP4_TOKEN_FLAG) {
- /* parse the flags list */
- for (i = 0; i < G_N_ELEMENTS (imap4_flags); i++) {
- if (!strcasecmp (imap4_flags[i].name, token.v.atom)) {
- new |= imap4_flags[i].flag;
- break;
- }
- }
-
-#if 0
- if (i == G_N_ELEMENTS (imap4_flags)) {
- for (i = 0; i < G_N_ELEMENTS (imap4_user_flags); i++) {
- if (!strcasecmp (imap4_user_flags[i].name, token.v.atom)) {
- new |= imap4_user_flags[i].flag;
- break;
- }
- }
-
- if (i == G_N_ELEMENTS (imap4_user_flags))
- fprintf (stderr, "Encountered unknown flag: %s\n", token.v.atom);
- }
-#else
- if (i == G_N_ELEMENTS (imap4_flags))
- fprintf (stderr, "Encountered unknown flag: %s\n", token.v.atom);
-#endif
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
- }
-
- if (token.token != ')') {
- d(fprintf (stderr, "Expected to find a ')' token terminating the flags list\n"));
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- *flags = new;
-
- return 0;
-}
-
-
-struct {
- const char *name;
- guint32 flag;
-} list_flags[] = {
- { "\\Marked", CAMEL_IMAP4_FOLDER_MARKED },
- { "\\Unmarked", CAMEL_IMAP4_FOLDER_UNMARKED },
- { "\\Noselect", CAMEL_FOLDER_NOSELECT },
- { "\\Noinferiors", CAMEL_FOLDER_NOINFERIORS },
- { "\\HasChildren", CAMEL_FOLDER_CHILDREN },
- { "\\HasNoChildren", CAMEL_FOLDER_NOCHILDREN },
-};
-
-int
-camel_imap4_untagged_list (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
-{
- GPtrArray *array = ic->user_data;
- camel_imap4_list_t *list;
- unsigned char *buf;
- guint32 flags = 0;
- GString *literal;
- char delim;
- size_t n;
- int i;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- /* parse the flag list */
- if (token->token != '(')
- goto unexpected;
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- while (token->token == CAMEL_IMAP4_TOKEN_FLAG || token->token == CAMEL_IMAP4_TOKEN_ATOM) {
- for (i = 0; i < G_N_ELEMENTS (list_flags); i++) {
- if (!g_ascii_strcasecmp (list_flags[i].name, token->v.atom)) {
- flags |= list_flags[i].flag;
- break;
- }
- }
-
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
- }
-
- if (token->token != ')')
- goto unexpected;
-
- /* parse the path delimiter */
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- delim = '\0';
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- delim = *token->v.qstring;
- break;
- default:
- goto unexpected;
- }
-
- /* parse the folder name */
- if (camel_imap4_engine_next_token (engine, token, ex) == -1)
- return -1;
-
- list = g_new (camel_imap4_list_t, 1);
- list->flags = flags;
- list->delim = delim;
-
- switch (token->token) {
- case CAMEL_IMAP4_TOKEN_ATOM:
- list->name = g_strdup (token->v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- list->name = g_strdup (token->v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- literal = g_string_new ("");
- while ((i = camel_imap4_stream_literal (engine->istream, &buf, &n)) == 1)
- g_string_append_len (literal, buf, n);
-
- if (i == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("IMAP server %s unexpectedly disconnected: %s"),
- engine->url->host, errno ? g_strerror (errno) : _("Unknown"));
- g_string_free (literal, TRUE);
- return -1;
- }
-
- g_string_append_len (literal, buf, n);
- list->name = literal->str;
- g_string_free (literal, FALSE);
- break;
- default:
- g_free (list);
- goto unexpected;
- }
-
- g_ptr_array_add (array, list);
-
- return camel_imap4_engine_eat_line (engine, ex);
-
- unexpected:
-
- camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
-
- return -1;
-}
diff --git a/camel/providers/imap4/camel-imap4-utils.h b/camel/providers/imap4/camel-imap4-utils.h
deleted file mode 100644
index ace7b4cad..000000000
--- a/camel/providers/imap4/camel-imap4-utils.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Camel
- * Copyright (C) 1999-2004 Jeffrey Stedfast
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __CAMEL_IMAP4_UTILS_H__
-#define __CAMEL_IMAP4_UTILS_H__
-
-#include <glib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* IMAP4 flag merging */
-typedef struct {
- guint32 changed;
- guint32 bits;
-} flags_diff_t;
-
-void camel_imap4_flags_diff (flags_diff_t *diff, guint32 old, guint32 new);
-guint32 camel_imap4_flags_merge (flags_diff_t *diff, guint32 flags);
-guint32 camel_imap4_merge_flags (guint32 original, guint32 local, guint32 server);
-
-
-struct _CamelIMAP4Engine;
-struct _CamelIMAP4Command;
-struct _camel_imap4_token_t;
-
-void camel_imap4_utils_set_unexpected_token_error (CamelException *ex, struct _CamelIMAP4Engine *engine, struct _camel_imap4_token_t *token);
-
-int camel_imap4_parse_flags_list (struct _CamelIMAP4Engine *engine, guint32 *flags, CamelException *ex);
-
-/* Note: make sure these don't clash with any bit flags in camel-store.h */
-#define CAMEL_IMAP4_FOLDER_MARKED (1 << 17)
-#define CAMEL_IMAP4_FOLDER_UNMARKED (1 << 18)
-
-typedef struct {
- guint32 flags;
- char delim;
- char *name;
-} camel_imap4_list_t;
-
-int camel_imap4_untagged_list (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Command *ic,
- guint32 index, struct _camel_imap4_token_t *token, CamelException *ex);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __CAMEL_IMAP4_UTILS_H__ */
diff --git a/camel/providers/imap4/libcamelimap4.urls b/camel/providers/imap4/libcamelimap4.urls
deleted file mode 100644
index 7ccb0b041..000000000
--- a/camel/providers/imap4/libcamelimap4.urls
+++ /dev/null
@@ -1 +0,0 @@
-imap4