dav/sync.c

changeset 577
f49964cf7228
parent 576
62cc92445234
child 578
bb1e60fada74
equal deleted inserted replaced
576:62cc92445234 577:f49964cf7228
79 { DAV_NS, "status" }, 79 { DAV_NS, "status" },
80 { DAV_NS, "finfo" }, 80 { DAV_NS, "finfo" },
81 { DAV_NS, "tags" }, 81 { DAV_NS, "tags" },
82 { DAV_NS, "xattributes" }, 82 { DAV_NS, "xattributes" },
83 { DAV_NS, "content-hash" }, 83 { DAV_NS, "content-hash" },
84 { DAV_NS, "split" } 84 { DAV_NS, "split" },
85 { DAV_NS, "link" }
85 }; 86 };
86 static size_t numdefprops = 6; 87 static size_t numdefprops = 8 ;
87 88
88 /* 89 /*
89 * strcmp version that works with NULL pointers 90 * strcmp version that works with NULL pointers
90 */ 91 */
91 static int nullstrcmp(const char *s1, const char *s2) { 92 static int nullstrcmp(const char *s1, const char *s2) {
1761 UcxList *elm = ls_new; 1762 UcxList *elm = ls_new;
1762 while(elm) { 1763 while(elm) {
1763 LocalResource *local = elm->data; 1764 LocalResource *local = elm->data;
1764 UcxList *prev = elm->prev; 1765 UcxList *prev = elm->prev;
1765 UcxList *next = elm->next; 1766 UcxList *next = elm->next;
1766 if(local->isdirectory) { 1767 if(local->isdirectory || local->link_target) {
1767 elm = elm->next; 1768 elm = elm->next;
1768 continue; 1769 continue;
1769 } 1770 }
1770 1771
1771 char *local_path = util_concat_path(dir->path, local->path); 1772 char *local_path = util_concat_path(dir->path, local->path);
2554 } else if(xattr) { 2555 } else if(xattr) {
2555 xattributes_free(xattr); 2556 xattributes_free(xattr);
2556 } 2557 }
2557 } 2558 }
2558 2559
2559 if(db_res->last_modified == res->last_modified && db_res->size == res->size) { 2560 if(nullstrcmp(db_res->link_target, res->link_target)) {
2561 res->link_updated = 1;
2562 } else if(db_res->last_modified == res->last_modified && db_res->size == res->size) {
2560 return 0; 2563 return 0;
2561 } 2564 }
2562 2565
2563 if(db_res->parts) { 2566 if(db_res->parts) {
2564 // if the resource is splitted, move the part infos to the new 2567 // if the resource is splitted, move the part infos to the new
2565 // LocalResource obj, because we need it later 2568 // LocalResource obj, because we need it later
2566 res->parts = db_res->parts; 2569 res->parts = db_res->parts;
2588 DavPropName properties[] = { 2591 DavPropName properties[] = {
2589 {"DAV:", "getetag"}, 2592 {"DAV:", "getetag"},
2590 {DAV_NS, "tags"}, 2593 {DAV_NS, "tags"},
2591 {DAV_NS, "version-collection"}, 2594 {DAV_NS, "version-collection"},
2592 {DAV_NS, "content-hash"}, 2595 {DAV_NS, "content-hash"},
2593 {DAV_NS, "split" } 2596 {DAV_NS, "split" },
2597 {DAV_NS, "link" }
2594 }; 2598 };
2595 int err = dav_load_prop(remote, properties, 4); 2599 int err = dav_load_prop(remote, properties, 6);
2596 2600
2597 if(res->restore) { 2601 if(res->restore) {
2598 return 0; 2602 return 0;
2599 } 2603 }
2600 2604
3477 perror(""); 3481 perror("");
3478 free(local_path); 3482 free(local_path);
3479 return -1; 3483 return -1;
3480 } 3484 }
3481 3485
3486 DavBool islink = local->link_target ? 1 : 0;
3487 if(!local->link_target && local->link_updated) {
3488 dav_remove_property_ns(res, DAV_NS, "link");
3489 }
3490
3482 size_t split_blocksize = resource_get_blocksize(dir, local, res, s.st_size); 3491 size_t split_blocksize = resource_get_blocksize(dir, local, res, s.st_size);
3483 3492
3484 FILE *in = sys_fopen(local_path, "rb"); 3493 FILE *in = sys_fopen(local_path, "rb");
3485 if(!in) { 3494 if(!in) {
3486 fprintf(stderr, "Cannot open file %s\n", local_path); 3495 fprintf(stderr, "Cannot open file %s\n", local_path);
3490 3499
3491 DavBool issplit = split_blocksize == 0 ? FALSE : TRUE; 3500 DavBool issplit = split_blocksize == 0 ? FALSE : TRUE;
3492 int split_err = 0; 3501 int split_err = 0;
3493 UcxList *parts = NULL; 3502 UcxList *parts = NULL;
3494 uint64_t blockcount = 0; 3503 uint64_t blockcount = 0;
3495 if(!issplit) { 3504
3496 // regular file upload 3505 if(islink) {
3497 dav_set_content(res, in, (dav_read_func)myread, (dav_seek_func)file_seek); 3506 dav_set_string_property_ns(res, DAV_NS, "link", local->link_target);
3498 dav_set_content_length(res, s.st_size); 3507 } else if(issplit) {
3499 } else {
3500 // set split property 3508 // set split property
3501 char blocksize_str[32]; 3509 char blocksize_str[32];
3502 snprintf(blocksize_str, 32, "%zu", split_blocksize); 3510 snprintf(blocksize_str, 32, "%zu", split_blocksize);
3503 dav_set_string_property_ns(res, DAV_NS, "split", blocksize_str); 3511 dav_set_string_property_ns(res, DAV_NS, "split", blocksize_str);
3504 3512
3509 in, 3517 in,
3510 s.st_size, 3518 s.st_size,
3511 split_blocksize, 3519 split_blocksize,
3512 &blockcount, 3520 &blockcount,
3513 &split_err); 3521 &split_err);
3522 } else {
3523 // regular file upload
3524 dav_set_content(res, in, (dav_read_func)myread, (dav_seek_func)file_seek);
3525 dav_set_content_length(res, s.st_size);
3514 } 3526 }
3515 if(split_err) { 3527 if(split_err) {
3516 free(local_path); 3528 free(local_path);
3517 return -1; 3529 return -1;
3518 } 3530 }
3561 // check contentlength and get new etag 3573 // check contentlength and get new etag
3562 DavResource *up_res = dav_get(res->session, res->path, "D:getetag,idav:status"); 3574 DavResource *up_res = dav_get(res->session, res->path, "D:getetag,idav:status");
3563 3575
3564 if(up_res) { 3576 if(up_res) {
3565 // the new content length must be equal or greater than the file size 3577 // the new content length must be equal or greater than the file size
3566 if(up_res->contentlength < s.st_size && !issplit) { 3578 if(up_res->contentlength < s.st_size && !issplit && !islink) {
3567 fprintf(stderr, "Incomplete Upload: %s\n", local_path); 3579 fprintf(stderr, "Incomplete Upload: %s\n", local_path);
3568 ret = -1; 3580 ret = -1;
3569 // try to set the resource status to 'broken' 3581 // try to set the resource status to 'broken'
3570 sync_set_status(res, "broken"); 3582 sync_set_status(res, "broken");
3571 } else { 3583 } else {

mercurial