266 struct stat s; |
266 struct stat s; |
267 if(local) { |
267 if(local) { |
268 int exists = 1; |
268 int exists = 1; |
269 if(stat(local_path, &s)) { |
269 if(stat(local_path, &s)) { |
270 // Ignore the fact, that the file is locally removed. If the |
270 // Ignore the fact, that the file is locally removed. If the |
271 // server has an updated version, we readd the file or the |
271 // server has an updated version, we read the file or the |
272 // next push will delete it on the server. |
272 // next push will delete it on the server. |
273 if(errno != ENOENT) { |
273 if(errno != ENOENT) { |
274 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
274 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
275 free(local_path); |
275 free(local_path); |
276 return -1; |
276 return -1; |
306 rename_local_file(dir, db, res->path); |
306 rename_local_file(dir, db, res->path); |
307 } |
307 } |
308 } |
308 } |
309 |
309 |
310 int ret = 0; |
310 int ret = 0; |
|
311 char *tmp_path = create_tmp_download_path(local_path); |
311 if(res->iscollection) { |
312 if(res->iscollection) { |
312 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
313 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
313 if(util_mkdir(local_path, mode) && errno != EEXIST) { |
314 if(util_mkdir(local_path, mode) && errno != EEXIST) { |
314 ret = -1; |
315 ret = -1; |
315 } |
316 } |
316 } else { |
317 } else { |
317 FILE *out = fopen(local_path, "wb"); |
318 if(!tmp_path) { |
|
319 fprintf(stderr, "Cannot create tmp path for %s\n", local_path); |
|
320 free(local_path); |
|
321 return -1; |
|
322 } |
|
323 FILE *out = fopen(tmp_path, "wb"); |
318 if(!out) { |
324 if(!out) { |
319 fprintf(stderr, "Cannot open output file: %s\n", local_path); |
325 fprintf(stderr, "Cannot open output file: %s\n", local_path); |
320 free(local_path); |
326 free(local_path); |
|
327 free(tmp_path); |
321 return -1; |
328 return -1; |
322 } |
329 } |
323 printf("get: %s\n", res->path); |
330 printf("get: %s\n", res->path); |
324 if(dav_get_content(res, out, (dav_write_func)fwrite)) { |
331 if(dav_get_content(res, out, (dav_write_func)fwrite)) { |
325 ret = -1; |
332 ret = -1; |
326 } |
333 } |
327 fclose(out); |
334 fclose(out); |
328 |
335 |
329 if(stat(local_path, &s)) { |
|
330 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
|
331 } |
|
332 |
|
333 if(ret == 0) { |
336 if(ret == 0) { |
|
337 if(dir->trash && dir->backuppull) { |
|
338 move_to_trash(dir, local_path); |
|
339 } |
|
340 if(rename(tmp_path, local_path)) { |
|
341 fprintf( |
|
342 stderr, |
|
343 "Cannot rename file %s to %s\n", |
|
344 tmp_path, |
|
345 local_path); |
|
346 perror(""); |
|
347 free(tmp_path); |
|
348 free(local_path); |
|
349 return -1; |
|
350 } |
|
351 |
|
352 if(stat(local_path, &s)) { |
|
353 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
|
354 perror(""); |
|
355 } |
|
356 |
334 if(!local) { |
357 if(!local) { |
335 // new local resource |
358 // new local resource |
336 local = calloc(1, sizeof(LocalResource)); |
359 local = calloc(1, sizeof(LocalResource)); |
337 local->path = strdup(res->path); |
360 local->path = strdup(res->path); |
338 ucx_map_cstr_put(db->resources, local->path, local); |
361 ucx_map_cstr_put(db->resources, local->path, local); |
343 } |
366 } |
344 // set metadata from stat |
367 // set metadata from stat |
345 local->etag = etag; |
368 local->etag = etag; |
346 local->last_modified = s.st_mtime; |
369 local->last_modified = s.st_mtime; |
347 local->size = s.st_size; |
370 local->size = s.st_size; |
348 } |
371 } else { |
349 } |
372 if(unlink(tmp_path)) { |
350 |
373 fprintf(stderr, "Cannot remove tmp file: %s\n", tmp_path); |
|
374 } |
|
375 } |
|
376 } |
|
377 |
|
378 free(tmp_path); |
351 free(local_path); |
379 free(local_path); |
352 return ret; |
380 return ret; |
353 } |
381 } |
354 |
382 |
355 void sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) { |
383 void sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) { |
407 } |
435 } |
408 rev++; |
436 rev++; |
409 free(new_path.ptr); |
437 free(new_path.ptr); |
410 } while(loop); |
438 } while(loop); |
411 free(parent); |
439 free(parent); |
|
440 } |
|
441 |
|
442 char* create_tmp_download_path(char *path) { |
|
443 char *new_path = NULL; |
|
444 char *parent = util_parent_path(path); |
|
445 for (int i=0;;i++) { |
|
446 sstr_t np = ucx_asprintf( |
|
447 ucx_default_allocator(), |
|
448 "%sdownload%d-%s", |
|
449 parent, |
|
450 i, |
|
451 util_resource_name(path)); |
|
452 |
|
453 struct stat s; |
|
454 if(stat(np.ptr, &s)) { |
|
455 if(errno == ENOENT) { |
|
456 new_path = np.ptr; |
|
457 } |
|
458 break; |
|
459 } |
|
460 free(np.ptr); |
|
461 }; |
|
462 |
|
463 free(parent); |
|
464 return new_path; |
412 } |
465 } |
413 |
466 |
414 void move_to_trash(SyncDirectory *dir, char *path) { |
467 void move_to_trash(SyncDirectory *dir, char *path) { |
415 char *new_path = NULL; |
468 char *new_path = NULL; |
416 for (int i=0;;i++) { |
469 for (int i=0;;i++) { |