adds dav-sync splitconfig parser

Fri, 22 Mar 2019 13:07:31 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 22 Mar 2019 13:07:31 +0100
changeset 534
9a4857d6444e
parent 533
5b9f20aa88c2
child 535
d814ee31c04f

adds dav-sync splitconfig parser

dav/scfg.c file | annotate | diff | comparison | revisions
dav/scfg.h file | annotate | diff | comparison | revisions
libidav/utils.c file | annotate | diff | comparison | revisions
libidav/utils.h file | annotate | diff | comparison | revisions
--- a/dav/scfg.c	Thu Mar 21 10:51:14 2019 +0100
+++ b/dav/scfg.c	Fri Mar 22 13:07:31 2019 +0100
@@ -250,6 +250,85 @@
     return tagconfig;
 }
 
+static SplitConfig* parse_split(xmlNode *node) {
+    char *pattern = NULL;
+    char *minsize = NULL;
+    char *blocksize = NULL;
+    
+    xmlNode *c = node->children;
+    while(c) {
+        char *value = util_xml_get_text(c);
+        if(xstreq(c->name, "pattern")) {
+            pattern = value;
+        } else if(xstreq(c->name, "minsize")) {
+            minsize = value;
+        } else if(xstreq(c->name, "blocksize")) {
+            blocksize = value;
+        }
+        c = c->next;
+    }
+    
+    uint64_t sz = 0;
+    if(!blocksize) {
+        fprintf(stderr, "splitconfig: no blocksize specified\n");
+        return NULL;
+    }
+    size_t bsz_len = strlen(blocksize);
+    if(bsz_len < 2) {
+        fprintf(stderr, "splitconfig: blocksize too small\n");
+        return NULL;
+    }
+    
+    if(!util_szstrtouint(blocksize, &sz)) {
+        fprintf(stderr, "splitconfig: blocksize is not a number\n");
+        return NULL;
+    }
+    
+    if(!pattern && !minsize) {
+        fprintf(stderr, "splitconfig: pattern or minsize must be specified\n");
+        return NULL;
+    }
+    
+    int64_t minsz = -1;
+    if(minsize) {
+        uint64_t m;
+        if(!util_szstrtouint(minsize, &m)) {
+            fprintf(stderr, "splitconfig: minsize is not a number\n");
+            return NULL;
+        }
+        minsz = (int64_t)m;
+    }
+    
+    SplitConfig *sc = calloc(1, sizeof(SplitConfig));
+    sc->pattern = pattern ? strdup(pattern) : NULL;
+    sc->minsize = minsz;
+    sc->blocksize = (size_t)sz;
+    return sc;    
+}
+
+static UcxList* parse_splitconfig(xmlNode *node, int *error) {
+    UcxList *splitconfig = NULL;
+    int err = 0;
+    xmlNode *c = node->children;
+    while(c) {
+        if(c->type == XML_ELEMENT_NODE && xstreq(c->name, "split")) {
+            SplitConfig *sc = parse_split(c);
+            if(sc) {
+                splitconfig = ucx_list_append(splitconfig, sc);
+            } else {
+                err = 1;
+                break;
+            }
+        }
+        c = c->next;
+    }
+    
+    if(error) {
+        *error = err;
+    }
+    return splitconfig;
+}
+
 static Versioning* parse_versioning_config(xmlNode *node) {
     Versioning v;
     v.always = FALSE;
@@ -299,6 +378,7 @@
     UcxList *include = NULL;
     UcxList *exclude = NULL;
     UcxList *tagfilter = NULL;
+    UcxList *splitconfig = NULL;
     int max_retry = 0;
     int allow_cmd = SYNC_CMD_PULL | SYNC_CMD_PUSH
                   | SYNC_CMD_ARCHIVE | SYNC_CMD_RESTORE;
@@ -341,6 +421,12 @@
                 database = value;
             } else if(xstreq(node->name, "tagconfig")) {
                 tagconfig = parse_tagconfig(node);
+            } else if(xstreq(node->name, "splitconfig")) {
+                int err = 0;
+                splitconfig = parse_splitconfig(node, &err);
+                if(err) {
+                    return 1;
+                }
             } else if(xstreq(node->name, "metadata")) {
                 char *error = NULL;
                 metadata = parse_finfo_settings(value, &error);
--- a/dav/scfg.h	Thu Mar 21 10:51:14 2019 +0100
+++ b/dav/scfg.h	Fri Mar 22 13:07:31 2019 +0100
@@ -49,8 +49,9 @@
 #define DEFAULT_TAG_XATTR "tags"
 #define MACOS_TAG_XATTR "com.apple.metadata:_kMDItemUserTags"
     
-typedef struct TagConfig  TagConfig;
-typedef struct Versioning Versioning;
+typedef struct TagConfig   TagConfig;
+typedef struct Versioning  Versioning;
+typedef struct SplitConfig SplitConfig;
     
 typedef struct SyncDirectory {
     char *name;
@@ -64,6 +65,7 @@
     UcxList *include;
     UcxList *exclude;
     UcxList *tagfilter;
+    UcxList *splitconfig;
     uint32_t metadata;
     int max_retry;
     int allow_cmd;
@@ -74,6 +76,23 @@
     uint32_t db_settings;
 } SyncDirectory;
 
+struct SplitConfig {
+    /*
+     * path regex pattern or NULL
+     */
+    char *pattern;
+    
+    /*
+     * minimum file size for activating file splitting
+     * a value of -1 means no size restriction
+     */
+    int64_t minsize;
+    
+    /*
+     * split files into blocks with this size
+     */
+    size_t blocksize;
+};
 
 enum TagFormat {
     TAG_FORMAT_TEXT = 0,
--- a/libidav/utils.c	Thu Mar 21 10:51:14 2019 +0100
+++ b/libidav/utils.c	Fri Mar 22 13:07:31 2019 +0100
@@ -224,6 +224,51 @@
     }
 }
 
