dav/main.c

changeset 747
efbd59642577
parent 744
f0d7178043c1
child 775
e5909dff0dbf
equal deleted inserted replaced
746:a569148841ff 747:efbd59642577
36 #include <time.h> 36 #include <time.h>
37 #include <sys/types.h> 37 #include <sys/types.h>
38 #ifndef _WIN32 38 #ifndef _WIN32
39 #include <sys/wait.h> 39 #include <sys/wait.h>
40 #endif 40 #endif
41 #include <ucx/string.h> 41 #include <cx/string.h>
42 #include <ucx/utils.h> 42 #include <cx/utils.h>
43 #include <cx/printf.h>
44 #include <cx/hash_map.h>
45 #include <cx/linked_list.h>
43 #include <dirent.h> 46 #include <dirent.h>
44 47
45 #include <libidav/utils.h> 48 #include <libidav/utils.h>
46 #include <libidav/crypto.h> 49 #include <libidav/crypto.h>
47 #include <libidav/session.h> 50 #include <libidav/session.h>
158 if(!strcasecmp(cmd, "list") || !strcasecmp(cmd, "ls")) { 161 if(!strcasecmp(cmd, "list") || !strcasecmp(cmd, "ls")) {
159 ret = cmd_list(args); 162 ret = cmd_list(args);
160 } else if(!strcasecmp(cmd, "get")) { 163 } else if(!strcasecmp(cmd, "get")) {
161 ret = cmd_get(args, FALSE); 164 ret = cmd_get(args, FALSE);
162 } else if(!strcasecmp(cmd, "cat")) { 165 } else if(!strcasecmp(cmd, "cat")) {
163 ucx_map_cstr_put(args->options, "output", "-"); 166 cxMapPut(args->options, cx_hash_key_str("output"), "-");
164 ret = cmd_get(args, FALSE); 167 ret = cmd_get(args, FALSE);
165 } else if(!strcasecmp(cmd, "edit")) { 168 } else if(!strcasecmp(cmd, "edit")) {
166 ret = cmd_edit(args); 169 ret = cmd_edit(args);
167 } else if(!strcasecmp(cmd, "put")) { 170 } else if(!strcasecmp(cmd, "put")) {
168 ret = cmd_put(args, FALSE); 171 ret = cmd_put(args, FALSE);
272 "date [url]", 275 "date [url]",
273 NULL 276 NULL
274 }; 277 };
275 278
276 char* find_usage_str(const char *cmd) { 279 char* find_usage_str(const char *cmd) {
277 scstr_t c = scstr(cmd); 280 cxstring c = cx_str(cmd);
278 for(int i=0;;i++) { 281 for(int i=0;;i++) {
279 char *str = cmdusageinfo[i]; 282 char *str = cmdusageinfo[i];
280 if(!str) { 283 if(!str) {
281 break; 284 break;
282 } 285 }
283 scstr_t u = scstr(str); 286 cxstring u = cx_str(str);
284 if(sstrprefix(u, c)) { 287 if(cx_strprefix(u, c)) {
285 return str; 288 return str;
286 } 289 }
287 } 290 }
288 return NULL; 291 return NULL;
289 } 292 }
589 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few":"many"); 592 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few":"many");
590 fprintf(stderr, "Usage: dav %s\n", find_usage_str("get")); 593 fprintf(stderr, "Usage: dav %s\n", find_usage_str("get"));
591 return -1; 594 return -1;
592 } 595 }
593 if(export) { 596 if(export) {
594 ucx_map_cstr_put(a->options, "recursive", ""); 597 cxMapPut(a->options, cx_hash_key_str("recursive"), "");
595 } 598 }
596 599
597 char *url = a->argv[0]; 600 char *url = a->argv[0];
598 char *path = NULL; 601 char *path = NULL;
599 Repository *repo = url2repo(url, &path); 602 Repository *repo = url2repo(url, &path);
692 "if the requested resource is a collection.\n"); 695 "if the requested resource is a collection.\n");
693 return -1; 696 return -1;
694 } 697 }
695 698
696 // get list of resources 699 // get list of resources
697 UcxList *reslist = NULL; 700 CxList *reslist = cxLinkedListCreateSimple(CX_STORE_POINTERS);
701 reslist->simple_destructor = (cx_destructor_func)free_getres;
698 uint64_t totalsize = 0; 702 uint64_t totalsize = 0;
699 uint64_t rescount = 0; 703 uint64_t rescount = 0;
700 704
701 GetResource *getres = malloc(sizeof(GetResource)); 705 GetResource *getres = malloc(sizeof(GetResource));
702 getres->res = res; 706 getres->res = res;
703 getres->path = strdup(basepath); 707 getres->path = strdup(basepath);
704 708
705 char *structure = cmd_getoption(a, "structure"); 709 char *structure = cmd_getoption(a, "structure");
706 710
707 // iterate over resource tree 711 // iterate over resource tree
708 UcxList *stack = ucx_list_prepend(NULL, getres); 712 CxList *stack = cxLinkedListCreateSimple(CX_STORE_POINTERS);
709 while(stack) { 713 cxListInsert(stack, 0, getres);
710 GetResource *g = stack->data; 714 while(stack->size > 0) {
711 stack = ucx_list_remove(stack, stack); 715 GetResource *g = cxListAt(stack, 0);
716 cxListRemove(stack, 0);
712 717
713 if(g->res->iscollection) { 718 if(g->res->iscollection) {
714 DavResource *child = g->res->children; 719 DavResource *child = g->res->children;
715 while(child) { 720 while(child) {
716 // add resource to stack 721 // add resource to stack
718 GetResource *newres = malloc(sizeof(GetResource)); 723 GetResource *newres = malloc(sizeof(GetResource));
719 newres->res = child; 724 newres->res = child;
720 newres->path = pathlen > 0 ? 725 newres->path = pathlen > 0 ?
721 util_concat_path(g->path, child->name) : strdup(child->name); 726 util_concat_path(g->path, child->name) : strdup(child->name);
722 727
723 stack = ucx_list_prepend(stack, newres); 728 cxListInsert(stack, 0, newres);
724 729
725 child = child->next; 730 child = child->next;
726 } 731 }
727 } else { 732 } else {
728 if(structure) { 733 if(structure) {
735 } 740 }
736 741
737 if(strlen(g->path) == 0) { 742 if(strlen(g->path) == 0) {
738 free_getres(g); 743 free_getres(g);
739 } else { 744 } else {
740 reslist = ucx_list_append(reslist, g); 745 cxListAdd(reslist, g);
741 } 746 }
742 } 747 }
748 cxListDestroy(stack);
743 749
744 // download resources 750 // download resources
745 pdata.total = totalsize; 751 pdata.total = totalsize;
746 752
747 int ret; 753 int ret;
756 } 762 }
757 tout = tar_open(tarfile); 763 tout = tar_open(tarfile);
758 } else { 764 } else {
759 get = get_resource; 765 get = get_resource;
760 } 766 }
761 UCX_FOREACH(elm, reslist) { 767 CxIterator i = cxListIterator(reslist);
762 GetResource *getres = elm->data; 768 cx_foreach(GetResource *, getres, i) {
763
764 ret = get(repo, getres, a, tout); 769 ret = get(repo, getres, a, tout);
765 if(ret) { 770 if(ret) {
766 break; 771 break;
767 } 772 }
768 } 773 }
772 fprintf(stderr, "tar stream broken\n"); 777 fprintf(stderr, "tar stream broken\n");
773 ret = -1; 778 ret = -1;
774 } 779 }
775 } 780 }
776 781
777 ucx_list_free_content(reslist, free_getres); 782 cxListDestroy(reslist);
778 ucx_list_free(reslist);
779 free(path); 783 free(path);
780 784
781 if(pdata.out && !pdata.isstdout) { 785 if(pdata.out && !pdata.isstdout) {
782 fclose(pdata.out); 786 fclose(pdata.out);
783 } 787 }
1133 } 1137 }
1134 } 1138 }
1135 } 1139 }
1136 1140
1137 if(import) { 1141 if(import) {
1138 ucx_map_cstr_put(a->options, "resursive", ""); 1142 cxMapPut(a->options, cx_hash_key_str("resursive"), "");
1139 } 1143 }
1140 1144
1141 char *url = a->argv[0]; 1145 char *url = a->argv[0];
1142 char *path = NULL; 1146 char *path = NULL;
1143 Repository *repo = url2repo(url, &path); 1147 Repository *repo = url2repo(url, &path);
1156 DavBool printfile = FALSE; 1160 DavBool printfile = FALSE;
1157 DavBool ignoredirerr = FALSE; 1161 DavBool ignoredirerr = FALSE;
1158 if(a->argc > 2) { 1162 if(a->argc > 2) {
1159 printfile = TRUE; 1163 printfile = TRUE;
1160 ignoredirerr = TRUE; 1164 ignoredirerr = TRUE;
1161 } else if(ucx_map_cstr_get(a->options, "recursive")) { 1165 } else if(cmd_getoption(a, "recursive")) {
1162 printfile = TRUE; 1166 printfile = TRUE;
1163 } 1167 }
1164 1168
1165 char *finfo_str = cmd_getoption(a, "finfo"); 1169 char *finfo_str = cmd_getoption(a, "finfo");
1166 uint32_t finfo = 0; 1170 uint32_t finfo = 0;
1287 FILE *in = sys_fopen(file, "rb"); 1291 FILE *in = sys_fopen(file, "rb");
1288 if(!in) { 1292 if(!in) {
1289 fprintf(stderr, "cannot open input file\n"); 1293 fprintf(stderr, "cannot open input file\n");
1290 return -1; 1294 return -1;
1291 } 1295 }
1292 char *filename = util_resource_name(file); 1296 const char *filename = util_resource_name(file);
1293 //path = util_concat_path(path, filename); 1297 //path = util_concat_path(path, filename);
1294 ret = put_file(repo, a, sn, path, filename, finfo, file, in, s.st_size); 1298 ret = put_file(repo, a, sn, path, filename, finfo, file, in, s.st_size);
1295 //free(path); 1299 //free(path);
1296 fclose(in); 1300 fclose(in);
1297 } 1301 }
1377 1381
1378 int put_file( 1382 int put_file(
1379 Repository *repo, 1383 Repository *repo,
1380 CmdArgs *a, 1384 CmdArgs *a,
1381 DavSession *sn, 1385 DavSession *sn,
1382 char *path, 1386 const char *path,
1383 char *name, 1387 const char *name,
1384 uint32_t finfo, 1388 uint32_t finfo,
1385 const char *fpath, 1389 const char *fpath,
1386 FILE *in, 1390 FILE *in,
1387 off_t len) 1391 off_t len)
1388 { 1392 {
1693 1697
1694 static size_t get_date_header_cb(void *header, int s, int n, void *data) { 1698 static size_t get_date_header_cb(void *header, int s, int n, void *data) {
1695 char **date_str = (char**)data; 1699 char **date_str = (char**)data;
1696 1700
1697 //printf("header: %.*s\n", s*n, header); 1701 //printf("header: %.*s\n", s*n, header);
1698 sstr_t h = sstrn(header, s*n); 1702 cxstring h = cx_strn(header, s*n);
1699 if(sstrprefix(h, S("Date:"))) { 1703 if(cx_strprefix(h, CX_STR("Date:"))) {
1700 sstr_t v = sstrsubs(h, 5); 1704 cxstring v = cx_strsubs(h, 5);
1701 v = sstrdup(sstrtrim(v)); 1705 *date_str = cx_strdup(cx_strtrim(v)).ptr;
1702 *date_str = v.ptr;
1703 } 1706 }
1704 return s*n; 1707 return s*n;
1705 } 1708 }
1706 1709
1707 int cmd_date(CmdArgs *a) { 1710 int cmd_date(CmdArgs *a) {
1924 1927
1925 char *url = a->argv[0]; 1928 char *url = a->argv[0];
1926 char *path = NULL; 1929 char *path = NULL;
1927 Repository *repo = url2repo(url, &path); 1930 Repository *repo = url2repo(url, &path);
1928 DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a); 1931 DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
1929 ucx_mempool_reg_destr(sn->mp, path, free); 1932 util_regdestr(sn->mp, path, free);
1930 1933
1931 if(set_session_config(sn, a)) { 1934 if(set_session_config(sn, a)) {
1932 return -1; 1935 return -1;
1933 } 1936 }
1934 1937
1935 time_t timeout = 0; 1938 time_t timeout = 0;
1936 char *timeoutstr = cmd_getoption(a, "timeout"); 1939 char *timeoutstr = cmd_getoption(a, "timeout");
1937 if(timeoutstr) { 1940 if(timeoutstr) {
1938 if(!sstrcasecmp(sstr(timeoutstr), S("infinite"))) { 1941 if(!cx_strcasecmp(cx_str(timeoutstr), CX_STR("infinite"))) {
1939 timeout = -1; 1942 timeout = -1;
1940 } else { 1943 } else {
1941 uint64_t i; 1944 uint64_t i;
1942 if(util_strtouint(timeoutstr, &i)) { 1945 if(util_strtouint(timeoutstr, &i)) {
1943 timeout = (time_t)i; 1946 timeout = (time_t)i;
1968 dav_session_destroy(sn); 1971 dav_session_destroy(sn);
1969 return 0; 1972 return 0;
1970 } 1973 }
1971 1974
1972 static char* read_line() { 1975 static char* read_line() {
1973 UcxBuffer *buf = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND); 1976 CxBuffer buf;
1977 cxBufferInit(&buf, NULL, 128, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
1974 int c; 1978 int c;
1975 while((c = getchar()) != EOF) { 1979 while((c = getchar()) != EOF) {
1976 if(c == '\n') { 1980 if(c == '\n') {
1977 break; 1981 break;
1978 } 1982 }
1979 ucx_buffer_putc(buf, c); 1983 cxBufferPut(&buf, c);
1980 } 1984 }
1981 char *str = NULL; 1985 char *str = NULL;
1982 sstr_t line = sstrtrim(sstrn(buf->space, buf->size)); 1986 cxstring line = cx_strtrim(cx_strn(buf.space, buf.size));
1983 if(line.length != 0) { 1987 if(line.length != 0) {
1984 str = sstrdup(line).ptr; 1988 str = cx_strdup(line).ptr;
1985 } 1989 }
1986 ucx_buffer_free(buf); 1990 cxBufferDestroy(&buf);
1987 return str; 1991 return str;
1988 } 1992 }
1989 1993
1990 int cmd_unlock(CmdArgs *a) { 1994 int cmd_unlock(CmdArgs *a) {
1991 if(a->argc != 1) { 1995 if(a->argc != 1) {
1996 2000
1997 char *url = a->argv[0]; 2001 char *url = a->argv[0];
1998 char *path = NULL; 2002 char *path = NULL;
1999 Repository *repo = url2repo(url, &path); 2003 Repository *repo = url2repo(url, &path);
2000 DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a); 2004 DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, a);
2001 ucx_mempool_reg_destr(sn->mp, path, free); 2005 util_regdestr(sn->mp, path, free);
2002 if(set_session_config(sn, a)) { 2006 if(set_session_config(sn, a)) {
2003 return -1; 2007 return -1;
2004 } 2008 }
2005 2009
2006 char *locktoken = cmd_getoption(a, "lock"); 2010 char *locktoken = cmd_getoption(a, "lock");
2107 last_ns = p.ns; 2111 last_ns = p.ns;
2108 } 2112 }
2109 2113
2110 DavXmlNode *xval = dav_get_property_ns(res, p.ns, p.name); 2114 DavXmlNode *xval = dav_get_property_ns(res, p.ns, p.name);
2111 if(dav_xml_isstring(xval)) { 2115 if(dav_xml_isstring(xval)) {
2112 sstr_t value = sstr(dav_xml_getstring(xval)); 2116 cxstring value = cx_str(dav_xml_getstring(xval));
2113 printf(" %s: %.*s\n", p.name, (int)value.length, value.ptr); 2117 printf(" %s: %.*s\n", p.name, (int)value.length, value.ptr);
2114 } else { 2118 } else {
2115 // find some xml elements 2119 // find some xml elements
2116 printf(" %s: ", p.name); 2120 printf(" %s: ", p.name);
2117 DavXmlNode *x = xval->type == DAV_XML_ELEMENT ? xval : dav_xml_nextelm(xval); 2121 DavXmlNode *x = xval->type == DAV_XML_ELEMENT ? xval : dav_xml_nextelm(xval);
2317 return ret; 2321 return ret;
2318 } 2322 }
2319 2323
2320 2324
2321 char* stdin2str() { 2325 char* stdin2str() {
2322 UcxBuffer *buf = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); 2326 CxBuffer buf;
2323 size_t size = ucx_stream_copy(stdin, buf, fread, ucx_buffer_write); 2327 cxBufferInit(&buf, NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
2328 size_t size = cx_stream_copy(stdin, &buf, (cx_read_func)fread, (cx_write_func)cxBufferWrite);
2324 if(size == 0) { 2329 if(size == 0) {
2325 ucx_buffer_free(buf); 2330 cxBufferDestroy(&buf);
2326 return NULL; 2331 return NULL;
2327 } else { 2332 } else {
2328 ucx_buffer_putc(buf, '\0'); 2333 cxBufferPut(&buf, '\0');
2329 char *str = buf->space; 2334 return buf.space;
2330 free(buf); 2335 }
2331 return str; 2336 }
2332 } 2337
2333 } 2338 static void xml2str_i(DavXmlNode *node, CxBuffer *buf, int indent) {
2334
2335 static void xml2str_i(DavXmlNode *node, UcxBuffer *buf, int indent) {
2336 while(node) { 2339 while(node) {
2337 if(node->type == DAV_XML_ELEMENT) { 2340 if(node->type == DAV_XML_ELEMENT) {
2338 if(node->children) { 2341 if(node->children) {
2339 if(dav_xml_isstring(node->children)) { 2342 if(dav_xml_isstring(node->children)) {
2340 sstr_t s = sstrtrim(sstr(dav_xml_getstring(node->children))); 2343 cxstring s = cx_strtrim(cx_str(dav_xml_getstring(node->children)));
2341 ucx_bprintf( 2344 cx_bprintf(
2342 buf, 2345 buf,
2343 "%*s<%s>%.*s</%s>\n", 2346 "%*s<%s>%.*s</%s>\n",
2344 indent, 2347 indent,
2345 "", 2348 "",
2346 node->name, 2349 node->name,
2347 (int)s.length, 2350 (int)s.length,
2348 s.ptr, 2351 s.ptr,
2349 node->name); 2352 node->name);
2350 } else { 2353 } else {
2351 ucx_bprintf(buf, "%*s<%s>\n", indent, "", node->name); 2354 cx_bprintf(buf, "%*s<%s>\n", indent, "", node->name);
2352 xml2str_i(node->children, buf, indent+2); 2355 xml2str_i(node->children, buf, indent+2);
2353 ucx_bprintf(buf, "%*s</%s>\n", indent, "", node->name); 2356 cx_bprintf(buf, "%*s</%s>\n", indent, "", node->name);
2354 } 2357 }
2355 } else { 2358 } else {
2356 ucx_bprintf(buf, "%*s<%s />", indent, "", node->name); 2359 cx_bprintf(buf, "%*s<%s />", indent, "", node->name);
2357 ucx_buffer_putc(buf, '\n'); 2360 cxBufferPut(buf, '\n');
2358 } 2361 }
2359 } else if(node->type == DAV_XML_TEXT) { 2362 } else if(node->type == DAV_XML_TEXT) {
2360 sstr_t val = sstrtrim(sstrn(node->content, node->contentlength)); 2363 cxstring val = cx_strtrim(cx_strn(node->content, node->contentlength));
2361 if(val.length > 0) { 2364 if(val.length > 0) {
2362 ucx_bprintf(buf, "%*.*s", indent, (int)val.length, val.ptr); 2365 cx_bprintf(buf, "%*.*s", indent, (int)val.length, val.ptr);
2363 } 2366 }
2364 } 2367 }
2365 2368
2366 node = node->next; 2369 node = node->next;
2367 } 2370 }
2368 } 2371 }
2369 2372
2370 char* xml2str(DavXmlNode *node) { 2373 char* xml2str(DavXmlNode *node) {
2371 char *str = malloc(256); 2374 CxBuffer buf;
2372 UcxBuffer *buf = ucx_buffer_new(str, 256, UCX_BUFFER_AUTOEXTEND); 2375 cxBufferInit(&buf, NULL, 256, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
2373 xml2str_i(node, buf, 0); 2376 xml2str_i(node, &buf, 0);
2374 ucx_buffer_putc(buf, 0); 2377 cxBufferPut(&buf, 0);
2375 char *space = buf->space; 2378 return buf.space;
2376 ucx_buffer_free(buf);
2377 return space;
2378 } 2379 }
2379 2380
2380 void printxmldoc(FILE *out, char *root, char *rootns, DavXmlNode *content) { 2381 void printxmldoc(FILE *out, char *root, char *rootns, DavXmlNode *content) {
2381 UcxMap *nsmap = ucx_map_new(16); 2382 CxMap *nsmap = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16);
2382 2383 nsmap->simple_destructor = free;
2383 ucx_map_cstr_put(nsmap, rootns, "x0"); 2384
2385 cxMapPut(nsmap, cx_hash_key_str(rootns), "x0");
2384 fprintf(out, "%s", "<?xml version=\"1.0\"?>\n"); 2386 fprintf(out, "%s", "<?xml version=\"1.0\"?>\n");
2385 fprintf(out, "<x0:%s xmlns:x0=\"%s\">", root, rootns); 2387 fprintf(out, "<x0:%s xmlns:x0=\"%s\">", root, rootns);
2386 2388
2387 dav_print_node(out, (write_func)fwrite, nsmap, content); 2389 dav_print_node(out, (cx_write_func)fwrite, nsmap, content);
2388 2390
2389 fprintf(out, "</x0:%s>\n", root); 2391 fprintf(out, "</x0:%s>\n", root);
2390 2392
2391 // cleanup namespace map 2393 // cleanup namespace map
2392 ucx_map_cstr_remove(nsmap, rootns); 2394 cxMapRemove(nsmap, cx_hash_key_str(rootns));
2393 ucx_map_free_content(nsmap, free); 2395 cxMapDestroy(nsmap);
2394 ucx_map_free(nsmap);
2395 } 2396 }
2396 2397
2397 2398
2398 /* ---------- config commands ---------- */ 2399 /* ---------- config commands ---------- */
2399 2400
2402 char *name = assistant_getcfg("name"); 2403 char *name = assistant_getcfg("name");
2403 if(!name) { 2404 if(!name) {
2404 fprintf(stderr, "Abort\n"); 2405 fprintf(stderr, "Abort\n");
2405 return -1; 2406 return -1;
2406 } 2407 }
2407 if(get_repository(sstr(name))) { 2408 if(get_repository(cx_str(name))) {
2408 fprintf(stderr, "Repository %s already exists.\nAbort\n", name); 2409 fprintf(stderr, "Repository %s already exists.\nAbort\n", name);
2409 return -1; 2410 return -1;
2410 } 2411 }
2411 2412
2412 printf("\nSpecify the repository base url.\n"); 2413 printf("\nSpecify the repository base url.\n");
2458 fprintf(stderr, "Usage: dav remove-repository <name...>\n"); 2459 fprintf(stderr, "Usage: dav remove-repository <name...>\n");
2459 return -1; 2460 return -1;
2460 } 2461 }
2461 2462
2462 for(int i = 0 ; i < args->argc ; i++) { 2463 for(int i = 0 ; i < args->argc ; i++) {
2463 sstr_t reponame = sstr(args->argv[i]); 2464 cxstring reponame = cx_str(args->argv[i]);
2464 Repository* repo = get_repository(reponame); 2465 Repository* repo = get_repository(reponame);
2465 if(repo) { 2466 if(repo) {
2466 if(remove_repository(repo)) { 2467 if(remove_repository(repo)) {
2467 fprintf(stderr, "Cannot write config.xml\n"); 2468 fprintf(stderr, "Cannot write config.xml\n");
2468 return -1; 2469 return -1;
2482 fprintf(stderr, "Too few arguments\n"); 2483 fprintf(stderr, "Too few arguments\n");
2483 fprintf(stderr, "Usage: dav repository-url [-p] <name>\n"); 2484 fprintf(stderr, "Usage: dav repository-url [-p] <name>\n");
2484 return -1; 2485 return -1;
2485 } 2486 }
2486 2487
2487 sstr_t reponame = sstr(args->argv[0]); 2488 cxstring reponame = cx_str(args->argv[0]);
2488 Repository* repo = get_repository(reponame); 2489 Repository* repo = get_repository(reponame);
2489 if(repo) { 2490 if(repo) {
2490 sstr_t url = sstr(repo->url); 2491 cxstring url = cx_str(repo->url);
2491 if(repo->user && !cmd_getoption(args, "plain")) { 2492 if(repo->user && !cmd_getoption(args, "plain")) {
2492 int hostindex = 0; 2493 int hostindex = 0;
2493 if(sstrprefix(url, S("https://"))) { 2494 if(cx_strprefix(url, CX_STR("https://"))) {
2494 printf("https://"); 2495 printf("https://");
2495 hostindex = 8; 2496 hostindex = 8;
2496 } else if(sstrprefix(url, S("http://"))) { 2497 } else if(cx_strprefix(url, CX_STR("http://"))) {
2497 printf("http://"); 2498 printf("http://");
2498 hostindex = 7; 2499 hostindex = 7;
2499 } 2500 }
2500 printf("%s", repo->user); 2501 printf("%s", repo->user);
2501 if(repo->password) { 2502 if(repo->password) {
2614 char *user = assistant_getcfg("User"); 2615 char *user = assistant_getcfg("User");
2615 char *password = util_password_input("Password: "); 2616 char *password = util_password_input("Password: ");
2616 2617
2617 // optionally, get one or more locations 2618 // optionally, get one or more locations
2618 char *location = NULL; 2619 char *location = NULL;
2619 UcxList *locations = NULL; 2620 CxList *locations = cxLinkedListCreateSimple(CX_STORE_POINTERS);
2621 locations->simple_destructor = free;
2620 while((location = assistant_getoptcfg("Location"))) { 2622 while((location = assistant_getoptcfg("Location"))) {
2621 locations = ucx_list_append(locations, location); 2623 cxListAdd(locations, location);
2622 } 2624 }
2623 2625
2624 int ret = 1; 2626 int ret = 1;
2625 if(user && password) { 2627 if(user && password) {
2626 pwdstore_put_index(secrets, id, locations); 2628 pwdstore_put_index(secrets, id, locations);
2633 2635
2634 if(id) free(id); 2636 if(id) free(id);
2635 if(user) free(user); 2637 if(user) free(user);
2636 if(password) free(password); 2638 if(password) free(password);
2637 2639
2638 ucx_list_free_content(locations, free); 2640 cxListDestroy(locations);
2639 ucx_list_free(locations);
2640 2641
2641 return ret; 2642 return ret;
2642 } 2643 }
2643 2644
2644 int cmd_add_user(CmdArgs *args) { 2645 int cmd_add_user(CmdArgs *args) {
2647 2648
2648 /* 2649 /*
2649 * called before the secret store is decrypted 2650 * called before the secret store is decrypted
2650 */ 2651 */
2651 static int cmd_ss_list_users_bc(CmdArgs *Args, PwdStore *secrets, int *ret) { 2652 static int cmd_ss_list_users_bc(CmdArgs *Args, PwdStore *secrets, int *ret) {
2652 if(secrets->index->count == 0) { 2653 if(secrets->index->size == 0) {
2653 return 1; // abort, because the secret store is empty 2654 return 1; // abort, because the secret store is empty
2654 } 2655 }
2655 // set ret to 1, because decrypt could fail and this should be an error 2656 // set ret to 1, because decrypt could fail and this should be an error
2656 *ret = 1; 2657 *ret = 1;
2657 return 0; 2658 return 0;
2661 * called after the secret store is decrypted 2662 * called after the secret store is decrypted
2662 */ 2663 */
2663 static int cmd_ss_list_users(CmdArgs *args, PwdStore *secrets, int *ret) { 2664 static int cmd_ss_list_users(CmdArgs *args, PwdStore *secrets, int *ret) {
2664 *ret = 0; 2665 *ret = 0;
2665 2666
2666 UcxList *list = secrets->locations; 2667 CxList *list = secrets->locations;
2667 for(int i=0;i<2;i++) { 2668 for(int i=0;i<2;i++) {
2668 UCX_FOREACH(elm, list) { 2669 if(list) {
2669 PwdIndexEntry *index = elm->data; 2670 CxIterator i = cxListIterator(list);
2670 PwdEntry *e = ucx_map_cstr_get(secrets->ids, index->id); 2671 cx_foreach(PwdIndexEntry*, index, i) {
2671 if(e) { 2672 PwdEntry *e = cxMapGet(secrets->ids, cx_hash_key_str(index->id));
2672 printf("Id: %s\n", e->id); 2673 if(e) {
2673 printf("User: %s\n", e->user); 2674 printf("Id: %s\n", e->id);
2674 UCX_FOREACH(loc, index->locations) { 2675 printf("User: %s\n", e->user);
2675 char *location = loc->data; 2676 if(index->locations) {
2676 printf("Location: %s\n", location); 2677 CxIterator loc_iter = cxListIterator(index->locations);
2678 cx_foreach(char *, location, loc_iter) {
2679 printf("Location: %s\n", location);
2680 }
2681 printf("\n");
2682 }
2683 } else {
2684 // broken index
2685 fprintf(stderr,
2686 "Warning: id '%s' not in secret store.\n",
2687 index->id);
2677 } 2688 }
2678 printf("\n");
2679 } else {
2680 // broken index
2681 fprintf(stderr,
2682 "Warning: id '%s' not in secret store.\n",
2683 index->id);
2684 } 2689 }
2685 } 2690 }
2686 list = secrets->noloc; 2691 list = secrets->noloc;
2687 } 2692 }
2688 2693
2727 PwdEntry *entry = pwdstore_get(secrets, id); 2732 PwdEntry *entry = pwdstore_get(secrets, id);
2728 if(!entry) { 2733 if(!entry) {
2729 return; 2734 return;
2730 } 2735 }
2731 2736
2732 PwdIndexEntry *index = ucx_map_cstr_get(secrets->index, id); 2737 PwdIndexEntry *index = cxMapGet(secrets->index, cx_hash_key_str(id));
2733 if(!index) { 2738 if(!index) {
2734 return; 2739 return;
2735 } 2740 }
2736 2741
2737 printf("Id: %s\n", entry->id); 2742 printf("Id: %s\n", entry->id);
2738 printf("User: %s\n", entry->user); 2743 printf("User: %s\n", entry->user);
2739 UCX_FOREACH(elm, index->locations) { 2744 if(index->locations) {
2740 printf("Location: %s\n", (char*)elm->data); 2745 CxIterator loc_iter = cxListIterator(index->locations);
2746 cx_foreach(char *, location, loc_iter) {
2747 printf("Location: %s\n", location);
2748 }
2741 } 2749 }
2742 } 2750 }
2743 2751
2744 static void secrets_remove_location(PwdIndexEntry *index) { 2752 static void secrets_remove_location(PwdIndexEntry *index) {
2745 if(!index->locations) { 2753 if(!index->locations || index->locations->size == 0) {
2746 printf("no locations\n"); 2754 printf("no locations\n");
2747 return; 2755 return;
2748 } 2756 }
2749 2757
2750 printf("0: abort\n"); 2758 printf("0: abort\n");
2751 int i = 1; 2759 int i = 1;
2752 UCX_FOREACH(elm, index->locations) { 2760 CxIterator loc_iter = cxListIterator(index->locations);
2753 printf("%d: %s\n", i, (char*)elm->data); 2761 cx_foreach(char *, location, loc_iter) {
2762 printf("%d: %s\n", i, location);
2754 i++; 2763 i++;
2755 } 2764 }
2756 2765
2757 char *input = assistant_getcfg("Choose location"); 2766 char *input = assistant_getcfg("Choose location");
2758 if(!input) { 2767 if(!input) {
2762 int64_t ln = 0; 2771 int64_t ln = 0;
2763 if(util_strtoint(input, &ln) && (ln >= 0 && ln < i)) { 2772 if(util_strtoint(input, &ln) && (ln >= 0 && ln < i)) {
2764 if(ln == 0) { 2773 if(ln == 0) {
2765 return; 2774 return;
2766 } else { 2775 } else {
2767 UcxList *elm = ucx_list_get(index->locations, ln - 1); 2776 char *location = cxListAt(index->locations, ln - 1);
2768 if(elm) { 2777 if(location) {
2769 free(elm->data); 2778 free(location);
2770 index->locations = ucx_list_remove(index->locations, elm); 2779 cxListRemove(index->locations, ln - 1);
2771 } 2780 }
2772 } 2781 }
2773 } else { 2782 } else {
2774 printf("illegal input, choose 0 - %d\n", i-1); 2783 printf("illegal input, choose 0 - %d\n", i-1);
2775 secrets_remove_location(index); // try again 2784 secrets_remove_location(index); // try again
2781 if(!id) { 2790 if(!id) {
2782 fprintf(stderr, "Identifier required.\n"); 2791 fprintf(stderr, "Identifier required.\n");
2783 return 1; 2792 return 1;
2784 } 2793 }
2785 PwdEntry *entry = pwdstore_get(secrets, id); 2794 PwdEntry *entry = pwdstore_get(secrets, id);
2786 PwdIndexEntry *index = ucx_map_cstr_get(secrets->index, id); 2795 PwdIndexEntry *index = cxMapGet(secrets->index, cx_hash_key_str(id));
2787 if(!entry || !index) { 2796 if(!entry || !index) {
2788 fprintf(stderr, "Credentials with this id doesn't exist.\n"); 2797 fprintf(stderr, "Credentials with this id doesn't exist.\n");
2789 return 1; 2798 return 1;
2790 } 2799 }
2791 2800
2835 } 2844 }
2836 case 2: { 2845 case 2: {
2837 // add location 2846 // add location
2838 char *location = assistant_getoptcfg("Location"); 2847 char *location = assistant_getoptcfg("Location");
2839 if(location) { 2848 if(location) {
2840 index->locations = ucx_list_append(index->locations, location); 2849 cxListAdd(index->locations, location);
2841 } 2850 }
2842 break; 2851 break;
2843 } 2852 }
2844 case 3: { 2853 case 3: {
2845 // remove location 2854 // remove location
2846 secrets_remove_location(index); 2855 secrets_remove_location(index);
2847 break; 2856 break;
2848 } 2857 }
2849 case 4: { 2858 case 4: {
2850 // list locations 2859 // list locations
2851 if(!index->locations) { 2860 if(!index->locations || index->locations->size == 0) {
2852 printf("no locations\n"); 2861 printf("no locations\n");
2853 } else { 2862 } else {
2854 UCX_FOREACH(elm, index->locations) { 2863 CxIterator i = cxListIterator(index->locations);
2855 printf("Location: %s\n", (char*)elm->data); 2864 cx_foreach(char *, location, i) {
2865 printf("Location: %s\n", location);
2856 } 2866 }
2857 } 2867 }
2858 break; 2868 break;
2859 } 2869 }
2860 case 5: { 2870 case 5: {
2908 return secretstore_cmd(args, FALSE, NULL, cmd_ss_set_master_pw, NULL); 2918 return secretstore_cmd(args, FALSE, NULL, cmd_ss_set_master_pw, NULL);
2909 } 2919 }
2910 2920
2911 static char** read_args_from_stdin(int *argc) { 2921 static char** read_args_from_stdin(int *argc) {
2912 // read stdin into buffer 2922 // read stdin into buffer
2913 UcxBuffer *in = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); 2923 CxBuffer *in = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
2914 ucx_stream_copy(stdin, in, (read_func)fread, (write_func)ucx_buffer_write); 2924 cx_stream_copy(stdin, in, (cx_read_func)fread, (cx_write_func)cxBufferWrite);
2915 2925
2916 // split input into lines 2926 // split input into lines
2917 ssize_t count = 0; 2927 ssize_t count = 0;
2918 sstr_t *lines = scstrsplit(scstrn(in->space, in->pos), SC("\n"), &count); 2928 cxmutstr *lines;
2929 count = cx_strsplit_ma(cxDefaultAllocator, cx_mutstrn(in->space, in->pos), CX_STR("\n"), INT_MAX, &lines);
2919 2930
2920 char **args = NULL; 2931 char **args = NULL;
2921 if(count > 0) { 2932 if(count > 0) {
2922 args = calloc(count, sizeof(char*)); 2933 args = calloc(count, sizeof(char*));
2923 for(int i=0;i<count;i++) { 2934 for(int i=0;i<count;i++) {
2929 } else { 2940 } else {
2930 *argc = 0; 2941 *argc = 0;
2931 } 2942 }
2932 2943
2933 // cleanup 2944 // cleanup
2934 ucx_buffer_free(in); 2945 cxBufferFree(in);
2935 2946
2936 return args; 2947 return args;
2937 } 2948 }
2938 2949
2939 int cmd_complete(CmdArgs *args) { 2950 int cmd_complete(CmdArgs *args) {
2995 3006
2996 } 3007 }
2997 3008
2998 int shell_completion(char *cmd, CmdArgs *args, int index) { 3009 int shell_completion(char *cmd, CmdArgs *args, int index) {
2999 if(index == 1) { 3010 if(index == 1) {
3000 sstr_t prefix = { NULL, 0 }; 3011 cxstring prefix = { NULL, 0 };
3001 if(cmd) { 3012 if(cmd) {
3002 prefix = sstr(cmd); 3013 prefix = cx_str(cmd);
3003 } 3014 }
3004 for(int i=0;;i++) { 3015 for(int i=0;;i++) {
3005 char *str = cmdusageinfo[i]; 3016 char *str = cmdusageinfo[i];
3006 if(!str) { 3017 if(!str) {
3007 break; 3018 break;
3013 maxlen = w; 3024 maxlen = w;
3014 break; 3025 break;
3015 } 3026 }
3016 } 3027 }
3017 if(prefix.ptr) { 3028 if(prefix.ptr) {
3018 if(!sstrprefix(sstrn(str, maxlen), prefix)) { 3029 if(!cx_strprefix(cx_strn(str, maxlen), prefix)) {
3019 continue; 3030 continue;
3020 } 3031 }
3021 } 3032 }
3022 printf("%.*s\n", (int)maxlen, str); 3033 printf("%.*s\n", (int)maxlen, str);
3023 } 3034 }
3051 3062
3052 return 0; 3063 return 0;
3053 } 3064 }
3054 3065
3055 int url_completion(CmdArgs *args, char *u) { 3066 int url_completion(CmdArgs *args, char *u) {
3056 sstr_t url; 3067 cxstring url;
3057 url.ptr = u; 3068 url.ptr = u;
3058 url.length = u ? strlen(u) : 0; 3069 url.length = u ? strlen(u) : 0;
3059 3070
3060 // if the user wants the URL to be quoted, we conform to their wish 3071 // if the user wants the URL to be quoted, we conform to their wish
3061 // a null-char is an indicator, that the strings shall not be quoted 3072 // a null-char is an indicator, that the strings shall not be quoted
3080 repocomp = 0; 3091 repocomp = 0;
3081 break; 3092 break;
3082 } 3093 }
3083 } 3094 }
3084 if(repocomp) { 3095 if(repocomp) {
3085 UcxList *repos = get_repositories(); 3096 CxIterator i = get_repositories();
3086 UCX_FOREACH(elm, repos) { 3097 cx_foreach(Repository*, repo, i) {
3087 Repository *repo = elm->data; 3098 if(cx_strprefix(cx_str(repo->name), url)) {
3088 if(sstrprefix(sstr(repo->name), url)) {
3089 if(quote == '\0') { 3099 if(quote == '\0') {
3090 printf("%s/\n", repo->name); 3100 printf("%s/\n", repo->name);
3091 } else { 3101 } else {
3092 printf("%c%s/%c\n", quote, repo->name, quote); 3102 printf("%c%s/%c\n", quote, repo->name, quote);
3093 } 3103 }
3094 } 3104 }
3095 3105
3096 } 3106 }
3097 } else { 3107 } else {
3098 // url completion 3108 // url completion
3099 ucx_map_cstr_put(args->options, "noinput", ""); 3109 cxMapPut(args->options, cx_hash_key_str("noinput"), "");
3100 3110
3101 char *path = NULL; 3111 char *path = NULL;
3102 Repository *repo = url2repo_s(url, &path); 3112 Repository *repo = url2repo_s(url, &path);
3103 DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, args); 3113 DavSession *sn = connect_to_repo(ctx, repo, path, request_auth, args);
3104 if(!sn) { 3114 if(!sn) {
3108 return 0; 3118 return 0;
3109 } 3119 }
3110 3120
3111 size_t plen = strlen(path); 3121 size_t plen = strlen(path);
3112 3122
3113 sstr_t filter; 3123 cxstring filter;
3114 char *lspath = NULL; 3124 char *lspath = NULL;
3115 if(path[plen-1] == '/') { 3125 if(path[plen-1] == '/') {
3116 lspath = strdup(path); 3126 lspath = strdup(path);
3117 filter = S(""); 3127 filter = CX_STR("");
3118 } else { 3128 } else {
3119 lspath = util_parent_path(path); 3129 lspath = util_parent_path(path);
3120 filter = sstr(util_resource_name(path)); 3130 filter = cx_str(util_resource_name(path));
3121 } 3131 }
3122 3132
3123 DavResource *ls = dav_query(sn, "select - from %s order by name", lspath); 3133 DavResource *ls = dav_query(sn, "select - from %s order by name", lspath);
3124 DavResource *elm = ls ? ls->children : NULL; 3134 DavResource *elm = ls ? ls->children : NULL;
3125 while(elm) { 3135 while(elm) {
3126 sstr_t name = sstr(elm->name); 3136 cxstring name = cx_str(elm->name);
3127 if(sstrprefix(name, filter)) { 3137 if(cx_strprefix(name, filter)) {
3128 int space = 0; 3138 int space = 0;
3129 for(int i=0;i<name.length;i++) { 3139 for(int i=0;i<name.length;i++) {
3130 if(name.ptr[i] == ' ') { 3140 if(name.ptr[i] == ' ') {
3131 space = 1; 3141 space = 1;
3132 break; 3142 break;
3133 } 3143 }
3134 } 3144 }
3135 3145
3136 UcxBuffer *out = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); 3146 CxBuffer *out = cxBufferCreate(NULL, 512, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
3137 ucx_buffer_puts(out, repo->name); 3147 cxBufferPutString(out, repo->name);
3138 if(space) { 3148 if(space) {
3139 size_t l = strlen(elm->path); 3149 size_t l = strlen(elm->path);
3140 for(int i=0;i<l;i++) { 3150 for(int i=0;i<l;i++) {
3141 // only if we do not quote, we have to escape 3151 // only if we do not quote, we have to escape
3142 char nextc = elm->path[i]; 3152 char nextc = elm->path[i];
3143 if(quote == '\0' && NULL != strchr( 3153 if(quote == '\0' && NULL != strchr(
3144 "!\"#$&'()*,;<>?[\\]^`{|}~ ", nextc)) { 3154 "!\"#$&'()*,;<>?[\\]^`{|}~ ", nextc)) {
3145 ucx_buffer_putc(out, '\\'); 3155 cxBufferPut(out, '\\');
3146 } 3156 }
3147 ucx_buffer_putc(out, nextc); 3157 cxBufferPut(out, nextc);
3148 } 3158 }
3149 } else { 3159 } else {
3150 ucx_buffer_puts(out, elm->path); 3160 cxBufferPutString(out, elm->path);
3151 } 3161 }
3152 if(elm->iscollection) { 3162 if(elm->iscollection) {
3153 if(out->space[out->pos-1] != '/') { 3163 if(out->space[out->pos-1] != '/') {
3154 ucx_buffer_putc(out, '/'); 3164 cxBufferPut(out, '/');
3155 } 3165 }
3156 } 3166 }
3157 if (quote == '\0') { 3167 if (quote == '\0') {
3158 printf("%.*s\n", (int)out->pos, out->space); 3168 printf("%.*s\n", (int)out->pos, out->space);
3159 } else { 3169 } else {
3160 printf("%c%.*s%c\n", 3170 printf("%c%.*s%c\n",
3161 quote, (int)out->pos, out->space, quote); 3171 quote, (int)out->pos, out->space, quote);
3162 } 3172 }
3163 3173
3164 ucx_buffer_free(out); 3174 cxBufferFree(out);
3165 } 3175 }
3166 elm = elm->next; 3176 elm = elm->next;
3167 } 3177 }
3168 3178
3169 free(lspath); 3179 free(lspath);

mercurial