dav/main.c

changeset 673
8e7e56cfc103
parent 655
4d33b672c33a
child 674
92bf06a65d08
--- 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);
             }

mercurial