diff options
Diffstat (limited to 'camel/providers/imap4')
-rw-r--r-- | camel/providers/imap4/camel-imap4-engine.c | 228 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-store.c | 271 |
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) { |