dav/config.c

changeset 795
05647e862a17
parent 747
efbd59642577
child 796
81e0f67386a6
--- a/dav/config.c	Sun Sep 17 13:51:01 2023 +0200
+++ b/dav/config.c	Sat Sep 30 16:33:47 2023 +0200
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <sys/types.h>
 #include <cx/hash_map.h>
+#include <cx/utils.h>
 #include <errno.h>
 #include <libxml/tree.h>
 
@@ -38,7 +39,10 @@
 #include "config.h"
 #include "main.h"
 #include "pwd.h"
+#include "system.h"
+
 #include <libidav/utils.h>
+#include <libidav/config.h>
 
 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
 #define xstrEQ(a,b) !xmlStrcasecmp(BAD_CAST a, BAD_CAST b)
@@ -64,6 +68,7 @@
 static CxMap *repos;
 static CxMap *keys;
 
+static DavConfig *davconfig;
 static PwdStore *pstore;
 
 static char *secretstore_unlock_cmd;
@@ -101,6 +106,20 @@
     return path;
 }
 
+cxmutstr config_load_file(const char *path) {
+    FILE *file = sys_fopen(path, "r");
+    if(!file) {
+        return (cxmutstr){NULL,0};
+    }
+    
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 1024, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
+    cx_stream_copy(file, &buf, (cx_read_func)fread, (cx_write_func)cxBufferWrite);
+    fclose(file);
+    
+    return cx_mutstrn(buf.space, buf.size);
+}
+
 int load_config(DavContext *ctx) {
     context = ctx;
     // TODO: free the config somewhere
@@ -127,6 +146,12 @@
     }
     
     xmlDoc *doc = xmlReadFile(file, NULL, 0);
+    
+    cxmutstr config_content = config_load_file(file);
+    int config_error;
+    davconfig = dav_config_load(config_content, &config_error);
+    free(config_content.ptr);
+    
     free(file);
     if(!doc) {
         fprintf(stderr, "Cannot load config.xml\n");
@@ -162,6 +187,39 @@
     return ret;
 }
 
+DavConfig* get_config(void) {
+    return davconfig;
+}
+
+int store_config(void) {
+    if(check_config_dir()) {
+        return 1;
+    }
+    
+    CxBuffer *buf = dav_config2buf(davconfig);
+    if(!buf) {
+        return 1;
+    }
+    
+    char *file = util_concat_path(ENV_HOME, ".dav/config.xml");
+    FILE *cout = sys_fopen(file, "w");
+    if(!cout) {
+        cxBufferFree(buf);
+        return 1;
+    }
+    
+    // should only fail if we run out of disk space or something like that
+    // in that case, the config file is only destroyed
+    // could only be prevented, if we write to a temp file first and than
+    // rename it
+    fwrite(buf->space, buf->size, 1, cout);
+    
+    cxBufferFree(buf);
+    fclose(cout);
+    
+    return 0;
+}
+
 void free_config(void) {
     if(repos) {
         CxIterator i = cxMapIteratorValues(repos);
@@ -813,7 +871,7 @@
 
 
 
-
+/*
 Repository* url2repo_s(cxstring url, char **path) {
     *path = NULL;
     
@@ -867,6 +925,7 @@
 Repository* url2repo(const char *url, char **path) {
     return url2repo_s(cx_str(url), path);
 }
+*/
 
 static int decrypt_secrets(CmdArgs *a, PwdStore *secrets) {
     if(cmd_getoption(a, "noinput")) {
@@ -960,7 +1019,7 @@
 }
 
 
-static int get_location_credentials(CmdArgs *a, Repository *repo, char *path, char **user, char **password) {
+static int get_location_credentials(CmdArgs *a, DavCfgRepository *repo, const char *path, char **user, char **password) {
     PwdStore *secrets = get_pwdstore();
     if(!secrets) {
         return 0;
@@ -976,19 +1035,20 @@
     cx_foreach(PwdIndexEntry*, e, i) {
         CxIterator entry_iter = cxListIterator(e->locations);
         cx_foreach(char *, loc, entry_iter) {
-            char *path;
-            Repository *r = url2repo(loc, &path);
+            cxmutstr rpath;
+            DavCfgRepository *r = dav_config_url2repo_s(davconfig, cx_str(loc), &rpath);
             CredLocation *urlentry = calloc(1, sizeof(CredLocation));
             urlentry->id = e->id;
-            urlentry->location = util_concat_path(r->url, path);
+            urlentry->location = util_concat_path_s(cx_strcast(r->url.value), cx_strcast(rpath)).ptr;
             cxListAdd(locations, urlentry);
+            free(rpath.ptr);
         }
     }
     // the list must be sorted
     cxListSort(locations);
     
     // create full request url string and remove protocol prefix
-    cxmutstr req_url_proto = cx_mutstr(util_concat_path(repo->url, path));
+    cxmutstr req_url_proto = util_concat_path_s(cx_strcast(repo->url.value), cx_str(path));
     cxstring req_url = cx_strcast(req_url_proto);
     if(cx_strprefix(req_url, CX_STR("http://"))) {
         req_url = cx_strsubs(req_url, 7);
@@ -1034,25 +1094,31 @@
     return ret;
 }
 
-DavSession* connect_to_repo(DavContext *ctx, Repository *repo, char *path, dav_auth_func authfunc, CmdArgs *a) {
-    char *user = repo->user;
-    char *password = repo->password;
+DavSession* connect_to_repo(DavContext *ctx, DavCfgRepository *repo, const char *path, dav_auth_func authfunc, CmdArgs *a) {
+    cxmutstr decodedpw = dav_repository_get_decodedpassword(repo);
+    
+    char *user = repo->user.value.ptr;
+    char *password = decodedpw.ptr;
     
     if(!user && !password) {
-        if(!get_stored_credentials(a, repo->stored_user, &user, &password)) {
+        if(!get_stored_credentials(a, repo->stored_user.value.ptr, &user, &password)) {
             get_location_credentials(a, repo, path, &user, &password);
         }
     }
     
-    DavSession *sn = dav_session_new_auth(ctx, repo->url, user, password);
-    sn->flags = get_repository_flags(repo);
-    sn->key = dav_context_get_key(ctx, repo->default_key);
+    DavSession *sn = dav_session_new_auth(ctx, repo->url.value.ptr, user, password);
+    if(password) {
+        free(password);
+    }
+    
+    sn->flags = dav_repository_get_flags(repo);
+    sn->key = dav_context_get_key(ctx, repo->default_key.value.ptr);
     curl_easy_setopt(sn->handle, CURLOPT_HTTPAUTH, repo->authmethods);
     curl_easy_setopt(sn->handle, CURLOPT_SSLVERSION, repo->ssl_version);
-    if(repo->cert) {
-        curl_easy_setopt(sn->handle, CURLOPT_CAINFO, repo->cert);
+    if(repo->cert.value.ptr) {
+        curl_easy_setopt(sn->handle, CURLOPT_CAINFO, repo->cert.value.ptr);
     }
-    if(!repo->verification || cmd_getoption(a, "insecure")) {
+    if(!repo->verification.value || cmd_getoption(a, "insecure")) {
         curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYPEER, 0);
         curl_easy_setopt(sn->handle, CURLOPT_SSL_VERIFYHOST, 0);
     }

mercurial