Thu, 10 Jul 2014 13:50:00 +0200
added conflict detection
dav/sync.c | file | annotate | diff | comparison | revisions | |
dav/sync.h | file | annotate | diff | comparison | revisions |
--- a/dav/sync.c Fri Jul 04 12:09:48 2014 +0200 +++ b/dav/sync.c Thu Jul 10 13:50:00 2014 +0200 @@ -35,6 +35,7 @@ #include <libxml/xmlerror.h> #include <sys/types.h> #include <ucx/string.h> +#include <ucx/utils.h> #include <dirent.h> #include <libidav/webdav.h> @@ -192,19 +193,19 @@ if(local) { if(stat(local_path, &s)) { if(errno == ENOENT) { - printf("removed %s\n", res->path); + printf("removed: %s\n", res->path); // the file is in the database, but doesn't exists // mark the file as removed to delete it on next push ucx_map_cstr_remove(db->resources, local->path); ucx_map_cstr_put(db->remove, local->path, local); return 0; } else { - fprintf(stderr, "stat failed: %s\n", local_path); + fprintf(stderr, "Cannot stat file: %s\n", local_path); free(local_path); return -1; } } - + if(local->etag) { sstr_t e = sstr(etag); if(sstrprefix(e, S("W/"))) { @@ -215,8 +216,21 @@ return 0; } } + + if(s.st_mtim.tv_sec != local->last_modified) { + // file modified on the server and on the client + rename_local_file(dir, db, local->path); + } + } else { + if(stat(local_path, &s)) { + if(errno != ENOENT) { + fprintf(stderr, "Cannot stat file: %s\n", local_path); + } + } else if(!S_ISDIR(s.st_mode)) { + rename_local_file(dir, db, res->path); + } } - + int ret = 0; if(res->iscollection) { mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; @@ -227,16 +241,20 @@ } else { FILE *out = fopen(local_path, "w"); if(!out) { - fprintf(stderr, "cannot open output file: %s\n", local_path); + fprintf(stderr, "Cannot open output file: %s\n", local_path); free(local_path); return -1; } - printf("get %s\n", res->path); + printf("get: %s\n", res->path); if(dav_get_content(res, out, (dav_write_func)fwrite)) { ret = -1; } fclose(out); + if(stat(local_path, &s)) { + fprintf(stderr, "Cannot stat file: %s\n", local_path); + } + if(ret == 0) { if(!local) { // new local resource @@ -279,6 +297,42 @@ free(local_path); } +void rename_local_file(SyncDirectory *dir, SyncDatabase *db, char *path) { + char *local_path = util_concat_path(dir->path, path); + char *parent = util_parent_path(local_path); + + int rev = 0; + struct stat s; + int loop = 1; + do { + sstr_t new_path = ucx_asprintf( + ucx_default_allocator(), + "%sorig.%d.%s", + parent, + rev, + util_resource_name(path)); + + + if(stat(new_path.ptr, &s)) { + if(errno == ENOENT) { + loop = 0; + printf("conflict: %s\n", local_path); + if(rename(local_path, new_path.ptr)) { + printf("errno: %d\n", errno); + fprintf( + stderr, + "Cannot rename file %s to %s\n", + local_path, + new_path.ptr); + } + } + } + rev++; + free(new_path.ptr); + } while(loop); + free(parent); +} + int cmd_push(CmdArgs *a) { if(a->argc != 1) { fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many");
--- a/dav/sync.h Fri Jul 04 12:09:48 2014 +0200 +++ b/dav/sync.h Thu Jul 10 13:50:00 2014 +0200 @@ -47,7 +47,7 @@ int sync_get_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db); void sync_remove_resource(SyncDirectory *dir, LocalResource *res); - +void rename_local_file(SyncDirectory *dir, SyncDatabase *db, char *path); UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db); int sync_put_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db);