Commit fb53814d fb53814d3acb7a08cd849ffbbdbe86d8a374590c by Sergey Poznyakoff

Fix parsing local URLs.

* include/mailutils/url.h (MU_URL_PARSE_LOCAL): New flag.
* libmailutils/tests/url-parse.c (parse_kwtab): New flag
"local".
* libmailutils/tests/url.at: Add new tests
* libmailutils/url/create.c (_mu_url_ctx_parse_host): Skip
parsing host part if MU_URL_PARSE_LOCAL is set.
(_mu_url_create_internal): Initialize rc. If MU_URL_PARSE_SLASH
is set and URL begins with "./" assume it is file.
If either MU_URL_PARSE_SLASH or MU_URL_PARSE_PIPE are given
and the URL is diagnosed as file or pipe, prever the scheme
from hints.
1 parent 8c0c0bfc
......@@ -61,6 +61,7 @@ extern "C" {
"file:///..." */
#define MU_URL_PARSE_DSLASH_OPTIONAL 0x0040 /* Double-slash after scheme:
part is optional */
#define MU_URL_PARSE_LOCAL 0x0080 /* Local URL: no host part */
#define MU_URL_PARSE_DEFAULT \
(MU_URL_PARSE_HEXCODE|MU_URL_PARSE_HIDEPASS|MU_URL_PARSE_PORTSRV|\
......
......@@ -83,6 +83,7 @@ struct mu_kwd parse_kwtab[] = {
{ "slash", MU_URL_PARSE_SLASH },
{ "dslash_optional", MU_URL_PARSE_DSLASH_OPTIONAL },
{ "default", MU_URL_PARSE_DEFAULT },
{ "local", MU_URL_PARSE_LOCAL },
{ "all", MU_URL_PARSE_ALL },
{ NULL }
};
......
......@@ -806,6 +806,44 @@ port 0
path </var/spool/mail/gray%40gnu.org>
])
m4_pushdef([URL_PARSE_OPTIONS],[slash])
TESTURL([],[],
[./file.db],
[scheme <file>
user <>
passwd <>
auth <>
host <>
port 0
path <./file.db>
])
m4_define([URL_PARSE_OPTIONS],[slash hint=gdbm://])
TESTURL([(gdbm) ./file.db],[],
[./file.db],
[scheme <gdbm>
user <>
passwd <>
auth <>
host <>
port 0
path <./file.db>
])
m4_popdef([URL_PARSE_OPTIONS])
m4_pushdef([URL_PARSE_OPTIONS],[local hint=db://])
TESTURL([],[],
[local],
[scheme <db>
user <>
passwd <>
auth <>
host <>
port 0
path <local>
])
m4_popdef([URL_PARSE_OPTIONS])
TESTURL([],[],
[| /bin/mailman request list%40dom],
[[scheme <prog>
......@@ -819,6 +857,21 @@ query[0] <request>
query[1] <list%40dom>
]])
m4_pushdef([URL_PARSE_OPTIONS],[pipe hint=ext://])
TESTURL([(ext) | /bin/mailman request list%40dom],[],
[| /bin/mailman request list%40dom],
[[scheme <ext>
user <>
passwd <>
auth <>
host <>
port 0
path </bin/mailman>
query[0] <request>
query[1] <list%40dom>
]])
m4_popdef([URL_PARSE_OPTIONS])
TESTURL([],[],
[prog:///bin/mailman?request&list%40dom],
[[scheme <prog>
......
......@@ -220,6 +220,9 @@ _mu_url_ctx_parse_host (struct mu_url_ctx *ctx, int has_host)
int rc;
mu_url_t url = ctx->url;
if (ctx->flags & MU_URL_PARSE_LOCAL)
return _mu_url_ctx_parse_path (ctx);
rc = getkn (ctx, "[:/;?");
if (rc)
return rc;
......@@ -400,18 +403,16 @@ _mu_url_ctx_parse (struct mu_url_ctx *ctx)
static int
_mu_url_create_internal (struct mu_url_ctx *ctx, mu_url_t hint)
{
int rc;
int rc = 0;
mu_url_t url = ctx->url;
const char *scheme = NULL;
if ((ctx->flags & MU_URL_PARSE_PIPE) && ctx->input[0] == '|')
{
struct mu_wordsplit ws;
size_t i;
rc = str_assign (&url->scheme, "prog");
if (rc)
return rc;
url->flags |= MU_URL_SCHEME;
scheme = "prog";
ctx->flags &= ~MU_URL_PARSE_HEXCODE;
if (mu_wordsplit (ctx->input + 1, &ws, MU_WRDSF_DEFFLAGS))
return errno;
......@@ -431,12 +432,11 @@ _mu_url_create_internal (struct mu_url_ctx *ctx, mu_url_t hint)
mu_wordsplit_free (&ws);
url->flags |= MU_URL_QUERY;
}
else if ((ctx->flags & MU_URL_PARSE_SLASH) && ctx->input[0] == '/')
else if ((ctx->flags & MU_URL_PARSE_SLASH) &&
(ctx->input[0] == '/' ||
(ctx->input[0] == '.' && ctx->input[1] == '/')))
{
rc = str_assign (&url->scheme, "file");
if (rc)
return rc;
url->flags |= MU_URL_SCHEME;
scheme = "file";
ctx->flags &= ~MU_URL_PARSE_HEXCODE;
rc = str_assign (&url->path, ctx->input);
if (rc == 0)
......@@ -457,7 +457,17 @@ _mu_url_create_internal (struct mu_url_ctx *ctx, mu_url_t hint)
}
if (!(url->flags & MU_URL_SCHEME))
return MU_ERR_URL_MISS_PARTS;
{
if (scheme)
{
rc = str_assign (&url->scheme, scheme);
if (rc)
return rc;
url->flags |= MU_URL_SCHEME;
}
else
return MU_ERR_URL_MISS_PARTS;
}
/* RFC 1738, section 2.1, lower the scheme case */
mu_strlower (url->scheme);
......