diff -r 16d6b97fbf33 -r 12bad63cf5a8 dav/sync.c --- a/dav/sync.c Thu Mar 17 20:24:37 2016 +0100 +++ b/dav/sync.c Thu Mar 17 21:11:19 2016 +0100 @@ -70,26 +70,38 @@ print_usage(argv[0]); return -1; } - - xmlGenericErrorFunc fnc = xmlerrorfnc; - initGenericErrorDefaultFunc(&fnc); - ctx = dav_context_new(); - ctx->key_input = util_key_input; - load_config(ctx); + int ret = EXIT_FAILURE; - // copy proxy config - memcpy(ctx->http_proxy, get_http_proxy(), sizeof(Proxy)); - memcpy(ctx->https_proxy, get_https_proxy(), sizeof(Proxy)); - - if(load_sync_config()) { - return EXIT_FAILURE; + int loadcfg = 1; + if(!strcasecmp(cmd, "version") || !strcasecmp(cmd, "-version") || !strcasecmp(cmd, "--version")) { + fprintf(stderr, "dav-sync %s\n", DAV_VERSION); + loadcfg = 0; } - int ret = EXIT_FAILURE; + if(loadcfg) { + xmlGenericErrorFunc fnc = xmlerrorfnc; + initGenericErrorDefaultFunc(&fnc); + ctx = dav_context_new(); + ctx->key_input = util_key_input; + load_config(ctx); + + // copy proxy config + memcpy(ctx->http_proxy, get_http_proxy(), sizeof(Proxy)); + memcpy(ctx->https_proxy, get_https_proxy(), sizeof(Proxy)); + + if(load_sync_config()) { + return EXIT_FAILURE; + } + } + if(!strcmp(cmd, "pull")) { ret = cmd_pull(args); } else if(!strcmp(cmd, "push")) { ret = cmd_push(args); + } else if(!strcmp(cmd, "resolve-conflicts")) { + ret = cmd_resolve_conflicts(args); + } else if(!strcmp(cmd, "delete-conflicts")) { + ret = cmd_delete_conflicts(args); } else if(!strcmp(cmd, "trash-info")) { ret = cmd_trash_info(args); } else if(!strcmp(cmd, "empty-trash")) { @@ -98,8 +110,6 @@ ret = cmd_add_directory(args); } else if(!strcmp(cmd, "list-directories")) { ret = list_syncdirs(); - } else if(!strcasecmp(cmd, "version") || !strcasecmp(cmd, "-version") || !strcasecmp(cmd, "--version")) { - fprintf(stderr, "dav-sync %s\n", DAV_VERSION); } // TODO: cleanup sync config (don't forget to call regfree for regex) @@ -1064,6 +1074,102 @@ return ret; } + +int cmd_resolve_conflicts(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; + } + + SyncDatabase *db = load_db(dir->database); + if(!db) { + fprintf(stderr, "Cannot load database file: %s\n", dir->database); + return -1; + } + + // remove conflicts + int num_conflict = db->conflict->count; + //TODO: ucx_map_free_content(db->conflict, destr); + ucx_map_clear(db->conflict); + + // store db + if(store_db(db, dir->database)) { + fprintf(stderr, "Cannot store sync db\n"); + fprintf(stderr, "Abort\n"); + return -1; // TODO: don't return here + } + + // Report + char *str_conflict = num_conflict == 1 ? "conflict" : "conflicts"; + printf("Result: %d %s resolved\n", num_conflict, str_conflict); + + return 0; +} + +int cmd_delete_conflicts(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; + } + + SyncDatabase *db = load_db(dir->database); + if(!db) { + fprintf(stderr, "Cannot load database file: %s\n", dir->database); + return -1; + } + + int num_del = 0; + int num_err = 0; + + // delete all conflict files + UcxMapIterator i = ucx_map_iterator(db->conflict); + LocalResource *res; + UCX_MAP_FOREACH(key, res, i) { + printf("delete: %s\n", res->path); + char *path = util_concat_path(dir->path, res->path); + if(unlink(path)) { + if(errno != ENOENT) { + perror("unlink"); + num_err++; + } + } else { + num_del++; + } + free(path); + } + //TODO: ucx_map_free_content(db->conflict, destr); + ucx_map_clear(db->conflict); + + // store db + if(store_db(db, dir->database)) { + fprintf(stderr, "Cannot store sync db\n"); + fprintf(stderr, "Abort\n"); + return -1; // TODO: don't return here + } + + // Report + char *str_delete = num_del == 1 ? "file" : "files"; + char *str_error = num_err == 1 ? "error" : "errors"; + printf("Result: %d conflict %s deleted, %d %s\n", + num_del, str_delete, + num_err, str_error); + + return 0; +} + + // TODO: remove code dup (main.c ls_size_str) static char* size_str(uint64_t size) { char *str = malloc(16);