# HG changeset patch # User Olaf Wintermann # Date 1505031805 -7200 # Node ID 395763c0ee69a3c0827bd8e50590c8e936d16429 # Parent 4e3769d4e782c4eb6a896bcc80240c96e54c8873 adds SIGINT handler to dav-sync diff -r 4e3769d4e782 -r 395763c0ee69 bsd.mk --- a/bsd.mk Thu Sep 07 18:42:51 2017 +0200 +++ b/bsd.mk Sun Sep 10 10:23:25 2017 +0200 @@ -43,5 +43,5 @@ APP_EXT = DAV_CFLAGS = `curl-config --cflags` `pkg-config --cflags libxml-2.0` -DAV_LDFLAGS = `curl-config --libs` `pkg-config --libs libxml-2.0` -lssl -lcrypto +DAV_LDFLAGS = `curl-config --libs` `pkg-config --libs libxml-2.0` -lssl -lcrypto -lpthread diff -r 4e3769d4e782 -r 395763c0ee69 clang.mk --- a/clang.mk Thu Sep 07 18:42:51 2017 +0200 +++ b/clang.mk Sun Sep 10 10:23:25 2017 +0200 @@ -43,5 +43,5 @@ APP_EXT = DAV_CFLAGS = `curl-config --cflags` `pkg-config --cflags openssl libxml-2.0` -DAV_LDFLAGS = `curl-config --libs` `pkg-config --libs openssl libxml-2.0` +DAV_LDFLAGS = `curl-config --libs` `pkg-config --libs openssl libxml-2.0` -lpthread diff -r 4e3769d4e782 -r 395763c0ee69 dav/sync.c --- a/dav/sync.c Thu Sep 07 18:42:51 2017 +0200 +++ b/dav/sync.c Sun Sep 10 10:23:25 2017 +0200 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -52,8 +53,12 @@ #include "sync.h" #include "libidav/session.h" +#include + static DavContext *ctx; +static int sync_shutdown = 0; + static void xmlerrorfnc(void * c, const char * msg, ... ) { va_list ap; va_start(ap, msg); @@ -88,6 +93,10 @@ ctx = dav_context_new(); int cfgret = load_config(ctx) || load_sync_config(); + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&mutex); + pthread_t tid; + if(!strcmp(cmd, "check") || !strcmp(cmd, "check-config")) { if(!cfgret) { fprintf(stdout, "Configuration OK.\n"); @@ -98,11 +107,17 @@ } } else if(!cfgret) { if(!strcmp(cmd, "pull")) { + tid = start_sighandler(&mutex); ret = cmd_pull(args); + stop_sighandler(&mutex, tid); } else if(!strcmp(cmd, "push")) { + tid = start_sighandler(&mutex); ret = cmd_push(args, FALSE); + stop_sighandler(&mutex, tid); } else if(!strcmp(cmd, "archive")) { + tid = start_sighandler(&mutex); ret = cmd_push(args, TRUE); + stop_sighandler(&mutex, tid); } else if(!strcmp(cmd, "resolve-conflicts")) { ret = cmd_resolve_conflicts(args); } else if(!strcmp(cmd, "delete-conflicts")) { @@ -164,6 +179,38 @@ fprintf(stderr, " check-repositories\n\n"); } +static void handlesig(int sig) { + if(sync_shutdown) { + exit(-1); + } + fprintf(stderr, "abort\n"); + sync_shutdown = 1; +} + +static void* sighandler(void *data) { + signal(SIGTERM, handlesig); + signal(SIGINT, handlesig); + + pthread_mutex_t *mutex = data; + pthread_mutex_lock(mutex); // block thread + return NULL; +} + +pthread_t start_sighandler(pthread_mutex_t *mutex) { + pthread_t tid; + if(pthread_create(&tid, NULL, sighandler, mutex)) { + perror("pthread_create"); + exit(-1); + } + return tid; +} + +void stop_sighandler(pthread_mutex_t *mutex, pthread_t tid) { + pthread_mutex_unlock(mutex); + void *data; + pthread_join(tid, &data); +} + static int res_matches_filter(SyncDirectory *dir, char *res_path) { // trash filter if (dir->trash) { @@ -336,7 +383,7 @@ } // download the resource - if(sync_get_resource(a, dir, res, db, &sync_success)) { + if(!sync_shutdown && sync_get_resource(a, dir, res, db, &sync_success)) { fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); sync_error++; } @@ -344,14 +391,15 @@ // add every resource from the server to svrres // then db-resources contains only resources which are not on the // server - LocalResource *local = ucx_map_cstr_get(db->resources, res->path); - ucx_map_cstr_put(svrres, res->path, local); - ucx_map_cstr_remove(db->resources, res->path); - - if(local->last_modified == 0) { - // stat this file later (directory) - statls = ucx_list_prepend(statls, local); - } + LocalResource *local = ucx_map_cstr_remove(db->resources, res->path); + if(local) { + ucx_map_cstr_put(svrres, res->path, local); + + if(local->last_modified == 0) { + // stat this file later (directory) + statls = ucx_list_prepend(statls, local); + } + } // else: sync_shutdown is TRUE if(res->children) { stack = ucx_list_prepend(stack, res->children); @@ -380,12 +428,17 @@ if (res_matches_filter(dir, local->path)) { continue; } - // sync_remove_resource does all necessary tests - int ret = sync_remove_local_resource(dir, local); - if(ret == -1) { - rmdirs = ucx_list_append(rmdirs, local); - } else if(ret == 0) { - sync_delete++; + + if(sync_shutdown) { + ucx_map_cstr_put(svrres, local->path, local_resource_copy(local)); + } else { + // sync_remove_resource does all necessary tests + int ret = sync_remove_local_resource(dir, local); + if(ret == -1) { + rmdirs = ucx_list_append(rmdirs, local); + } else if(ret == 0) { + sync_delete++; + } } } UCX_FOREACH(elm, rmdirs) { @@ -823,12 +876,26 @@ UCX_FOREACH(elm, resources) { LocalResource *local_res = elm->data; if (!res_matches_filter(dir, local_res->path+1)) { + if(sync_shutdown) { + LocalResource *lr = ucx_map_cstr_remove(db->resources, local_res->path); + if(lr) { + local_res->size = lr->size; + local_res->last_modified = lr->last_modified; + local_res->etag = lr->etag ? strdup(lr->etag) : NULL; + local_resource_free(lr); + ucx_map_cstr_put(lclres, local_res->path, local_res); + } + elm->data = NULL; + continue; + } + + if(res_isconflict(db, local_res)) { printf("skip: %s\n", local_res->path); sync_skipped++; continue; } - + // upload every changed file int error = 0; if (local_resource_is_changed(dir, db, local_res)) { @@ -886,8 +953,10 @@ LocalResource *local; UCX_MAP_FOREACH(key, local, i) { if (!res_matches_filter(dir, local->path+1)) { - if(sync_delete_remote_resource(sn, local, &sync_delete)) { - ucx_map_cstr_put(lclres, local->path, local); + if(sync_shutdown) { + ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); + } else if(sync_delete_remote_resource(sn, local, &sync_delete)) { + ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); if(sn->error != DAV_NOT_FOUND) { print_resource_error(sn, local->path); sync_error++; @@ -1070,6 +1139,24 @@ } } +LocalResource* local_resource_copy(LocalResource *res) { + LocalResource *newres = calloc(1, sizeof(LocalResource)); + if(res->name) { + newres->name = strdup(res->name); + } + if(res->path) { + newres->path = strdup(res->path); + } + if(res->etag) { + newres->etag = strdup(res->etag); + } + newres->skipped = res->skipped; + newres->size = res->size; + newres->last_modified = res->last_modified; + newres->isdirectory = res->isdirectory; + return newres; +} + int local_resource_is_changed(SyncDirectory *dir, SyncDatabase *db, LocalResource *res) { LocalResource *db_res = ucx_map_cstr_get(db->resources, res->path); if(db_res) { diff -r 4e3769d4e782 -r 395763c0ee69 dav/sync.h --- a/dav/sync.h Thu Sep 07 18:42:51 2017 +0200 +++ b/dav/sync.h Sun Sep 10 10:23:25 2017 +0200 @@ -37,14 +37,23 @@ #include "version.h" +#ifdef _WIN32 +// TODO: thread includes +#else +#include +#endif /* _WIN32 */ + #ifdef __cplusplus extern "C" { #endif #define STDIN_BUF_SIZE 2048 - + void print_usage(char *cmd); +pthread_t start_sighandler(pthread_mutex_t *mutex) ; +void stop_sighandler(pthread_mutex_t *mutex, pthread_t tid); + int cmd_pull(CmdArgs *args); int cmd_push(CmdArgs *args, DavBool archive); @@ -62,6 +71,7 @@ UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db); UcxList* read_changes(SyncDirectory *dir, SyncDatabase *db); LocalResource* local_resource_new(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir); +LocalResource* local_resource_copy(LocalResource *res); int local_resource_is_changed(SyncDirectory *dir, SyncDatabase *db, LocalResource *res); int remote_resource_is_changed( DavSession *sn, diff -r 4e3769d4e782 -r 395763c0ee69 gcc.mk --- a/gcc.mk Thu Sep 07 18:42:51 2017 +0200 +++ b/gcc.mk Sun Sep 10 10:23:25 2017 +0200 @@ -43,5 +43,5 @@ APP_EXT = DAV_CFLAGS = `curl-config --cflags` `pkg-config --cflags openssl libxml-2.0` -DAV_LDFLAGS = `curl-config --libs` `pkg-config --libs openssl libxml-2.0` +DAV_LDFLAGS = `curl-config --libs` `pkg-config --libs openssl libxml-2.0` -lpthread diff -r 4e3769d4e782 -r 395763c0ee69 osx.mk --- a/osx.mk Thu Sep 07 18:42:51 2017 +0200 +++ b/osx.mk Sun Sep 10 10:23:25 2017 +0200 @@ -43,4 +43,4 @@ APP_EXT = DAV_CFLAGS = `xml2-config --cflags` -DAV_LDFLAGS = -lcurl -lxml2 -lssl -lcrypto +DAV_LDFLAGS = -lcurl -lxml2 -lssl -lcrypto -lpthread diff -r 4e3769d4e782 -r 395763c0ee69 suncc.mk --- a/suncc.mk Thu Sep 07 18:42:51 2017 +0200 +++ b/suncc.mk Sun Sep 10 10:23:25 2017 +0200 @@ -43,5 +43,5 @@ APP_EXT = DAV_CFLAGS = `curl-config --cflags` `pkg-config --cflags openssl libxml-2.0` -DAV_LDFLAGS = `pkg-config --libs openssl libxml-2.0` `curl-config --libs` +DAV_LDFLAGS = `pkg-config --libs openssl libxml-2.0` `curl-config --libs` -lpthread