Fri, 13 Jun 2014 13:52:59 +0200
added new sync tool
dav/Makefile | file | annotate | diff | comparison | revisions | |
dav/db.c | file | annotate | diff | comparison | revisions | |
dav/db.h | file | annotate | diff | comparison | revisions | |
dav/main.c | file | annotate | diff | comparison | revisions | |
dav/scfg.c | file | annotate | diff | comparison | revisions | |
dav/scfg.h | file | annotate | diff | comparison | revisions | |
dav/sopt.c | file | annotate | diff | comparison | revisions | |
dav/sopt.h | file | annotate | diff | comparison | revisions | |
dav/sync.c | file | annotate | diff | comparison | revisions | |
dav/sync.h | file | annotate | diff | comparison | revisions | |
libidav/webdav.c | file | annotate | diff | comparison | revisions |
--- a/dav/Makefile Thu Jun 05 16:53:53 2014 +0200 +++ b/dav/Makefile Fri Jun 13 13:52:59 2014 +0200 @@ -28,17 +28,29 @@ include ../$(CONF).mk -SRC = main.c -SRC += config.c -SRC += optparser.c +DAV_SRC = main.c +DAV_SRC += config.c +DAV_SRC += optparser.c + +SYNC_SRC = sync.c +SYNC_SRC += config.c +SYNC_SRC += scfg.c +SYNC_SRC += sopt.c +SYNC_SRC += db.c -OBJ = $(SRC:%.c=../build/tool/%.$(OBJ_EXT)) +DAV_OBJ = $(DAV_SRC:%.c=../build/tool/%.$(OBJ_EXT)) +SYNC_OBJ = $(SYNC_SRC:%.c=../build/tool/%.$(OBJ_EXT)) + +all: ../build/dav ../build/dav-sync -all: ../build/dav +../build/dav: $(DAV_OBJ) ../build/libidav.$(LIB_EXT) + $(LD) -o ../build/dav$(APP_EXT) $(DAV_OBJ) \ + ../build/libidav.$(LIB_EXT) ../build/libucx.$(LIB_EXT) \ + $(LDFLAGS) $(DAV_LDFLAGS) -../build/dav: $(OBJ) - $(LD) -o ../build/dav$(APP_EXT) $(OBJ) \ +../build/dav-sync: $(SYNC_OBJ) ../build/libidav.$(LIB_EXT) + $(LD) -o ../build/dav-sync$(APP_EXT) $(SYNC_OBJ) \ ../build/libidav.$(LIB_EXT) ../build/libucx.$(LIB_EXT) \ $(LDFLAGS) $(DAV_LDFLAGS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/db.c Fri Jun 13 13:52:59 2014 +0200 @@ -0,0 +1,146 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "db.h" + +#include <libidav/utils.h> + + +#define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) + +#ifdef _WIN32 +#define ENV_HOME getenv("USERPROFILE") +#else +#define ENV_HOME getenv("HOME") +#endif /* _WIN32 */ + +UcxMap* load_db(char *name) { + char *dav_dir = util_concat_path(ENV_HOME, ".dav"); + char *db_file = util_concat_path(dav_dir, name); + free(dav_dir); + + xmlTextReaderPtr reader = xmlReaderForFile(db_file, NULL, 0); + if(!reader) { + fprintf(stderr, "Cannot open database file: %s\n", db_file); + free(db_file); + return NULL; + } + free(db_file); + + UcxMap *map = ucx_map_new(2048); + int error = 0; + while(xmlTextReaderRead(reader)) { + int type = xmlTextReaderNodeType(reader); + const xmlChar *name = xmlTextReaderConstName(reader); + + if(type == XML_READER_TYPE_ELEMENT) { + if(xstreq(name, "resource")) { + LocalResource *res = process_resource(reader); + if(res) { + ucx_map_cstr_put(map, res->path, res); + } else { + error = 1; + break; + } + } + } + } + + xmlFreeTextReader(reader); + if(error) { + // TODO: free resources and map + return NULL; + } else { + return map; + } +} + +LocalResource* process_resource(xmlTextReaderPtr reader) { + LocalResource *res = calloc(1, sizeof(LocalResource)); + + int field = -1; + while(xmlTextReaderRead(reader)) { + int type = xmlTextReaderNodeType(reader); + const xmlChar *name = xmlTextReaderConstName(reader); + + if(type == XML_READER_TYPE_ELEMENT) { + if(xstreq(name, "path")) { + field = 0; + } else if(xstreq(name, "etag")) { + field = 1; + } else if(xstreq(name, "lastmodified")) { + field = 2; + } else if(xstreq(name, "size")) { + field = 3; + } + } else if(type == XML_READER_TYPE_TEXT) { + const xmlChar *value = xmlTextReaderConstValue(reader); + int b = 0; + switch(field) { + case 0: { + res->name = strdup((char*)value); + break; + } + case 1: { + res->etag = strdup((char*)value); + break; + } + case 2: { + res->last_modified = util_parse_lastmodified((char*)value); + break; + } + case 3: { + res->size = atoi((char*)value); + break; + } + } + } else if(XML_READER_TYPE_END_ELEMENT) { + if(xstreq(name, "resource")) { + break; + } else { + field = -1; + } + } + } + + if(!res->name || !res->path || res->last_modified == 0) { + // TODO: free res + return NULL; + } else { + return res; + } +} + +int store_db(UcxMap *db, char *name) { + // TODO: + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/db.h Fri Jun 13 13:52:59 2014 +0200 @@ -0,0 +1,63 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DB_H +#define DB_H + +#include <libidav/webdav.h> +#include <ucx/map.h> +#include <time.h> + +#include <libxml/xmlreader.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct LocalResource LocalResource; + +struct LocalResource { + char *name; + char *path; + char *etag; + time_t last_modified; + off_t size; +}; + +UcxMap* load_db(char *name); +int store_db(UcxMap *db, char *name); + +LocalResource* process_resource(xmlTextReaderPtr reader); + + +#ifdef __cplusplus +} +#endif + +#endif /* DB_H */ +
--- a/dav/main.c Thu Jun 05 16:53:53 2014 +0200 +++ b/dav/main.c Fri Jun 13 13:52:59 2014 +0200 @@ -45,7 +45,7 @@ static DavContext *ctx; -void xmlerrorfnc(void * c, const char * msg, ... ) { +static void xmlerrorfnc(void * c, const char * msg, ... ) { // nothing }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/scfg.c Fri Jun 13 13:52:59 2014 +0200 @@ -0,0 +1,151 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <libidav/utils.h> +#include <ucx/map.h> + +#include "scfg.h" + +#define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) + +#ifdef _WIN32 +#define ENV_HOME getenv("USERPROFILE") +#else +#define ENV_HOME getenv("HOME") +#endif /* _WIN32 */ + +static UcxMap *directories; + +int load_sync_config() { + char *file = util_concat_path(ENV_HOME, ".dav/sync.xml"); + xmlDoc *doc = xmlReadFile(file, NULL, 0); + if(!doc) { + fprintf(stderr, "Missing configuration file\n"); + scfg_print_example(); + return -1; + } + + directories = ucx_map_new(8); + + int ret = 0; + xmlNode *node = xmlDocGetRootElement(doc)->children; + while(node) { + if(node->type == XML_ELEMENT_NODE) { + if(xstreq(node->name, "directory")) { + if(scfg_load_directory(node)) { + ret = 1; + ucx_map_free(directories); + break; + } + } + } + node = node->next; + } + + xmlFreeDoc(doc); + + return ret; +} + +int scfg_load_directory(xmlNode *node) { + char *name = NULL; + char *path = NULL; + char *repository = NULL; + char *database = NULL; + + node = node->children; + while(node) { + if(node->type == XML_ELEMENT_NODE) { + char *value = util_xml_get_text(node); + if(!value) { + // next + } else if(xstreq(node->name, "name")) { + name = value; + } else if(xstreq(node->name, "path")) { + path = value; + } else if(xstreq(node->name, "repository")) { + repository = value; + } else if(xstreq(node->name, "database")) { + database = value; + } + } + node = node->next; + } + + if(!name) { + fprintf(stderr, "Missing name element for directory\n"); + return -1; + } + if(!path) { + fprintf(stderr, "Missing path element for directory\n"); + return -1; + } + if(!repository) { + fprintf(stderr, "Missing repository element for directory\n"); + return -1; + } + if(!database) { + fprintf(stderr, "Missing database element for directory\n"); + return -1; + } + + SyncDirectory *dir = malloc(sizeof(SyncDirectory)); + dir->name = strdup(name); + dir->path = strdup(path); + dir->repository = strdup(repository); + dir->database = strdup(database); + + ucx_map_cstr_put(directories, name, dir); + + return 0; +} + +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</database>\n"); + fprintf(stderr, " </directory>\n"); + fprintf(stderr, "</configuration>\n"); +} + +SyncDirectory* scfg_get_dir(char *name) { + return ucx_map_cstr_get(directories, name); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/scfg.h Fri Jun 13 13:52:59 2014 +0200 @@ -0,0 +1,61 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SCFG_H +#define SCFG_H + +#include <ucx/string.h> +#include <stdbool.h> +#include <libidav/webdav.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SyncDirectory { + char *name; + char *path; + char *repository; + char *database; +} SyncDirectory; + +int load_sync_config(); + +int scfg_load_directory(xmlNode *node); + +void scfg_print_example(); + +SyncDirectory* scfg_get_dir(char *name); + + +#ifdef __cplusplus +} +#endif + +#endif /* SCFG_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/sopt.c Fri Jun 13 13:52:59 2014 +0200 @@ -0,0 +1,140 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "optparser.h" + +void cmd_args_free(CmdArgs *args) { + ucx_map_free(args->options); + free(args->argv); +} + +CmdArgs* cmd_parse_args(int argc, char **argv) { + CmdArgs *a = malloc(sizeof(CmdArgs)); + a->options = ucx_map_new(16); + a->argv = calloc(argc, sizeof(char*)); + a->argc = 0; + + char *option = NULL; + char optchar = 0; + for(int i=0;i<argc;i++) { + char *arg = argv[i]; + size_t len = strlen(arg); + if(len > 1 && arg[0] == '-') { + for(int c=1;c<len;c++) { + switch(arg[c]) { + default: { + fprintf(stderr, "Unknown option -%c", arg[c]); + cmd_args_free(a); + return NULL; + } + case 'k': { + if(!option) { + option = "key"; + optchar = 'k'; + } else { + fprintf( + stderr, + "Missing argument for option -%c\n", + optchar); + cmd_args_free(a); + return NULL; + } + break; + } + case 'p': { + ucx_map_cstr_put(a->options, "plain", ""); + break; + } + case 'c': { + ucx_map_cstr_put(a->options, "crypt", ""); + break; + } + case 'a': { + ucx_map_cstr_put(a->options, "all", ""); + break; + } + case 'l': { + ucx_map_cstr_put(a->options, "list", ""); + break; + } + case 't': { + ucx_map_cstr_put(a->options, "type", ""); + break; + } + case 'R': { + ucx_map_cstr_put(a->options, "recursive", ""); + break; + } + case 'o': { + if(!option) { + option = "output"; + optchar = 'o'; + } else { + fprintf( + stderr, + "Missing argument for option -%c\n", + optchar); + cmd_args_free(a); + return NULL; + } + break; + } + case 'u': { + if(!option) { + option = "update"; + optchar = 'u'; + } else { + fprintf( + stderr, + "Missing argument for option -%c\n", + optchar); + cmd_args_free(a); + return NULL; + } + break; + } + } + } + } else if(option) { + ucx_map_cstr_put(a->options, option, arg); + option = NULL; + } else { + a->argv[a->argc++] = arg; + } + } + + return a; +} + +char* cmd_getoption(CmdArgs *arg, char *name) { + return ucx_map_cstr_get(arg->options, name); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/sopt.h Fri Jun 13 13:52:59 2014 +0200 @@ -0,0 +1,52 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef OPTPARSER_H +#define OPTPARSER_H + +#include <ucx/map.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + UcxMap *options; + char **argv; + int argc; +} CmdArgs; + +CmdArgs* cmd_parse_args(int argc, char **argv); +char* cmd_getoption(CmdArgs *arg, char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* OPTPARSER_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/sync.c Fri Jun 13 13:52:59 2014 +0200 @@ -0,0 +1,211 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <time.h> +#include <libxml/xmlerror.h> +#include <sys/types.h> +#include <ucx/string.h> +#include <dirent.h> + +#include <libidav/webdav.h> +#include <libidav/utils.h> + +#include "config.h" +#include "scfg.h" +#include "sopt.h" +#include "db.h" + +#include "sync.h" + +static DavContext *ctx; + +static void xmlerrorfnc(void * c, const char * msg, ... ) { + // nothing +} + +int main(int argc, char **argv) { + if(argc < 2) { + fprintf(stderr, "Missing command\n"); + print_usage(argv[0]); + return -1; + } + + char *cmd = argv[1]; + CmdArgs *args = cmd_parse_args(argc - 2, argv + 2); + if(!args) { + print_usage(argv[0]); + return -1; + } + + xmlGenericErrorFunc fnc = xmlerrorfnc; + initGenericErrorDefaultFunc(&fnc); + ctx = dav_context_new(); + load_config(ctx); + if(load_sync_config()) { + return EXIT_FAILURE; + } + + int ret = EXIT_FAILURE; + if(!strcmp(cmd, "pull")) { + ret = cmd_pull(args); + } else if(!strcmp(cmd, "push")) { + ret = cmd_pull(args); + } else if(!strcmp(cmd, "sync")) { + ret = cmd_sync(args); + } + + return ret; +} + +void print_usage(char *cmd) { + +} + +int cmd_pull(CmdArgs *a) { + if(a->argc != 1) { + fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); + return -1; + } + + SyncDirectory *dir = scfg_get_dir(a->argv[0]); + if(!dir) { + fprintf(stderr, "Unknown sync dir: %s\n", a->argv[0]); + return -1; + } + + Repository *repo = get_repository(sstr(dir->repository)); + if(!repo) { + fprintf(stderr, "Unkown repository %s\n", dir->name); + return -1; + } + + UcxMap *db = load_db(dir->database); + if(!db) { + fprintf(stderr, "Cannot load database file: %s\n", dir->database); + return -1; + } + + DavSession *sn = dav_session_new_auth( + ctx, + repo->url, + repo->user, + repo->password); + dav_session_set_flags(sn, get_repository_flags(repo)); + sn->key = dav_context_get_key(ctx, repo->default_key); + + DavResource *ls = dav_query(sn, "get D:getetag from / where lastmodified > 0 with depth -1"); + if(!ls) { + fprintf(stderr, "Error\n"); + // TODO: free + return -1; + } + + if(!ls->children) { + // TODO: free + return 0; // empty repository + } + + UcxList *stack = ucx_list_prepend(NULL, ls->children); + while(stack) { + DavResource *res = stack->data; + stack = ucx_list_remove(stack, stack); + + while(res) { + if(sync_get_resource(dir, res, db)) { + fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); + } + + if(res->children) { + stack = ucx_list_prepend(stack, res->children); + } + res = res->next; + } + } + + // store db + + + return 0; +} + +int sync_get_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) { + LocalResource *local = ucx_map_cstr_get(db, res->path); + char *etag = dav_get_property(res, "D:getetag"); + if(local) { + if(local->etag && !strcmp(etag, local->etag)) { + // resource is already up-to-date on the client + return 0; + } + } + + char *local_path = util_concat_path(dir->path, res->path); + 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; + } + } else { + FILE *out = fopen(local_path, "w"); + if(!out) { + fprintf(stderr, "cannot open output file: %s\n", local_path); + free(local_path); + return -1; + } + printf("get %s\n", res->path); + if(dav_get_content(res, out, (dav_write_func)fwrite)) { + ret = -1; + } else { + if(local) { + if(local->etag) { + free(local->etag); + } + local->etag = etag; + } + } + fclose(out); + } + + free(local_path); + return ret; +} + +int cmd_push(CmdArgs *a) { + return 0; +} + +int cmd_sync(CmdArgs *a) { + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/sync.h Fri Jun 13 13:52:59 2014 +0200 @@ -0,0 +1,55 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SYNC_H +#define SYNC_H + +#include <curl/curl.h> +#include <libidav/webdav.h> + +#include "sopt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void print_usage(char *cmd); + +int cmd_pull(CmdArgs *args); +int cmd_push(CmdArgs *args); +int cmd_sync(CmdArgs *args); + +int sync_get_resource(SyncDirectory *dir, DavResource *res, UcxMap *db); + + +#ifdef __cplusplus +} +#endif + +#endif /* SYNC_H */ +
--- a/libidav/webdav.c Thu Jun 05 16:53:53 2014 +0200 +++ b/libidav/webdav.c Fri Jun 13 13:52:59 2014 +0200 @@ -237,7 +237,7 @@ DavResource* dav_query_get(DavSession *sn, DavGetQuery *query) { char *path; - int depth = 0; + int depth = query->depth; /* if(parse_path_query(query->from, &path, &depth)) { sn->error = DAV_ERROR; @@ -266,7 +266,6 @@ dav_resource_free(resource); resource = NULL; } - ucx_buffer_free(rqbuf); int error = 0; if(resource && depth == -1) { @@ -284,6 +283,8 @@ stack = propfind_stack_push(stack, sr->children); // add children } } + + ucx_buffer_free(rqbuf); return resource; }