aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@novell.com>2004-06-11 03:47:46 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2004-06-11 03:47:46 +0800
commitd46d24e504b30b8b9f7b1045c5a2d252b9daf1d4 (patch)
treeb8ec8d986d2edf5af609cdbe3a74c98be1d8e248 /camel/providers
parentb1c7fda1bcdb890774764aa8dbf7be1581eadc76 (diff)
downloadgsoc2013-evolution-d46d24e504b30b8b9f7b1045c5a2d252b9daf1d4.tar.gz
gsoc2013-evolution-d46d24e504b30b8b9f7b1045c5a2d252b9daf1d4.tar.zst
gsoc2013-evolution-d46d24e504b30b8b9f7b1045c5a2d252b9daf1d4.zip
If flags does not include FOLDER_INFO_FAST, get the total/unread counts
2004-06-10 Jeffrey Stedfast <fejj@novell.com> * providers/imap4/camel-imap4-store.c (imap4_build_folder_info): If flags does not include FOLDER_INFO_FAST, get the total/unread counts for the folder-info. * providers/imap4/camel-imap4-engine.c (engine_parse_status): Removed. (camel_imap4_engine_handle_untagged_1): Don't handle untagged STATUS responses anymore. Let the STATUS requestor handle them instead. * providers/imap4/camel-imap4-utils.c (camel_imap4_untagged_status): New function to parse untagged status events. svn path=/trunk/; revision=26291
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/imap4/camel-imap4-engine.c164
-rw-r--r--camel/providers/imap4/camel-imap4-store.c78
-rw-r--r--camel/providers/imap4/camel-imap4-utils.c149
-rw-r--r--camel/providers/imap4/camel-imap4-utils.h26
4 files changed, 249 insertions, 168 deletions
diff --git a/camel/providers/imap4/camel-imap4-engine.c b/camel/providers/imap4/camel-imap4-engine.c
index 73d3136152..059c7dbe22 100644
--- a/camel/providers/imap4/camel-imap4-engine.c
+++ b/camel/providers/imap4/camel-imap4-engine.c
@@ -558,162 +558,6 @@ engine_parse_flags (CamelIMAP4Engine *engine, CamelException *ex)
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)
{
@@ -1212,14 +1056,6 @@ camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, camel_imap4_toke
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)
diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c
index fbead28e68..333914123a 100644
--- a/camel/providers/imap4/camel-imap4-store.c
+++ b/camel/providers/imap4/camel-imap4-store.c
@@ -996,9 +996,59 @@ list_remove_duplicates (GPtrArray *array)
}
}
+static void
+imap4_status (CamelStore *store, CamelFolderInfo *fi)
+{
+ CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
+ camel_imap4_status_attr_t *attr, *next;
+ camel_imap4_status_t *status;
+ CamelIMAP4Command *ic;
+ GPtrArray *array;
+ char *mailbox;
+ int id, i;
+
+ mailbox = imap4_folder_utf7_name (store, fi->full_name, '\0');
+ ic = camel_imap4_engine_queue (engine, NULL, "STATUS %S (MESSAGES UNSEEN)\r\n", mailbox);
+ g_free (mailbox);
+
+ camel_imap4_command_register_untagged (ic, "STATUS", camel_imap4_untagged_status);
+ ic->user_data = array = g_ptr_array_new ();
+
+ while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
+ ;
+
+ if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
+ camel_imap4_command_unref (ic);
+ g_ptr_array_free (array, TRUE);
+ return;
+ }
+
+ for (i = 0; i < array->len; i++) {
+ status = array->pdata[i];
+ attr = status->attr_list;
+ while (attr != NULL) {
+ next = attr->next;
+ if (attr->type == CAMEL_IMAP4_STATUS_MESSAGES)
+ fi->total = attr->value;
+ else if (attr->type == CAMEL_IMAP4_STATUS_UNSEEN)
+ fi->unread = attr->value;
+ g_free (attr);
+ attr = next;
+ }
+
+ g_free (status->mailbox);
+ g_free (status);
+ }
+
+ camel_imap4_command_unref (ic);
+ g_ptr_array_free (array, TRUE);
+}
+
static CamelFolderInfo *
-imap4_build_folder_info (CamelIMAP4Engine *engine, guint32 flags, GPtrArray *array, const char *top)
+imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtrArray *array)
{
+ CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
+ CamelFolder *folder = (CamelFolder *) engine->folder;
camel_imap4_list_t *list;
CamelFolderInfo *fi;
char *name, *p;
@@ -1029,11 +1079,31 @@ imap4_build_folder_info (CamelIMAP4Engine *engine, guint32 flags, GPtrArray *arr
fi->name = g_strdup (p ? p + 1: 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;
+ if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
+ if (folder && !strcmp (folder->full_name, fi->full_name)) {
+ 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);
@@ -1117,7 +1187,7 @@ imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelE
g_free (pattern);
- fi = imap4_build_folder_info (engine, flags, array, top);
+ fi = imap4_build_folder_info (store, top, flags, array);
done:
diff --git a/camel/providers/imap4/camel-imap4-utils.c b/camel/providers/imap4/camel-imap4-utils.c
index 67dd828134..2efac2ff42 100644
--- a/camel/providers/imap4/camel-imap4-utils.c
+++ b/camel/providers/imap4/camel-imap4-utils.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include <errno.h>
#include <camel/camel-store.h>
@@ -313,3 +314,151 @@ camel_imap4_untagged_list (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guin
return -1;
}
+
+
+static struct {
+ const char *name;
+ int type;
+} imap4_status[] = {
+ { "MESSAGES", CAMEL_IMAP4_STATUS_MESSAGES },
+ { "RECENT", CAMEL_IMAP4_STATUS_RECENT },
+ { "UIDNEXT", CAMEL_IMAP4_STATUS_UIDNEXT },
+ { "UIDVALIDITY", CAMEL_IMAP4_STATUS_UIDVALIDITY },
+ { "UNSEEN", CAMEL_IMAP4_STATUS_UNSEEN },
+ { NULL, CAMEL_IMAP4_STATUS_UNKNOWN },
+};
+
+
+void
+camel_imap4_status_free (camel_imap4_status_t *status)
+{
+ camel_imap4_status_attr_t *attr, *next;
+
+ attr = status->attr_list;
+ while (attr != NULL) {
+ next = attr->next;
+ g_free (attr);
+ attr = next;
+ }
+
+ g_free (status->mailbox);
+ g_free (status);
+}
+
+
+int
+camel_imap4_untagged_status (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex)
+{
+ camel_imap4_status_attr_t *attr, *tail, *list = NULL;
+ GPtrArray *array = ic->user_data;
+ camel_imap4_status_t *status;
+ char *mailbox;
+ size_t len;
+ int type;
+
+ if (camel_imap4_engine_next_token (engine, token, ex) == -1)
+ return -1;
+
+ switch (token->token) {
+ case CAMEL_IMAP4_TOKEN_ATOM:
+ mailbox = g_strdup (token->v.atom);
+ break;
+ case CAMEL_IMAP4_TOKEN_QSTRING:
+ mailbox = g_strdup (token->v.qstring);
+ break;
+ case CAMEL_IMAP4_TOKEN_LITERAL:
+ if (camel_imap4_engine_literal (engine, (unsigned char **) &mailbox, &len, ex) == -1)
+ return -1;
+ break;
+ default:
+ fprintf (stderr, "Unexpected token in IMAP4 untagged STATUS response: %s%c\n",
+ token->token == CAMEL_IMAP4_TOKEN_NIL ? "NIL" : "",
+ (unsigned char) (token->token & 0xff));
+ camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
+ return -1;
+ }
+
+ if (camel_imap4_engine_next_token (engine, token, ex) == -1) {
+ g_free (mailbox);
+ return -1;
+ }
+
+ if (token->token != '(') {
+ d(fprintf (stderr, "Expected to find a '(' token after the mailbox token in the STATUS response\n"));
+ camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
+ g_free (mailbox);
+ return -1;
+ }
+
+ if (camel_imap4_engine_next_token (engine, token, ex) == -1) {
+ g_free (mailbox);
+ return -1;
+ }
+
+ tail = (camel_imap4_status_attr_t *) &list;
+
+ while (token->token == CAMEL_IMAP4_TOKEN_ATOM) {
+ /* parse the status messages list */
+ for (type = 0; type < G_N_ELEMENTS (imap4_status); type++) {
+ if (!g_ascii_strcasecmp (imap4_status[type].name, token->v.atom))
+ break;
+ }
+
+ if (type == CAMEL_IMAP4_STATUS_UNKNOWN)
+ fprintf (stderr, "unrecognized token in STATUS list: %s\n", token->v.atom);
+
+ if (camel_imap4_engine_next_token (engine, token, ex) == -1)
+ goto exception;
+
+ if (token->token != CAMEL_IMAP4_TOKEN_NUMBER)
+ break;
+
+ attr = g_new (camel_imap4_status_attr_t, 1);
+ attr->next = NULL;
+ attr->type = type;
+ attr->value = token->v.number;
+
+ tail->next = attr;
+ tail = attr;
+
+ if (camel_imap4_engine_next_token (engine, token, ex) == -1)
+ goto exception;
+ }
+
+ status = g_new (camel_imap4_status_t, 1);
+ status->mailbox = mailbox;
+ status->attr_list = list;
+ list = NULL;
+
+ g_ptr_array_add (array, status);
+
+ if (token->token != ')') {
+ d(fprintf (stderr, "Expected to find a ')' token terminating the untagged STATUS response\n"));
+ camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
+ return -1;
+ }
+
+ if (camel_imap4_engine_next_token (engine, token, ex) == -1)
+ return -1;
+
+ if (token->token != '\n') {
+ d(fprintf (stderr, "Expected to find a '\\n' token after the STATUS response\n"));
+ camel_imap4_utils_set_unexpected_token_error (ex, engine, token);
+ return -1;
+ }
+
+ return 0;
+
+ exception:
+
+ g_free (mailbox);
+
+ attr = list;
+ while (attr != NULL) {
+ list = attr->next;
+ g_free (attr);
+ attr = list;
+ }
+
+ return -1;
+}
diff --git a/camel/providers/imap4/camel-imap4-utils.h b/camel/providers/imap4/camel-imap4-utils.h
index ace7b4cad0..cfaf6a4dc4 100644
--- a/camel/providers/imap4/camel-imap4-utils.h
+++ b/camel/providers/imap4/camel-imap4-utils.h
@@ -60,6 +60,32 @@ typedef struct {
int camel_imap4_untagged_list (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Command *ic,
guint32 index, struct _camel_imap4_token_t *token, CamelException *ex);
+
+enum {
+ CAMEL_IMAP4_STATUS_MESSAGES,
+ CAMEL_IMAP4_STATUS_RECENT,
+ CAMEL_IMAP4_STATUS_UIDNEXT,
+ CAMEL_IMAP4_STATUS_UIDVALIDITY,
+ CAMEL_IMAP4_STATUS_UNSEEN,
+ CAMEL_IMAP4_STATUS_UNKNOWN,
+};
+
+typedef struct _camel_imap4_status_attr {
+ struct _camel_imap4_status_attr *next;
+ guint32 type;
+ guint32 value;
+} camel_imap4_status_attr_t;
+
+typedef struct {
+ camel_imap4_status_attr_t *attr_list;
+ char *mailbox;
+} camel_imap4_status_t;
+
+void camel_imap4_status_free (camel_imap4_status_t *status);
+
+int camel_imap4_untagged_status (struct _CamelIMAP4Engine *engine, struct _CamelIMAP4Command *ic,
+ guint32 index, struct _camel_imap4_token_t *token, CamelException *ex);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */