343 free(password); |
343 free(password); |
344 |
344 |
345 return 0; |
345 return 0; |
346 } |
346 } |
347 |
347 |
348 static Repository* url2repo(char *url, char **path) { |
348 static Repository* url2repo_s(sstr_t url, char **path) { |
349 size_t ulen = strlen(url); |
|
350 *path = NULL; |
349 *path = NULL; |
351 |
350 |
352 int s; |
351 int s; |
353 if(ulen > 7 && !strncasecmp(url, "http://", 7)) { |
352 if(sstrprefix(url, SC("http://"))) { |
354 s = 7; |
353 s = 7; |
355 } else if(ulen > 8 && !strncasecmp(url, "https://", 8)) { |
354 } else if(sstrprefix(url, SC("https://"))) { |
356 s = 8; |
355 s = 8; |
357 } else { |
356 } else { |
358 s = 1; |
357 s = 1; |
359 } |
358 } |
360 |
359 |
361 sstr_t r = sstr(url); |
360 // split URL into repository and path |
362 sstr_t p = sstr("/"); |
361 sstr_t r = sstrsubs(url, s); |
363 for(int i=s;i<ulen;i++) { |
362 sstr_t p = sstrchr(r, '/'); |
364 char c = url[i]; |
363 r = sstrsubsl(url, 0, url.length-p.length); |
365 if(c == '/') { |
364 if(p.length == 0) { |
366 r = sstrn(url, i); |
365 p = sstrn("/", 1); |
367 p = sstrsubs(sstr(url), i); |
|
368 if(p.length == 0) { |
|
369 p = sstrn("/", 1); |
|
370 } |
|
371 break; |
|
372 } |
|
373 } |
366 } |
374 |
367 |
375 Repository *repo = get_repository(r); |
368 Repository *repo = get_repository(r); |
376 if(repo) { |
369 if(repo) { |
377 *path = sstrdup(p).ptr; |
370 *path = sstrdup(p).ptr; |
381 repo = calloc(1, sizeof(Repository)); |
374 repo = calloc(1, sizeof(Repository)); |
382 repo->name = strdup(""); |
375 repo->name = strdup(""); |
383 repo->decrypt_content = true; |
376 repo->decrypt_content = true; |
384 repo->verification = true; |
377 repo->verification = true; |
385 repo->authmethods = CURLAUTH_BASIC; |
378 repo->authmethods = CURLAUTH_BASIC; |
386 if(url[ulen-1] == '/') { |
379 if(url.ptr[url.length-1] == '/') { |
387 repo->url = strdup(url); |
380 repo->url = sstrdup(url).ptr; |
388 *path = strdup("/"); |
381 *path = strdup("/"); |
389 } else if (strchr(url, '/')) { |
382 } else if (sstrchr(url, '/').length > 0) { |
390 repo->url = util_url_base(url); |
383 // TODO: fix the following workaround after |
391 *path = strdup(util_url_path(url)); |
384 // fixing the inconsistent behavior of util_url_*() |
|
385 repo->url = util_url_base_s(url); |
|
386 sstr_t truncated = sstrdup(url); |
|
387 *path = strdup(util_url_path(truncated.ptr)); |
|
388 free(truncated.ptr); |
392 } else { |
389 } else { |
393 repo->url = strdup(url); |
390 repo->url = sstrdup(url).ptr; |
394 *path = strdup("/"); |
391 *path = strdup("/"); |
395 } |
392 } |
396 } |
393 } |
397 |
394 |
398 return repo; |
395 return repo; |
|
396 } |
|
397 |
|
398 static Repository* url2repo(char *url, char **path) { |
|
399 return url2repo_s(sstr(url), path); |
399 } |
400 } |
400 |
401 |
401 static int set_session_config(DavSession *sn, CmdArgs *a) { |
402 static int set_session_config(DavSession *sn, CmdArgs *a) { |
402 char *plain = cmd_getoption(a, "plain"); |
403 char *plain = cmd_getoption(a, "plain"); |
403 char *crypt = cmd_getoption(a, "crypt"); |
404 char *crypt = cmd_getoption(a, "crypt"); |
3040 |
3041 |
3041 //printf("index: {%s}\n", args->argv[0]); |
3042 //printf("index: {%s}\n", args->argv[0]); |
3042 //printf("dav: {%s}\n", args->argv[1]); |
3043 //printf("dav: {%s}\n", args->argv[1]); |
3043 //printf("cmd: {%s}\n", cmd); |
3044 //printf("cmd: {%s}\n", cmd); |
3044 //printf("url: {%s}\n", url); |
3045 //printf("url: {%s}\n", url); |
3045 //printf("file: {%s}\n", file); |
|
3046 |
3046 |
3047 if(index == 2) { |
3047 if(index == 2) { |
3048 // url completion |
3048 // url completion |
3049 return url_completion(url); |
3049 return url_completion(url); |
3050 } else if (index == 3) { |
3050 } else if (index == 3) { |
3058 } |
3058 } |
3059 |
3059 |
3060 return 0; |
3060 return 0; |
3061 } |
3061 } |
3062 |
3062 |
3063 int url_completion(char *u) { |
3063 int url_completion(char *u) { |
3064 sstr_t url; |
3064 sstr_t url; |
3065 url.ptr = u; |
3065 url.ptr = u; |
3066 url.length = u ? strlen(u) : 0; |
3066 url.length = u ? strlen(u) : 0; |
|
3067 |
|
3068 // if the user wants the URL to be quoted, we conform to their wish |
|
3069 // a null-char is an indicator, that the strings shall not be quoted |
|
3070 char quote = '\0'; |
|
3071 if(url.length > 0 && (url.ptr[0] == '\'' || url.ptr[0] == '\"' )) { |
|
3072 quote = url.ptr[0]; |
|
3073 |
|
3074 // for completing the url, we want to proceed without the quote |
|
3075 url.ptr++; |
|
3076 url.length--; |
|
3077 |
|
3078 // the user may have also prepared the ending quote, remove it for now |
|
3079 if (url.ptr[url.length-1] == quote) { |
|
3080 url.length--; |
|
3081 } |
|
3082 } |
3067 |
3083 |
3068 // repo completion |
3084 // repo completion |
3069 int repocomp = 1; |
3085 int repocomp = 1; |
3070 for(int i=0;i<url.length;i++) { |
3086 for(int i=0;i<url.length;i++) { |
3071 if(url.ptr[i] == '/') { |
3087 if(url.ptr[i] == '/') { |
3076 if(repocomp) { |
3092 if(repocomp) { |
3077 UcxList *repos = get_repositories(); |
3093 UcxList *repos = get_repositories(); |
3078 UCX_FOREACH(elm, repos) { |
3094 UCX_FOREACH(elm, repos) { |
3079 Repository *repo = elm->data; |
3095 Repository *repo = elm->data; |
3080 if(sstrprefix(sstr(repo->name), url)) { |
3096 if(sstrprefix(sstr(repo->name), url)) { |
3081 printf("%s/\n", repo->name); |
3097 if(quote == '\0') { |
|
3098 printf("%s/\n", repo->name); |
|
3099 } else { |
|
3100 printf("%c%s/%c\n", quote, repo->name, quote); |
|
3101 } |
3082 } |
3102 } |
3083 |
3103 |
3084 } |
3104 } |
3085 } else { |
3105 } else { |
3086 // url completion |
3106 // url completion |
3089 memset(&a, 0, sizeof(CmdArgs)); |
3109 memset(&a, 0, sizeof(CmdArgs)); |
3090 a.options = ucx_map_new(4); |
3110 a.options = ucx_map_new(4); |
3091 ucx_map_cstr_put(a.options, "noinput", ""); |
3111 ucx_map_cstr_put(a.options, "noinput", ""); |
3092 |
3112 |
3093 char *path = NULL; |
3113 char *path = NULL; |
3094 Repository *repo = url2repo(u, &path); |
3114 Repository *repo = url2repo_s(url, &path); |
3095 DavSession *sn = connect_to_repo(repo, path, &a); |
3115 DavSession *sn = connect_to_repo(repo, path, &a); |
3096 ucx_map_free(a.options); |
3116 ucx_map_free(a.options); |
3097 if(!sn) { |
3117 if(!sn) { |
3098 return 0; |
3118 return 0; |
3099 } |
3119 } |
3126 UcxBuffer *out = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); |
3146 UcxBuffer *out = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); |
3127 ucx_buffer_puts(out, repo->name); |
3147 ucx_buffer_puts(out, repo->name); |
3128 if(space) { |
3148 if(space) { |
3129 size_t l = strlen(elm->path); |
3149 size_t l = strlen(elm->path); |
3130 for(int i=0;i<l;i++) { |
3150 for(int i=0;i<l;i++) { |
3131 if(elm->path[i] == ' ') { |
3151 // only if we do not quote, we have to escape spaces |
|
3152 if(elm->path[i] == ' ' && quote == '\0') { |
3132 ucx_buffer_puts(out, "\\ "); |
3153 ucx_buffer_puts(out, "\\ "); |
3133 } else { |
3154 } else { |
3134 ucx_buffer_putc(out, elm->path[i]); |
3155 ucx_buffer_putc(out, elm->path[i]); |
3135 } |
3156 } |
3136 } |
3157 } |
3140 if(elm->iscollection) { |
3161 if(elm->iscollection) { |
3141 if(out->space[out->pos-1] != '/') { |
3162 if(out->space[out->pos-1] != '/') { |
3142 ucx_buffer_putc(out, '/'); |
3163 ucx_buffer_putc(out, '/'); |
3143 } |
3164 } |
3144 } |
3165 } |
3145 printf("%.*s\n", (int)out->pos, out->space); |
3166 if (quote == '\0') { |
|
3167 printf("%.*s\n", (int)out->pos, out->space); |
|
3168 } else { |
|
3169 printf("%c%.*s%c\n", |
|
3170 quote, (int)out->pos, out->space, quote); |
|
3171 } |
3146 |
3172 |
3147 ucx_buffer_free(out); |
3173 ucx_buffer_free(out); |
3148 } |
3174 } |
3149 elm = elm->next; |
3175 elm = elm->next; |
3150 } |
3176 } |