Sat, 26 Oct 2019 12:38:33 +0200
adds support for quotes in dav bash completion
* add: url2repo_s()
* add: util_url_base_s()
* change: url2repo() is now wrapper for url2repo_s()
* change: util_url_base() is now wrapper for util_url_base_s()
dav/main.c | file | annotate | diff | comparison | revisions | |
libidav/utils.c | file | annotate | diff | comparison | revisions | |
libidav/utils.h | file | annotate | diff | comparison | revisions | |
scripts/dav-bash-completion.bash | file | annotate | diff | comparison | revisions |
--- a/dav/main.c Sat Oct 26 11:32:27 2019 +0200 +++ b/dav/main.c Sat Oct 26 12:38:33 2019 +0200 @@ -345,31 +345,24 @@ return 0; } -static Repository* url2repo(char *url, char **path) { - size_t ulen = strlen(url); +static Repository* url2repo_s(sstr_t url, char **path) { *path = NULL; int s; - if(ulen > 7 && !strncasecmp(url, "http://", 7)) { + if(sstrprefix(url, SC("http://"))) { s = 7; - } else if(ulen > 8 && !strncasecmp(url, "https://", 8)) { + } else if(sstrprefix(url, SC("https://"))) { s = 8; } else { s = 1; } - - sstr_t r = sstr(url); - sstr_t p = sstr("/"); - for(int i=s;i<ulen;i++) { - char c = url[i]; - if(c == '/') { - r = sstrn(url, i); - p = sstrsubs(sstr(url), i); - if(p.length == 0) { - p = sstrn("/", 1); - } - break; - } + + // split URL into repository and path + sstr_t r = sstrsubs(url, s); + sstr_t p = sstrchr(r, '/'); + r = sstrsubsl(url, 0, url.length-p.length); + if(p.length == 0) { + p = sstrn("/", 1); } Repository *repo = get_repository(r); @@ -383,14 +376,18 @@ repo->decrypt_content = true; repo->verification = true; repo->authmethods = CURLAUTH_BASIC; - if(url[ulen-1] == '/') { - repo->url = strdup(url); + if(url.ptr[url.length-1] == '/') { + repo->url = sstrdup(url).ptr; *path = strdup("/"); - } else if (strchr(url, '/')) { - repo->url = util_url_base(url); - *path = strdup(util_url_path(url)); + } else if (sstrchr(url, '/').length > 0) { + // TODO: fix the following workaround after + // fixing the inconsistent behavior of util_url_*() + repo->url = util_url_base_s(url); + sstr_t truncated = sstrdup(url); + *path = strdup(util_url_path(truncated.ptr)); + free(truncated.ptr); } else { - repo->url = strdup(url); + repo->url = sstrdup(url).ptr; *path = strdup("/"); } } @@ -398,6 +395,10 @@ return repo; } +static Repository* url2repo(char *url, char **path) { + return url2repo_s(sstr(url), path); +} + static int set_session_config(DavSession *sn, CmdArgs *a) { char *plain = cmd_getoption(a, "plain"); char *crypt = cmd_getoption(a, "crypt"); @@ -3042,7 +3043,6 @@ //printf("dav: {%s}\n", args->argv[1]); //printf("cmd: {%s}\n", cmd); //printf("url: {%s}\n", url); - //printf("file: {%s}\n", file); if(index == 2) { // url completion @@ -3060,11 +3060,27 @@ return 0; } -int url_completion(char *u) { +int url_completion(char *u) { sstr_t url; url.ptr = u; url.length = u ? strlen(u) : 0; + // if the user wants the URL to be quoted, we conform to their wish + // a null-char is an indicator, that the strings shall not be quoted + char quote = '\0'; + if(url.length > 0 && (url.ptr[0] == '\'' || url.ptr[0] == '\"' )) { + quote = url.ptr[0]; + + // for completing the url, we want to proceed without the quote + url.ptr++; + url.length--; + + // the user may have also prepared the ending quote, remove it for now + if (url.ptr[url.length-1] == quote) { + url.length--; + } + } + // repo completion int repocomp = 1; for(int i=0;i<url.length;i++) { @@ -3078,7 +3094,11 @@ UCX_FOREACH(elm, repos) { Repository *repo = elm->data; if(sstrprefix(sstr(repo->name), url)) { - printf("%s/\n", repo->name); + if(quote == '\0') { + printf("%s/\n", repo->name); + } else { + printf("%c%s/%c\n", quote, repo->name, quote); + } } } @@ -3091,7 +3111,7 @@ ucx_map_cstr_put(a.options, "noinput", ""); char *path = NULL; - Repository *repo = url2repo(u, &path); + Repository *repo = url2repo_s(url, &path); DavSession *sn = connect_to_repo(repo, path, &a); ucx_map_free(a.options); if(!sn) { @@ -3128,7 +3148,8 @@ if(space) { size_t l = strlen(elm->path); for(int i=0;i<l;i++) { - if(elm->path[i] == ' ') { + // only if we do not quote, we have to escape spaces + if(elm->path[i] == ' ' && quote == '\0') { ucx_buffer_puts(out, "\\ "); } else { ucx_buffer_putc(out, elm->path[i]); @@ -3142,7 +3163,12 @@ ucx_buffer_putc(out, '/'); } } - printf("%.*s\n", (int)out->pos, out->space); + if (quote == '\0') { + printf("%.*s\n", (int)out->pos, out->space); + } else { + printf("%c%.*s%c\n", + quote, (int)out->pos, out->space, quote); + } ucx_buffer_free(out); }
--- a/libidav/utils.c Sat Oct 26 11:32:27 2019 +0200 +++ b/libidav/utils.c Sat Oct 26 12:38:33 2019 +0200 @@ -273,36 +273,37 @@ } } -char* util_url_base(char *url) { - sstr_t u = sstr(url); - int len = u.length; - int slashcount = 0; - int slmax; - if(len > 7 && !strncasecmp(url, "http://", 7)) { - slmax = 3; - } else if(len > 8 && !strncasecmp(url, "https://", 8)) { - slmax = 3; - } else { - slmax = 1; - } - char c; - int i = 0; - for(i=0;i<len;i++) { - c = url[i]; - if(c == '/') { - slashcount++; - if(slashcount == slmax) { - i++; - break; +char* util_url_base_s(sstr_t url) { + size_t i = 0; + if(url.length > 0) { + int slmax; + if(sstrprefix(url, SC("http://"))) { + slmax = 3; + } else if(sstrprefix(url, SC("https://"))) { + slmax = 3; + } else { + slmax = 1; + } + int slashcount = 0; + for(i=0;i<url.length;i++) { + if(url.ptr[i] == '/') { + slashcount++; + if(slashcount == slmax) { + i++; + break; + } } } - } - sstr_t server = sstrsubsl(u, 0, i); - server = sstrdup(server); - return server.ptr; + } + sstr_t server = sstrsubsl(url, 0, i); + return sstrdup(server).ptr; } -char* util_url_path(char *url) { +char* util_url_base(char *url) { + return util_url_base_s(sstr(url)); +} + +char* util_url_path(char *url) { char *path = NULL; size_t len = strlen(url); int slashcount = 0;
--- a/libidav/utils.h Sat Oct 26 11:32:27 2019 +0200 +++ b/libidav/utils.h Sat Oct 26 12:38:33 2019 +0200 @@ -65,6 +65,7 @@ int util_mkdir(char *path, mode_t mode); char* util_url_base(char *url); +char* util_url_base_s(sstr_t url); char* util_url_path(char *url); char* util_url_decode(DavSession *sn, char *url); char* util_resource_name(char *url);
--- a/scripts/dav-bash-completion.bash Sat Oct 26 11:32:27 2019 +0200 +++ b/scripts/dav-bash-completion.bash Sat Oct 26 12:38:33 2019 +0200 @@ -1,16 +1,14 @@ dav_completion() { - local davcmd local out local cmd_res - davcmd="${COMP_WORDS[0]} complete $COMP_CWORD ${COMP_WORDS[@]}" - out=$(eval $davcmd) + out="$(${COMP_WORDS[0]} complete $COMP_CWORD ${COMP_WORDS[@]})" cmd_res=$? - if [ $cmd_res == 10 ]; then + if [[ $cmd_res -eq 10 ]]; then compopt -o nospace fi - if [ $cmd_res == 12 ]; then + if [[ $cmd_res -eq 12 ]]; then compopt -o default COMPREPLY=() else