+int util_szstrtouint(const char *str, uint64_t *value) {
+    char *end;
+    errno = 0;
+    size_t len = strlen(str);
+    uint64_t val = strtoull(str, &end, 0);
+    if(end == str+len) {
+        *value = val;
+        return 1;
+    } else if(end == str+len-1) {
+        uint64_t mul = 1;
+        switch(end[0]) {
+            case 'k':
+            case 'K': mul = 1024; break;
+            case 'm':
+            case 'M': mul = 1024*1024; break;
+            case 'g':
+            case 'G': mul = 1024*1024*1024; break;
+            default: return 0;
+        }
+        
+        uint64_t result = 0;
+        if(util_uint_mul(val, mul, &result)) {
+            return 0;
+        }
+        *value = result;
+        return 1;
+    }
+    return 0;
+}
+
+int util_uint_mul(uint64_t a, uint64_t b, uint64_t *result) {
+    if(a == 0 || b == 0) {
+        *result = 0;
+        return 0;
+    }
+    uint64_t r = a * b;
+    if(r / b == a) {
+        *result = r;
+        return 0;
+    } else {
+        *result = 0;
+        return 1;
+    }
+}
+
 char* util_url_base(char *url) {
     sstr_t u = sstr(url);
     int len = u.length;
--- a/libidav/utils.h	Thu Mar 21 10:51:14 2019 +0100
+++ b/libidav/utils.h	Fri Mar 22 13:07:31 2019 +0100
@@ -80,6 +80,9 @@
 int util_getboolean(char *v);
 int util_strtouint(char *str, uint64_t *value);
 int util_strtoint(char *str, int64_t *value);
+int util_szstrtouint(const char *str, uint64_t *value);
+
+int util_uint_mul(uint64_t a, uint64_t b, uint64_t *result);
 
 char* util_xml_get_text(const xmlNode *elm);
 

mercurial