Fix bug concerning urls with spaces
This commit is contained in:
parent
d12d77382e
commit
5b849d6ff3
@ -1,6 +1,11 @@
|
||||
ChangeLog for davfs2
|
||||
--------------------
|
||||
|
||||
2009-04-26 Werner Baumann (werner.baumann@onlinehome.de)
|
||||
* mount_davfs.c:
|
||||
New function split_uri; allow arbitrary characters
|
||||
in path component, including spaces.
|
||||
|
||||
2009-04-14 Werner Baumann (werner.baumann@onlinehome.de)
|
||||
* Reverted to fuse_kernel.h from 2.5.3 because of
|
||||
different length of struct fuse_attr.
|
||||
|
@ -48,12 +48,11 @@ using the \fI\-t davfs\fP option. After mounting it runs as a daemon. To unmount
|
||||
the \fBumount\fR(8) command is used.
|
||||
|
||||
.PP
|
||||
\fIwebdavserver\fP must be a complete url, including scheme, fully qualified
|
||||
domain name and path. Scheme may be \fBhttp\fR or \fBhttps\fR. If the path
|
||||
contains spaces or other characters, that might be interpreted by the shell,
|
||||
the url must be enclosed in double quotes
|
||||
(e.g. \fI"http://foo.bar/name with spaces"\fP). See \fBURLS AND MOUNT POINTS
|
||||
WITH SPACES\fR.
|
||||
\fIwebdavserver\fP is the URI of the server. It must at least contain the
|
||||
host name. It may additionally contain the scheme, the port and the path.
|
||||
Missing components are set to sensible default values. The path component must
|
||||
\fBnot\fR be %-encoded, but when entering the URI at the command line or in
|
||||
/etc/fstab the escaping rules of the shell or fstab must be obeyed.
|
||||
|
||||
.PP
|
||||
\fIdir\fP is the mountpoint where the WebDAV resource is mounted on.
|
||||
|
@ -191,6 +191,9 @@ ignore_home(const char *name, const char *ignore_list);
|
||||
static dav_args *
|
||||
new_args(void);
|
||||
|
||||
static void
|
||||
log_dbg_cmdline(char *argv[]);
|
||||
|
||||
static void
|
||||
log_dbg_config(char *argv[], dav_args *args);
|
||||
|
||||
@ -209,8 +212,8 @@ read_no_proxy_list(dav_args *args);
|
||||
static void
|
||||
read_secrets(dav_args *args, const char *filename);
|
||||
|
||||
static void
|
||||
split_proxy(char **host, int *port, const char *arg);
|
||||
static int
|
||||
split_uri(char **scheme, char **host, int *port,char **path, const char *uri);
|
||||
|
||||
static void
|
||||
usage(void);
|
||||
@ -910,6 +913,7 @@ is_mounted(void)
|
||||
static dav_args *
|
||||
parse_commandline(int argc, char *argv[])
|
||||
{
|
||||
log_dbg_cmdline(argv);
|
||||
dav_args *args = new_args();
|
||||
|
||||
char *short_options = "vwVho:";
|
||||
@ -976,35 +980,11 @@ parse_commandline(int argc, char *argv[])
|
||||
|
||||
if (!url)
|
||||
error(EXIT_FAILURE, 0, _("no WebDAV-server specified"));
|
||||
ne_uri *uri = (ne_uri *) ne_malloc(sizeof(ne_uri));
|
||||
if (ne_uri_parse(url, uri) != 0 || !uri->host || !uri->path)
|
||||
if (split_uri(&args->scheme, &args->host, &args->port, &args->path,
|
||||
url) != 0)
|
||||
error(EXIT_FAILURE, 0, _("invalid URL"));
|
||||
|
||||
if (uri->scheme) {
|
||||
args->scheme = uri->scheme;
|
||||
uri->scheme = NULL;
|
||||
} else {
|
||||
args->scheme = ne_strdup("http");
|
||||
}
|
||||
|
||||
args->host = uri->host;
|
||||
uri->host = NULL;
|
||||
if (uri->port) {
|
||||
args->port = uri->port;
|
||||
} else {
|
||||
if (!args->port)
|
||||
args->port = ne_uri_defaultport(args->scheme);
|
||||
}
|
||||
|
||||
if (strlen(uri->path) < 1
|
||||
|| *(uri->path + strlen(uri->path) -1) != '/') {
|
||||
args->path = ne_concat(uri->path, "/", NULL);
|
||||
} else {
|
||||
args->path = uri->path;
|
||||
uri->path = NULL;
|
||||
}
|
||||
|
||||
ne_uri_free(uri);
|
||||
free(uri);
|
||||
|
||||
return args;
|
||||
}
|
||||
@ -1786,7 +1766,7 @@ new_args(void)
|
||||
|
||||
|
||||
static void
|
||||
log_dbg_config(char *argv[], dav_args *args)
|
||||
log_dbg_cmdline(char *argv[])
|
||||
{
|
||||
size_t len;
|
||||
char *cmdline;
|
||||
@ -1795,7 +1775,12 @@ log_dbg_config(char *argv[], dav_args *args)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), cmdline);
|
||||
free(cmdline);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
log_dbg_config(char *argv[], dav_args *args)
|
||||
{
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
"Configuration:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
@ -2070,27 +2055,21 @@ proxy_from_env(dav_args *args)
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
char *proxy;
|
||||
if (strstr(env, "://") == NULL) {
|
||||
proxy = ne_concat("http://", env, NULL);
|
||||
} else {
|
||||
proxy = ne_strdup(env);
|
||||
char *scheme = NULL;
|
||||
char *host = NULL;
|
||||
int port = 0;
|
||||
split_uri(&scheme, &host, &port, NULL, env);
|
||||
|
||||
if (scheme && strcmp(scheme, "http") == 0 && host) {
|
||||
if (args->p_host) free(args->p_host);
|
||||
args->p_host = host;
|
||||
host = NULL;
|
||||
if (port)
|
||||
args->p_port = port;
|
||||
}
|
||||
|
||||
ne_uri *uri = (ne_uri *) ne_malloc(sizeof(ne_uri));
|
||||
if (ne_uri_parse(proxy, uri) == 0 && uri->host
|
||||
&& (!uri->scheme || strcmp(uri->scheme, "http") == 0)) {
|
||||
if (args->p_host)
|
||||
free(args->p_host);
|
||||
args->p_host = uri->host;
|
||||
uri->host = NULL;
|
||||
if (uri->port)
|
||||
args->p_port = uri->port;
|
||||
}
|
||||
|
||||
ne_uri_free(uri);
|
||||
free(uri);
|
||||
free(proxy);
|
||||
if (scheme) free(scheme);
|
||||
if (host) free(host);
|
||||
}
|
||||
|
||||
|
||||
@ -2163,9 +2142,10 @@ read_config(dav_args *args, const char * filename, int system)
|
||||
free(args->clicert);
|
||||
args->clicert = ne_strdup(parmv[1]);
|
||||
} else if (system && strcmp(parmv[0], "proxy") == 0) {
|
||||
if (args->p_host)
|
||||
free(args->p_host);
|
||||
split_proxy(&args->p_host, &args->p_port, parmv[1]);
|
||||
if (split_uri(NULL, &args->p_host, &args->p_port, NULL,
|
||||
parmv[1]) != 0)
|
||||
error_at_line(EXIT_FAILURE, 0, filename, lineno,
|
||||
_("malformed line"));
|
||||
} else if (system && strcmp(parmv[0], "use_proxy") == 0) {
|
||||
args->useproxy = arg_to_int(parmv[1], 10, parmv[0]);
|
||||
} else if (strcmp(parmv[0], "ask_auth") == 0) {
|
||||
@ -2357,26 +2337,11 @@ read_secrets(dav_args *args, const char *filename)
|
||||
|
||||
if (count == 2 || count == 3) {
|
||||
|
||||
char *phost = NULL;
|
||||
int pport = 0;
|
||||
split_proxy(&phost, &pport, parmv[0]);
|
||||
|
||||
ne_uri *uri = (ne_uri *) ne_malloc(sizeof(ne_uri));
|
||||
if (!uri) abort();
|
||||
if (ne_uri_parse(parmv[0], uri) == 0 && uri->host && uri->path) {
|
||||
if (!uri->port)
|
||||
uri->port = ne_uri_defaultport(args->scheme);
|
||||
if (strlen(uri->path) < 1
|
||||
|| *(uri->path + strlen(uri->path) -1) != '/') {
|
||||
char *tmp = ne_concat(uri->path, "/", NULL);
|
||||
free(uri->path);
|
||||
uri->path = tmp;
|
||||
}
|
||||
} else {
|
||||
ne_uri_free(uri);
|
||||
free(uri);
|
||||
uri = NULL;
|
||||
}
|
||||
char *scheme = NULL;
|
||||
char *host = NULL;
|
||||
int port = 0;
|
||||
char *path = 0;
|
||||
split_uri(&scheme, &host, &port, &path, parmv[0]);
|
||||
|
||||
char *ccert = NULL;
|
||||
if (args->clicert) {
|
||||
@ -2391,11 +2356,12 @@ read_secrets(dav_args *args, const char *filename)
|
||||
|| (mpoint && strstr(parmv[0], mpoint) == parmv[0]
|
||||
&& *(parmv[0] + strlen(mpoint)) == '/'
|
||||
&& *(parmv[0] + strlen(mpoint) + 1) == '\0')
|
||||
|| (uri && args->scheme && args->host && args->path
|
||||
&& strcmp(uri->scheme, args->scheme) == 0
|
||||
&& strcmp(uri->host, args->host) == 0
|
||||
&& uri->port == args->port
|
||||
&& strcmp(uri->path, args->path) == 0)) {
|
||||
|| (scheme && args->scheme
|
||||
&& strcmp(scheme, args->scheme) == 0
|
||||
&& host && args->host && strcmp(host, args->host) == 0
|
||||
&& port == args->port
|
||||
&& path && args->path
|
||||
&& strcmp(path, args->path) == 0)) {
|
||||
|
||||
if (args->username) {
|
||||
memset(args->username, '\0', strlen(args->username));
|
||||
@ -2410,9 +2376,9 @@ read_secrets(dav_args *args, const char *filename)
|
||||
args->password = ne_strdup(parmv[2]);
|
||||
|
||||
} else if (strcmp(parmv[0], "proxy") == 0
|
||||
|| (args->p_host && phost
|
||||
&& strcmp(phost, args->p_host) == 0
|
||||
&& (!pport || pport == args->p_port))) {
|
||||
|| (host && args->p_host
|
||||
&& strcmp(host, args->p_host) == 0
|
||||
&& (!port || port == args->p_port))) {
|
||||
|
||||
if (args->p_user) {
|
||||
memset(args->p_user, '\0', strlen(args->p_user));
|
||||
@ -2440,12 +2406,9 @@ read_secrets(dav_args *args, const char *filename)
|
||||
args->clicert_pw = ne_strdup(parmv[1]);
|
||||
}
|
||||
|
||||
if (uri) {
|
||||
ne_uri_free(uri);
|
||||
free(uri);
|
||||
}
|
||||
if (phost)
|
||||
free(phost);
|
||||
if (scheme) free(scheme);
|
||||
if (host) free(host);
|
||||
if (path) free(path);
|
||||
}
|
||||
|
||||
for (parmc = 0; parmc < count; parmc++) {
|
||||
@ -2465,24 +2428,107 @@ read_secrets(dav_args *args, const char *filename)
|
||||
}
|
||||
|
||||
|
||||
/* Splits arg into hostname and port if there is a colon in arg. If there is no
|
||||
colon, arg is taken als hostname, and port is set to DAV_DEFAULT_PROXY_PORT.
|
||||
The string host will be newly allacoated. The calling function is
|
||||
responsible to free it.
|
||||
host : A pointer to a string to return the hostname.
|
||||
port : A pointer to an integer to return the port number.
|
||||
arg : the string to be split. */
|
||||
static void
|
||||
split_proxy(char **host, int *port, const char *arg)
|
||||
/* Splits an uri and returns the components.
|
||||
The uri must contain a host, the other components are optional. It must
|
||||
not contain userinfo. It shall not contain a query or fragment component;
|
||||
they would be treated as part of path.
|
||||
The path component must *not* be %-encoded. scheme, if present in uri,
|
||||
must be either http or https. If host is a IPv6 address, it must be enclosed
|
||||
in square brackets.
|
||||
The pointers to the components may be NULL. If they point to a non-NULL
|
||||
string, it is freed and then replaced by a newly allocated string.
|
||||
If no scheme is foud the default sheme "http" is returned.
|
||||
If no path is foud "/" is returned as path. path will always end with "/".
|
||||
There is *no* default value returned for port.
|
||||
return value : 0 on success, -1 otherwise. */
|
||||
static int
|
||||
split_uri(char **scheme, char **host, int *port,char **path, const char *uri)
|
||||
{
|
||||
char *ps = strchr(arg, ':');
|
||||
if (!ps) {
|
||||
*host = ne_strdup(arg);
|
||||
if (!uri || !*uri) return -1;
|
||||
|
||||
const char *sch = NULL;
|
||||
int po = 0;
|
||||
const char *ho = strstr(uri, "://");
|
||||
if (ho) {
|
||||
if ((ho - uri) == 4 && strcasestr(uri, "http") == uri) {
|
||||
sch = "http";
|
||||
} else if ((ho - uri) == 5 && strcasestr(uri, "https") == uri) {
|
||||
sch = "https";
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
ho += 3;
|
||||
} else {
|
||||
*host = ne_strndup(arg, strlen(arg) - strlen(ps));
|
||||
ps++;
|
||||
*port = arg_to_int(ps, 10, "proxy:port");
|
||||
ho = uri;
|
||||
}
|
||||
if (!*ho) return -1;
|
||||
|
||||
const char *pa = strchrnul(ho, '/');
|
||||
if (pa == ho) return -1;
|
||||
|
||||
const char *end = strchr(ho, '@');
|
||||
if (end && end < pa) return -1;
|
||||
|
||||
if (*ho == '[') {
|
||||
end = strchr(ho, ']');
|
||||
if (!end || end >= pa) return -1;
|
||||
end++;
|
||||
} else {
|
||||
end = strchr(ho, ':');
|
||||
if (!end)
|
||||
end = pa;
|
||||
}
|
||||
|
||||
if (end < pa) {
|
||||
if (end == ho || end == (pa - 1) || *end != ':') return -1;
|
||||
char *tail = NULL;
|
||||
po = strtol(end + 1, &tail, 10);
|
||||
if (po <= 0 || tail != pa) return -1;
|
||||
}
|
||||
|
||||
if (scheme) {
|
||||
if (*scheme) free(*scheme);
|
||||
if (sch) {
|
||||
*scheme = strdup(sch);
|
||||
} else {
|
||||
*scheme = strdup("http");
|
||||
}
|
||||
if (!*scheme) abort();
|
||||
}
|
||||
|
||||
if (port && po)
|
||||
*port = po;
|
||||
|
||||
if (host) {
|
||||
if (*host) free(*host);
|
||||
*host = malloc(end - ho + 1);
|
||||
if (!*host) abort();
|
||||
int i;
|
||||
for (i = 0; i < (end - ho); i++) {
|
||||
if (*ho == '[') {
|
||||
*(*host + i) = islower(*(ho + i))
|
||||
? toupper(*(ho + i)) : *(ho + i);
|
||||
} else {
|
||||
*(*host + i) = isupper(*(ho + i))
|
||||
? tolower(*(ho + i)) : *(ho + i);
|
||||
}
|
||||
}
|
||||
*(*host + i) = '\0';
|
||||
}
|
||||
|
||||
if (path) {
|
||||
if (*path) free(*path);
|
||||
if (!*pa) {
|
||||
*path = strdup("/");
|
||||
} else if (*(pa + strlen(pa) - 1) == '/') {
|
||||
*path = strdup(pa);
|
||||
} else {
|
||||
if (asprintf(path, "%s/", pa) < 1) abort();
|
||||
}
|
||||
if (!*path) abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user