diff options
author | Dan Winship <danw@src.gnome.org> | 2000-10-30 11:24:15 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2000-10-30 11:24:15 +0800 |
commit | d4656431e9de8e6e3ab526d71323f0d0543c587e (patch) | |
tree | 59b0ff39e227e6079d696c3dd29c8e1e0344dec2 /camel/providers/imap/camel-imap-utils.c | |
parent | 9e6c10a18be76719fbba41c36c61abc9c1542710 (diff) | |
download | gsoc2013-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.c | 138 |
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; +} |