adds support for quotes in dav bash completion

Sat, 26 Oct 2019 12:38:33 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 26 Oct 2019 12:38:33 +0200
changeset 673
8e7e56cfc103
parent 672
4bfe452a2665
child 674
92bf06a65d08

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

mercurial