diff options
author | Dan Winship <danw@src.gnome.org> | 2001-01-03 06:07:44 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2001-01-03 06:07:44 +0800 |
commit | b1a4da002f0414ceb1c8f579edba47c600762a9c (patch) | |
tree | 5e6d7f9807ab82ecfe4c74a789ba05ccda3d2063 | |
parent | a8b13bc0443aa150a3c007ea5e6bc48cc8ebbc51 (diff) | |
download | gsoc2013-evolution-b1a4da002f0414ceb1c8f579edba47c600762a9c.tar.gz gsoc2013-evolution-b1a4da002f0414ceb1c8f579edba47c600762a9c.tar.zst gsoc2013-evolution-b1a4da002f0414ceb1c8f579edba47c600762a9c.zip |
IMAP randomness.
* providers/imap/camel-imap-stream.[ch]: Remove. To be replaced.
* providers/imap/Makefile.am (libcamelimapinclude_HEADERS): Remove
camel-imap-stream.h
* providers/imap/camel-imap-utils.c (imap_parse_flag_list): Take a
char ** instead of char *, to return the position at the end of
parsing like the string parsing functions.
(imap_parse_string_generic): New function to parse a string,
nstring, or astring.
(imap_parse_nstring, imap_parse_astring): Now macros
(imap_parse_string): Added
* providers/imap/camel-imap-folder.h: Remove the "exists" field
from CamelImapFolder.
* providers/imap/camel-imap-folder.c: Remove unused include of
camel-imap-stream.h.
(camel_imap_folder_init): Remove no-longer-relevant summary
initialization.
(camel_imap_folder_new): Update for imap_parse_flag_list change,
exists removal, and imap_rescan.
(imap_rescan): New function that does most of the work of the old
imap_refresh_info, but taking "exists" as an argument instead of
getting it from the folder. Also calls camel_imap_folder_changed
to do the summary updating and signalling, rather than duplicating
that code.
(imap_refresh_info): Just call imap_rescan (using the size of the
folder summary as "exists").
(imap_update_summary): Update for imap_parse_flag_list change
(camel_imap_folder_changed): Update for "exists" change.
svn path=/trunk/; revision=7216
-rw-r--r-- | camel/ChangeLog | 36 | ||||
-rw-r--r-- | camel/providers/imap/Makefile.am | 1 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-folder.c | 104 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-folder.h | 1 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-stream.c | 220 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-stream.h | 71 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-utils.c | 93 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-utils.h | 16 |
8 files changed, 138 insertions, 404 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 4888a385e5..802fdae253 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,41 @@ 2001-01-02 Dan Winship <danw@helixcode.com> + IMAP randomness. + + * providers/imap/camel-imap-stream.[ch]: Remove. To be replaced. + + * providers/imap/Makefile.am (libcamelimapinclude_HEADERS): Remove + camel-imap-stream.h + + * providers/imap/camel-imap-utils.c (imap_parse_flag_list): Take a + char ** instead of char *, to return the position at the end of + parsing like the string parsing functions. + (imap_parse_string_generic): New function to parse a string, + nstring, or astring. + (imap_parse_nstring, imap_parse_astring): Now macros + (imap_parse_string): Added + + * providers/imap/camel-imap-folder.h: Remove the "exists" field + from CamelImapFolder. + + * providers/imap/camel-imap-folder.c: Remove unused include of + camel-imap-stream.h. + (camel_imap_folder_init): Remove no-longer-relevant summary + initialization. + (camel_imap_folder_new): Update for imap_parse_flag_list change, + exists removal, and imap_rescan. + (imap_rescan): New function that does most of the work of the old + imap_refresh_info, but taking "exists" as an argument instead of + getting it from the folder. Also calls camel_imap_folder_changed + to do the summary updating and signalling, rather than duplicating + that code. + (imap_refresh_info): Just call imap_rescan (using the size of the + folder summary as "exists"). + (imap_update_summary): Update for imap_parse_flag_list change + (camel_imap_folder_changed): Update for "exists" change. + +2001-01-02 Dan Winship <danw@helixcode.com> + * camel-mime-utils.c (header_content_type_simple): New function to return just foo/bar with no parameters. 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); |