143 DavResource *res = stack->data; |
152 DavResource *res = stack->data; |
144 stack = ucx_list_remove(stack, stack); |
153 stack = ucx_list_remove(stack, stack); |
145 |
154 |
146 while(res) { |
155 while(res) { |
147 // download the resource |
156 // download the resource |
148 if(sync_get_resource(dir, res, db)) { |
157 if(sync_get_resource(a, dir, res, db)) { |
149 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); |
158 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); |
150 } |
159 } |
151 |
160 |
152 LocalResource *local = ucx_map_cstr_get(db->resources, res->path); |
161 LocalResource *local = ucx_map_cstr_get(db->resources, res->path); |
153 ucx_map_cstr_put(svrres, res->path, local); |
162 ucx_map_cstr_put(svrres, res->path, local); |
215 // resource is already up-to-date on the client |
225 // resource is already up-to-date on the client |
216 return 0; |
226 return 0; |
217 } |
227 } |
218 } |
228 } |
219 |
229 |
220 if(s.st_mtim.tv_sec != local->last_modified) { |
230 if(cdt && s.st_mtim.tv_sec != local->last_modified) { |
221 // file modified on the server and on the client |
231 // file modified on the server and on the client |
222 rename_local_file(dir, db, local->path); |
232 rename_local_file(dir, db, local->path); |
223 } |
233 } |
224 } else { |
234 } else { |
225 if(stat(local_path, &s)) { |
235 if(stat(local_path, &s)) { |
226 if(errno != ENOENT) { |
236 if(errno != ENOENT) { |
227 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
237 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
228 } |
238 } |
229 } else if(!S_ISDIR(s.st_mode)) { |
239 } else if(cdt && !S_ISDIR(s.st_mode)) { |
230 rename_local_file(dir, db, res->path); |
240 rename_local_file(dir, db, res->path); |
231 } |
241 } |
232 } |
242 } |
233 |
243 |
234 int ret = 0; |
244 int ret = 0; |
364 repo->password); |
374 repo->password); |
365 dav_session_set_flags(sn, get_repository_flags(repo)); |
375 dav_session_set_flags(sn, get_repository_flags(repo)); |
366 sn->key = dav_context_get_key(ctx, repo->default_key); |
376 sn->key = dav_context_get_key(ctx, repo->default_key); |
367 |
377 |
368 // upload all changed files |
378 // upload all changed files |
369 UcxList *resources = local_scan(dir, db); |
379 //UcxList *resources = local_scan(dir, db); |
|
380 //UcxList *resources = read_changes(dir, db); |
|
381 UcxList *resources = cmd_getoption(a, "read") ? |
|
382 read_changes(dir, db) : local_scan(dir, db); |
|
383 |
370 UCX_FOREACH(elm, resources) { |
384 UCX_FOREACH(elm, resources) { |
371 char *path = elm->data; |
385 char *path = elm->data; |
372 printf("put: %s\n", path); |
386 printf("put: %s\n", path); |
373 DavResource *res = dav_resource_new(sn, path); |
387 DavResource *res = dav_resource_new(sn, path); |
374 sync_put_resource(dir, res, db); |
388 sync_put_resource(dir, res, db); |
432 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { |
446 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { |
433 continue; |
447 continue; |
434 } |
448 } |
435 |
449 |
436 char *new_path = util_concat_path(p, ent->d_name); |
450 char *new_path = util_concat_path(p, ent->d_name); |
437 char *file_path = util_concat_path(dir->path, new_path); |
451 int isdir; |
438 struct stat s; |
452 LocalResource *res = path_to_local_resource(dir, db, new_path, &isdir); |
439 if(stat(file_path, &s)) { |
453 if(isdir) { |
440 fprintf(stderr, "Cannot stat file %s\n", file_path); |
454 stack = ucx_list_prepend(stack, new_path); |
|
455 } else if(res) { |
|
456 resources = ucx_list_append(resources, strdup(res->path)); |
441 free(new_path); |
457 free(new_path); |
442 free(file_path); |
|
443 continue; |
|
444 } |
|
445 free(file_path); |
|
446 |
|
447 if(S_ISDIR(s.st_mode)) { |
|
448 stack = ucx_list_prepend(stack, new_path); |
|
449 } else { |
458 } else { |
450 LocalResource *res = ucx_map_cstr_get( |
459 free(new_path); |
451 db->resources, |
|
452 new_path); |
|
453 if(res) { |
|
454 // the file is already in the database |
|
455 // compare length and lastmodified date |
|
456 |
|
457 if(res->last_modified == s.st_mtim.tv_sec |
|
458 && res->size == s.st_size) |
|
459 { |
|
460 // skip this file |
|
461 free(new_path); |
|
462 } else { |
|
463 // add file to list |
|
464 resources = ucx_list_append( |
|
465 resources, |
|
466 new_path); |
|
467 |
|
468 // update db entries |
|
469 res->size = s.st_size; |
|
470 res->last_modified = s.st_mtim.tv_sec; |
|
471 } |
|
472 } else { |
|
473 // add file to list |
|
474 LocalResource *res = calloc(1, sizeof(LocalResource)); |
|
475 res->path = strdup(new_path); |
|
476 res->etag = NULL; |
|
477 res->last_modified = s.st_mtim.tv_sec; |
|
478 res->size = s.st_size; |
|
479 ucx_map_cstr_put(db->resources, res->path, res); |
|
480 resources = ucx_list_append(resources, new_path); |
|
481 } |
|
482 } |
460 } |
483 } |
461 } |
484 closedir(local_dir); |
462 closedir(local_dir); |
485 free(ent); |
463 free(ent); |
486 } |
464 } |
487 free(local_path); |
465 free(local_path); |
488 free(p); |
466 free(p); |
489 } |
467 } |
490 |
468 |
491 return resources; |
469 return resources; |
|
470 } |
|
471 |
|
472 UcxList* read_changes(SyncDirectory *dir, SyncDatabase *db) { |
|
473 UcxProperties *parser = ucx_properties_new(); |
|
474 parser->delimiter = ':'; |
|
475 |
|
476 UcxList *resources = NULL; |
|
477 sstr_t name; |
|
478 sstr_t value; |
|
479 |
|
480 char buf[STDIN_BUF_SIZE]; |
|
481 size_t r; |
|
482 while(!feof(stdin)) { |
|
483 r = fread(buf, 1, STDIN_BUF_SIZE, stdin); |
|
484 ucx_properties_fill(parser, buf, r); |
|
485 while(ucx_properties_next(parser, &name, &value)) { |
|
486 if(value.length == 0) { |
|
487 fprintf(stderr, "Wrong input\n"); |
|
488 continue; |
|
489 } |
|
490 if(value.ptr[0] == '"' |
|
491 && value.length > 2 |
|
492 && value.ptr[value.length - 1] == '"') |
|
493 { |
|
494 value.ptr[value.length - 1] = '\0'; |
|
495 value.ptr++; |
|
496 value.length -= 2; |
|
497 } |
|
498 value = sstrdup(value); |
|
499 |
|
500 if(!sstrcmp(name, S("put"))) { |
|
501 int isdir; |
|
502 LocalResource *res = path_to_local_resource(dir, db, value.ptr, &isdir); |
|
503 if(res) { |
|
504 resources = ucx_list_append(resources, strdup(res->path)); |
|
505 } |
|
506 } else if(!sstrcmp(name, S("remove"))) { |
|
507 int isdir; |
|
508 //LocalResource *res = path_to_local_resource(dir, db, value.ptr, &isdir); |
|
509 LocalResource *res = calloc(1, sizeof(LocalResource)); |
|
510 res->path = sstrdup(value).ptr; |
|
511 if(res) { |
|
512 ucx_map_sstr_put(db->remove, value, res); |
|
513 ucx_map_sstr_remove(db->resources, value); |
|
514 } |
|
515 |
|
516 } |
|
517 |
|
518 free(value.ptr); |
|
519 } |
|
520 } |
|
521 ucx_properties_free(parser); |
|
522 |
|
523 return resources; |
|
524 } |
|
525 |
|
526 LocalResource* path_to_local_resource(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir) { |
|
527 char *file_path = util_concat_path(dir->path, path); |
|
528 struct stat s; |
|
529 if(stat(file_path, &s)) { |
|
530 fprintf(stderr, "Cannot stat file %s\n", file_path); |
|
531 free(file_path); |
|
532 return NULL; |
|
533 } |
|
534 free(file_path); |
|
535 |
|
536 if(!S_ISDIR(s.st_mode)) { |
|
537 *isdir = 0; |
|
538 LocalResource *res = ucx_map_cstr_get(db->resources, path); |
|
539 if(res) { |
|
540 // the file is already in the database |
|
541 // compare length and lastmodified date |
|
542 |
|
543 if(res->last_modified == s.st_mtim.tv_sec |
|
544 && res->size == s.st_size) |
|
545 { |
|
546 // file unchanged |
|
547 return NULL; |
|
548 } else { |
|
549 // update db entries |
|
550 res->size = s.st_size; |
|
551 res->last_modified = s.st_mtim.tv_sec; |
|
552 |
|
553 return res; |
|
554 } |
|
555 } else { |
|
556 LocalResource *res = calloc(1, sizeof(LocalResource)); |
|
557 res->path = strdup(path); |
|
558 res->etag = NULL; |
|
559 res->last_modified = s.st_mtim.tv_sec; |
|
560 res->size = s.st_size; |
|
561 ucx_map_cstr_put(db->resources, res->path, res); |
|
562 return res; |
|
563 } |
|
564 } else { |
|
565 *isdir = 1; |
|
566 } |
|
567 return NULL; |
492 } |
568 } |
493 |
569 |
494 int sync_put_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) { |
570 int sync_put_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) { |
495 char *local_path = util_concat_path(dir->path, res->path); |
571 char *local_path = util_concat_path(dir->path, res->path); |
496 FILE *in = fopen(local_path, "r"); |
572 FILE *in = fopen(local_path, "r"); |