aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/imap/Makefile.am1
-rw-r--r--camel/providers/imap/camel-imap-folder.c104
-rw-r--r--camel/providers/imap/camel-imap-folder.h1
-rw-r--r--camel/providers/imap/camel-imap-stream.c220
-rw-r--r--camel/providers/imap/camel-imap-stream.h71
-rw-r--r--camel/providers/imap/camel-imap-utils.c93
-rw-r--r--camel/providers/imap/camel-imap-utils.h16
7 files changed, 102 insertions, 404 deletions
diff --git a/camel/providers/imap/Makefile.am b/camel/providers/imap/Makefile.am
index 35a4a97e77..77cf3059e2 100644
--- a/camel/providers/imap/Makefile.am
+++ b/camel/providers/imap/Makefile.am
@@ -36,7 +36,6 @@ libcamelimapinclude_HEADERS = \
camel-imap-folder.h \
camel-imap-search.h \
camel-imap-store.h \
- camel-imap-stream.h \
camel-imap-summary.h \
camel-imap-utils.h
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 4d163b4038..005affb629 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -41,7 +41,6 @@
#include "camel-imap-command.h"
#include "camel-imap-search.h"
#include "camel-imap-store.h"
-#include "camel-imap-stream.h"
#include "camel-imap-summary.h"
#include "camel-imap-utils.h"
#include "string-utils.h"
@@ -65,6 +64,7 @@
static CamelFolderClass *parent_class = NULL;
static void imap_finalize (CamelObject *object);
+static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex);
static void imap_refresh_info (CamelFolder *folder, CamelException *ex);
static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
static const char *imap_get_full_name (CamelFolder *folder);
@@ -122,7 +122,6 @@ camel_imap_folder_init (gpointer object, gpointer klass)
folder->has_summary_capability = TRUE;
folder->has_search_capability = TRUE;
- folder->summary = NULL;
imap_folder->priv = g_malloc0(sizeof(*imap_folder->priv));
#ifdef ENABLE_THREADS
imap_folder->priv->search_lock = g_mutex_new();
@@ -155,11 +154,10 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name,
{
CamelImapStore *imap_store = CAMEL_IMAP_STORE (parent);
CamelFolder *folder = CAMEL_FOLDER (camel_object_new (camel_imap_folder_get_type ()));
- CamelImapFolder *imap_folder = (CamelImapFolder *)folder;
CamelImapResponse *response;
- const char *resp;
+ char *resp;
guint32 validity = 0;
- int i;
+ int i, exists;
camel_folder_construct (folder, parent, folder_name, short_name);
@@ -175,18 +173,18 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name,
for (i = 0; i < response->untagged->len; i++) {
resp = response->untagged->pdata[i] + 2;
if (!g_strncasecmp (resp, "FLAGS ", 6)) {
- folder->permanent_flags =
- imap_parse_flag_list (resp + 6);
+ resp += 6;
+ folder->permanent_flags = imap_parse_flag_list (&resp);
} else if (!g_strncasecmp (resp, "OK [PERMANENTFLAGS ", 19)) {
- folder->permanent_flags =
- imap_parse_flag_list (resp + 19);
+ resp += 19;
+ folder->permanent_flags = imap_parse_flag_list (&resp);
} else if (!g_strncasecmp (resp, "OK [UIDVALIDITY ", 16)) {
validity = strtoul (resp + 16, NULL, 10);
} else if (isdigit ((unsigned char)*resp)) {
- unsigned long num = strtoul (resp, (char **)&resp, 10);
+ unsigned long num = strtoul (resp, &resp, 10);
if (!g_strncasecmp (resp, " EXISTS", 7))
- imap_folder->exists = num;
+ exists = num;
}
}
camel_imap_response_free (response);
@@ -200,7 +198,7 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name,
return NULL;
}
- imap_refresh_info (folder, ex);
+ imap_rescan (folder, exists, ex);
if (camel_exception_is_set (ex)) {
camel_object_unref (CAMEL_OBJECT (folder));
return NULL;
@@ -226,35 +224,36 @@ imap_finalize (CamelObject *object)
static void
imap_refresh_info (CamelFolder *folder, CamelException *ex)
{
+ imap_rescan (folder, camel_folder_summary_count (folder->summary), ex);
+}
+
+static void
+imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
+{
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelImapResponse *response;
struct {
char *uid;
guint32 flags;
} *new = NULL;
- char *resp, *p;
- const char *uid, *flags;
- int i, seq, summary_len;
+ char *resp, *p, *flags;
+ const char *uid;
+ int i, j, seq, summary_len;
CamelMessageInfo *info;
CamelImapMessageInfo *iinfo;
- CamelFolderChangeInfo *changes;
-
- changes = camel_folder_change_info_new ();
+ GArray *removed;
/* Get UIDs and flags of all messages. */
- if (imap_folder->exists) {
+ if (exists > 0) {
CAMEL_IMAP_STORE_LOCK(store, command_lock);
response = camel_imap_command (store, folder, ex,
"FETCH 1:%d (UID FLAGS)",
- imap_folder->exists);
+ exists);
CAMEL_IMAP_STORE_UNLOCK(store, command_lock);
- if (!response) {
- camel_folder_change_info_free (changes);
+ if (!response)
return;
- }
- new = g_malloc0 (imap_folder->exists * sizeof (*new));
+ new = g_malloc0 (exists * sizeof (*new));
for (i = 0; i < response->untagged->len; i++) {
resp = response->untagged->pdata[i];
@@ -272,7 +271,7 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
flags = e_strstrcase (resp, "FLAGS ");
if (flags) {
flags += 6;
- new[seq - 1].flags = imap_parse_flag_list (flags);
+ new[seq - 1].flags = imap_parse_flag_list (&flags);
}
}
camel_imap_response_free (response);
@@ -282,8 +281,9 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
* the UID in the folder, that it means the message was
* deleted on the server, so we remove it from the summary.
*/
+ removed = g_array_new (FALSE, FALSE, sizeof (int));
summary_len = camel_folder_summary_count (folder->summary);
- for (i = 0; i < summary_len && i < imap_folder->exists; i++) {
+ for (i = 0; i < summary_len && i < exists; i++) {
/* Shouldn't happen, but... */
if (!new[i].uid)
continue;
@@ -292,9 +292,8 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
iinfo = (CamelImapMessageInfo *)info;
if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
- camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
- camel_folder_summary_remove (folder->summary, info);
- camel_folder_summary_info_free(folder->summary, info);
+ seq = i + 1 - removed->len;
+ g_array_append_val (removed, seq);
g_free (new[i].uid);
i--;
summary_len--;
@@ -311,7 +310,9 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
info->flags = (info->flags | server_set) & ~server_cleared;
iinfo->server_flags = new[i].flags;
- camel_folder_change_info_change_uid (changes, new[i].uid);
+ camel_object_trigger_event (CAMEL_OBJECT (folder),
+ "message_changed",
+ g_strdup (new[i].uid));
}
camel_folder_summary_info_free(folder->summary, info);
@@ -320,29 +321,19 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
}
/* Remove any leftover cached summary messages. */
- while (summary_len > i + 1) {
- info = camel_folder_summary_index (folder->summary, --summary_len);
- camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
- camel_folder_summary_remove (folder->summary, info);
- camel_folder_summary_info_free(folder->summary, info);
+ for (j = i + 1; j < summary_len; j++) {
+ seq = j - removed->len;
+ g_array_append_val (removed, seq);
}
- /* Add any new folder messages. */
- if (i < imap_folder->exists) {
- /* Fetch full summary for the remaining messages. */
- imap_update_summary (folder, i + 1, imap_folder->exists,
- changes, ex);
-
- while (i < imap_folder->exists)
- g_free (new[i++].uid);
- }
+ /* Free remaining memory. */
+ while (i < exists)
+ g_free (new[i++].uid);
g_free (new);
- if (camel_folder_change_info_changed (changes)) {
- camel_object_trigger_event (CAMEL_OBJECT (folder),
- "folder_changed", changes);
- }
- camel_folder_change_info_free (changes);
+ /* And finally update the summary. */
+ camel_imap_folder_changed (folder, exists, removed, ex);
+ g_array_free (removed, TRUE);
}
static void
@@ -662,9 +653,8 @@ imap_update_summary (CamelFolder *folder, int first, int last,
if (!(flags = strstr (headers->pdata[i], "FLAGS "))) {
d(fprintf (stderr, "We didn't seem to get any flags for %d...\n", i));
} else {
- for (flags += 6; *flags && *flags != '('; flags++)
- ;
- info->flags = imap_parse_flag_list (flags);
+ flags += 6;
+ info->flags = imap_parse_flag_list (&flags);
iinfo->server_flags = info->flags;
}
@@ -723,9 +713,9 @@ void
camel_imap_folder_changed (CamelFolder *folder, int exists,
GArray *expunged, CamelException *ex)
{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelFolderChangeInfo *changes;
CamelMessageInfo *info;
+ int len;
changes = camel_folder_change_info_new ();
if (expunged) {
@@ -740,9 +730,9 @@ camel_imap_folder_changed (CamelFolder *folder, int exists,
}
}
- imap_update_summary (folder, imap_folder->exists + 1, exists,
- changes, ex);
- imap_folder->exists = exists;
+ len = camel_folder_summary_count (folder->summary);
+ if (exists > len)
+ imap_update_summary (folder, len, exists, changes, ex);
if (camel_folder_change_info_changed (changes)) {
camel_object_trigger_event (CAMEL_OBJECT (folder),
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
index ffc7b5ec21..cf237f155e 100644
--- a/camel/providers/imap/camel-imap-folder.h
+++ b/camel/providers/imap/camel-imap-folder.h
@@ -47,7 +47,6 @@ typedef struct {
struct _CamelImapFolderPrivate *priv;
CamelFolderSearch *search;
- int exists;
} CamelImapFolder;
diff --git a/camel/providers/imap/camel-imap-stream.c b/camel/providers/imap/camel-imap-stream.c
deleted file mode 100644
index 4e9ee046d7..0000000000
--- a/camel/providers/imap/camel-imap-stream.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#include <config.h>
-#include "camel-imap-stream.h"
-#include "camel/camel-exception.h"
-#include <sys/types.h>
-#include <errno.h>
-#include <stdlib.h>
-
-static CamelStreamClass *parent_class = NULL;
-
-/* Returns the class for a CamelImapStream */
-#define CIS_CLASS(so) CAMEL_IMAP_STREAM_CLASS (CAMEL_OBJECT_GET_CLASS(so))
-
-static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n);
-static int stream_reset (CamelStream *stream);
-static gboolean stream_eos (CamelStream *stream);
-
-static void finalize (CamelObject *object);
-
-static void
-camel_imap_stream_class_init (CamelImapStreamClass *camel_imap_stream_class)
-{
- CamelStreamClass *camel_stream_class =
- CAMEL_STREAM_CLASS (camel_imap_stream_class);
-
- parent_class = CAMEL_STREAM_CLASS (camel_type_get_global_classfuncs (camel_stream_get_type ()));
-
- /* virtual method overload */
- camel_stream_class->read = stream_read;
- camel_stream_class->reset = stream_reset;
- camel_stream_class->eos = stream_eos;
-}
-
-static void
-camel_imap_stream_init (gpointer object, gpointer klass)
-{
- CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (object);
-
- imap_stream->cache = NULL;
- imap_stream->cache_ptr = NULL;
-}
-
-CamelType
-camel_imap_stream_get_type (void)
-{
- static CamelType camel_imap_stream_type = CAMEL_INVALID_TYPE;
-
- if (camel_imap_stream_type == CAMEL_INVALID_TYPE) {
- camel_imap_stream_type =
- camel_type_register (camel_stream_get_type (), "CamelImapStream",
- sizeof (CamelImapStream),
- sizeof (CamelImapStreamClass),
- (CamelObjectClassInitFunc) camel_imap_stream_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_stream_init,
- (CamelObjectFinalizeFunc) finalize);
- }
-
- return camel_imap_stream_type;
-}
-
-CamelStream *
-camel_imap_stream_new (CamelImapFolder *folder, char *command)
-{
- CamelImapStream *imap_stream;
-
- imap_stream = CAMEL_IMAP_STREAM(camel_object_new (camel_imap_stream_get_type ()));
-
- imap_stream->folder = folder;
- camel_object_ref (CAMEL_OBJECT (imap_stream->folder));
-
- imap_stream->command = g_strdup (command);
-
- return CAMEL_STREAM (imap_stream);
-}
-
-static void
-finalize (CamelObject *object)
-{
- CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (object);
-
- g_free (imap_stream->cache);
- g_free (imap_stream->command);
-
- if (imap_stream->folder)
- camel_object_unref (CAMEL_OBJECT (imap_stream->folder));
-}
-
-static ssize_t
-stream_read (CamelStream *stream, char *buffer, size_t n)
-{
- ssize_t nread;
-
- /* do we want to do any IMAP specific parsing in here? If not, maybe rename to camel-stream-cache? */
- CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (stream);
-
- if (!imap_stream->cache) {
- /* We need to send the IMAP command since this is our first fetch */
- CamelFolder *folder = CAMEL_FOLDER (imap_stream->folder);
- CamelException ex;
- gchar *result, *p, *q;
- gint status, part_len;
-
- camel_exception_init (&ex);
- status = camel_imap_fetch_command (CAMEL_IMAP_STORE (folder->parent_store),
- CAMEL_FOLDER (imap_stream->folder),
- &result, &ex, "%s\r\n",
- imap_stream->command);
- /* FIXME: exception is ignored */
- camel_exception_clear (&ex);
-
- if (!result || status != CAMEL_IMAP_OK) {
- /* we got an error, dump this stuff */
- g_free (result);
- imap_stream->cache = NULL;
- camel_object_unref (CAMEL_OBJECT (imap_stream->folder));
-
- return -1;
- }
-
- /* we don't need the folder anymore... */
- camel_object_unref (CAMEL_OBJECT (imap_stream->folder));
-
- /* parse out the message part */
- for (p = result; *p && *p != '{' && *p != '"' && *p != '\n'; p++);
- switch (*p) {
- case '"':
- /* a quoted string - section 4.3 */
- p++;
- for (q = p; *q && *q != '"' && *q != '\n'; q++);
- part_len = (gint) (q - p);
-
- break;
- case '{':
- /* a literal string - section 4.3 */
- part_len = atoi (p + 1);
- for ( ; *p && *p != '\n'; p++);
- if (*p != '\n') {
- g_free (result);
- return -1;
- }
-
- /* advance to the beginning of the actual data */
- p++;
-
- /* calculate the new part-length */
- for (q = p; *q && (q - p) <= part_len; q++) {
- if (*q == '\n')
- part_len--;
- }
-
- /* FIXME: This is a hack for IMAP daemons that send us a UID at the end of each FETCH */
- for ( ; q > p && *(q-1) != '\n'; q--, part_len--);
- part_len++;
-
- break;
- default:
- /* Bad input */
- g_free (result);
- return -1;
- }
-
- imap_stream->cache = g_strndup (p, part_len);
- g_free (result);
-
- imap_stream->cache_ptr = imap_stream->cache;
- }
-
- /* we've already read this stream, so return whats in the cache */
- nread = MIN (n, strlen (imap_stream->cache_ptr));
-
- if (nread > 0) {
- memcpy (buffer, imap_stream->cache_ptr, nread);
- imap_stream->cache_ptr += nread;
- } else {
- nread = -1;
- }
-
- return nread;
-}
-
-static int
-stream_reset (CamelStream *stream)
-{
- CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (stream);
-
- imap_stream->cache_ptr = imap_stream->cache;
-
- return 1;
-}
-
-static gboolean
-stream_eos (CamelStream *stream)
-{
- CamelImapStream *imap_stream = CAMEL_IMAP_STREAM (stream);
-
- return (imap_stream->cache_ptr && strlen (imap_stream->cache_ptr));
-}
diff --git a/camel/providers/imap/camel-imap-stream.h b/camel/providers/imap/camel-imap-stream.h
deleted file mode 100644
index 88881e7c1f..0000000000
--- a/camel/providers/imap/camel-imap-stream.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors: Jeffrey Stedfast <fejj@helixcode.com>
- *
- * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#ifndef CAMEL_IMAP_STREAM_H
-#define CAMEL_IMAP_STREAM_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus }*/
-
-#include <camel/camel-stream.h>
-#include "camel-imap-folder.h"
-#include "camel-imap-store.h"
-#include <sys/types.h>
-
-#define CAMEL_IMAP_STREAM_TYPE (camel_imap_stream_get_type ())
-#define CAMEL_IMAP_STREAM(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_STREAM_TYPE, CamelImapStream))
-#define CAMEL_IMAP_STREAM_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAP_STREAM_TYPE, CamelImapStreamClass))
-#define CAMEL_IS_IMAP_STREAM(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAP_STREAM_TYPE))
-
-typedef struct _CamelImapStream CamelImapStream;
-typedef struct _CamelImapStreamClass CamelImapStreamClass;
-
-struct _CamelImapStream {
- CamelStream parent_object;
-
- CamelImapFolder *folder;
- char *command;
- char *cache;
- char *cache_ptr;
-};
-
-struct _CamelImapStreamClass {
- CamelStreamClass parent_class;
-
- /* Virtual methods */
-};
-
-/* Standard Camel function */
-CamelType camel_imap_stream_get_type (void);
-
-/* public methods */
-CamelStream *camel_imap_stream_new (CamelImapFolder *folder, char *command);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CAMEL_IMAP_STREAM_H */
diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c
index 3e3f4af031..1b4aaba499 100644
--- a/camel/providers/imap/camel-imap-utils.c
+++ b/camel/providers/imap/camel-imap-utils.c
@@ -155,15 +155,18 @@ imap_create_flag_list (guint32 flags)
}
guint32
-imap_parse_flag_list (const char *flag_list)
+imap_parse_flag_list (char **flag_list_p)
{
+ char *flag_list = *flag_list_p;
guint32 flags = 0;
int len;
- if (*flag_list++ != '(')
+ if (*flag_list++ != '(') {
+ *flag_list_p = NULL;
return 0;
+ }
- while (*flag_list != ')') {
+ while (*flag_list && *flag_list != ')') {
len = strcspn (flag_list, " )");
if (!g_strncasecmp (flag_list, "\\Answered", len))
flags |= CAMEL_MESSAGE_ANSWERED;
@@ -180,20 +183,40 @@ imap_parse_flag_list (const char *flag_list)
if (*flag_list == ' ')
flag_list++;
}
-
+
+ if (*flag_list++ != ')') {
+ *flag_list_p = NULL;
+ return 0;
+ }
+
+ *flag_list_p = flag_list;
return flags;
}
+static char imap_atom_specials[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+};
+#define imap_is_atom_char(ch) (isascii (ch) && !imap_atom_specials[ch])
+
/**
- * imap_parse_nstring:
+ * imap_parse_string_generic:
* @str_p: a pointer to a string
* @len: a pointer to an int to return the length in
+ * @type: type of string (#IMAP_STRING, #IMAP_ASTRING, or #IMAP_NSTRING)
+ * to parse.
*
- * This parses an "nstring" (NIL, a quoted string, or a literal)
- * starting at *@str_p. On success, *@str_p will point to the first
- * character after the end of the nstring, and *@len will contain
- * the length of the returned string. On failure, *@str_p will be
- * set to %NULL.
+ * This parses an IMAP "string" (quoted string or literal), "nstring"
+ * (NIL or string), or "astring" (atom or string) starting at *@str_p.
+ * On success, *@str_p will point to the first character after the end
+ * of the string, and *@len will contain the length of the returned
+ * string. On failure, *@str_p will be set to %NULL.
*
* This assumes that the string is in the form returned by
* camel_imap_command(): that line breaks are indicated by LF rather
@@ -204,7 +227,7 @@ imap_parse_flag_list (const char *flag_list)
* latter, it will point to the character after the NIL.)
**/
char *
-imap_parse_nstring (char **str_p, int *len)
+imap_parse_string_generic (char **str_p, int *len, int type)
{
char *str = *str_p;
char *out;
@@ -248,10 +271,19 @@ imap_parse_nstring (char **str_p, int *len)
out = g_strndup (str, *len);
*str_p = str + *len;
return out;
- } else if (!g_strncasecmp (str, "nil", 3)) {
+ } else if (type == IMAP_NSTRING && !g_strncasecmp (str, "nil", 3)) {
*str_p += 3;
*len = 0;
return NULL;
+ } else if (type == IMAP_ASTRING &&
+ imap_is_atom_char ((unsigned char)*str)) {
+ while (imap_is_atom_char ((unsigned char)*str))
+ str++;
+
+ *len = str - *str_p;
+ str = g_strndup (*str_p, *len);
+ *str_p += *len;
+ return str;
} else {
*str_p = NULL;
return NULL;
@@ -259,43 +291,6 @@ imap_parse_nstring (char **str_p, int *len)
}
/**
- * imap_parse_astring:
- * @str_p: a pointer to a string
- * @len: a pointer to an int to return the length in
- *
- * This parses an "astring" (an atom, a quoted string, or a literal)
- * starting at *@str_p. On success, *@str_p will point to the first
- * character after the end of the astring, and *@len will contain
- * the length of the returned string. On failure, *@str_p will be
- * set to %NULL.
- *
- * This assumes that the string is in the form returned by
- * camel_imap_command(): that line breaks are indicated by LF rather
- * than CRLF.
- *
- * Return value: the parsed string, or %NULL if no string
- * was parsed. (In this case, *@str_p will also be %NULL.)
- **/
-char *
-imap_parse_astring (char **str_p, int *len)
-{
- char *p;
-
- if (**str_p == '{' || **str_p == '"')
- return imap_parse_nstring (str_p, len);
-
- p = *str_p;
- while (isascii ((unsigned char)*p) &&
- !strchr ("(){ \"\\%*", *p))
- p++;
-
- *len = p - *str_p;
- p = g_strndup (*str_p, *len);
- *str_p += *len;
- return p;
-}
-
-/**
* imap_quote_string:
* @str: the string to quote, which must not contain CR or LF
*
diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h
index 015ad91e16..d6df958ac9 100644
--- a/camel/providers/imap/camel-imap-utils.h
+++ b/camel/providers/imap/camel-imap-utils.h
@@ -28,7 +28,7 @@ extern "C" {
#pragma }
#endif /* __cplusplus }*/
-#include <glib.h>
+#include "camel-folder-summary.h"
char *imap_next_word (const char *buf);
@@ -39,10 +39,16 @@ char *imap_next_word (const char *buf);
gboolean imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder);
char *imap_create_flag_list (guint32 flags);
-guint32 imap_parse_flag_list (const char *flag_list);
-
-char *imap_parse_nstring (char **str_p, int *len);
-char *imap_parse_astring (char **str_p, int *len);
+guint32 imap_parse_flag_list (char **flag_list);
+
+enum { IMAP_STRING, IMAP_NSTRING, IMAP_ASTRING };
+char *imap_parse_string_generic (char **str_p, int *len, int type);
+#define imap_parse_string(str_p, len_p) \
+ imap_parse_string_generic (str_p, len_p, IMAP_STRING)
+#define imap_parse_nstring(str_p, len_p) \
+ imap_parse_string_generic (str_p, len_p, IMAP_NSTRING)
+#define imap_parse_astring(str_p, len_p) \
+ imap_parse_string_generic (str_p, len_p, IMAP_ASTRING)
char *imap_quote_string (const char *str);