recursive list and get

Sat, 17 Aug 2013 14:17:48 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 17 Aug 2013 14:17:48 +0200
changeset 18
651989681053
parent 17
11dffb40cd91
child 19
18efd2c2973d

recursive list and get

dav/config.c file | annotate | diff | comparison | revisions
dav/main.c file | annotate | diff | comparison | revisions
dav/main.h file | annotate | diff | comparison | revisions
dav/optparser.c file | annotate | diff | comparison | revisions
suncc.mk file | annotate | diff | comparison | revisions
--- a/dav/config.c	Sat Aug 17 12:04:04 2013 +0200
+++ b/dav/config.c	Sat Aug 17 14:17:48 2013 +0200
@@ -95,7 +95,7 @@
     xmlNode *node = reponode->children;
     Repository *repo = calloc(1, sizeof(Repository));
     repo->store_key_property = true;
-    repo->decrypt = true;
+    repo->decrypt = false;
     while(node) {
         if(node->type == XML_ELEMENT_NODE) {
             char *value = util_xml_get_text(node);
--- a/dav/main.c	Sat Aug 17 12:04:04 2013 +0200
+++ b/dav/main.c	Sat Aug 17 14:17:48 2013 +0200
@@ -96,8 +96,8 @@
 void print_usage(char *cmd) {
     fprintf(stderr, "Usage: %s command [options] arguments...\n\n", cmd);
     fprintf(stderr, "Commands:\n");
-    fprintf(stderr, "        list [-alt] <url>\n");
-    fprintf(stderr, "        get [-p] [-k <key>] [-o <file>] <url>\n");
+    fprintf(stderr, "        list [-altR] <url>\n");
+    fprintf(stderr, "        get [-pR] [-k <key>] [-o <file>] <url>\n");
     fprintf(stderr, "        put [-p] [-k <key>] <url> <file>\n");
     fprintf(stderr, "        mkdir <url>\n");
     fprintf(stderr, "        remove <url>\n");
@@ -106,6 +106,9 @@
     fprintf(stderr,
             "        -k <key>   Key to use for encryption or decryption\n");
     fprintf(stderr, "        -p         Don't encrypt or decrypt files\n");
+    fprintf(stderr,
+            "        -R         "
+            "Recursively do the operation for all children\n");
     fprintf(stderr, "        -o <file>  Write output to file\n");
     fprintf(stderr, "        -a         show all files\n");
     fprintf(stderr, "        -l         print resources in long list format\n");
@@ -193,21 +196,30 @@
     char *url = a->argv[0];
     char *root = NULL;
     char *path = NULL;
+    char *base = NULL;
     url_get_parts(url, &root, &path);
     
     Repository *repo = get_repository(root);
     if(repo) {
-        sn = dav_session_new_auth(ctx, repo->url, repo->user, repo->password);
+        base = util_concat_path(repo->url, path);
+        sn = dav_session_new_auth(ctx, base, repo->user, repo->password);
     } else {
-        sn = dav_session_new(ctx, root);
+        base = util_concat_path(root, path);
+        sn = dav_session_new(ctx, base);
     }
     
-    //printf("baseurl: %s\n", sn->base_url);
-    
-    //DavResource *ls = dav_get(sn, path, "U:crypto-key");
-    DavResource *ls = dav_query(sn, "get U:crypto-key from %s", path);
+    DavResource *ls;
+    if(cmd_getoption(a, "recursive")) {
+        printf("base: %s\n", base);
+        ls = dav_query(sn, "get U:crypto-key from /*");
+    } else {
+        ls = dav_query(sn, "get U:crypto-key from /");
+    }
     if(!ls) {
         print_resource_error(sn, path);
+        free(root);
+        free(path);
+        free(base);
         return -1;
     }
     
@@ -227,6 +239,10 @@
         child = child->next;
     }
     
+    free(root);
+    free(path);
+    free(base);
+    
     return 0;
 }
 
@@ -314,6 +330,8 @@
 }
 
 void ls_print_list_elm(DavResource *res, CmdArgs *a) {
+    int recursive = cmd_getoption(a, "recursive") ? 1 : 0;
+    
     char flags[16];
     memset(flags, '-', 15);
     flags[2] = '\0';
@@ -342,19 +360,37 @@
     
     char *date = ls_date_str(res->lastmodified);
     char *size = ls_size_str(res);
+    char *name = recursive ? res->path+1 : res->name;
     printf(
             "%s %*s %10s  %12s  %s\n",
             flags,
             type_width, type,
             size,
             date,
-            res->name);
+            name);
     free(date);
     free(size);
+    
+    if(recursive) {
+        DavResource *child = res->children;
+        while(child) {
+            ls_print_list_elm(child, a);
+            child = child->next;
+        }
+    }
 }
 
 void ls_print_elm(DavResource *res, CmdArgs *a) {
-    printf("%s\n", res->name);
+    int recursive = cmd_getoption(a, "recursive") ? 1 : 0;
+    char *name = recursive ? res->path+1 : res->name;
+    printf("%s\n", name);
+    if(recursive) {
+        DavResource *child = res->children;
+        while(child) {
+            ls_print_elm(child, a);
+            child = child->next;
+        }
+    }
 }
 
 int cmd_get(CmdArgs *a) {
@@ -376,11 +412,24 @@
         sn = dav_session_new(ctx, root);
     }
     
