goto fail;
}
- mailbox_name = camel_imapx_parse_mailbox (stream, cancellable, error);
+ /* The separator character should be known by now. */
+ mailbox_name = camel_imapx_parse_mailbox (
+ stream, response->priv->separator, cancellable, error);
if (mailbox_name == NULL)
goto fail;
/* Parse mailbox name. */
- response->priv->mailbox_name =
- camel_imapx_parse_mailbox (stream, cancellable, error);
+ response->priv->mailbox_name = camel_imapx_parse_mailbox (
+ stream, response->priv->separator, cancellable, error);
if (response->priv->mailbox_name == NULL)
goto fail;
GHashTable *known_alerts;
GMutex known_alerts_lock;
+
+ /* INBOX separator character, so we can correctly normalize
+ * INBOX and descendants of INBOX in IMAP responses that do
+ * not include a separator character with the mailbox name,
+ * such as STATUS. Used for camel_imapx_parse_mailbox(). */
+ gchar inbox_separator;
};
enum {
mailbox_name = camel_imapx_list_response_get_mailbox_name (response);
separator = camel_imapx_list_response_get_separator (response);
+ /* Record the INBOX separator character once we know it. */
+ if (camel_imapx_mailbox_is_inbox (mailbox_name))
+ is->priv->inbox_separator = separator;
+
job = imapx_match_active_job (is, IMAPX_JOB_LIST, mailbox_name);
data = camel_imapx_job_get_data (job);
g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
response = camel_imapx_status_response_new (
- stream, cancellable, error);
+ stream, is->priv->inbox_separator, cancellable, error);
if (response == NULL)
return FALSE;
/**
* camel_imapx_status_response_new:
* @stream: a #CamelIMAPXStream
+ * @inbox_separator: the separator character for INBOX
* @cancellable: a #GCancellable
* @error: return location for a #GError, or %NULL
*
**/
CamelIMAPXStatusResponse *
camel_imapx_status_response_new (CamelIMAPXStream *stream,
+ gchar inbox_separator,
GCancellable *cancellable,
GError **error)
{
/* Parse mailbox name. */
- response->priv->mailbox_name =
- camel_imapx_parse_mailbox (stream, cancellable, error);
+ response->priv->mailbox_name = camel_imapx_parse_mailbox (
+ stream, inbox_separator, cancellable, error);
if (response->priv->mailbox_name == NULL)
goto fail;
CamelIMAPXStatusResponse *
camel_imapx_status_response_new
(CamelIMAPXStream *stream,
+ gchar inbox_separator,
GCancellable *cancellable,
GError **error);
const gchar * camel_imapx_status_response_get_mailbox_name
return NULL;
}
+ camel_imapx_normalize_mailbox (mailbox_name, *separator);
+
/* NB: this is done again for compatability */
if (camel_imapx_mailbox_is_inbox (mailbox_name))
si->flags |=
CamelService *service;
CamelStoreSummary *store_summary;
const gchar *user_cache_dir;
- gboolean is_inbox;
service = CAMEL_SERVICE (store);
user_cache_dir = camel_service_get_user_cache_dir (service);
store_summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
si = camel_store_summary_path (store_summary, folder_name);
- is_inbox = camel_imapx_mailbox_is_inbox (folder_name);
-
- if (si == NULL && is_inbox) {
- /* XXX This function takes a mailbox name but we're passing
- * a folder path. Are they always identical for INBOX? */
- si = (CamelStoreInfo *) camel_imapx_store_summary_mailbox (
- imapx_store->summary, folder_name);
- }
if (si != NULL) {
gchar *base_dir;
gchar *folder_dir;
- /* Note: Although the INBOX is defined to be case-insensitive
- * in the IMAP RFC, it is still up to the server how to
- * acutally name it in a LIST response. Since we stored
- * the name as the server provided it us in the summary
- * we take that name to look up the folder.
- *
- * But for the on-disk cache we always capitalize the
- * Inbox no matter what the server provided.
- */
base_dir = g_build_filename (user_cache_dir, "folders", NULL);
- folder_dir = imapx_path_to_physical (
- base_dir, is_inbox ? "INBOX" : folder_name);
+ folder_dir = imapx_path_to_physical (base_dir, folder_name);
new_folder = camel_imapx_folder_new (
store, folder_dir, folder_name, error);
g_free (folder_dir);
/**
* camel_imapx_parse_mailbox:
* @is: a #CamelIMAPXStream
+ * @separator: the mailbox separator character
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
* described in <ulink url="http://tools.ietf.org/html/rfc3501#section-5.1">
* RFC 3501 section 5.1</ulink>.
*
+ * The @separator character is used to identify INBOX and convert its name
+ * to all caps, both for INBOX itself and its descendants. If a separator
+ * character was provided in the server response being parsed (such as for
+ * LIST or LSUB), pass that for @separator. If no separator character was
+ * provided in the server response being parsed (such as for STATUS), then
+ * pass the separator character specifically for INBOX.
+ *
+ * If an error occurs, the function sets @error and returns %NULL.
+ *
+ * Returns: a newly-allocated mailbox name, or %NULL
+ *
* Since: 3.10
**/
gchar *
camel_imapx_parse_mailbox (CamelIMAPXStream *is,
+ gchar separator,
GCancellable *cancellable,
GError **error)
{
guchar *token;
- gchar *mailbox;
+ gchar *mailbox_name;
g_return_val_if_fail (CAMEL_IS_IMAPX_STREAM (is), NULL);
- /* mailbox ::= "INBOX" / astring
- * INBOX is case-insensitive. All case variants of
- * INBOX (e.g., "iNbOx") MUST be interpreted as INBOX
- * not as an astring. An astring which consists of
- * the case-insensitive sequence "I" "N" "B" "O" "X"
- * is considered to be INBOX and not an astring. */
-
if (!camel_imapx_stream_astring (is, &token, cancellable, error))
return NULL;
- if (g_ascii_strcasecmp ((gchar *) token, "INBOX") == 0)
- mailbox = g_strdup ("INBOX");
- else
- mailbox = camel_utf7_utf8 ((gchar *) token);
+ mailbox_name = camel_utf7_utf8 ((gchar *) token);
+
+ camel_imapx_normalize_mailbox (mailbox_name, separator);
- return mailbox;
+ return mailbox_name;
}
/**
/* ********************************************************************** */
gchar * camel_imapx_parse_mailbox (struct _CamelIMAPXStream *is,
+ gchar separator,
GCancellable *cancellable,
GError **error);
void camel_imapx_normalize_mailbox (gchar *mailbox_name,