added include / exclude patterns

Tue, 05 Aug 2014 14:00:35 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 05 Aug 2014 14:00:35 +0200
changeset 58
1708cba82ca3
parent 57
3c1ce5f203d7
child 59
ec68175aad25

added include / exclude patterns

dav/scfg.c file | annotate | diff | comparison | revisions
dav/scfg.h file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
--- a/dav/scfg.c	Tue Aug 05 13:05:03 2014 +0200
+++ b/dav/scfg.c	Tue Aug 05 14:00:35 2014 +0200
@@ -29,7 +29,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
 #include <libidav/utils.h>
 #include <ucx/map.h>
 
@@ -76,12 +75,24 @@
     return ret;
 }
 
+static UcxList* add_regex_pattern(UcxList *list, char *value) {
+    regex_t *regex = malloc(sizeof(regex_t));
+    if (regcomp(regex, value, REG_EXTENDED|REG_NOSUB)) {
+        fprintf(stderr, "Invalid regular expression (%s) ... skipped\n", value);
+        return list;
+    } else {
+        return ucx_list_append(list, regex);
+    }
+}
+
 int scfg_load_directory(xmlNode *node) {
     char *name = NULL;
     char *path = NULL;
     char *collection = NULL;
     char *repository = NULL;
     char *database = NULL;
+    UcxList *include = NULL;
+    UcxList *exclude = NULL;
     
     node = node->children;
     while(node) {
@@ -99,6 +110,10 @@
                 repository = value;
             } else if(xstreq(node->name, "database")) {
                 database = value;
+            } else if(xstreq(node->name, "include")) {
+                include = add_regex_pattern(include, value);
+            } else if(xstreq(node->name, "exclude")) {
+                exclude = add_regex_pattern(exclude, value);
             }
         }
         node = node->next;
@@ -127,6 +142,20 @@
     dir->collection = collection ? strdup(collection) : NULL;
     dir->repository = strdup(repository);
     dir->database = strdup(database);
+    if (include) {
+        dir->include = include;
+    } else {
+        regex_t *matchall = malloc(sizeof(regex_t));
+        regcomp(matchall, ".*", REG_NOSUB);
+        dir->include = ucx_list_append(NULL, matchall);
+    }
+    if (exclude) {
+        dir->exclude = exclude;
+    } else {
+        regex_t *matchnothing = malloc(sizeof(regex_t));
+        regcomp(matchnothing, "///", REG_NOSUB);
+        dir->exclude = ucx_list_append(NULL, matchnothing);
+    }
     
     ucx_map_cstr_put(directories, name, dir);
     
@@ -134,20 +163,23 @@
 }
 
 void scfg_print_example() {
-    fprintf(stderr, "example sync.xml\n\n");
-    fprintf(stderr, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
-    fprintf(stderr, "<configuration>\n");
-    fprintf(stderr, "  <directory>\n");
-    fprintf(stderr, "    <!-- identifier -->\n");
-    fprintf(stderr, "    <name>documents</name>\n\n");
-    fprintf(stderr, "    <!-- local path to the directory -->\n");
-    fprintf(stderr, "    <path>/home/user/Documents</path>\n\n");
-    fprintf(stderr, "    <!-- repository name specified in config.xml -->\n");
-    fprintf(stderr, "    <repository>server</repository>\n\n");
-    fprintf(stderr, "    <!-- database file name -->\n");
-    fprintf(stderr, "    <database>documents-db.xml</database>\n");
-    fprintf(stderr, "  </directory>\n");
-    fprintf(stderr, "</configuration>\n");
+    fprintf(stderr, 
+        "example sync.xml\n\n"
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+        "<configuration>\n"
+        "  <directory>\n"
+        "    <!-- identifier -->\n"
+        "    <name>documents</name>\n\n"
+        "    <!-- local path to the directory -->\n"
+        "    <path>/home/user/Documents</path>\n\n"
+        "    <!-- repository name specified in config.xml -->\n"
+        "    <repository>server</repository>\n\n"
+        "    <!-- collection to synchronize (optional) -->\n"
+        "    <collection>somecol</collection>\n\n"
+        "    <!-- database file name -->\n"
+        "    <database>documents-db.xml</database>\n"
+        "  </directory>\n"
+        "</configuration>\n");
 }
 
 SyncDirectory* scfg_get_dir(char *name) {
--- a/dav/scfg.h	Tue Aug 05 13:05:03 2014 +0200
+++ b/dav/scfg.h	Tue Aug 05 14:00:35 2014 +0200
@@ -32,6 +32,7 @@
 #include <ucx/string.h>
 #include <stdbool.h>
 #include <libidav/webdav.h>
+#include <regex.h>
 
 #ifdef	__cplusplus
 extern "C" {
@@ -43,6 +44,8 @@
     char *collection;
     char *repository;
     char *database;
+    UcxList *include;
+    UcxList *exclude;
 } SyncDirectory;
 
 int load_sync_config();
--- a/dav/sync.c	Tue Aug 05 13:05:03 2014 +0200
+++ b/dav/sync.c	Tue Aug 05 14:00:35 2014 +0200
@@ -91,6 +91,8 @@
         ret = cmd_sync(args);
     }
     
+    // TODO: cleanup sync config (don't forget to call regfree for regex)
+    
     return ret;
 }
 
