Tue, 05 Aug 2014 14:00:35 +0200
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 {