aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap4
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/imap4')
-rw-r--r--camel/providers/imap4/camel-imap4-engine.c228
-rw-r--r--camel/providers/imap4/camel-imap4-store.c271
2 files changed, 147 insertions, 352 deletions
diff --git a/camel/providers/imap4/camel-imap4-engine.c b/camel/providers/imap4/camel-imap4-engine.c
index d6f17532ee..adbf862747 100644
--- a/camel/providers/imap4/camel-imap4-engine.c
+++ b/camel/providers/imap4/camel-imap4-engine.c
@@ -28,7 +28,6 @@
#include <camel/camel-sasl.h>
#include <camel/camel-stream-buffer.h>
-#include <camel/camel-i18n.h>
#include "camel-imap4-summary.h"
#include "camel-imap4-command.h"
@@ -115,6 +114,22 @@ camel_imap4_engine_init (CamelIMAP4Engine *engine, CamelIMAP4EngineClass *klass)
}
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;
@@ -129,9 +144,9 @@ camel_imap4_engine_finalize (CamelObject *object)
g_hash_table_foreach (engine->authtypes, (GHFunc) g_free, NULL);
g_hash_table_destroy (engine->authtypes);
- camel_imap4_namespace_clear (&engine->namespaces.personal);
- camel_imap4_namespace_clear (&engine->namespaces.other);
- camel_imap4_namespace_clear (&engine->namespaces.shared);
+ 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);
@@ -148,7 +163,6 @@ camel_imap4_engine_finalize (CamelObject *object)
/**
* camel_imap4_engine_new:
* @service: service
- * @reconnect: reconnect callback function
*
* Returns a new imap4 engine
**/
@@ -334,16 +348,6 @@ camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex)
}
-/**
- * camel_imap4_engine_select_folder:
- * @engine: IMAP4 engine
- * @folder: folder to select
- * @ex: exception
- *
- * Convenience function to select @folder.
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_select_folder (CamelIMAP4Engine *engine, CamelFolder *folder, CamelException *ex)
{
@@ -435,15 +439,11 @@ static struct {
{ "IMAP4", CAMEL_IMAP4_CAPABILITY_IMAP4 },
{ "IMAP4REV1", CAMEL_IMAP4_CAPABILITY_IMAP4REV1 },
{ "STATUS", CAMEL_IMAP4_CAPABILITY_STATUS },
- { "NAMESPACE", CAMEL_IMAP4_CAPABILITY_NAMESPACE }, /* rfc2342 */
- { "UIDPLUS", CAMEL_IMAP4_CAPABILITY_UIDPLUS }, /* rfc2359 */
- { "LITERAL+", CAMEL_IMAP4_CAPABILITY_LITERALPLUS }, /* rfc2088 */
+ { "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 },
- { "QUOTA", CAMEL_IMAP4_CAPABILITY_QUOTA }, /* rfc2087 */
- { "ACL", CAMEL_IMAP4_CAPABILITY_ACL }, /* rfc2086 */
- { "IDLE", CAMEL_IMAP4_CAPABILITY_IDLE }, /* rfc2177 */
- { "MULTIAPPEND", CAMEL_IMAP4_CAPABILITY_MULTIAPPEND }, /* rfc3502 */
{ NULL, 0 }
};
@@ -469,7 +469,7 @@ engine_parse_capability (CamelIMAP4Engine *engine, int sentinel, CamelException
return -1;
while (token.token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!g_ascii_strncasecmp ("AUTH=", token.v.atom, 5)) {
+ if (!strncasecmp ("AUTH=", token.v.atom, 5)) {
CamelServiceAuthType *auth;
if ((auth = camel_sasl_authtype (token.v.atom + 5)) != NULL)
@@ -563,9 +563,9 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
camel_imap4_token_t token;
int i, n = 0;
- camel_imap4_namespace_clear (&engine->namespaces.personal);
- camel_imap4_namespace_clear (&engine->namespaces.other);
- camel_imap4_namespace_clear (&engine->namespaces.shared);
+ 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;
@@ -604,19 +604,8 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
goto exception;
}
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- node->sep = '\0';
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- if (strlen (token.v.qstring) == 1) {
- node->sep = *token.v.qstring;
- break;
- } else {
- /* invalid, fall thru */
- }
- default:
- d(fprintf (stderr, "Expected to find a nil or a valid qstring token as second element in NAMESPACE pair\n"));
+ 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);
@@ -624,6 +613,7 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
goto exception;
}
+ node->sep = *token.v.qstring;
tail->next = node;
tail = node;
@@ -682,7 +672,7 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
exception:
for (i = 0; i <= n; i++)
- camel_imap4_namespace_clear (&namespaces[i]);
+ imap4_namespace_clear (&namespaces[i]);
return -1;
}
@@ -723,15 +713,6 @@ static struct {
};
-/**
- * camel_imap4_engine_parse_resp_code:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Parses a RESP-CODE
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -900,34 +881,26 @@ camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex
if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
return -1;
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an atom or numeric token as the second argument to the COPYUID RESP-CODE\n"));
+ 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) {
- if (token.token == CAMEL_IMAP4_TOKEN_NUMBER)
- resp->v.copyuid.srcset = g_strdup_printf ("%u", token.v.number);
- else
- resp->v.copyuid.srcset = g_strdup (token.v.atom);
- }
+ if (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 && token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an atom or numeric token as the third argument to the APPENDUID RESP-CODE\n"));
+ 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) {
- if (token.token == CAMEL_IMAP4_TOKEN_NUMBER)
- resp->v.copyuid.destset = g_strdup_printf ("%u", token.v.number);
- else
- resp->v.copyuid.destset = g_strdup (token.v.atom);
- }
+ if (resp != NULL)
+ resp->v.copyuid.destset = g_strdup (token.v.atom);
break;
default:
@@ -986,17 +959,8 @@ camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex
}
-/**
- * camel_imap4_engine_handle_untagged_1:
- * @engine: IMAP4 engine
- * @token: IMAP4 token
- * @ex: exception
- *
- * Handles a single untagged response
- *
- * Returns -1 on error or one of
- * CAMEL_IMAP4_UNTAGGED_[OK,NO,BAD,PREAUTH,HANDLED] on success
- **/
+
+/* 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)
{
@@ -1149,13 +1113,6 @@ camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, camel_imap4_toke
}
-/**
- * camel_imap4_engine_handle_untagged:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Handle a stream of untagged responses.
- **/
void
camel_imap4_engine_handle_untagged (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -1254,7 +1211,6 @@ engine_state_change (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
return retval;
}
-
/**
* camel_imap4_engine_iterate:
* @engine: IMAP4 engine
@@ -1421,13 +1377,6 @@ camel_imap4_engine_prequeue (CamelIMAP4Engine *engine, CamelFolder *folder, cons
}
-/**
- * camel_imap4_engine_dequeue:
- * @engine: IMAP4 engine
- * @ic: IMAP4 command
- *
- * Removes @ic from the processing queue.
- **/
void
camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
{
@@ -1444,18 +1393,6 @@ camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
}
-/**
- * camel_imap4_engine_next_token:
- * @engine: IMAP4 engine
- * @token: IMAP4 token
- * @ex: exception
- *
- * Wraps camel_imap4_stream_next_token() to set an exception on
- * failure and updates the engine state to DISCONNECTED if the stream
- * gets disconencted.
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
{
@@ -1473,15 +1410,6 @@ camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *to
}
-/**
- * camel_imap4_engine_eat_line:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Gobbles up the remainder of the response line.
- *
- * Returns 0 on success or -1 on fail
- **/
int
camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -1514,19 +1442,6 @@ camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex)
}
-/**
- * camel_imap4_engine_line:
- * @engine: IMAP4 engine
- * @line: line pointer
- * @len: length pointer
- * @ex: exception
- *
- * Reads in a single line of input from the IMAP4 server and updates
- * @line to point to the line buffer. @len is set to the length of the
- * line buffer. @line must be free'd using g_free().
- *
- * Returns 0 on success or -1 on fail
- **/
int
camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t *len, CamelException *ex)
{
@@ -1569,20 +1484,6 @@ camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t
}
-/**
- * camel_imap4_engine_literal:
- * @engine: IMAP4 engine
- * @literal: literal pointer
- * @len: len pointer
- * @ex: exception
- *
- * Reads in an entire literal string and updates @literal to point to
- * it. @len is set to the length of the literal. @literal will also
- * conveniently be terminated with a nul-byte. @literal must be free'd
- * using g_free().
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, size_t *len, CamelException *ex)
{
@@ -1626,55 +1527,6 @@ camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, s
}
-/**
- * camel_imap4_engine_nstring:
- * @engine: IMAP4 engine
- * @nstring: nstring pointer
- * @ex: exception
- *
- * Reads in an nstring (NIL, atom, qstring or literal) and updates
- * @nstring to point to it. @nstring must be free'd using g_free().
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_nstring (CamelIMAP4Engine *engine, unsigned char **nstring, CamelException *ex)
-{
- camel_imap4_token_t token;
- size_t n;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- *nstring = NULL;
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- *nstring = g_strdup (token.v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- *nstring = g_strdup (token.v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, nstring, &n, ex) == -1)
- return -1;
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_resp_code_free:
- * @rcode: RESP-CODE
- *
- * Free's the RESP-CODE
- **/
void
camel_imap4_resp_code_free (CamelIMAP4RespCode *rcode)
{
diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c
index 2e7308d75d..0d33f43c5d 100644
--- a/camel/providers/imap4/camel-imap4-store.c
+++ b/camel/providers/imap4/camel-imap4-store.c
@@ -34,9 +34,6 @@
#include <camel/camel-private.h>
-#include <camel/camel-i18n.h>
-#include <camel/camel-net-utils.h>
-
#include "camel-imap4-store.h"
#include "camel-imap4-engine.h"
#include "camel-imap4-folder.h"
@@ -44,9 +41,7 @@
#include "camel-imap4-command.h"
#include "camel-imap4-utils.h"
#include "camel-imap4-summary.h"
-#include "camel-imap4-store-summary.h"
-#define d(x) x
static void camel_imap4_store_class_init (CamelIMAP4StoreClass *klass);
static void camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass);
@@ -148,7 +143,6 @@ static void
camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass)
{
store->engine = NULL;
- store->summary = NULL;
}
static void
@@ -156,11 +150,6 @@ camel_imap4_store_finalize (CamelObject *object)
{
CamelIMAP4Store *store = (CamelIMAP4Store *) object;
- if (store->summary) {
- camel_store_summary_save ((CamelStoreSummary *) store->summary);
- camel_object_unref (store->summary);
- }
-
if (store->engine)
camel_object_unref (store->engine);
@@ -172,7 +161,6 @@ static void
imap4_construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
{
CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- char *buf;
CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
if (camel_exception_is_set (ex))
@@ -180,20 +168,6 @@ imap4_construct (CamelService *service, CamelSession *session, CamelProvider *pr
store->storage_path = camel_session_get_storage_path (session, service, ex);
store->engine = camel_imap4_engine_new (service, imap4_reconnect);
-
- /* setup/load the summary */
- buf = g_alloca (strlen (store->storage_path) + 32);
- sprintf (buf, "%s/.summary", store->storage_path);
- store->summary = camel_imap4_store_summary_new ();
- camel_store_summary_set_filename ((CamelStoreSummary *) store->summary, buf);
-
- buf = camel_url_to_string (service->url, CAMEL_URL_HIDE_ALL);
- url = camel_url_new (buf, NULL);
- g_free (buf);
- camel_store_summary_set_uri_base ((CamelStoreSummary *) store->summary, url);
- camel_url_free (url);
-
- camel_store_summary_load ((CamelStoreSummary *) store->summary);
}
static char *
@@ -226,7 +200,7 @@ connect_to_server (CamelIMAP4Engine *engine, struct addrinfo *ai, int ssl_mode,
if (ssl_mode != MODE_CLEAR) {
#ifdef HAVE_SSL
if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
+ tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
} else {
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
@@ -262,8 +236,6 @@ connect_to_server (CamelIMAP4Engine *engine, struct addrinfo *ai, int ssl_mode,
if (camel_imap4_engine_capability (engine, ex) == -1)
return FALSE;
- camel_imap4_store_summary_set_capabilities (((CamelIMAP4Store *) service)->summary, engine->capa);
-
if (ssl_mode != MODE_TLS) {
/* we're done */
return TRUE;
@@ -320,9 +292,9 @@ connect_to_server_wrapper (CamelIMAP4Engine *engine, CamelException *ex)
struct addrinfo *ai, hints;
const char *ssl_mode;
int mode, ret, i;
- const char *port;
char *serv;
-
+ const char *port;
+
if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
for (i = 0; ssl_options[i].value; i++)
if (!strcmp (ssl_options[i].value, ssl_mode))
@@ -353,13 +325,7 @@ connect_to_server_wrapper (CamelIMAP4Engine *engine, CamelException *ex)
if (ai == NULL)
return FALSE;
- if (!(ret = connect_to_server (engine, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (engine, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (engine, ai, MODE_CLEAR, ex);
- }
+ ret = connect_to_server (engine, ai, mode, ex);
camel_freeaddrinfo (ai);
@@ -389,7 +355,7 @@ sasl_auth (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, const unsigned char
if (!(challenge = camel_sasl_challenge_base64 (sasl, (const char *) linebuf, ex)))
return -1;
- d(fprintf (stderr, "sending : %s\r\n", challenge));
+ fprintf (stderr, "sending : %s\r\n", challenge);
if (camel_stream_printf (engine->ostream, "%s\r\n", challenge) == -1) {
g_free (challenge);
@@ -437,7 +403,7 @@ imap4_try_authenticate (CamelIMAP4Engine *engine, gboolean reprompt, const char
CamelServiceAuthType *mech;
mech = g_hash_table_lookup (engine->authtypes, service->url->authmech);
- sasl = camel_sasl_new ("imap", mech->authproto, service);
+ sasl = camel_sasl_new ("imap4", mech->authproto, service);
ic = camel_imap4_engine_prequeue (engine, NULL, "AUTHENTICATE %s\r\n", service->url->authmech);
ic->plus = sasl_auth;
@@ -501,8 +467,6 @@ imap4_reconnect (CamelIMAP4Engine *engine, CamelException *ex)
g_free (errmsg);
errmsg = g_strdup (lex.desc);
camel_exception_clear (&lex);
- g_free (service->url->passwd);
- service->url->passwd = NULL;
reprompt = TRUE;
}
g_free (errmsg);
@@ -515,25 +479,16 @@ imap4_reconnect (CamelIMAP4Engine *engine, CamelException *ex)
if (camel_imap4_engine_namespace (engine, ex) == -1)
return FALSE;
- camel_imap4_store_summary_set_namespaces (((CamelIMAP4Store *) service)->summary, &engine->namespaces);
-
return TRUE;
}
static gboolean
imap4_connect (CamelService *service, CamelException *ex)
{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
gboolean retval;
- if (!camel_session_is_online (service->session))
- return TRUE;
-
CAMEL_SERVICE_LOCK (service, connect_lock);
- if (store->engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED)
- retval = imap4_reconnect (store->engine, ex);
- else
- retval = TRUE;
+ retval = imap4_reconnect (((CamelIMAP4Store *) service)->engine, ex);
CAMEL_SERVICE_UNLOCK (service, connect_lock);
return retval;
@@ -546,18 +501,13 @@ imap4_disconnect (CamelService *service, gboolean clean, CamelException *ex)
CamelIMAP4Command *ic;
int id;
- if (!camel_session_is_online (service->session))
- return TRUE;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- if (clean && store->engine->state != CAMEL_IMAP4_ENGINE_DISCONNECTED) {
+ 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_SERVICE_UNLOCK (store, connect_lock);
return 0;
}
@@ -572,9 +522,6 @@ imap4_query_auth_types (CamelService *service, CamelException *ex)
GList *sasl_types, *t, *next;
gboolean connected;
- if (!camel_session_is_online (service->session))
- return NULL;
-
CAMEL_SERVICE_LOCK (store, connect_lock);
connected = connect_to_server_wrapper (store->engine, ex);
CAMEL_SERVICE_UNLOCK (store, connect_lock);
@@ -595,30 +542,83 @@ imap4_query_auth_types (CamelService *service, CamelException *ex)
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 = '\0';
+ char sep;
int len;
- if (*folder_name) {
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, folder_name);
-
- if (sep != '/') {
- p = real_name = g_alloca (strlen (folder_name) + 1);
- strcpy (real_name, folder_name);
- while (*p != '\0') {
- if (*p == '/')
- *p = sep;
- p++;
- }
-
- folder_name = real_name;
+ 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
+ else
real_name = g_strdup ("");
if (wildcard) {
@@ -639,7 +639,6 @@ static CamelFolder *
imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *folder = NULL;
camel_imap4_list_t *list;
CamelIMAP4Command *ic;
@@ -651,18 +650,6 @@ imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Cam
CAMEL_SERVICE_LOCK (store, connect_lock);
- if (!camel_session_is_online (session)) {
- if ((flags & CAMEL_STORE_FOLDER_CREATE) != 0) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create IMAP folders in offline mode."));
- } else {
- folder = camel_imap4_folder_new (store, folder_name, ex);
- }
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return folder;
- }
-
/* make sure the folder exists - try LISTing it? */
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
ic = camel_imap4_engine_queue (engine, NULL, "LIST \"\" %S\r\n", utf7_name);
@@ -740,7 +727,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
* contain subfolders - delete them and re-create with the
* proper hint */
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolderInfo *fi = NULL;
CamelIMAP4Command *ic;
char *utf7_name;
@@ -750,7 +736,7 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
char sep;
int id;
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, parent_name);
+ sep = imap4_get_path_delim (engine, parent_name);
c = folder_name;
while (*c != '\0') {
@@ -765,11 +751,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
c++;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create IMAP folders in offline mode."));
- return NULL;
- }
-
if (parent_name != NULL && *parent_name)
name = g_strdup_printf ("%s/%s", parent_name, folder_name);
else
@@ -807,8 +788,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_created", fi);
break;
case CAMEL_IMAP4_RESULT_NO:
@@ -841,7 +820,6 @@ static void
imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *selected = (CamelFolder *) engine->folder;
CamelIMAP4Command *ic, *ic0 = NULL;
CamelFolderInfo *fi;
@@ -858,11 +836,6 @@ imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException
return;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot delete IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
if (selected && !strcmp (folder_name, selected->full_name))
@@ -909,8 +882,6 @@ imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_unnote_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_deleted", fi);
camel_folder_info_free (fi);
@@ -937,7 +908,6 @@ static void
imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
char *old_uname, *new_uname;
CamelIMAP4Command *ic;
int id;
@@ -950,11 +920,6 @@ imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_na
return;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot rename IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
old_uname = imap4_folder_utf7_name (store, old_name, '\0');
@@ -977,7 +942,6 @@ imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_na
switch (ic->result) {
case CAMEL_IMAP4_RESULT_OK:
/* FIXME: need to update state on the renamed folder object */
- /* FIXME: need to update cached summary info too */
break;
case CAMEL_IMAP4_RESULT_NO:
/* FIXME: would be good to save the NO reason into the err message */
@@ -1091,11 +1055,6 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
url = camel_url_copy (engine->url);
- if (!strcmp (top, "") && (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)) {
- /* clear the folder-info cache */
- camel_store_summary_clear ((CamelStoreSummary *) ((CamelIMAP4Store *) store)->summary);
- }
-
for (i = 0; i < array->len; i++) {
list = array->pdata[i];
fi = g_malloc0 (sizeof (CamelFolderInfo));
@@ -1116,20 +1075,34 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
fi->flags = list->flags;
fi->unread = -1;
fi->total = -1;
-
- /* SELECTED folder, just get it from the folder */
- if (folder && !strcmp (folder->full_name, fi->full_name)) {
- camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &fi->total, CAMEL_FOLDER_UNREAD, &fi->unread, 0);
- } else if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
- imap4_status (store, fi);
+
+ if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
+ if (folder && !strcmp (folder->full_name, fi->full_name)) {
+ /* can't STATUS this folder since it is SELECTED, besides - it would be wasteful */
+ CamelMessageInfo *info;
+ int index;
+
+ fi->total = camel_folder_summary_count (folder->summary);
+
+ fi->unread = 0;
+ for (index = 0; index < fi->total; index++) {
+ if (!(info = camel_folder_summary_index (folder->summary, index)))
+ continue;
+
+ if ((info->flags & CAMEL_MESSAGE_SEEN) == 0)
+ fi->unread++;
+
+ camel_folder_summary_info_free (folder->summary, info);
+ }
+ } else {
+ imap4_status (store, fi);
+ }
}
g_free (list->name);
g_free (list);
array->pdata[i] = fi;
-
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
}
fi = camel_folder_info_build (array, top, '/', TRUE);
@@ -1138,8 +1111,6 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
g_ptr_array_free (array, TRUE);
- camel_store_summary_save ((CamelStoreSummary *) ((CamelIMAP4Store *) store)->summary);
-
return fi;
}
@@ -1147,7 +1118,6 @@ static CamelFolderInfo *
imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic, *ic0 = NULL;
CamelFolderInfo *fi = NULL;
camel_imap4_list_t *list;
@@ -1157,30 +1127,23 @@ imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelE
char wildcard;
int id, i;
- if (top == NULL)
- top = "";
-
CAMEL_SERVICE_LOCK (store, connect_lock);
- if (!camel_session_is_online (session) || engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED) {
- fi = camel_imap4_store_summary_get_folder_info (((CamelIMAP4Store *) store)->summary, top, flags);
- if (fi == NULL && camel_session_is_online (session)) {
- /* folder info hasn't yet been cached and the store hasn't been
- * connected yet, but the network is available so we can connect
- * and query the server. */
- goto check_online;
- }
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return fi;
+ if (engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED) {
+ if (!camel_service_connect ((CamelService *) store, ex))
+ return NULL;
+
+ engine = ((CamelIMAP4Store *) store)->engine;
}
- check_online:
-
if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
cmd = "LSUB";
else
cmd = "LIST";
+ if (top == NULL)
+ top = "";
+
wildcard = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? '*' : '%';
pattern = imap4_folder_utf7_name (store, top, wildcard);
array = g_ptr_array_new ();
@@ -1268,7 +1231,6 @@ static void
imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic;
CamelFolderInfo *fi;
char *utf7_name;
@@ -1276,11 +1238,6 @@ imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelExcepti
const char *p;
int id;
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot subscribe to IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
@@ -1314,8 +1271,6 @@ imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelExcepti
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_subscribed", fi);
camel_folder_info_free (fi);
break;
@@ -1341,7 +1296,6 @@ static void
imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic;
CamelFolderInfo *fi;
char *utf7_name;
@@ -1349,11 +1303,6 @@ imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelExcep
const char *p;
int id;
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot unsubscribe from IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
@@ -1387,8 +1336,6 @@ imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelExcep
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_unnote_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_unsubscribed", fi);
camel_folder_info_free (fi);
break;
@@ -1414,14 +1361,10 @@ static void
imap4_noop (CamelStore *store, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *folder = (CamelFolder *) engine->folder;
CamelIMAP4Command *ic;
int id;
- if (!camel_session_is_online (session))
- return;
-
CAMEL_SERVICE_LOCK (store, connect_lock);
if (folder) {