# HG changeset patch # User Olaf Wintermann # Date 1508946755 -7200 # Node ID 000cdd1241150b701acbd2d2b6c9ed1d1b66f8d1 # Parent 5587282ebe1cb68afa333efe47f04c96980f94dd refactores cmd_get diff -r 5587282ebe1c -r 000cdd124115 dav/main.c --- a/dav/main.c Sun Oct 22 13:45:13 2017 +0200 +++ b/dav/main.c Wed Oct 25 17:52:35 2017 +0200 @@ -647,6 +647,12 @@ } } +static void free_getres(void *r) { + GetResource *getres = r; + free(getres->path); + free(getres); +} + int cmd_get(CmdArgs *a) { if(a->argc != 1) { // TODO: change this, when get supports retrieval of multiple files @@ -725,9 +731,68 @@ return -1; } - int ret = get_resource(repo, res, a, outfile); + // get list of resources + UcxList *reslist = NULL; + uint64_t totalsize = 0; + uint64_t rescount = 0; + + GetResource *getres = malloc(sizeof(GetResource)); + getres->res = res; + getres->path = strdup(outfile); + + char *structure = cmd_getoption(a, "structure"); + // iterate over resource tree + UcxList *stack = ucx_list_prepend(NULL, getres); + while(stack) { + GetResource *g = stack->data; + stack = ucx_list_remove(stack, stack); + + if(g->res->iscollection) { + DavResource *child = g->res->children; + while(child) { + // add resource to stack + size_t pathlen = strlen(g->path); + GetResource *newres = malloc(sizeof(GetResource)); + newres->res = child; + newres->path = pathlen > 0 ? + util_concat_path(g->path, child->name) : child->name; + + stack = ucx_list_prepend(stack, newres); + + child = child->next; + } + } else { + if(structure) { + // download only directory structure + // this is a hidden feature and will be replaced in the future + continue; // skip non-collection resource + } + totalsize += g->res->contentlength; + rescount++; + } + + if(strlen(g->path) == 0) { + free_getres(g); + } else { + reslist = ucx_list_append(reslist, g); + } + } + + int ret; + UCX_FOREACH(elm, reslist) { + GetResource *getres = elm->data; + + ret = get_resource(repo, getres->res, a, getres->path); + if(ret) { + break; + } + } + + ucx_list_free_content(reslist, free_getres); + ucx_list_free(reslist); free(path); + return ret; } @@ -737,33 +802,14 @@ if(res->iscollection) { printf("get: %s\n", res->path); - // create directory - if(outlen != 0) { - mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - int ret = util_mkdir(out, mode); - if(ret != 0 && errno != EEXIST) { - return 1; - } + mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + int ret = util_mkdir(out, mode); + if(ret != 0 && errno != EEXIST) { + fprintf(stderr, "Cannot create directory '%s': ", out); + perror(""); + return 1; } - DavResource *child = res->children; - while(child) { - char *newout = outlen > 0 ? - util_concat_path(out, child->name) : child->name; - int ret = get_resource(repo, child, a, newout); - if(outlen > 0) { - free(newout); - } - if(ret) { - return 1; - } - child = child->next; - } - - return 0; - } else if(cmd_getoption(a, "structure")) { - // download only directory structure - // this is a hidden feature and will be replaced in the future return 0; } diff -r 5587282ebe1c -r 000cdd124115 dav/main.h --- a/dav/main.h Sun Oct 22 13:45:13 2017 +0200 +++ b/dav/main.h Wed Oct 25 17:52:35 2017 +0200 @@ -39,6 +39,11 @@ extern "C" { #endif +typedef struct { + DavResource *res; + char *path; +} GetResource; + void print_usage(char *cmd); char* password_input(char *prompt); int request_auth(Repository *repo, DavSession *sn, CmdArgs *args);