-    DavResource *res = dav_get(sn, path, "U:crypto-key");
+    int recursive = cmd_getoption(a, "recursive") ? 1 : 0;
+    DavResource *res;
+    if(recursive) {
+        res = dav_query(sn, "get U:crypto-key from %s*", path);
+    } else {
+        res = dav_query(sn, "get U:crypto-key from %s", path);
+    }
     if(!res) {
         print_resource_error(sn, path);
         return -1;
     }
+    if(!recursive && res->iscollection) {
+        char *res_url = util_concat_path(sn->base_url, path);
+        fprintf(stderr, "Resource %s is a collection.\n", res_url);
+        fprintf(stderr, "Use the -R option to download collections.\n");
+        free(res_url);
+        return -1;
+    }
     
     /*
      * determine the output file
@@ -388,21 +437,72 @@
      */
     char *outfile = cmd_getoption(a, "output");
     if(!outfile) {
-        outfile = res->name;
+        if(res->iscollection) {
+            outfile = "";
+        } else {
+            outfile = res->name;
+        }
+    } else if(res->iscollection && !strcmp(outfile, "-")) {
+        fprintf(
+                stderr,
+                "Cannot write output to stdout "
+                "if the requested resource is a collection.\n");
+        return -1;
+    }
+    
+    int ret = get_resource(repo, res, a, outfile);
+    
+    return ret;
+}
+
+int get_resource(Repository *repo, DavResource *res, CmdArgs *a, char *out) {
+    size_t outlen = strlen(out);
+    // print some status message in recursive mode
+    if(cmd_getoption(a, "recursive")) {
+        char *res_url = util_concat_path(res->session->base_url, res->path);
+        printf("get: %s\n", res_url);
+        free(res_url);
     }
-    FILE *out = !strcmp(outfile, "-") ? stdout : fopen(outfile, "w");
-    if(!out) {
+    
+    if(res->iscollection) {
+        // create directory
+        if(outlen != 0) {
+            mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+            int ret = mkdir(out, mode);
+            if(ret != 0 && errno != EEXIST) {
+                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;
+    }
+     
+    FILE *fout = !strcmp(out, "-") ? stdout : fopen(out, "w");
+    if(!fout) {
         fprintf(stderr, "cannot open output file\n");
         return -1;
     }
     
-    
     /*
      * if the -p (plain) option is specified we don't decrypt files
      * use a key specified with the -k (key) option, a key from the
      * key property or the repository default key
      */
-    void *out_stream = out;
+    void *out_stream = fout;
     dav_write_func write_func = (dav_write_func)fwrite;
     AESDecrypter *dec = NULL;
     char *plain = cmd_getoption(a, "plain");
@@ -424,14 +524,26 @@
         if(kn) {
             key = get_key(kn);
             if(!key) {
-                fprintf(stderr, "Key %s not found!\nAbort.\n", kn);
+                fprintf(stderr, "Key %s not found!\n", kn);
                 // TODO: free
-                return -1;
+                if(cmd_getoption(a, "recursive")) {
+                    // skip the file in recursive mode
+                    char *res_url = util_concat_path(
+                            res->session->base_url,
+                            res->path);
+                    printf("Skip resource: %s\n", res_url);
+                    free(res_url);
+                    return 0;
+                } else {
+                    printf("Abort.\n");
+                    // abort
+                    return 1;
+                }
             }
         }
         
         if(key) {
-            dec = aes_decrypter_new(key, out, (dav_write_func)fwrite);
+            dec = aes_decrypter_new(key, fout, (dav_write_func)fwrite);
             out_stream = dec;
             write_func = (dav_write_func)aes_write;
         }
@@ -441,9 +553,9 @@
     if(dec) {
         aes_decrypter_close(dec);
     }
-    fclose(out);
-    if(ret && strcmp(outfile, "-")) {
-        unlink(outfile);
+    fclose(fout);
+    if(ret && strcmp(out, "-")) {
+        unlink(out);
     }
     
     return 0;
--- a/dav/main.h	Sat Aug 17 12:04:04 2013 +0200
+++ b/dav/main.h	Sat Aug 17 14:17:48 2013 +0200
@@ -44,6 +44,8 @@
 void ls_print_elm(DavResource *res, CmdArgs *args);
 
 int cmd_get(CmdArgs *args);
+int get_resource(Repository *repo, DavResource *res, CmdArgs *a, char *out);
+
 int cmd_put(CmdArgs *args);
 int cmd_remove(CmdArgs *args);
 int cmd_mkdir(CmdArgs *args);
--- a/dav/optparser.c	Sat Aug 17 12:04:04 2013 +0200
+++ b/dav/optparser.c	Sat Aug 17 14:17:48 2013 +0200
@@ -86,6 +86,10 @@
                         ucx_map_cstr_put(a->options, "type", "");
                         break;
                     }
+                    case 'R': {
+                        ucx_map_cstr_put(a->options, "recursive", "");
+                        break;
+                    }
                     case 'o': {
                         if(!option) {
                             option = "output";
--- a/suncc.mk	Sat Aug 17 12:04:04 2013 +0200
+++ b/suncc.mk	Sat Aug 17 14:17:48 2013 +0200
@@ -31,7 +31,7 @@
 AR = ar
 RM = rm
 
-CFLAGS  = -g -c -xc99
+CFLAGS  = -g -c -xc99 -D_REENTRANT
 COFLAGS = -o
 LDFLAGS =
 LOFLAGS = -o

mercurial