summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2017-01-04 21:40:31 +0200
committerSergey Poznyakoff <gray@gnu.org>2017-01-04 21:40:31 +0200
commit00c27bc22c1d032e0b9716bc87abbf6b68cbbb43 (patch)
tree05ab96f1f30ee5046058118009f6b4b41e5aa95f
parent5e425f04eeb5fad1f299fcf449404cef3b061c55 (diff)
downloadmailutils-00c27bc22c1d032e0b9716bc87abbf6b68cbbb43.tar.gz
mailutils-00c27bc22c1d032e0b9716bc87abbf6b68cbbb43.tar.bz2
Improve handling of namespace references
* imap4d/list.c (refinfo) <pfxlen>: Remove. (list_fun): Change the algorithm for restoring the printable reference name. (imap4d_list): Use actual reference, not the prefix value. * imap4d/namespace.c: Fix handling of NS_OTHER prefixes. * imap4d/tests/list.at: Change the testcase.
-rw-r--r--imap4d/list.c61
-rw-r--r--imap4d/namespace.c47
-rw-r--r--imap4d/tests/list.at15
3 files changed, 38 insertions, 85 deletions
diff --git a/imap4d/list.c b/imap4d/list.c
index 07cea67c2..4a2590564 100644
--- a/imap4d/list.c
+++ b/imap4d/list.c
@@ -24,7 +24,6 @@ struct refinfo
char *refptr; /* Original reference */
size_t reflen; /* Length of the original reference */
struct namespace_prefix const *pfx;
- size_t pfxlen;
size_t dirlen; /* Length of the current directory prefix */
char *buf;
size_t bufsize;
@@ -43,8 +42,8 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data)
name = resp->name;
size = strlen (name);
- if (size == refinfo->pfxlen + 6
- && memcmp (name + refinfo->pfxlen + 1, "INBOX", 5) == 0)
+ if (size == refinfo->reflen + 6
+ && memcmp (name + refinfo->reflen + 1, "INBOX", 5) == 0)
return 0;
io_sendf ("* %s", "LIST (");
@@ -59,37 +58,25 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data)
io_sendf (") \"%c\" ", refinfo->pfx->delim);
name = resp->name + refinfo->dirlen + 1;
- size = strlen (name) + refinfo->pfxlen + 2;
+ size = strlen (name) + refinfo->reflen + 2;
if (size > refinfo->bufsize)
{
if (refinfo->buf == NULL)
{
refinfo->bufsize = size;
- refinfo->buf = malloc (refinfo->bufsize);
- if (!refinfo->buf)
- {
- mu_error ("%s", mu_strerror (errno));
- return 1;
- }
- memcpy (refinfo->buf, refinfo->refptr, refinfo->reflen);
+ refinfo->buf = mu_alloc (refinfo->bufsize);
}
else
{
- char *p = realloc (refinfo->buf, size);
- if (!p)
- {
- mu_error ("%s", mu_strerror (errno));
- return 1;
- }
- refinfo->buf = p;
+ refinfo->buf = mu_realloc (refinfo->buf, size);
refinfo->bufsize = size;
}
}
- if (refinfo->pfxlen)
+ if (refinfo->refptr[0])
{
- p = mu_stpcpy (refinfo->buf, refinfo->pfx->prefix);
- if (*name)
+ p = mu_stpcpy (refinfo->buf, refinfo->refptr);
+ if (refinfo->refptr[refinfo->reflen-1] != refinfo->pfx->delim)
*p++ = refinfo->pfx->delim;
}
else
@@ -185,35 +172,16 @@ imap4d_list (struct imap4d_session *session,
struct refinfo refinfo;
size_t i;
struct namespace_prefix const *pfx;
-
- if (*wcard == '~')
- {
- for (i = 1;
- mu_c_is_class (wcard[i], MU_CTYPE_ALPHA|MU_CTYPE_DIGIT)
- || wcard[i] == '_'; i++)
- ;
- ref = mu_alloc (i + 1);
- memcpy (ref, wcard, i);
- ref[i] = 0;
- wcard += i;
- }
- else
- ref = mu_strdup (ref);
cwd = namespace_translate_name (ref, 0, &pfx);
if (!cwd)
{
- free (ref);
return io_completion_response (command, RESP_NO,
"The requested item could not be found.");
}
free (cwd);
-
- if (*wcard == pfx->delim && ref[0] != '~')
- {
- /* Absolute Path in wcard, dump the old ref. */
- ref[0] = 0;
- }
+
+ ref = mu_strdup (ref);
/* Find the longest directory prefix */
i = strcspn (wcard, "%*");
@@ -223,14 +191,9 @@ imap4d_list (struct imap4d_session *session,
if (i)
{
size_t reflen = strlen (ref);
- int addslash = (reflen > 0
- && ref[reflen-1] != pfx->delim
- && *wcard != pfx->delim);
- size_t len = i + reflen + addslash;
+ size_t len = i + reflen;
ref = mu_realloc (ref, len);
- if (addslash)
- ref[reflen++] = pfx->delim;
memcpy (ref + reflen, wcard, i - 1); /* omit the trailing / */
ref[len-1] = 0;
@@ -278,8 +241,6 @@ imap4d_list (struct imap4d_session *session,
mu_url_sget_path (url, &dir);
refinfo.dirlen = strlen (dir);
- refinfo.pfxlen = strlen (pfx->prefix);
-
/* The special name INBOX is included in the output from LIST, if
INBOX is supported by this server for this user and if the
uppercase string "INBOX" matches the interpreted reference and
diff --git a/imap4d/namespace.c b/imap4d/namespace.c
index cd3ae4373..cf5e550bf 100644
--- a/imap4d/namespace.c
+++ b/imap4d/namespace.c
@@ -104,7 +104,6 @@ namespace_init (void)
}
pfx->ns = i;
- trim_delim (pfx->prefix, pfx->delim);
trim_delim (pfx->dir, '/');
rc = mu_assoc_install (prefixes, pfx->prefix, pfx);
@@ -182,9 +181,7 @@ prefix_translate_name (struct namespace_prefix const *pfx, char const *name,
{
size_t pfxlen = strlen (pfx->prefix);
- if (pfxlen <= namelen
- && memcmp (pfx->prefix, name, pfxlen) == 0
- && (pfxlen == 0 || pfxlen == namelen || name[pfxlen] == pfx->delim))
+ if (pfxlen <= namelen && memcmp (pfx->prefix, name, pfxlen) == 0)
{
char *tmpl, *p;
@@ -212,10 +209,17 @@ prefix_translate_name (struct namespace_prefix const *pfx, char const *name,
p = mu_stpcpy (p, pfx->dir);
if (*name)
{
- *p++ = '/';
+ if (pfx->ns == NS_OTHER
+ && pfx->prefix[strlen(pfx->prefix) - 1] != pfx->delim)
+ {
+ while (*name && *name != pfx->delim)
+ name++;
+ }
+ else if (*name != pfx->delim)
+ *p++ = '/';
translate_delim (p, name, '/', pfx->delim);
}
-
+
return tmpl;
}
return NULL;
@@ -230,15 +234,6 @@ i_translate_name (char const *name, int url, int ns,
char *res = NULL;
size_t namelen = strlen (name);
-#if 0
- FIXME
- if (namelen >= 5
- && strcmp (name + namelen - 5, "INBOX") == 0
- && (namelen == 5 && name[namelen - 6] == '/'))
- {
- }
-#endif
-
rc = mu_assoc_get_iterator (prefixes, &itr);
if (rc)
{
@@ -285,7 +280,10 @@ extract_username (char const *name, struct namespace_prefix const *pfx)
len = end - p;
else
len = strlen (p);
-
+
+ if (len == 0)
+ return mu_strdup (auth_data->name);
+
user = mu_alloc (len + 1);
memcpy (user, p, len);
user[len] = 0;
@@ -310,17 +308,10 @@ namespace_translate_name (char const *name, int url,
struct namespace_prefix const *pfx;
char *env[] = ENV_INITIALIZER;
- if (name[0] == '~')
+ if (mu_c_strcasecmp (name, "INBOX") == 0 && auth_data->change_uid)
{
- if (name[1] == 0 || name[1] == '/')
- {
- if (mu_c_strcasecmp (name, "INBOX") == 0 && auth_data->change_uid)
- res = mu_strdup (auth_data->mailbox);
- else
- res = i_translate_name (name, url, NS_PRIVATE, &pfx);
- }
- else
- res = i_translate_name (name, url, NS_OTHER, &pfx);
+ res = mu_strdup (auth_data->mailbox);
+ pfx = mu_assoc_get (prefixes, "");
}
else
res = i_translate_name (name, url, NS_MAX, &pfx);
@@ -336,7 +327,7 @@ namespace_translate_name (char const *name, int url,
env[ENV_HOME] = real_homedir;
break;
- case NS_SHARED:
+ case NS_OTHER:
{
struct mu_auth_data *adata;
env[ENV_USER] = extract_username (name, pfx);
@@ -349,7 +340,7 @@ namespace_translate_name (char const *name, int url,
}
break;
- case NS_OTHER:
+ case NS_SHARED:
break;
}
diff --git a/imap4d/tests/list.at b/imap4d/tests/list.at
index d880b9067..f49eb59ff 100644
--- a/imap4d/tests/list.at
+++ b/imap4d/tests/list.at
@@ -76,16 +76,17 @@ LIST_CHECK([empty ref + asterisk],[list02],
* LIST (\NoInferiors) NIL INBOX
])
+# FIXME: I'm not sure whether it should include / in the reply.
LIST_CHECK([root ref + asterisk],[list03],
["/" "*"],
[dnl
-* LIST (\NoInferiors) "/" bigto.mbox
-* LIST (\NoInferiors) "/" mbox
-* LIST (\NoInferiors) "/" mbox1
-* LIST (\NoInferiors) "/" relational.mbox
-* LIST (\NoInferiors) "/" search.mbox
-* LIST (\NoInferiors) "/" sieve.mbox
-* LIST (\NoInferiors) "/" teaparty.mbox
+* LIST (\NoInferiors) "/" /bigto.mbox
+* LIST (\NoInferiors) "/" /mbox
+* LIST (\NoInferiors) "/" /mbox1
+* LIST (\NoInferiors) "/" /relational.mbox
+* LIST (\NoInferiors) "/" /search.mbox
+* LIST (\NoInferiors) "/" /sieve.mbox
+* LIST (\NoInferiors) "/" /teaparty.mbox
])
LIST_CHECK([absolute reference + asterisk],[list04],

Return to:

Send suggestions and report system problems to the System administrator.