aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap/camel-imap-utils.c
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2000-10-30 11:24:15 +0800
committerDan Winship <danw@src.gnome.org>2000-10-30 11:24:15 +0800
commitd4656431e9de8e6e3ab526d71323f0d0543c587e (patch)
tree59b0ff39e227e6079d696c3dd29c8e1e0344dec2 /camel/providers/imap/camel-imap-utils.c
parent9e6c10a18be76719fbba41c36c61abc9c1542710 (diff)
downloadgsoc2013-evolution-d4656431e9de8e6e3ab526d71323f0d0543c587e.tar
gsoc2013-evolution-d4656431e9de8e6e3ab526d71323f0d0543c587e.tar.gz
gsoc2013-evolution-d4656431e9de8e6e3ab526d71323f0d0543c587e.tar.bz2
gsoc2013-evolution-d4656431e9de8e6e3ab526d71323f0d0543c587e.tar.lz
gsoc2013-evolution-d4656431e9de8e6e3ab526d71323f0d0543c587e.tar.xz
gsoc2013-evolution-d4656431e9de8e6e3ab526d71323f0d0543c587e.tar.zst
gsoc2013-evolution-d4656431e9de8e6e3ab526d71323f0d0543c587e.zip
Improved IMAP namespace handling: leave the namespace in the
folder names rather than constantly prepending it and stripping it off. Also some subscription fixes. * camel-store.c (camel_folder_info_build): Fix for the case where @top isn't in @folders. * providers/imap/camel-imap-folder.c (camel_imap_folder_new): Add a "short_name" argument rather than figuring it out ourselves. (imap_get_full_name): Implementation of CamelFolder::get_full_name that strips off namespace so the user doesn't have to see it. (imap_append_message, imap_copy_message_to, imap_move_message_to): Use folder->full_name rather than calling camel_imap_store_get_folder_path. * providers/imap/camel-imap-utils.c (imap_parse_list_response): Update this: make @flags a bitmask and @sep a char rather than a string. Make all of the out arguments optional. Handle literals in the server response. * providers/imap/camel-imap-store.c (imap_connect): Do a better job of getting the correct dir_sep for the namespace we're using. Construct a base_url here that will be used by get_folder_info. (camel_imap_store_folder_path): Removed (imap_folder_exists): Add an argument to return the short name of the folder (parsed out of the LIST response). Update for imap_parse_list_response change. (get_folder): Update for the various other changes. (get_folder_info): Update for the various other changes. Be more consistent about the returned layout: put everything underneath the "namespace" directory, including INBOX, even if it doesn't belong there. Don't destroy the list of subscribed folders until we've actually gotten the new list. (folder_subscribed, subscribe_folder, unsubscribe_folder): Use folder_name directly rather than camel_imap_store_folder_Path. * providers/imap/camel-imap-command.c (camel_imap_command): Update for folder name changes. svn path=/trunk/; revision=6256
Diffstat (limited to 'camel/providers/imap/camel-imap-utils.c')
-rw-r--r--camel/providers/imap/camel-imap-utils.c138
1 files changed, 96 insertions, 42 deletions
diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c
index e4d8bfeb02..b38024ecc6 100644
--- a/camel/providers/imap/camel-imap-utils.c
+++ b/camel/providers/imap/camel-imap-utils.c
@@ -20,6 +20,7 @@
*
*/
+#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
@@ -46,64 +47,81 @@ imap_next_word (const char *buf)
return word;
}
+/**
+ * imap_parse_list_response:
+ * @buf: the LIST or LSUB response
+ * @flags: a pointer to a variable to store the flags in, or %NULL
+ * @sep: a pointer to a variable to store the hierarchy separator in, or %NULL
+ * @folder: a pointer to a variable to store the folder name in, or %NULL
+ *
+ * Parses a LIST or LSUB response and returns the desired parts of it.
+ * If @folder is non-%NULL, its value must be freed by the caller.
+ *
+ * Return value: whether or not the response was successfully parsed.
+ **/
gboolean
-imap_parse_list_response (const char *buf, const char *namespace, char **flags, char **sep, char **folder)
+imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder)
{
- char *word, *ep, *f;
-
- *flags = NULL;
- *sep = NULL;
- *folder = NULL;
-
+ char *word;
+ int len;
+
if (*buf != '*')
return FALSE;
-
+
word = imap_next_word (buf);
if (g_strncasecmp (word, "LIST", 4) && g_strncasecmp (word, "LSUB", 4))
return FALSE;
-
+
/* get the flags */
word = imap_next_word (word);
if (*word != '(')
return FALSE;
-
+
+ if (flags)
+ *flags = 0;
+
word++;
- for (ep = word; *ep && *ep != ')'; ep++);
- if (*ep != ')')
- return FALSE;
-
- *flags = g_strndup (word, (gint)(ep - word));
-
- /* get the directory separator */
- word = imap_next_word (ep);
- if (*word) {
- if (!strncmp (word, "NIL", 3)) {
- *sep = NULL;
- } else {
- for (ep = word; *ep && *ep != ' '; ep++);
- *sep = g_strndup (word, (gint)(ep - word));
- string_unquote (*sep);
+ while (*word != ')') {
+ len = strcspn (word, " )");
+ if (flags) {
+ if (!g_strncasecmp (word, "\\Noinferiors", len))
+ *flags |= IMAP_LIST_FLAG_NOINFERIORS;
+ else if (!g_strncasecmp (word, "\\Noselect", len))
+ *flags |= IMAP_LIST_FLAG_NOSELECT;
+ else if (!g_strncasecmp (word, "\\Marked", len))
+ *flags |= IMAP_LIST_FLAG_MARKED;
+ else if (!g_strncasecmp (word, "\\Unmarked", len))
+ *flags |= IMAP_LIST_FLAG_UNMARKED;
}
- } else {
- return FALSE;
+
+ word += len;
+ while (*word == ' ')
+ word++;
}
-
- /* get the folder name */
+
+ /* get the directory separator */
word = imap_next_word (word);
- *folder = g_strdup (word);
- g_strstrip (*folder);
- string_unquote (*folder);
-
- /* chop out the folder prefix */
- if (*namespace && !strncmp (*folder, namespace, strlen (namespace))) {
- f = *folder + strlen (namespace);
- if (*sep && !strncmp (f, *sep, strlen (*sep)))
- f += strlen (*sep);
- memmove (*folder, f, strlen (f) + 1);
+ if (!strncmp (word, "NIL", 3)) {
+ if (sep)
+ *sep = '\0';
+ } else if (*word++ == '"') {
+ if (*word == '\\')
+ word++;
+ if (sep)
+ *sep = *word;
+ word++;
+ if (*word++ != '"')
+ return FALSE;
+ } else
+ return FALSE;
+
+ if (folder) {
+ /* get the folder name */
+ word = imap_next_word (word);
+ *folder = imap_parse_astring (&word, &len);
+ return *folder != NULL;
}
-
- string_unquote (*folder); /* unquote the mailbox if it's quoted */
-
+
return TRUE;
}
@@ -632,3 +650,39 @@ 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;
+}