tolerate INBOX mis-casing in Path
while it's technically reasonable to expect the user to match the server's casing of INBOX if they set Path, this might come as a surprise to those who know that the IMAP INBOX is case-insensitive. so tolerate any casing instead. as a minor side effect, we'd now even be able to deal with a server using different casing in NAMESPACE and LIST.
This commit is contained in:
parent
4b185e35fe
commit
d8feb67dae
|
@ -35,7 +35,6 @@ typedef struct driver driver_t;
|
||||||
struct store_conf *next; \
|
struct store_conf *next; \
|
||||||
char *name; \
|
char *name; \
|
||||||
driver_t *driver; \
|
driver_t *driver; \
|
||||||
const char *path; /* should this be here? its interpretation is driver-specific */ \
|
|
||||||
const char *flat_delim; \
|
const char *flat_delim; \
|
||||||
const char *map_inbox; \
|
const char *map_inbox; \
|
||||||
const char *trash; \
|
const char *trash; \
|
||||||
|
|
|
@ -74,6 +74,7 @@ typedef union imap_store_conf {
|
||||||
struct {
|
struct {
|
||||||
STORE_CONF
|
STORE_CONF
|
||||||
imap_server_conf_t *server;
|
imap_server_conf_t *server;
|
||||||
|
char *path; // Note: this may be modified after the delimiter is determined.
|
||||||
char delimiter;
|
char delimiter;
|
||||||
char use_namespace;
|
char use_namespace;
|
||||||
char use_lsub;
|
char use_lsub;
|
||||||
|
@ -114,8 +115,8 @@ union imap_store {
|
||||||
struct {
|
struct {
|
||||||
STORE(union imap_store)
|
STORE(union imap_store)
|
||||||
const char *label; // foreign
|
const char *label; // foreign
|
||||||
const char *prefix;
|
|
||||||
const char *name;
|
const char *name;
|
||||||
|
char *prefix;
|
||||||
uint ref_count;
|
uint ref_count;
|
||||||
uint opts;
|
uint opts;
|
||||||
enum { SST_BAD, SST_HALF, SST_GOOD } state;
|
enum { SST_BAD, SST_HALF, SST_GOOD } state;
|
||||||
|
@ -1374,6 +1375,13 @@ is_INBOX( imap_store_t *ctx, const char *arg, int argl )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
normalize_INBOX( imap_store_t *ctx, char *arg, int argl )
|
||||||
|
{
|
||||||
|
if (is_inbox( ctx, arg, argl ))
|
||||||
|
memcpy( arg, "INBOX", 5 );
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_list_rsp_p2( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
|
parse_list_rsp_p2( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
|
||||||
{
|
{
|
||||||
|
@ -1388,14 +1396,15 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
|
||||||
}
|
}
|
||||||
arg = list->val;
|
arg = list->val;
|
||||||
argl = (int)list->len;
|
argl = (int)list->len;
|
||||||
|
// The server might be weird and have a non-uppercase INBOX. It
|
||||||
|
// may legitimately do so, but we need the canonical spelling.
|
||||||
|
normalize_INBOX( ctx, arg, argl );
|
||||||
if ((l = strlen( ctx->prefix ))) {
|
if ((l = strlen( ctx->prefix ))) {
|
||||||
if (!starts_with( arg, argl, ctx->prefix, l )) {
|
if (!starts_with( arg, argl, ctx->prefix, l )) {
|
||||||
if (is_inbox( ctx, arg, argl )) {
|
if (!is_INBOX( ctx, arg, argl ))
|
||||||
// INBOX and its subfolders bypass the namespace.
|
|
||||||
goto inbox;
|
|
||||||
}
|
|
||||||
return LIST_OK;
|
return LIST_OK;
|
||||||
}
|
// INBOX and its subfolders bypass the namespace.
|
||||||
|
} else {
|
||||||
arg += l;
|
arg += l;
|
||||||
argl -= l;
|
argl -= l;
|
||||||
// A folder named "INBOX" would be indistinguishable from the
|
// A folder named "INBOX" would be indistinguishable from the
|
||||||
|
@ -1407,14 +1416,7 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
|
||||||
warn( "IMAP warning: ignoring INBOX in %s\n", ctx->prefix );
|
warn( "IMAP warning: ignoring INBOX in %s\n", ctx->prefix );
|
||||||
return LIST_OK;
|
return LIST_OK;
|
||||||
}
|
}
|
||||||
} else if (is_inbox( ctx, arg, argl )) {
|
}
|
||||||
inbox:
|
|
||||||
// The server might be weird and have a non-uppercase INBOX. It
|
|
||||||
// may legitimately do so, but we need the canonical spelling.
|
|
||||||
// Note that we do that only after prefix matching, under the
|
|
||||||
// assumption that the NAMESPACE (or Path) matches the
|
|
||||||
// capitalization of LIST.
|
|
||||||
memcpy( arg, "INBOX", 5 );
|
|
||||||
}
|
}
|
||||||
if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround broken servers */
|
if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround broken servers */
|
||||||
return LIST_OK;
|
return LIST_OK;
|
||||||
|
@ -2539,6 +2541,8 @@ imap_open_store_finalize( imap_store_t *ctx )
|
||||||
ctx->state = SST_GOOD;
|
ctx->state = SST_GOOD;
|
||||||
if (!ctx->prefix)
|
if (!ctx->prefix)
|
||||||
ctx->prefix = "";
|
ctx->prefix = "";
|
||||||
|
else
|
||||||
|
normalize_INBOX( ctx, ctx->prefix, -1 );
|
||||||
ctx->trashnc = TrashUnknown;
|
ctx->trashnc = TrashUnknown;
|
||||||
ctx->callbacks.imap_open( DRV_OK, ctx->callback_aux );
|
ctx->callbacks.imap_open( DRV_OK, ctx->callback_aux );
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ typedef union maildir_store_conf {
|
||||||
store_conf_t gen;
|
store_conf_t gen;
|
||||||
struct {
|
struct {
|
||||||
STORE_CONF
|
STORE_CONF
|
||||||
|
char *path;
|
||||||
char *inbox;
|
char *inbox;
|
||||||
#ifdef USE_DB
|
#ifdef USE_DB
|
||||||
int alt_map;
|
int alt_map;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user