28 |
28 |
29 #include <stdio.h> |
29 #include <stdio.h> |
30 #include <stdlib.h> |
30 #include <stdlib.h> |
31 #include <string.h> |
31 #include <string.h> |
32 #include <errno.h> |
32 #include <errno.h> |
33 #include <unistd.h> |
33 |
34 #include <signal.h> |
34 #include <signal.h> |
35 #include <time.h> |
35 #include <time.h> |
36 #include <utime.h> |
|
37 #include <libxml/xmlerror.h> |
36 #include <libxml/xmlerror.h> |
38 #include <sys/types.h> |
37 #include <sys/types.h> |
39 #include <cx/map.h> |
38 #include <cx/map.h> |
40 #include <cx/string.h> |
39 #include <cx/string.h> |
41 #include <cx/utils.h> |
40 #include <cx/utils.h> |
42 #include <cx/list.h> |
41 #include <cx/list.h> |
43 #include <cx/hash_map.h> |
42 #include <cx/hash_map.h> |
44 #include <cx/printf.h> |
43 #include <cx/printf.h> |
45 #include <dirent.h> |
44 |
|
45 #ifndef _WIN32 |
|
46 // unix includes |
|
47 #include <unistd.h> |
|
48 #include <utime.h> |
|
49 #include <pthread.h> |
|
50 #else |
|
51 //windows includes |
|
52 |
|
53 #endif |
|
54 |
46 |
55 |
47 #include <math.h> |
56 #include <math.h> |
48 |
57 |
49 #include <libidav/webdav.h> |
58 #include <libidav/webdav.h> |
50 #include <libidav/utils.h> |
59 #include <libidav/utils.h> |
297 #ifndef _WIN32 |
316 #ifndef _WIN32 |
298 struct sigaction act; |
317 struct sigaction act; |
299 memset(&act, 0, sizeof(struct sigaction)); |
318 memset(&act, 0, sizeof(struct sigaction)); |
300 act.sa_handler = SIG_IGN; |
319 act.sa_handler = SIG_IGN; |
301 sigaction(SIGPIPE, &act, NULL); |
320 sigaction(SIGPIPE, &act, NULL); |
302 #endif |
321 |
303 |
|
304 // prepare signal handler thread |
322 // prepare signal handler thread |
305 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
323 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
306 pthread_mutex_lock(&mutex); |
324 pthread_mutex_lock(&mutex); |
307 pthread_t tid; |
325 pthread_t tid; |
|
326 #else |
|
327 int tid; |
|
328 int mutex; |
|
329 #endif |
308 |
330 |
309 if(!strcmp(cmd, "check") || !strcmp(cmd, "check-config")) { |
331 if(!strcmp(cmd, "check") || !strcmp(cmd, "check-config")) { |
310 if(!cfgret) { |
332 if(!cfgret) { |
311 fprintf(stdout, "Configuration OK.\n"); |
333 fprintf(stdout, "Configuration OK.\n"); |
312 ret = EXIT_SUCCESS; |
334 ret = EXIT_SUCCESS; |
430 } |
452 } |
431 fprintf(stderr, "abort\n"); |
453 fprintf(stderr, "abort\n"); |
432 sync_shutdown = 1; |
454 sync_shutdown = 1; |
433 } |
455 } |
434 |
456 |
|
457 #ifndef _WIN32 |
435 static void* sighandler(void *data) { |
458 static void* sighandler(void *data) { |
436 signal(SIGTERM, handlesig); |
459 signal(SIGTERM, handlesig); |
437 signal(SIGINT, handlesig); |
460 signal(SIGINT, handlesig); |
438 |
461 |
439 pthread_mutex_t *mutex = data; |
462 pthread_mutex_t *mutex = data; |
453 void stop_sighandler(pthread_mutex_t *mutex, pthread_t tid) { |
476 void stop_sighandler(pthread_mutex_t *mutex, pthread_t tid) { |
454 pthread_mutex_unlock(mutex); |
477 pthread_mutex_unlock(mutex); |
455 void *data; |
478 void *data; |
456 pthread_join(tid, &data); |
479 pthread_join(tid, &data); |
457 } |
480 } |
|
481 #else |
|
482 |
|
483 int start_sighandler(int* mutex) { |
|
484 return 0; |
|
485 } |
|
486 int stop_sighandler(int* mutex, int tid) { |
|
487 return 0; |
|
488 } |
|
489 |
|
490 #endif |
458 |
491 |
459 static char* create_local_path(SyncDirectory *dir, const char *path) { |
492 static char* create_local_path(SyncDirectory *dir, const char *path) { |
460 char *local_path = util_concat_path(dir->path, path); |
493 char *local_path = util_concat_path(dir->path, path); |
461 size_t local_path_len = strlen(local_path); |
494 size_t local_path_len = strlen(local_path); |
462 if(local_path[local_path_len-1] == '/') { |
495 if(local_path[local_path_len-1] == '/') { |
1362 local->uid = s->st_uid; |
1395 local->uid = s->st_uid; |
1363 local->gid = s->st_gid; |
1396 local->gid = s->st_gid; |
1364 local->size = s->st_size; |
1397 local->size = s->st_size; |
1365 } |
1398 } |
1366 |
1399 |
|
1400 #ifdef _WIN32 |
|
1401 #define fseeko fseek |
|
1402 #define ftello ftell |
|
1403 #endif |
|
1404 |
1367 static CxList* sync_download_changed_parts( |
1405 static CxList* sync_download_changed_parts( |
1368 DavResource *res, |
1406 DavResource *res, |
1369 LocalResource *local, |
1407 LocalResource *local, |
1370 FILE *out, |
1408 FILE *out, |
1371 size_t blocksize, |
1409 size_t blocksize, |
1664 } |
1702 } |
1665 |
1703 |
1666 if(issplit || (SYNC_HASHING(dir) && !link)) { |
1704 if(issplit || (SYNC_HASHING(dir) && !link)) { |
1667 if(truncate_file >= 0) { |
1705 if(truncate_file >= 0) { |
1668 // only true if issplit is true |
1706 // only true if issplit is true |
1669 if(truncate(local_path, truncate_file)) { |
1707 if(sys_truncate(local_path, truncate_file)) { |
1670 perror("truncate"); |
1708 perror("truncate"); |
1671 } |
1709 } |
1672 } |
1710 } |
1673 |
1711 |
1674 char *res_hash = sync_get_content_hash(res); |
1712 char *res_hash = sync_get_content_hash(res); |
3053 // we dont want resource names with this extension |
3091 // we dont want resource names with this extension |
3054 // and possibly sync this to other operating systems |
3092 // and possibly sync this to other operating systems |
3055 // therefore we remove the .lnk extension from the file name |
3093 // therefore we remove the .lnk extension from the file name |
3056 // change res->path |
3094 // change res->path |
3057 // we only do this, if there isn't any other file with this name |
3095 // we only do this, if there isn't any other file with this name |
3058 sstr_t fpath = sstr(file_path); |
3096 cxstring fpath = cx_str(file_path); |
3059 sstr_t rpath = sstr(path); |
3097 cxstring rpath = cx_str(path); |
3060 // remove last 4 chars (.lnk) |
3098 // remove last 4 chars (.lnk) |
3061 sstr_t new_file_path = sstrdup(sstrsubsl(fpath, 0 , fpath.length-4)); |
3099 cxmutstr new_file_path = cx_strdup(cx_strsubsl(fpath, 0 , fpath.length-4)); |
3062 // check if a file with this name exists |
3100 // check if a file with this name exists |
3063 SYS_STAT nfp_s; |
3101 SYS_STAT nfp_s; |
3064 if(!sys_stat(new_file_path.ptr, &nfp_s)) { |
3102 if(!sys_stat(new_file_path.ptr, &nfp_s)) { |
3065 // we can't upload the link without the file extension, because |
3103 // we can't upload the link without the file extension, because |
3066 // there is another file with this name |
3104 // there is another file with this name |
3067 free(lnkbuf); |
3105 free(lnkbuf); |
3068 lnkbuf = NULL; |
3106 lnkbuf = NULL; |
3069 } else { |
3107 } else { |
3070 sstr_t new_path = sstrdup(sstrsubsl(rpath, 0, rpath.length-4)); |
3108 cxmutstr new_path = cx_strdup(cx_strsubsl(rpath, 0, rpath.length-4)); |
3071 res->local_path = res->path; |
3109 res->local_path = res->path; |
3072 res->path = new_path.ptr; // remove .lnk ext from resource path |
3110 res->path = new_path.ptr; // remove .lnk ext from resource path |
3073 } |
3111 } |
3074 free(new_file_path.ptr); |
3112 free(new_file_path.ptr); |
3075 #endif |
3113 #endif |
3408 |
3446 |
3409 char* resource_local_path(DavResource *res) { |
3447 char* resource_local_path(DavResource *res) { |
3410 #ifdef SYS_LINK_EXT |
3448 #ifdef SYS_LINK_EXT |
3411 // on Windows, add .lnk extension to links |
3449 // on Windows, add .lnk extension to links |
3412 if(dav_get_property_ns(res, DAV_PROPS_NS, "link")) { |
3450 if(dav_get_property_ns(res, DAV_PROPS_NS, "link")) { |
3413 return ucx_sprintf("%s%s", res->path, SYS_LINK_EXT).ptr; |
3451 return cx_asprintf("%s%s", res->path, SYS_LINK_EXT).ptr; |
3414 } else { |
3452 } else { |
3415 // not a link |
3453 // not a link |
3416 return strdup(res->path); |
3454 return strdup(res->path); |
3417 } |
3455 } |
3418 #else |
3456 #else |
3561 DavXmlNode *fileinfo = dav_get_property_ns(res, DAV_PROPS_NS, "finfo"); |
3599 DavXmlNode *fileinfo = dav_get_property_ns(res, DAV_PROPS_NS, "finfo"); |
3562 if(fileinfo) { |
3600 if(fileinfo) { |
3563 FileInfo f; |
3601 FileInfo f; |
3564 finfo_get_values(fileinfo, &f); |
3602 finfo_get_values(fileinfo, &f); |
3565 if((dir->metadata & FINFO_MTIME) == FINFO_MTIME && f.date_set) { |
3603 if((dir->metadata & FINFO_MTIME) == FINFO_MTIME && f.date_set) { |
|
3604 // TODO: implement on windows |
|
3605 #ifndef _WIN32 |
3566 // set mtime |
3606 // set mtime |
3567 struct utimbuf t; |
3607 struct utimbuf t; |
3568 t.actime = f.last_modified; |
3608 t.actime = f.last_modified; |
3569 t.modtime = f.last_modified; |
3609 t.modtime = f.last_modified; |
3570 if(utime(path, &t)) { |
3610 if(utime(path, &t)) { |
3571 log_error("utime failed for file: %s : %s\n", path, strerror(errno)); |
3611 log_error("utime failed for file: %s : %s\n", path, strerror(errno)); |
3572 ret = 1; |
3612 ret = 1; |
3573 } else { |
3613 } else { |
3574 local->last_modified = f.last_modified; |
3614 local->last_modified = f.last_modified; |
3575 } |
3615 } |
|
3616 #else |
|
3617 local->last_modified = 0; |
|
3618 #endif |
3576 } |
3619 } |
3577 if((dir->metadata & FINFO_MODE) == FINFO_MODE && f.mode_set) { |
3620 if((dir->metadata & FINFO_MODE) == FINFO_MODE && f.mode_set) { |
3578 // set mode |
3621 // set mode |
3579 if(chmod(path, f.mode)) { |
3622 if(chmod(path, f.mode)) { |
3580 log_error("chmod failed for file: %s : %s\n", path, strerror(errno)); |
3623 log_error("chmod failed for file: %s : %s\n", path, strerror(errno)); |