# HG changeset patch # User Olaf Wintermann # Date 1443871995 -7200 # Node ID c2c02c9b3be420820c20a38bb7eed93e5600cd17 # Parent d8b01bed3d83f3c5e9aa9a3d03b625f549fea03d dav-sync detects broken uploads diff -r d8b01bed3d83 -r c2c02c9b3be4 dav/db.c --- a/dav/db.c Sat Oct 03 00:09:23 2015 +0200 +++ b/dav/db.c Sat Oct 03 13:33:15 2015 +0200 @@ -127,7 +127,7 @@ } } else if(type == XML_READER_TYPE_TEXT) { const xmlChar *value = xmlTextReaderConstValue(reader); - int b = 0; + //int b = 0; switch(field) { case 0: { res->path = strdup((char*)value); diff -r d8b01bed3d83 -r c2c02c9b3be4 dav/main.c --- a/dav/main.c Sat Oct 03 00:09:23 2015 +0200 +++ b/dav/main.c Sat Oct 03 13:33:15 2015 +0200 @@ -398,7 +398,6 @@ } // parameters - int show_all = cmd_getoption(a, "all") ? 1 : 0; void (*print_func)(DavResource*, CmdArgs *); if(cmd_getoption(a, "list")) { print_func = ls_print_list_elm; @@ -419,7 +418,7 @@ free(path); //free(base); - //dav_session_destroy(sn); + dav_session_destroy(sn); return ret; } diff -r d8b01bed3d83 -r c2c02c9b3be4 dav/scfg.c --- a/dav/scfg.c Sat Oct 03 00:09:23 2015 +0200 +++ b/dav/scfg.c Sat Oct 03 13:33:15 2015 +0200 @@ -146,6 +146,7 @@ dir->collection = collection ? strdup(collection) : NULL; dir->repository = strdup(repository); dir->database = strdup(database); + dir->max_retry = DAV_MAX_RETRY; if (include) { dir->include = include; } else { diff -r d8b01bed3d83 -r c2c02c9b3be4 dav/scfg.h --- a/dav/scfg.h Sat Oct 03 00:09:23 2015 +0200 +++ b/dav/scfg.h Sat Oct 03 13:33:15 2015 +0200 @@ -38,6 +38,8 @@ extern "C" { #endif +#define DAV_MAX_RETRY 1 + typedef struct SyncDirectory { char *name; char *path; @@ -47,6 +49,7 @@ char *database; UcxList *include; UcxList *exclude; + int max_retry; } SyncDirectory; int load_sync_config(); diff -r d8b01bed3d83 -r c2c02c9b3be4 dav/sopt.c --- a/dav/sopt.c Sat Oct 03 00:09:23 2015 +0200 +++ b/dav/sopt.c Sat Oct 03 13:33:15 2015 +0200 @@ -46,7 +46,7 @@ const char *NOARG = ""; char *option = NULL; - char optchar = 0; + //char optchar = 0; for(int i=0;ihandle, CURLOPT_STDERR, stderr); } - DavResource *ls = dav_query(sn, "select D:getetag from / depth -1 where lastmodified > 0 with"); + DavResource *ls = dav_query(sn, "select D:getetag,idav:status from / with depth = infinity"); if(!ls) { fprintf(stderr, "Error\n"); // TODO: free @@ -207,6 +207,12 @@ continue; } + char *status = dav_get_property(res, "idav:status"); + if(status && !strcmp(status, "broken")) { + res = res->next; + continue; + } + // download the resource if(sync_get_resource(a, dir, res, db)) { fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); @@ -665,53 +671,99 @@ } +int sync_set_status(DavResource *res, char *status) { + DavResource *resource = dav_resource_new(res->session, res->path); + dav_set_property(resource, "idav:status", status); + int ret = dav_store(resource); + dav_resource_free(resource); + return ret; +} + +int sync_remove_status(DavResource *res) { + DavResource *resource = dav_resource_new(res->session, res->path); + dav_remove_property(resource, "idav:status"); + int ret = dav_store(resource); + dav_resource_free(resource); + return ret; +} + int sync_put_resource(SyncDirectory *dir, DavResource *res, LocalResource *local) { char *local_path = util_concat_path(dir->path, res->path); + + struct stat s; + if(stat(local_path, &s)) { + fprintf(stderr, "cannot stat file: %s\n", local_path); + perror(""); + free(local_path); + return -1; + } + FILE *in = fopen(local_path, "rb"); if(!in) { fprintf(stderr, "Cannot open file %s\n", local_path); free(local_path); return -1; } - free(local_path); dav_set_content(res, in, (dav_read_func)fread); int ret = -1; - for(;;) { - if(dav_create(res)) { - break; + int created = 0; + for(int i=0;imax_retry;i++) { + if(!created && dav_create(res)) { + continue; } + created = 1; if(dav_store(res)) { - break; + continue; } ret = 0; break; } + + if(ret == 0) { - // get new etag + // check contentlength and get new etag DavResource *up_res = dav_get(res->session, res->path, "D:getetag"); - char *etag = dav_get_property(up_res, "D:getetag"); - if(etag) { - if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') { - etag = etag + 2; - } - } - if(local->etag) { - free(local->etag); + if(up_res) { + // the new content length must be equal or greater than the file size + if(up_res->contentlength < s.st_size) { + fprintf(stderr, "Incomplete Upload: %s", local_path); + ret = -1; + // try to set the resource status to 'broken' + sync_set_status(res, "broken"); + } else { + // everything seems fine, we can update the local resource + char *etag = dav_get_property(up_res, "D:getetag"); + if(etag) { + if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') { + etag = etag + 2; + } + } + + if(local->etag) { + free(local->etag); + } + + if(etag) { + local->etag = strdup(etag); + } else { + local->etag = NULL; + } + dav_resource_free(up_res); + + sync_remove_status(res); + } } - - if(etag) { - local->etag = strdup(etag); - } else { - local->etag = NULL; - } - dav_resource_free(up_res); + } else { + ret = -1; + sync_set_status(res, "broken"); } fclose(in); + free(local_path); return ret; } diff -r d8b01bed3d83 -r c2c02c9b3be4 dav/sync.h --- a/dav/sync.h Sat Oct 03 00:09:23 2015 +0200 +++ b/dav/sync.h Sat Oct 03 13:33:15 2015 +0200 @@ -56,6 +56,8 @@ LocalResource* local_resource_new(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir); int local_resource_is_changed(SyncDirectory *dir, SyncDatabase *db, LocalResource *res); +int sync_set_status(DavResource *res, char *status); +int sync_remove_status(DavResource *res); int sync_put_resource(SyncDirectory *dir, DavResource *res, LocalResource *local); int sync_delete_remote_resource(DavSession *sn, LocalResource *res); diff -r d8b01bed3d83 -r c2c02c9b3be4 libidav/davqlexec.c --- a/libidav/davqlexec.c Sat Oct 03 00:09:23 2015 +0200 +++ b/libidav/davqlexec.c Sat Oct 03 13:33:15 2015 +0200 @@ -674,6 +674,7 @@ ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); break; } + default: break; } break; } @@ -709,6 +710,7 @@ cmd.type = DAVQL_CMD_OP_BINARY_XOR; break; } + default: break; } ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); break; @@ -793,6 +795,7 @@ ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); break; } + default: break; } break; } @@ -827,6 +830,7 @@ numcmd += add_cmd(ctx, a, bcode, expr->right, ap); break; } + default: break; } break; } diff -r d8b01bed3d83 -r c2c02c9b3be4 libidav/resource.c --- a/libidav/resource.c Sat Oct 03 00:09:23 2015 +0200 +++ b/libidav/resource.c Sat Oct 03 13:33:15 2015 +0200 @@ -639,7 +639,7 @@ CURL *handle = sn->handle; util_set_url(res->session, dav_resource_get_href(res)); - // check encryptions + // check encryption AESDecrypter *dec = NULL; if(DAV_DECRYPT_CONTENT(sn)) { char *keyname = dav_get_property_ns(res, DAV_NS, "crypto-key");