@@ -106,6 +108,25 @@
     fprintf(stderr, "        -r         Read changes from stdin\n\n");
 }
 
+static int res_matches_filter(SyncDirectory *dir, char *res_path) {
+    
+    UCX_FOREACH(inc, dir->include) {
+        regex_t* pattern = (regex_t*) inc->data;
+        if (regexec(pattern, res_path, 0, NULL, 0)) {
+            return 1;
+        }
+    }
+    
+    UCX_FOREACH(exc, dir->exclude) {
+        regex_t* pattern = (regex_t*) exc->data;
+        if (!regexec(pattern, res_path, 0, NULL, 0)) {
+            return 1;
+        }
+    }
+    
+    return 0;
+}
+
 int cmd_pull(CmdArgs *a) {
     if(a->argc != 1) {
         fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many");
@@ -164,7 +185,12 @@
         DavResource *res = stack->data;
         stack = ucx_list_remove(stack, stack);
          
-        while(res) { 
+        while(res) {
+            if (res_matches_filter(dir, res->path)) {
+                res = res->next;
+                continue;
+            }
+            
             // download the resource
             if(sync_get_resource(a, dir, res, db)) {
                 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path);
@@ -184,12 +210,15 @@
     UcxMapIterator i = ucx_map_iterator(db->resources);
     LocalResource *local;
     UCX_MAP_FOREACH(key, local, i) {
+        if (res_matches_filter(dir, local->path)) {
+            continue;
+        }
         sync_remove_resource(dir, local);
     }
     ucx_map_free(db->resources);
     db->resources = svrres;
     
-    // TODO: cleanup
+    // TODO: cleanup - BUT DONT CLEANUP SYNC CONFIG (do this in main!)
     
     // store db
     if(store_db(db, dir->database)) {
@@ -256,7 +285,6 @@
     int ret = 0;
     if(res->iscollection) {
         mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
-        //printf("mkdir %s\n", local_path);
         if(util_mkdir(local_path, mode) && errno != EEXIST) {
             ret = -1;
         }
@@ -395,19 +423,20 @@
     sn->key = dav_context_get_key(ctx, repo->default_key);
     
     // upload all changed files
-    //UcxList *resources = local_scan(dir, db);
-    //UcxList *resources = read_changes(dir, db);
     UcxList *resources = cmd_getoption(a, "read") ?
             read_changes(dir, db) : local_scan(dir, db);
     
     UCX_FOREACH(elm, resources) {
         LocalResource *local_res = elm->data;
-        printf("put: %s\n", local_res->path);
-        DavResource *res = dav_resource_new(sn, local_res->path);
-        if(!sync_put_resource(dir, res, db)) {
+        if (!res_matches_filter(dir, local_res->path+1)) {
+            printf("put: %s\n", local_res->path);
             ucx_map_cstr_put(db->resources, local_res->path, local_res);
+            DavResource *res = dav_resource_new(sn, local_res->path);
+            if(sync_put_resource(dir, res, db)) {
+                ucx_map_cstr_remove(db->resources, local_res->path);
+            }
+            dav_resource_free(res);
         }
-        dav_resource_free(res);
     }
     ucx_list_free(resources);
     
@@ -519,8 +548,6 @@
                     resources = ucx_list_append(resources, res);
                 }
             } else if(!sstrcmp(name, S("remove"))) {
-                int isdir;
-                //LocalResource *res = path_to_local_resource(dir, db, value.ptr, &isdir);
                 LocalResource *res = calloc(1, sizeof(LocalResource));
                 res->path = sstrdup(value).ptr;
                 if(res) {
@@ -539,6 +566,7 @@
 }
 
 LocalResource* path_to_local_resource(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir) {
+    
     char *file_path = util_concat_path(dir->path, path);
     struct stat s;
     if(stat(file_path, &s)) {
@@ -566,14 +594,13 @@
                 res->last_modified = s.st_mtime;
                 
                 return res;
-            }                       
+            }
         } else {
             LocalResource *res = calloc(1, sizeof(LocalResource));
             res->path = strdup(path);
             res->etag = NULL;
             res->last_modified = s.st_mtime;
             res->size = s.st_size;
-            //ucx_map_cstr_put(db->resources, res->path, res);
             return res;
         }
     } else {

mercurial