| File src/fops_cpmv.c changed (mode: 100644) (index 3aca949f5..549224f0d) |
| ... |
... |
verify_args_t; |
| 51 |
51 |
|
|
| 52 |
52 |
static int cp_file(const char src_dir[], const char dst_dir[], const char src[], |
static int cp_file(const char src_dir[], const char dst_dir[], const char src[], |
| 53 |
53 |
const char dst[], CopyMoveLikeOp op, int cancellable, ops_t *ops, |
const char dst[], CopyMoveLikeOp op, int cancellable, ops_t *ops, |
| 54 |
|
int force); |
|
|
54 |
|
int force, int deep); |
| 55 |
55 |
static int is_erroneous(view_t *view, const char dst_dir[], int force); |
static int is_erroneous(view_t *view, const char dst_dir[], int force); |
| 56 |
56 |
static int cpmv_prepare(view_t *view, char ***list, int *nlines, |
static int cpmv_prepare(view_t *view, char ***list, int *nlines, |
| 57 |
57 |
CopyMoveLikeOp op, int ignore_conflicts, char undo_msg[], |
CopyMoveLikeOp op, int ignore_conflicts, char undo_msg[], |
| |
| ... |
... |
static const char * cmlo_to_str(CopyMoveLikeOp op); |
| 64 |
64 |
static void cpmv_files_in_bg(bg_op_t *bg_op, void *arg); |
static void cpmv_files_in_bg(bg_op_t *bg_op, void *arg); |
| 65 |
65 |
static void set_cpmv_bg_descr(bg_op_t *bg_op, bg_args_t *args, size_t i); |
static void set_cpmv_bg_descr(bg_op_t *bg_op, bg_args_t *args, size_t i); |
| 66 |
66 |
static void cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], |
static void cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], |
| 67 |
|
int move, int force, int skip, int from_trash, const char dst_dir[]); |
|
|
67 |
|
int move, int force, int skip, int deep, int from_trash, |
|
68 |
|
const char dst_dir[]); |
| 68 |
69 |
static int cp_file_f(const char src[], const char dst[], CopyMoveLikeOp op, |
static int cp_file_f(const char src[], const char dst[], CopyMoveLikeOp op, |
| 69 |
|
int bg, int cancellable, ops_t *ops, int force); |
|
|
70 |
|
int bg, int cancellable, ops_t *ops, int force, int deep); |
| 70 |
71 |
|
|
| 71 |
72 |
int |
int |
| 72 |
73 |
fops_cpmv(view_t *view, char *list[], int nlines, CopyMoveLikeOp op, int flags) |
fops_cpmv(view_t *view, char *list[], int nlines, CopyMoveLikeOp op, int flags) |
| 73 |
74 |
{ |
{ |
| 74 |
75 |
const int force = (flags & CMLF_FORCE); |
const int force = (flags & CMLF_FORCE); |
| 75 |
76 |
const int skip = (flags & CMLF_SKIP); |
const int skip = (flags & CMLF_SKIP); |
|
77 |
|
const int deep = (flags & CMLF_DEEP); |
| 76 |
78 |
|
|
| 77 |
79 |
int err; |
int err; |
| 78 |
80 |
int nmarked_files; |
int nmarked_files; |
| |
| ... |
... |
fops_cpmv(view_t *view, char *list[], int nlines, CopyMoveLikeOp op, int flags) |
| 122 |
124 |
return 0; |
return 0; |
| 123 |
125 |
} |
} |
| 124 |
126 |
|
|
| 125 |
|
nmarked_files = fops_enqueue_marked_files(ops, view, dst_dir, 0); |
|
|
127 |
|
nmarked_files = |
|
128 |
|
fops_enqueue_marked_files(ops, view, dst_dir, /*to_trash=*/0, deep); |
| 126 |
129 |
|
|
| 127 |
130 |
un_group_open(undo_msg); |
un_group_open(undo_msg); |
| 128 |
131 |
i = 0; |
i = 0; |
| |
| ... |
... |
fops_cpmv(view_t *view, char *list[], int nlines, CopyMoveLikeOp op, int flags) |
| 188 |
191 |
else |
else |
| 189 |
192 |
{ |
{ |
| 190 |
193 |
err = cp_file(entry->origin, dst_dir, entry->name, dst, op, 1, ops, |
err = cp_file(entry->origin, dst_dir, entry->name, dst, op, 1, ops, |
| 191 |
|
0); |
|
|
194 |
|
0, deep); |
| 192 |
195 |
} |
} |
| 193 |
196 |
|
|
| 194 |
197 |
ops_advance(ops, err == 0); |
ops_advance(ops, err == 0); |
| |
| ... |
... |
fops_replace_entry(ops_t *ops, view_t *src, const dir_entry_t *src_entry, |
| 265 |
268 |
{ |
{ |
| 266 |
269 |
/* Not forcing as destination path shouldn't exist. */ |
/* Not forcing as destination path shouldn't exist. */ |
| 267 |
270 |
if(cp_file_f(src_full, dst_full, CMLO_COPY, /*bg=*/0, /*cancellable=*/1, |
if(cp_file_f(src_full, dst_full, CMLO_COPY, /*bg=*/0, /*cancellable=*/1, |
| 268 |
|
ops, /*force=*/0) == 0 && !dst_exists) |
|
|
271 |
|
ops, /*force=*/0, /*deep=*/0) == 0 && !dst_exists) |
| 269 |
272 |
{ |
{ |
| 270 |
273 |
/* Update the destination entry to not be fake. */ |
/* Update the destination entry to not be fake. */ |
| 271 |
274 |
replace_string(&dst_entry->name, src_entry->name); |
replace_string(&dst_entry->name, src_entry->name); |
| |
| ... |
... |
fops_replace_entry(ops_t *ops, view_t *src, const dir_entry_t *src_entry, |
| 280 |
283 |
* parts. */ |
* parts. */ |
| 281 |
284 |
static int |
static int |
| 282 |
285 |
cp_file(const char src_dir[], const char dst_dir[], const char src[], |
cp_file(const char src_dir[], const char dst_dir[], const char src[], |
| 283 |
|
const char dst[], CopyMoveLikeOp op, int cancellable, ops_t *ops, int force) |
|
|
286 |
|
const char dst[], CopyMoveLikeOp op, int cancellable, ops_t *ops, int force, |
|
287 |
|
int deep) |
| 284 |
288 |
{ |
{ |
| 285 |
289 |
char full_src[PATH_MAX + 1], full_dst[PATH_MAX + 1]; |
char full_src[PATH_MAX + 1], full_dst[PATH_MAX + 1]; |
| 286 |
290 |
|
|
| 287 |
291 |
to_canonic_path(src, src_dir, full_src, sizeof(full_src)); |
to_canonic_path(src, src_dir, full_src, sizeof(full_src)); |
| 288 |
292 |
to_canonic_path(dst, dst_dir, full_dst, sizeof(full_dst)); |
to_canonic_path(dst, dst_dir, full_dst, sizeof(full_dst)); |
| 289 |
293 |
|
|
| 290 |
|
return cp_file_f(full_src, full_dst, op, 0, cancellable, ops, force); |
|
|
294 |
|
return cp_file_f(full_src, full_dst, op, 0, cancellable, ops, force, deep); |
| 291 |
295 |
} |
} |
| 292 |
296 |
|
|
| 293 |
297 |
int |
int |
| |
| ... |
... |
fops_cpmv_bg(view_t *view, char *list[], int nlines, int move, int flags) |
| 295 |
299 |
{ |
{ |
| 296 |
300 |
const int force = (flags & CMLF_FORCE); |
const int force = (flags & CMLF_FORCE); |
| 297 |
301 |
const int skip = (flags & CMLF_SKIP); |
const int skip = (flags & CMLF_SKIP); |
|
302 |
|
const int deep = (flags & CMLF_DEEP); |
| 298 |
303 |
|
|
| 299 |
304 |
int err; |
int err; |
| 300 |
305 |
size_t i; |
size_t i; |
| |
| ... |
... |
fops_cpmv_bg(view_t *view, char *list[], int nlines, int move, int flags) |
| 311 |
316 |
args->move = move; |
args->move = move; |
| 312 |
317 |
args->force = force; |
args->force = force; |
| 313 |
318 |
args->skip = skip; |
args->skip = skip; |
|
319 |
|
args->deep = deep; |
| 314 |
320 |
|
|
| 315 |
321 |
const int ignore_conflicts = (force || skip); |
const int ignore_conflicts = (force || skip); |
| 316 |
322 |
err = cpmv_prepare(view, &list, &args->nlines, move ? CMLO_MOVE : CMLO_COPY, |
err = cpmv_prepare(view, &list, &args->nlines, move ? CMLO_MOVE : CMLO_COPY, |
| |
| ... |
... |
cpmv_files_in_bg(bg_op_t *bg_op, void *arg) |
| 601 |
607 |
{ |
{ |
| 602 |
608 |
const char *const src = args->sel_list[i]; |
const char *const src = args->sel_list[i]; |
| 603 |
609 |
const char *const dst = args->list[i]; |
const char *const dst = args->list[i]; |
| 604 |
|
ops_enqueue(ops, src, dst); |
|
|
610 |
|
ops_enqueue(ops, src, dst, args->deep); |
| 605 |
611 |
} |
} |
| 606 |
612 |
} |
} |
| 607 |
613 |
|
|
| |
| ... |
... |
cpmv_files_in_bg(bg_op_t *bg_op, void *arg) |
| 613 |
619 |
set_cpmv_bg_descr(bg_op, args, i); |
set_cpmv_bg_descr(bg_op, args, i); |
| 614 |
620 |
|
|
| 615 |
621 |
cpmv_file_in_bg(ops, src, dst, args->move, args->force, args->skip, |
cpmv_file_in_bg(ops, src, dst, args->move, args->force, args->skip, |
| 616 |
|
args->is_in_trash[i], args->path); |
|
|
622 |
|
args->deep, args->is_in_trash[i], args->path); |
| 617 |
623 |
++bg_op->done; |
++bg_op->done; |
| 618 |
624 |
} |
} |
| 619 |
625 |
|
|
| |
| ... |
... |
set_cpmv_bg_descr(bg_op_t *bg_op, bg_args_t *args, size_t i) |
| 658 |
664 |
/* Actual implementation of background file copying/moving. */ |
/* Actual implementation of background file copying/moving. */ |
| 659 |
665 |
static void |
static void |
| 660 |
666 |
cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], int move, |
cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], int move, |
| 661 |
|
int force, int skip, int from_trash, const char dst_dir[]) |
|
|
667 |
|
int force, int skip, int deep, int from_trash, const char dst_dir[]) |
| 662 |
668 |
{ |
{ |
| 663 |
669 |
char dst_full[PATH_MAX + 1]; |
char dst_full[PATH_MAX + 1]; |
| 664 |
670 |
snprintf(dst_full, sizeof(dst_full), "%s/%s", dst_dir, dst); |
snprintf(dst_full, sizeof(dst_full), "%s/%s", dst_dir, dst); |
| |
| ... |
... |
cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], int move, |
| 682 |
688 |
} |
} |
| 683 |
689 |
else |
else |
| 684 |
690 |
{ |
{ |
| 685 |
|
(void)cp_file_f(src, dst_full, CMLO_COPY, 1, 1, ops, 0); |
|
|
691 |
|
(void)cp_file_f(src, dst_full, CMLO_COPY, 1, 1, ops, 0, deep); |
| 686 |
692 |
} |
} |
| 687 |
693 |
} |
} |
| 688 |
694 |
|
|
| |
| ... |
... |
cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], int move, |
| 690 |
696 |
* non-zero is returned. */ |
* non-zero is returned. */ |
| 691 |
697 |
static int |
static int |
| 692 |
698 |
cp_file_f(const char src[], const char dst[], CopyMoveLikeOp op, int bg, |
cp_file_f(const char src[], const char dst[], CopyMoveLikeOp op, int bg, |
| 693 |
|
int cancellable, ops_t *ops, int force) |
|
|
699 |
|
int cancellable, ops_t *ops, int force, int deep) |
| 694 |
700 |
{ |
{ |
| 695 |
701 |
if(strcmp(src, dst) == 0) |
if(strcmp(src, dst) == 0) |
| 696 |
702 |
{ |
{ |
| |
| ... |
... |
cp_file_f(const char src[], const char dst[], CopyMoveLikeOp op, int bg, |
| 719 |
725 |
} |
} |
| 720 |
726 |
} |
} |
| 721 |
727 |
|
|
| 722 |
|
void *flags = ops_flags(cancellable ? DF_NONE : DF_NO_CANCEL); |
|
|
728 |
|
int f = (cancellable ? DF_NONE : DF_NO_CANCEL) |
|
729 |
|
| (deep ? DF_DEEP_COPY : DF_NONE); |
|
730 |
|
void *flags = ops_flags(f); |
| 723 |
731 |
OpsResult result = perform_operation(file_op, ops, flags, src, dst); |
OpsResult result = perform_operation(file_op, ops, flags, src, dst); |
| 724 |
732 |
if(result != OPS_SUCCEEDED) |
if(result != OPS_SUCCEEDED) |
| 725 |
733 |
{ |
{ |
| File src/fops_misc.c changed (mode: 100644) (index 52de3f3a4..67de96895) |
| ... |
... |
fops_delete(view_t *view, int reg, int use_trash) |
| 160 |
160 |
ops = fops_get_ops(OP_REMOVE, use_trash ? "deleting" : "Deleting", curr_dir, |
ops = fops_get_ops(OP_REMOVE, use_trash ? "deleting" : "Deleting", curr_dir, |
| 161 |
161 |
curr_dir); |
curr_dir); |
| 162 |
162 |
|
|
| 163 |
|
nmarked_files = fops_enqueue_marked_files(ops, view, NULL, use_trash); |
|
|
163 |
|
nmarked_files = |
|
164 |
|
fops_enqueue_marked_files(ops, view, NULL, use_trash, /*deep=*/0); |
| 164 |
165 |
|
|
| 165 |
166 |
entry = NULL; |
entry = NULL; |
| 166 |
167 |
i = 0; |
i = 0; |
| |
| ... |
... |
delete_files_in_bg(bg_op_t *bg_op, void *arg) |
| 407 |
408 |
{ |
{ |
| 408 |
409 |
const char *const src = args->sel_list[i]; |
const char *const src = args->sel_list[i]; |
| 409 |
410 |
char *trash_dir = (args->use_trash ? trash_pick_dir(src) : args->path); |
char *trash_dir = (args->use_trash ? trash_pick_dir(src) : args->path); |
| 410 |
|
ops_enqueue(ops, src, trash_dir); |
|
|
411 |
|
ops_enqueue(ops, src, trash_dir, /*deep=*/0); |
| 411 |
412 |
if(trash_dir != args->path) |
if(trash_dir != args->path) |
| 412 |
413 |
{ |
{ |
| 413 |
414 |
free(trash_dir); |
free(trash_dir); |
| |
| ... |
... |
retarget_many(view_t *view, char *files[], int nfiles) |
| 696 |
697 |
{ |
{ |
| 697 |
698 |
char full_path[PATH_MAX + 1]; |
char full_path[PATH_MAX + 1]; |
| 698 |
699 |
get_full_path_of(entry, sizeof(full_path), full_path); |
get_full_path_of(entry, sizeof(full_path), full_path); |
| 699 |
|
ops_enqueue(ops, full_path, full_path); |
|
|
700 |
|
ops_enqueue(ops, full_path, full_path, /*deep=*/0); |
| 700 |
701 |
} |
} |
| 701 |
702 |
|
|
| 702 |
703 |
int i = 0; |
int i = 0; |
| |
| ... |
... |
fops_clone(view_t *view, char *list[], int nlines, int force, int copies) |
| 843 |
844 |
ops_t *ops = fops_get_ops(OP_COPY, "Cloning", curr_dir, |
ops_t *ops = fops_get_ops(OP_COPY, "Cloning", curr_dir, |
| 844 |
845 |
with_dir ? list[0] : curr_dir); |
with_dir ? list[0] : curr_dir); |
| 845 |
846 |
|
|
| 846 |
|
int nmarked_files = fops_enqueue_marked_files(ops, view, dst_path, 0); |
|
|
847 |
|
int nmarked_files = |
|
848 |
|
fops_enqueue_marked_files(ops, view, dst_path, /*to_trash=*/0, /*deep=*/0); |
| 847 |
849 |
|
|
| 848 |
850 |
const int custom_fnames = (nlines > 0); |
const int custom_fnames = (nlines > 0); |
| 849 |
851 |
|
|
| |
| ... |
... |
fops_chown(int u, int g, uid_t uid, gid_t gid) |
| 1411 |
1413 |
replace_home_part(curr_dir)); |
replace_home_part(curr_dir)); |
| 1412 |
1414 |
|
|
| 1413 |
1415 |
ops = fops_get_ops(OP_CHOWN, "re-owning", curr_dir, curr_dir); |
ops = fops_get_ops(OP_CHOWN, "re-owning", curr_dir, curr_dir); |
| 1414 |
|
(void)fops_enqueue_marked_files(ops, view, NULL, 0); |
|
|
1416 |
|
(void)fops_enqueue_marked_files(ops, view, NULL, /*to_trash=*/0, /*deep=*/0); |
| 1415 |
1417 |
|
|
| 1416 |
1418 |
fops_append_marked_files(view, undo_msg, NULL); |
fops_append_marked_files(view, undo_msg, NULL); |
| 1417 |
1419 |
un_group_open(undo_msg); |
un_group_open(undo_msg); |
| File src/ops.c changed (mode: 100644) (index d8e263933..347717889) |
| ... |
... |
ops_describe(const ops_t *ops) |
| 218 |
218 |
} |
} |
| 219 |
219 |
|
|
| 220 |
220 |
void |
void |
| 221 |
|
ops_enqueue(ops_t *ops, const char src[], const char dst[]) |
|
|
221 |
|
ops_enqueue(ops_t *ops, const char src[], const char dst[], int deep) |
| 222 |
222 |
{ |
{ |
| 223 |
223 |
++ops->total; |
++ops->total; |
| 224 |
224 |
|
|
| |
| ... |
... |
ops_enqueue(ops_t *ops, const char src[], const char dst[]) |
| 264 |
264 |
} |
} |
| 265 |
265 |
} |
} |
| 266 |
266 |
|
|
| 267 |
|
ioeta_calculate(ops->estim, src, ops->shallow_eta, /*deep=*/0); |
|
|
267 |
|
ioeta_calculate(ops->estim, src, ops->shallow_eta, deep); |
| 268 |
268 |
} |
} |
| 269 |
269 |
|
|
| 270 |
270 |
void |
void |
| |
| ... |
... |
op_cp(ops_t *ops, void *data, const char src[], const char dst[], |
| 514 |
514 |
ConflictAction conflict_action) |
ConflictAction conflict_action) |
| 515 |
515 |
{ |
{ |
| 516 |
516 |
const int cancellable = ((data_flags(data) & DF_NO_CANCEL) == 0); |
const int cancellable = ((data_flags(data) & DF_NO_CANCEL) == 0); |
|
517 |
|
const int deep_copy = ((data_flags(data) & DF_DEEP_COPY) != 0); |
| 517 |
518 |
const int fast_file_cloning = (ops == NULL) |
const int fast_file_cloning = (ops == NULL) |
| 518 |
519 |
? cfg.fast_file_cloning |
? cfg.fast_file_cloning |
| 519 |
520 |
: ops->fast_file_cloning; |
: ops->fast_file_cloning; |
| |
| ... |
... |
op_cp(ops_t *ops, void *data, const char src[], const char dst[], |
| 535 |
536 |
} |
} |
| 536 |
537 |
|
|
| 537 |
538 |
snprintf(cmd, sizeof(cmd), |
snprintf(cmd, sizeof(cmd), |
| 538 |
|
"cp %s %s -R " PRESERVE_FLAGS " %s %s", |
|
|
539 |
|
"cp %s %s %s -R " PRESERVE_FLAGS " %s %s", |
| 539 |
540 |
(conflict_action == CA_FAIL) ? NO_CLOBBER : "", |
(conflict_action == CA_FAIL) ? NO_CLOBBER : "", |
| 540 |
541 |
fast_file_cloning ? REFLINK_AUTO : "", |
fast_file_cloning ? REFLINK_AUTO : "", |
|
542 |
|
deep_copy ? "-L" : "", |
| 541 |
543 |
escaped_src, escaped_dst); |
escaped_src, escaped_dst); |
| 542 |
544 |
LOG_INFO_MSG("Running cp command: \"%s\"", cmd); |
LOG_INFO_MSG("Running cp command: \"%s\"", cmd); |
| 543 |
545 |
OpsResult result = run_operation_command(ops, cmd, cancellable); |
OpsResult result = run_operation_command(ops, cmd, cancellable); |
| |
| ... |
... |
op_cp(ops_t *ops, void *data, const char src[], const char dst[], |
| 567 |
569 |
free(escaped_src); |
free(escaped_src); |
| 568 |
570 |
free(escaped_dst); |
free(escaped_dst); |
| 569 |
571 |
|
|
| 570 |
|
if(is_vista_and_above()) |
|
|
572 |
|
if(!deep_copy && is_vista_and_above()) |
|
573 |
|
{ |
| 571 |
574 |
strcat(cmd, "/B "); |
strcat(cmd, "/B "); |
|
575 |
|
} |
| 572 |
576 |
if(conflict_action != CA_FAIL) |
if(conflict_action != CA_FAIL) |
| 573 |
577 |
{ |
{ |
| 574 |
578 |
strcat(cmd, "/Y "); |
strcat(cmd, "/Y "); |
| |
| ... |
... |
op_cp(ops_t *ops, void *data, const char src[], const char dst[], |
| 596 |
600 |
.arg4 = { |
.arg4 = { |
| 597 |
601 |
.fast_file_cloning = fast_file_cloning, |
.fast_file_cloning = fast_file_cloning, |
| 598 |
602 |
.data_sync = data_sync, |
.data_sync = data_sync, |
|
603 |
|
.deep_copying = deep_copy, |
| 599 |
604 |
}, |
}, |
| 600 |
605 |
}; |
}; |
| 601 |
606 |
return exec_io_op(ops, &ior_cp, &args, cancellable); |
return exec_io_op(ops, &ior_cp, &args, cancellable); |
| File tests/fileops/cpmv_files.c changed (mode: 100644) (index 0199e4cd9..2cc9cba5d) |
| ... |
... |
TEST(broken_link_behaves_like_a_regular_file_on_conflict, IF(not_windows)) |
| 543 |
543 |
} |
} |
| 544 |
544 |
} |
} |
| 545 |
545 |
|
|
|
546 |
|
TEST(deep_copy_file_link, IF(not_windows), REPEAT(2)) |
|
547 |
|
{ |
|
548 |
|
cfg.use_system_calls = STIC_TEST_PARAM; |
|
549 |
|
|
|
550 |
|
char new_fname[] = "copy"; |
|
551 |
|
char *list[] = { &new_fname[0] }; |
|
552 |
|
|
|
553 |
|
const char *contents = "target contents"; |
|
554 |
|
|
|
555 |
|
make_file("target", contents); |
|
556 |
|
|
|
557 |
|
update_string(&lwin.dir_entry[0].name, "good-file-symlink"); |
|
558 |
|
assert_success(make_symlink("target", "good-file-symlink")); |
|
559 |
|
|
|
560 |
|
lwin.dir_entry[0].marked = 1; |
|
561 |
|
lwin.dir_entry[0].type = FT_LINK; |
|
562 |
|
(void)fops_cpmv(&lwin, list, ARRAY_LEN(list), CMLO_COPY, CMLF_DEEP); |
|
563 |
|
|
|
564 |
|
restore_cwd(saved_cwd); |
|
565 |
|
saved_cwd = save_cwd(); |
|
566 |
|
|
|
567 |
|
assert_true(is_symlink(SANDBOX_PATH "/good-file-symlink")); |
|
568 |
|
assert_false(is_symlink(SANDBOX_PATH "/copy")); |
|
569 |
|
|
|
570 |
|
const char *lines[] = { contents }; |
|
571 |
|
file_is(SANDBOX_PATH "/copy", lines, ARRAY_LEN(lines)); |
|
572 |
|
|
|
573 |
|
remove_file(SANDBOX_PATH "/good-file-symlink"); |
|
574 |
|
remove_file(SANDBOX_PATH "/copy"); |
|
575 |
|
remove_file(SANDBOX_PATH "/target"); |
|
576 |
|
} |
|
577 |
|
|
|
578 |
|
TEST(deep_copy_dir_link, IF(not_windows), REPEAT(2)) |
|
579 |
|
{ |
|
580 |
|
cfg.use_system_calls = STIC_TEST_PARAM; |
|
581 |
|
|
|
582 |
|
char new_fname[] = "copy"; |
|
583 |
|
char *list[] = { &new_fname[0] }; |
|
584 |
|
|
|
585 |
|
create_dir("target"); |
|
586 |
|
|
|
587 |
|
update_string(&lwin.dir_entry[0].name, "good-dir-symlink"); |
|
588 |
|
assert_success(make_symlink("target", "good-dir-symlink")); |
|
589 |
|
|
|
590 |
|
lwin.dir_entry[0].marked = 1; |
|
591 |
|
lwin.dir_entry[0].type = FT_LINK; |
|
592 |
|
(void)fops_cpmv(&lwin, list, ARRAY_LEN(list), CMLO_COPY, CMLF_DEEP); |
|
593 |
|
|
|
594 |
|
restore_cwd(saved_cwd); |
|
595 |
|
saved_cwd = save_cwd(); |
|
596 |
|
|
|
597 |
|
assert_true(is_symlink(SANDBOX_PATH "/good-dir-symlink")); |
|
598 |
|
assert_false(is_symlink(SANDBOX_PATH "/copy")); |
|
599 |
|
|
|
600 |
|
remove_file(SANDBOX_PATH "/good-dir-symlink"); |
|
601 |
|
remove_dir(SANDBOX_PATH "/copy"); |
|
602 |
|
remove_dir(SANDBOX_PATH "/target"); |
|
603 |
|
} |
|
604 |
|
|
|
605 |
|
TEST(deep_copy_link_in_dir, IF(not_windows), REPEAT(2)) |
|
606 |
|
{ |
|
607 |
|
cfg.use_system_calls = STIC_TEST_PARAM; |
|
608 |
|
|
|
609 |
|
char new_fname[] = "copy"; |
|
610 |
|
char *list[] = { &new_fname[0] }; |
|
611 |
|
|
|
612 |
|
create_dir("target"); |
|
613 |
|
create_dir("dir"); |
|
614 |
|
|
|
615 |
|
update_string(&lwin.dir_entry[0].name, "dir"); |
|
616 |
|
assert_success(make_symlink("../target", "dir/dir-symlink")); |
|
617 |
|
|
|
618 |
|
lwin.dir_entry[0].marked = 1; |
|
619 |
|
lwin.dir_entry[0].type = FT_DIR; |
|
620 |
|
(void)fops_cpmv(&lwin, list, ARRAY_LEN(list), CMLO_COPY, CMLF_DEEP); |
|
621 |
|
|
|
622 |
|
restore_cwd(saved_cwd); |
|
623 |
|
saved_cwd = save_cwd(); |
|
624 |
|
|
|
625 |
|
assert_true(is_symlink(SANDBOX_PATH "/dir/dir-symlink")); |
|
626 |
|
assert_false(is_symlink(SANDBOX_PATH "/copy/dir-symlink")); |
|
627 |
|
|
|
628 |
|
remove_file(SANDBOX_PATH "/dir/dir-symlink"); |
|
629 |
|
remove_dir(SANDBOX_PATH "/dir"); |
|
630 |
|
|
|
631 |
|
remove_dir(SANDBOX_PATH "/copy/dir-symlink"); |
|
632 |
|
remove_dir(SANDBOX_PATH "/copy"); |
|
633 |
|
|
|
634 |
|
remove_dir(SANDBOX_PATH "/target"); |
|
635 |
|
} |
|
636 |
|
|
|
637 |
|
TEST(deep_copy_bad_link, IF(not_windows), REPEAT(2)) |
|
638 |
|
{ |
|
639 |
|
cfg.use_system_calls = STIC_TEST_PARAM; |
|
640 |
|
|
|
641 |
|
char new_fname[] = "copy"; |
|
642 |
|
char *list[] = { &new_fname[0] }; |
|
643 |
|
|
|
644 |
|
update_string(&lwin.dir_entry[0].name, "bad-symlink"); |
|
645 |
|
assert_success(make_symlink("notarget", "bad-symlink")); |
|
646 |
|
|
|
647 |
|
lwin.dir_entry[0].marked = 1; |
|
648 |
|
lwin.dir_entry[0].type = FT_LINK; |
|
649 |
|
(void)fops_cpmv(&lwin, list, ARRAY_LEN(list), CMLO_COPY, CMLF_DEEP); |
|
650 |
|
|
|
651 |
|
restore_cwd(saved_cwd); |
|
652 |
|
saved_cwd = save_cwd(); |
|
653 |
|
|
|
654 |
|
assert_true(is_symlink(SANDBOX_PATH "/bad-symlink")); |
|
655 |
|
remove_file(SANDBOX_PATH "/bad-symlink"); |
|
656 |
|
|
|
657 |
|
/* There is no actual file to copy but the symlink itself. */ |
|
658 |
|
if(cfg.use_system_calls) |
|
659 |
|
{ |
|
660 |
|
assert_true(is_symlink(SANDBOX_PATH "/copy")); |
|
661 |
|
remove_file(SANDBOX_PATH "/copy"); |
|
662 |
|
} |
|
663 |
|
} |
|
664 |
|
|
|
665 |
|
TEST(deep_copy_file_link_loop, IF(not_windows), REPEAT(2)) |
|
666 |
|
{ |
|
667 |
|
cfg.use_system_calls = STIC_TEST_PARAM; |
|
668 |
|
|
|
669 |
|
char new_fname[] = "copy"; |
|
670 |
|
char *list[] = { &new_fname[0] }; |
|
671 |
|
|
|
672 |
|
update_string(&lwin.dir_entry[0].name, "link"); |
|
673 |
|
assert_success(make_symlink("link", "link")); |
|
674 |
|
|
|
675 |
|
lwin.dir_entry[0].marked = 1; |
|
676 |
|
lwin.dir_entry[0].type = FT_LINK; |
|
677 |
|
(void)fops_cpmv(&lwin, list, ARRAY_LEN(list), CMLO_COPY, CMLF_DEEP); |
|
678 |
|
|
|
679 |
|
restore_cwd(saved_cwd); |
|
680 |
|
saved_cwd = save_cwd(); |
|
681 |
|
|
|
682 |
|
assert_true(is_symlink(SANDBOX_PATH "/link")); |
|
683 |
|
remove_file(SANDBOX_PATH "/link"); |
|
684 |
|
|
|
685 |
|
/* There is no actual file to copy but the symlink itself. */ |
|
686 |
|
if(cfg.use_system_calls) |
|
687 |
|
{ |
|
688 |
|
assert_true(is_symlink(SANDBOX_PATH "/copy")); |
|
689 |
|
remove_file(SANDBOX_PATH "/copy"); |
|
690 |
|
} |
|
691 |
|
} |
|
692 |
|
|
|
693 |
|
TEST(deep_copy_dir_link_loop, IF(not_windows), REPEAT(2)) |
|
694 |
|
{ |
|
695 |
|
cfg.use_system_calls = STIC_TEST_PARAM; |
|
696 |
|
|
|
697 |
|
char new_fname[] = "copy"; |
|
698 |
|
char *list[] = { &new_fname[0] }; |
|
699 |
|
|
|
700 |
|
create_dir("dir"); |
|
701 |
|
|
|
702 |
|
update_string(&lwin.dir_entry[0].name, "dir"); |
|
703 |
|
assert_success(make_symlink("../dir", "dir/parent-symlink")); |
|
704 |
|
|
|
705 |
|
lwin.dir_entry[0].marked = 1; |
|
706 |
|
lwin.dir_entry[0].type = FT_DIR; |
|
707 |
|
(void)fops_cpmv(&lwin, list, ARRAY_LEN(list), CMLO_COPY, CMLF_DEEP); |
|
708 |
|
|
|
709 |
|
restore_cwd(saved_cwd); |
|
710 |
|
saved_cwd = save_cwd(); |
|
711 |
|
|
|
712 |
|
assert_true(is_symlink(SANDBOX_PATH "/dir/parent-symlink")); |
|
713 |
|
|
|
714 |
|
remove_file(SANDBOX_PATH "/dir/parent-symlink"); |
|
715 |
|
remove_dir(SANDBOX_PATH "/dir"); |
|
716 |
|
|
|
717 |
|
/* There is no actual file to copy but the symlink itself. */ |
|
718 |
|
if(cfg.use_system_calls) |
|
719 |
|
{ |
|
720 |
|
assert_true(is_symlink(SANDBOX_PATH "/copy/parent-symlink")); |
|
721 |
|
remove_file(SANDBOX_PATH "/copy/parent-symlink"); |
|
722 |
|
} |
|
723 |
|
remove_dir(SANDBOX_PATH "/copy"); |
|
724 |
|
} |
|
725 |
|
|
| 546 |
726 |
static void |
static void |
| 547 |
727 |
check_directory_clash(int parent_to_child, CopyMoveLikeOp op) |
check_directory_clash(int parent_to_child, CopyMoveLikeOp op) |
| 548 |
728 |
{ |
{ |