From f789abbd422604206c386199c80fb5eac8e34733 Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Mon, 6 Aug 2001 19:00:32 +0000 Subject: Completely hide the namespace from everything external to the IMAP code, 2001-08-06 Peter Williams Completely hide the namespace from everything external to the IMAP code, which Dan W says is the way it should be. * providers/imap/camel-imap-command.c (imap_command_strdup_vprintf): Add a new %F argument, which is like %S but will add the namespace (for folder names). (camel_imap_command): Use %F here. * providers/imap/camel-imap-utils.c (imap_parse_list_response): Changed to strip out the namespec when returning *folder. In order to do this we need to be passed the CamelImapStore. (imap_concat): Move to here from camel-imap-store.c, un-static (imap_namespace_concat): New function, adds the namespace to the folder name, unless it's INBOX. * providers/imap/camel-imap-utils.h: Prototypes. * providers/imap/camel-imap-store.c (imap_connect_online): Extra arg to imap_parse_list_response. (imap_connect_offline): Here too. (get_folder_status): Use %F. (get_folder_online): Here too. (delete_folder): Here too. (create_folder): Here too, and arg to imap_parse_list_response. (parse_list_response_as_folder_info): Arg to i_p_l_r. (get_subscribed_folders_by_hand): Use %F. (get_folders_online): Here too. (get_folder_info_online): Instead of checking for NULL @name, check for name = NULL or "", and set to "" instead of namespace. Pass "" instead of namespace to camel_folder_info_build. (subscribe_folder): Use %F. (unsubscribe_folder): Here too. * providers/imap/camel-imap-folder.c (imap_get_full_name): This now just returns folder->full_name. (do_append): Use %F (do_copy): Here too. svn path=/trunk/; revision=11705 --- camel/ChangeLog | 40 ++++++++++++++++++++++ camel/providers/imap/camel-imap-command.c | 22 +++++++++--- camel/providers/imap/camel-imap-folder.c | 25 ++------------ camel/providers/imap/camel-imap-store.c | 57 ++++++++++++------------------- camel/providers/imap/camel-imap-utils.c | 44 ++++++++++++++++++++++-- camel/providers/imap/camel-imap-utils.h | 6 +++- 6 files changed, 128 insertions(+), 66 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index 35fc7c8ad4..3bf218d170 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,43 @@ +2001-08-06 Peter Williams + + Completely hide the namespace from everything external to the IMAP + code, which Dan W says is the way it should be. + + * providers/imap/camel-imap-command.c + (imap_command_strdup_vprintf): Add a new %F argument, which is like + %S but will add the namespace (for folder names). + (camel_imap_command): Use %F here. + + * providers/imap/camel-imap-utils.c (imap_parse_list_response): + Changed to strip out the namespec when returning *folder. In order + to do this we need to be passed the CamelImapStore. + (imap_concat): Move to here from camel-imap-store.c, un-static + (imap_namespace_concat): New function, adds the namespace to the + folder name, unless it's INBOX. + + * providers/imap/camel-imap-utils.h: Prototypes. + + * providers/imap/camel-imap-store.c (imap_connect_online): Extra + arg to imap_parse_list_response. + (imap_connect_offline): Here too. + (get_folder_status): Use %F. + (get_folder_online): Here too. + (delete_folder): Here too. + (create_folder): Here too, and arg to imap_parse_list_response. + (parse_list_response_as_folder_info): Arg to i_p_l_r. + (get_subscribed_folders_by_hand): Use %F. + (get_folders_online): Here too. + (get_folder_info_online): Instead of checking for NULL @name, check + for name = NULL or "", and set to "" instead of namespace. Pass "" + instead of namespace to camel_folder_info_build. + (subscribe_folder): Use %F. + (unsubscribe_folder): Here too. + + * providers/imap/camel-imap-folder.c (imap_get_full_name): This + now just returns folder->full_name. + (do_append): Use %F + (do_copy): Here too. + 2001-08-06 Jeffrey Stedfast * camel-pgp-context.c (pgp_verify): Always do --no-auto-key-retrieve. diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c index 428ecf565d..4c84b47fbb 100644 --- a/camel/providers/imap/camel-imap-command.c +++ b/camel/providers/imap/camel-imap-command.c @@ -98,7 +98,7 @@ camel_imap_command (CamelImapStore *store, CamelFolder *folder, } store->current_folder = folder; camel_object_ref (CAMEL_OBJECT (folder)); - cmd = imap_command_strdup_printf (store, "SELECT %S", + cmd = imap_command_strdup_printf (store, "SELECT %F", folder->full_name); } @@ -127,11 +127,15 @@ camel_imap_command (CamelImapStore *store, CamelFolder *folder, * @fmt can include the following %-escapes ONLY: * %s, %d, %%: as with printf * %S: an IMAP "string" (quoted string or literal) + * %F: an IMAP folder name * * %S strings will be passed as literals if the server supports LITERAL+ * and quoted strings otherwise. (%S does not support strings that * contain newlines.) * + * %F will have the imap store's namespace prepended and then be processed + * like %S. + * * On success, the store's command_lock will be locked. It will be * freed when %CAMEL_IMAP_RESPONSE_TAGGED or %CAMEL_IMAP_RESPONSE_ERROR * is returned from camel_imap_command_response(). (The lock is @@ -621,7 +625,6 @@ camel_imap_response_extract_continuation (CamelImapStore *store, return NULL; } - static char * imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt, va_list ap) @@ -629,7 +632,7 @@ imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt, GPtrArray *args; const char *p, *start; char *out, *op, *string; - int num, len, i; + int num, len, i, arglen; args = g_ptr_array_new (); @@ -657,12 +660,16 @@ imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt, break; case 'S': + case 'F': string = va_arg (ap, char *); + arglen = strlen (string); + if (*p == 'F') + arglen += strlen (store->namespace) + 1; g_ptr_array_add (args, string); if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) - len += strlen (string) + 15; + len += arglen + 15; else - len += strlen (string) * 2; + len += arglen * 2; start = p + 1; break; @@ -704,7 +711,10 @@ imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt, break; case 'S': + case 'F': string = args->pdata[i++]; + if (*p == 'F') + string = imap_namespace_concat (store, string); if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) { op += sprintf (op, "{%d+}\r\n%s", strlen (string), string); @@ -713,6 +723,8 @@ imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt, op += sprintf (op, "%s", quoted); g_free (quoted); } + if (*p == 'F') + g_free (string); break; default: diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index ba30ac7cc1..054fd7c6a0 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -72,7 +72,6 @@ static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex); static void imap_refresh_info (CamelFolder *folder, CamelException *ex); static void imap_sync_online (CamelFolder *folder, CamelException *ex); static void imap_sync_offline (CamelFolder *folder, CamelException *ex); -static const char *imap_get_full_name (CamelFolder *folder); static void imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, CamelException *ex); static void imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, CamelException *ex); static void imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelException *ex); @@ -114,7 +113,6 @@ camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class) disco_folder_class = CAMEL_DISCO_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_disco_folder_get_type ())); /* virtual method overload */ - camel_folder_class->get_full_name = imap_get_full_name; camel_folder_class->get_message = imap_get_message; camel_folder_class->move_messages_to = imap_move_messages_to; camel_folder_class->search_by_expression = imap_search_by_expression; @@ -859,25 +857,6 @@ imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelExceptio CAMEL_IMAP_STORE_UNLOCK (store, command_lock); } -static const char * -imap_get_full_name (CamelFolder *folder) -{ - CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); - char *name; - int len; - - name = folder->full_name; - if (store->namespace && *store->namespace) { - len = strlen (store->namespace); - if (!strncmp (store->namespace, folder->full_name, len) && - strlen (folder->full_name) > len) - name += len; - if (*name == store->dir_sep) - name++; - } - return name; -} - static void imap_append_offline (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex) @@ -944,7 +923,7 @@ do_append (CamelFolder *folder, CamelMimeMessage *message, camel_object_unref (CAMEL_OBJECT (crlf_filter)); camel_object_unref (CAMEL_OBJECT (memstream)); - response = camel_imap_command (store, NULL, ex, "APPEND %S%s%s {%d}", + response = camel_imap_command (store, NULL, ex, "APPEND %F%s%s {%d}", folder->full_name, flagstr ? " " : "", flagstr ? flagstr : "", ba->len); g_free (flagstr); @@ -1166,7 +1145,7 @@ do_copy (CamelFolder *source, GPtrArray *uids, char *set; set = imap_uid_array_to_set (source->summary, uids); - response = camel_imap_command (store, source, ex, "UID COPY %s %S", + response = camel_imap_command (store, source, ex, "UID COPY %s %F", set, destination->full_name); if (response && (store->capabilities & IMAP_CAPABILITY_UIDPLUS)) handle_copyuid (response, source, destination); diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 580a889078..4f8571bfae 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -640,7 +640,7 @@ imap_connect_online (CamelService *service, CamelException *ex) result = camel_imap_response_extract (store, response, "LIST", NULL); if (result) { - imap_parse_list_response (result, NULL, &store->dir_sep, NULL); + imap_parse_list_response (store, result, NULL, &store->dir_sep, NULL); g_free (result); } if (!store->dir_sep) @@ -659,7 +659,7 @@ imap_connect_online (CamelService *service, CamelException *ex) store->subscribed_folders = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; i < response->untagged->len; i++) { result = response->untagged->pdata[i]; - if (!imap_parse_list_response (result, &flags, NULL, &name)) + if (!imap_parse_list_response (store, result, &flags, NULL, &name)) continue; if (flags & (IMAP_LIST_FLAG_MARKED | IMAP_LIST_FLAG_UNMARKED)) store->capabilities |= IMAP_CAPABILITY_useful_lsub; @@ -729,7 +729,7 @@ imap_connect_offline (CamelService *service, CamelException *ex) /* Get subscribed folders */ store->subscribed_folders = g_hash_table_new (g_str_hash, g_str_equal); while (camel_file_util_decode_string (storeinfo, &buf) == 0) { - if (!imap_parse_list_response (buf, NULL, NULL, &name)) { + if (!imap_parse_list_response (store, buf, NULL, NULL, &name)) { g_free (buf); continue; } @@ -838,7 +838,7 @@ get_folder_status (CamelImapStore *imap_store, const char *folder_name, const ch /* FIXME: we assume the server is STATUS-capable */ response = camel_imap_command (imap_store, NULL, NULL, - "STATUS %S (%s)", + "STATUS %F (%s)", folder_name, type); @@ -882,18 +882,18 @@ get_folder_online (CamelStore *store, const char *folder_name, imap_store->current_folder = NULL; } response = camel_imap_command (imap_store, NULL, NULL, - "SELECT %S", folder_name); + "SELECT %F", folder_name); if (!response) { if (!flags & CAMEL_STORE_FOLDER_CREATE) return no_such_folder (folder_name, ex); response = camel_imap_command (imap_store, NULL, ex, - "CREATE %S", folder_name); + "CREATE %F", folder_name); if (response) { camel_imap_response_free (imap_store, response); response = camel_imap_command (imap_store, NULL, NULL, - "SELECT %S", folder_name); + "SELECT %F", folder_name); } if (!response) { CAMEL_IMAP_STORE_UNLOCK (imap_store, command_lock); @@ -947,18 +947,6 @@ get_folder_offline (CamelStore *store, const char *folder_name, return new_folder; } -static char * -imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix) -{ - int len; - - len = strlen (prefix); - if (len == 0 || prefix[len - 1] == imap_store->dir_sep) - return g_strdup_printf ("%s%s", prefix, suffix); - else - return g_strdup_printf ("%s%c%s", prefix, imap_store->dir_sep, suffix); -} - static void delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) { @@ -979,7 +967,7 @@ delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) /* delete the old parent and recreate it */ - response = camel_imap_command (imap_store, NULL, ex, "DELETE %S", + response = camel_imap_command (imap_store, NULL, ex, "DELETE %F", folder_name); if (response) camel_imap_response_free (imap_store, response); @@ -999,12 +987,12 @@ create_folder (CamelStore *store, const char *parent_name, if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex)) return NULL; if (!parent_name) - parent_name = imap_store->namespace; + parent_name = ""; /* check if the parent allows inferiors */ need_convert = FALSE; - response = camel_imap_command (imap_store, NULL, ex, "LIST \"\" %S", + response = camel_imap_command (imap_store, NULL, ex, "LIST \"\" %F", parent_name); if (!response) /* whoa, this is bad */ return NULL; @@ -1013,7 +1001,7 @@ create_folder (CamelStore *store, const char *parent_name, for (i = 0; i < response->untagged->len; i++) { resp = response->untagged->pdata[i]; - if (!imap_parse_list_response (resp, &flags, NULL, &thisone)) + if (!imap_parse_list_response (imap_store, resp, &flags, NULL, &thisone)) continue; if (strcmp (thisone, parent_name) == 0) { @@ -1046,7 +1034,7 @@ create_folder (CamelStore *store, const char *parent_name, /* add the dirsep to the end of parent_name */ name = g_strdup_printf ("%s%c", parent_name, imap_store->dir_sep); - response = camel_imap_command (imap_store, NULL, ex, "CREATE %S", + response = camel_imap_command (imap_store, NULL, ex, "CREATE %F", name); g_free (name); @@ -1060,7 +1048,7 @@ create_folder (CamelStore *store, const char *parent_name, /* ok now we can create the folder */ full_name = imap_concat (imap_store, parent_name, folder_name); - response = camel_imap_command (imap_store, NULL, ex, "CREATE %S", + response = camel_imap_command (imap_store, NULL, ex, "CREATE %F", full_name); if (response) { camel_imap_response_free (imap_store, response); @@ -1081,7 +1069,7 @@ parse_list_response_as_folder_info (CamelImapStore *imap_store, char sep, *dir, *name = NULL; CamelURL *url; - if (!imap_parse_list_response (response, &flags, &sep, &dir)) + if (!imap_parse_list_response (imap_store, response, &flags, &sep, &dir)) return NULL; if (sep) { @@ -1136,7 +1124,7 @@ get_subscribed_folders_by_hand (CamelImapStore *imap_store, const char *top, for (i = 0; i < names->len; i++) { response = camel_imap_command (imap_store, NULL, ex, - "LIST \"\" %S", + "LIST \"\" %F", names->pdata[i]); if (!response) { g_ptr_array_free (names, TRUE); @@ -1175,7 +1163,7 @@ get_folders_online (CamelImapStore *imap_store, const char *pattern, int i; response = camel_imap_command (imap_store, NULL, ex, - "%s \"\" %S", lsub ? "LSUB" : "LIST", + "%s \"\" %F", lsub ? "LSUB" : "LIST", pattern); if (!response) return; @@ -1205,9 +1193,9 @@ get_folder_info_online (CamelStore *store, const char *top, return NULL; name = top; - if (!name) { + if (!name || name[0] == '\0') { need_inbox = TRUE; - name = imap_store->namespace; + name = ""; } folders = g_ptr_array_new (); @@ -1218,9 +1206,8 @@ get_folder_info_online (CamelStore *store, const char *top, goto lose; if (folders->len) { fi = folders->pdata[0]; - /* note that == is okay; see above */ if (strstr (fi->url, "noselect=yes") && - name == imap_store->namespace) { + name[0] == '\0') { camel_folder_info_free (fi); g_ptr_array_remove_index (folders, 0); } @@ -1379,7 +1366,7 @@ get_folder_info_offline (CamelStore *store, const char *top, fi = NULL; } else { g_ptr_array_remove_index_fast (folders, 0); - fi = camel_folder_info_build (folders, imap_store->namespace, + fi = camel_folder_info_build (folders, "", imap_store->dir_sep, TRUE); } @@ -1413,7 +1400,7 @@ subscribe_folder (CamelStore *store, const char *folder_name, return; response = camel_imap_command (imap_store, NULL, ex, - "SUBSCRIBE %S", folder_name); + "SUBSCRIBE %F", folder_name); if (!response) return; camel_imap_response_free (imap_store, response); @@ -1451,7 +1438,7 @@ unsubscribe_folder (CamelStore *store, const char *folder_name, return; response = camel_imap_command (imap_store, NULL, ex, - "UNSUBSCRIBE %S", folder_name); + "UNSUBSCRIBE %F", folder_name); if (!response) return; camel_imap_response_free (imap_store, response); diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c index f2909fb6a4..944165aebb 100644 --- a/camel/providers/imap/camel-imap-utils.c +++ b/camel/providers/imap/camel-imap-utils.c @@ -27,6 +27,7 @@ #include "camel-imap-utils.h" #include "camel-imap-summary.h" +#include "camel-imap-store.h" #include "camel-folder.h" #define d(x) x @@ -47,6 +48,7 @@ imap_next_word (const char *buf) /** * imap_parse_list_response: + * @store: the IMAP store whose list response we're parsing * @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 @@ -58,7 +60,7 @@ imap_next_word (const char *buf) * Return value: whether or not the response was successfully parsed. **/ gboolean -imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder) +imap_parse_list_response (CamelImapStore *store, const char *buf, int *flags, char *sep, char **folder) { char *word; int len; @@ -114,9 +116,22 @@ imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder) return FALSE; if (folder) { + char *real_name; + int n_len; + /* get the folder name */ word = imap_next_word (word); - *folder = imap_parse_astring (&word, &len); + real_name = imap_parse_astring (&word, &len); + n_len = strlen (store->namespace); + if (!strncmp (real_name, store->namespace, n_len)) + *folder = g_strdup (real_name + n_len); + else if (!g_strcasecmp (real_name, "INBOX")) { + *folder = g_strdup (real_name); + } else { + g_warning ("IMAP folder name \"%s\" does not begin with \"%s\"", real_name, store->namespace); + *folder = g_strdup (real_name); + } + g_free (real_name); return *folder != NULL; } @@ -730,3 +745,28 @@ imap_uid_array_free (GPtrArray *arr) g_free (arr->pdata[i]); g_ptr_array_free (arr, TRUE); } + +char * +imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix) +{ + int len; + + len = strlen (prefix); + if (len == 0 || prefix[len - 1] == imap_store->dir_sep) + return g_strdup_printf ("%s%s", prefix, suffix); + else + return g_strdup_printf ("%s%c%s", prefix, imap_store->dir_sep, suffix); +} + +char * +imap_namespace_concat (CamelImapStore *store, const char *name) +{ + if (!name || *name == '\0') + return g_strdup (store->namespace); + + if (!g_strcasecmp (name, "INBOX")) + return g_strdup ("INBOX"); + + return imap_concat (store, store->namespace, name); +} + diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h index a3b4bbdfdc..1d20ffe175 100644 --- a/camel/providers/imap/camel-imap-utils.h +++ b/camel/providers/imap/camel-imap-utils.h @@ -29,6 +29,7 @@ extern "C" { #endif /* __cplusplus }*/ #include "camel-folder-summary.h" +#include "camel-imap-types.h" char *imap_next_word (const char *buf); @@ -36,7 +37,7 @@ char *imap_next_word (const char *buf); #define IMAP_LIST_FLAG_NOSELECT (1 << 1) #define IMAP_LIST_FLAG_MARKED (1 << 2) #define IMAP_LIST_FLAG_UNMARKED (1 << 3) -gboolean imap_parse_list_response (const char *buf, int *flags, char *sep, char **folder); +gboolean imap_parse_list_response (CamelImapStore *store, const char *buf, int *flags, char *sep, char **folder); char *imap_create_flag_list (guint32 flags); guint32 imap_parse_flag_list (char **flag_list); @@ -61,6 +62,9 @@ char * imap_uid_array_to_set (CamelFolderSummary *summary, GPtrArray *uids); GPtrArray *imap_uid_set_to_array (CamelFolderSummary *summary, const char *uids); void imap_uid_array_free (GPtrArray *arr); +char *imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix); +char *imap_namespace_concat (CamelImapStore *store, const char *name); + #ifdef __cplusplus } #endif /* __cplusplus */ -- cgit v1.2.3