diff -r 08d5544c92fb -r c5759ac76c1b dav/sync.c --- a/dav/sync.c Sun Jun 15 20:12:48 2014 +0200 +++ b/dav/sync.c Thu Jul 03 15:50:13 2014 +0200 @@ -109,7 +109,7 @@ return -1; } - UcxMap *db = load_db(dir->database); + SyncDatabase *db = load_db(dir->database); if(!db) { fprintf(stderr, "Cannot load database file: %s\n", dir->database); return -1; @@ -134,12 +134,12 @@ // 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); @@ -163,10 +163,28 @@ return 0; } -int sync_get_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) { - LocalResource *local = ucx_map_cstr_get(db, res->path); +int sync_get_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) { + LocalResource *local = ucx_map_cstr_get(db->resources, res->path); + char *local_path = util_concat_path(dir->path, res->path); + char *etag = dav_get_property(res, "D:getetag"); + struct stat s; if(local) { + if(stat(local_path, &s)) { + if(errno == ENOENT) { + 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); + free(local_path); + return -1; + } + } + if(local->etag) { sstr_t e = sstr(etag); if(sstrprefix(e, S("W/"))) { @@ -179,7 +197,6 @@ } } - 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; @@ -201,22 +218,17 @@ fclose(out); if(ret == 0) { - // get file informations for db update - struct stat s; - if(stat(local_path, &s)) { - fprintf(stderr, "stat failed: %s\n", local_path); - ret = -1; - } - if(!local) { + // new local resource local = calloc(1, sizeof(LocalResource)); local->path = strdup(res->path); - ucx_map_cstr_put(db, local->path, local); + ucx_map_cstr_put(db->resources, local->path, local); } if(local->etag) { free(local->etag); } + // set metadata from stat local->etag = etag; local->last_modified = s.st_mtim.tv_sec; local->size = s.st_size; @@ -245,7 +257,7 @@ return -1; } - UcxMap *db = load_db(dir->database); + SyncDatabase *db = load_db(dir->database); if(!db) { fprintf(stderr, "Cannot load database file: %s\n", dir->database); return -1; @@ -279,7 +291,7 @@ return 0; } -UcxList* local_scan(SyncDirectory *dir, UcxMap *db) { +UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db) { UcxList *resources = NULL; char *path = strdup("/"); @@ -322,7 +334,9 @@ if(S_ISDIR(s.st_mode)) { stack = ucx_list_prepend(stack, new_path); } else { - LocalResource *res = ucx_map_cstr_get(db, new_path); + LocalResource *res = ucx_map_cstr_get( + db->resources, + new_path); if(res) { // the file is already in the database // compare length and lastmodified date @@ -349,7 +363,7 @@ res->etag = NULL; res->last_modified = s.st_mtim.tv_sec; res->size = s.st_size; - ucx_map_cstr_put(db, res->path, res); + ucx_map_cstr_put(db->resources, res->path, res); resources = ucx_list_append(resources, new_path); } } @@ -364,7 +378,7 @@ return resources; } -int sync_put_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) { +int sync_put_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) { char *local_path = util_concat_path(dir->path, res->path); FILE *in = fopen(local_path, "r"); if(!in) { @@ -389,25 +403,22 @@ } if(ret == 0) { - LocalResource *local_res = ucx_map_cstr_get(db, res->path); + LocalResource *local_res = ucx_map_cstr_get(db->resources, res->path); if(local_res->etag) { free(local_res->etag); } DavResource *up_res = dav_get(res->session, res->path, "D:getetag"); - char *etag_str = dav_get_property(up_res, "D:getetag"); - sstr_t etag; - etag.ptr = NULL; - if(etag_str) { - etag = sstr(etag_str); - } - if(sstrprefix(etag, S("W/"))) { - etag = sstrsubs(etag, 2); + char *etag = dav_get_property(up_res, "D:getetag"); + if(etag) { + if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') { + etag = etag + 2; + } } - if(etag.ptr) { - local_res->etag = strdup(etag.ptr); + if(etag) { + local_res->etag = strdup(etag); } else { local_res->etag = NULL; }