dav/main.c

changeset 5
88625853ae74
parent 4
ae5a98f0545c
child 8
4503498deb22
--- a/dav/main.c	Sat Dec 01 20:34:55 2012 +0100
+++ b/dav/main.c	Mon Aug 12 14:40:19 2013 +0200
@@ -29,13 +29,17 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #include <unistd.h>
 #include <libxml/xmlerror.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <ucx/string.h>
 
-#include "propfind.h"
+#include "webdav.h"
 #include "utils.h"
+#include "config.h"
+#include "crypto.h"
 #include "main.h"
 
 void xmlerrorfnc(void * ctx, const char * msg, ... ) {
@@ -43,8 +47,9 @@
 }
 
 int main(int argc, char **argv) {
-    xmlGenericErrorFunc fnc = xmlerrorfnc;
+   xmlGenericErrorFunc fnc = xmlerrorfnc;
     initGenericErrorDefaultFunc(&fnc);
+    load_config();
     
     if(argc < 2) {
         print_usage();
@@ -67,94 +72,71 @@
     
 }
 
-void get_file(CURL *curl, char *url, char *path) {
-    curl_easy_setopt(curl, CURLOPT_URL, url);
-    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
-    
-    FILE *out = fopen(path, "w");
+void url_get_parts(char *url, char **root, char **path) {
+    size_t ulen = strlen(url);
+    *root = NULL;
+    *path = NULL;
     
-    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
-    curl_easy_setopt(curl, CURLOPT_WRITEDATA, out);
-    
-    CURLcode res = curl_easy_perform(curl);
+    int s;
+    if(ulen > 7 && !strncmp(url, "http://", 7)) {
+        s = 7;
+    } else if(ulen > 8 && !strncmp(url, "https://", 8)) {
+        s = 8;
+    } else {
+        s = 1;
+    }
     
-    fclose(out);
-    // handle some errors (http://curl.haxx.se/libcurl/c/libcurl-errors.html)
-    switch(res) {
-        case CURLE_OK: {
+    for(int i=s;i<ulen;i++) {
+        char c = url[i];
+        if(c == '/') {
+            sstr_t r = sstrn(url, i);
+            sstr_t p = sstrsubs(sstr(url), i);
+            if(p.length == 0) {
+                p = sstrn("/", 1);
+            }
+            *root = sstrdup(r).ptr;
+            *path = sstrdup(p).ptr;
             return;
         }
-        case CURLE_REMOTE_ACCESS_DENIED: {
-            
-            break;
-        }
-        case CURLE_SSL_CONNECT_ERROR: {
-            
-            break;
-        }
-        case CURLE_LOGIN_DENIED: {
-            
-            break;
-        }
-        case CURLE_REMOTE_FILE_NOT_FOUND: {
-            
-            break;
-        }
-        default: {
-            
-            break;
-        }
     }
     
-    unlink(path);
+    *root = strdup(url);
+    *path = strdup("/");
 }
 
-void put_file(CURL *curl, char *url, char *path) {
-    curl_easy_setopt(curl, CURLOPT_URL, url);
-    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
-    
-    curl_easy_setopt(curl, CURLOPT_PUT, 1L);
-    
-    struct stat s;
-    if(stat(path, &s) != 0) {
-        perror("stat");
-        fprintf(stderr, "file: %s\n", path);
-        return;
-    }
-    
-    FILE *in = fopen(path, "r");
-    
-    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
-    curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread);
-    curl_easy_setopt(curl, CURLOPT_READDATA, in);
-    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)s.st_size);
-    
-    CURLcode res = curl_easy_perform(curl);
-    fclose(in);
-    
-    if(res != CURLE_OK) {
-        fprintf(stderr, "put_file: %s\n", curl_easy_strerror(res));
-    }
-}
 
 int cmd_list(int argc, char **argv) {
     if(argc == 0) {
         return -1;
     }
     
-    char *url = argv[0]; // TODO: use arg as url or alias
     
-    CURL *curl = curl_easy_init();
-    curl_easy_setopt(curl, CURLOPT_URL, url);
-    Propfind *propfind = dav_propfind(curl);
+    DavContext *ctx = dav_context_new();
+    DavSession *sn = NULL;
+    char *url = argv[0];
+    char *root = NULL;
+    char *path = NULL;
+    url_get_parts(url, &root, &path);
     
-    UCX_FOREACH(UcxDlist*, propfind->children, ch) {
-        DavResource *resource = ch->data;
-        printf("%s\n", resource->name);
+    Repository *repo = get_repository(root);
+    if(repo) {
+        sn = dav_session_new_auth(ctx, repo->url, repo->user, repo->password);
+    } else {
+        sn = dav_session_new(ctx, root);
     }
     
-    // TODO: free propfind stuff
-    curl_easy_cleanup(curl);
+    //printf("baseurl: %s\n", sn->base_url);
+    
+    DavResource *ls = dav_get(sn, path, NULL);
+    if(!ls) {
+        fprintf(stderr, "error\n");
+        return -1;
+    }
+    DavResource *child = ls->children;
+    while(child) {
+        printf("%s\n", child->name);
+        child = child->next;
+    }
     
     return 0;
 }
@@ -164,51 +146,107 @@
         return -1;
     }
     
-    char *url = argv[0]; // TODO: use arg as url or alias
-    
-    CURL *curl = curl_easy_init();
-    curl_easy_setopt(curl, CURLOPT_URL, url);
-    Propfind *propfind = dav_propfind(curl);
+    DavContext *ctx = dav_context_new();
+    dav_add_namespace(ctx, "U", "http://www.uap-core.de/");
+    DavSession *sn = NULL;
+    char *url = argv[0];
+    char *root = NULL;
+    char *path = NULL;
+    url_get_parts(url, &root, &path);
     
-    if(propfind->resource->collection) {
-        UCX_FOREACH(UcxDlist*, propfind->children, chd) {
-            DavResource *resource = chd->data;
-            if(!resource->collection) {
-                char *resurl = util_child_url(propfind->url, resource->href);
-                get_file(curl, resurl, resource->name);
-            }
-        }
+    Repository *repo = get_repository(root);
+    if(repo) {
+        sn = dav_session_new_auth(ctx, repo->url, repo->user, repo->password);
     } else {
-        get_file(curl, propfind->url, propfind->resource->name);
+        sn = dav_session_new(ctx, root);
     }
     
-    // TODO: free propfind stuff
-    curl_easy_cleanup(curl);
+    DavResource *res = dav_get(sn, path, "U:crypto-key");
+    if(!res) {
+        fprintf(stderr, "error\n");
+        return -1;
+    }
+    FILE *out = fopen(res->name, "w");
+    if(!out) {
+        fprintf(stderr, "cannot open output file\n");
+        return -1;
+    }
+    
+    AESDecrypter *dec = NULL;
+    char *keyprop = dav_get_property_ns(res, "http://www.uap-core.de/", "crypto-key");
+    if(repo) {
+        Key *key = get_key(keyprop);
+        if(repo->encrypt && key) {
+            dec = aes_decrypter_new(key, out, (dav_write_func)fwrite);
+        }
+    }
+    
+    int ret;
+    if(dec && keyprop) {
+        ret = dav_get_content(res, dec, (dav_write_func)aes_write);
+    } else {
+        ret = dav_get_content(res, out, (dav_write_func)fwrite);
+    }
+    if(dec) {
+        aes_decrypter_close(dec);
+    }
+    fclose(out);
+    if(ret) {
+        unlink(res->name);
+    }
     
     return 0;
 }
 
 int cmd_put(int argc, char **argv) {
-    if(argc == 0) {
+    if(argc < 2) {
         return -1;
     }
     
-    char *url = argv[0]; // TODO: use arg as url or alias
-    char *path;
-    if(argc > 0) {
-        path = argv[1];
+    DavContext *ctx = dav_context_new();
+    DavSession *sn = NULL;
+    char *url = argv[0];
+    char *file = argv[1];
+    char *root = NULL;
+    char *path = 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);
     } else {
-        fprintf(stderr, "put: missing file argument\n");
-        return -1;
+        sn = dav_session_new(ctx, root);
     }
     
-    char *uploadurl = util_upload_url(url, path);
-    
-    CURL *curl = curl_easy_init();
+    DavResource *res = dav_resource_new(sn, path);
+    if(!res) {
+        fprintf(stderr, "error\n");
+        return -1;
+    }
+    FILE *in = fopen(file, "r");
+    if(!in) {
+        fprintf(stderr, "cannot open input file\n");
+        return -1;
+    }
+    AESEncrypter *enc = NULL;
+    if(repo) {
+        Key *key = get_key(repo->default_key);
+        if(repo->encrypt && key) {
+            enc = aes_encrypter_new(key, in, (dav_read_func)fread);
+        }
+    }
+    if(enc) {
+        dav_set_content(res, enc, (dav_read_func)aes_read);
+        dav_set_property_ns(res, "http://www.uap-core.de/", "crypto-key", repo->default_key);
+    } else {
+        dav_set_content(res, in, (dav_read_func)fread);
+    }
     
-    // TODO: check possible name conflicts
-    
-    put_file(curl, uploadurl, path);
-    
-    curl_easy_cleanup(curl);
+    if(dav_store(res)) {
+        fprintf(stderr, "cannot upload file\n");
+        fclose(in);
+        return -1;
+    }
+    fclose(in);
+    return 0;
 }

mercurial