|
Lines 107-112
Link Here
|
| 107 |
#include "misc.h" |
107 |
#include "misc.h" |
| 108 |
#include "progressmeter.h" |
108 |
#include "progressmeter.h" |
| 109 |
|
109 |
|
|
|
110 |
#ifdef HAVE_COPYFILE_H |
| 111 |
#include <libgen.h> |
| 112 |
#include <copyfile.h> |
| 113 |
#endif |
| 114 |
|
| 110 |
extern char *__progname; |
115 |
extern char *__progname; |
| 111 |
|
116 |
|
| 112 |
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); |
117 |
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); |
|
Lines 134-139
Link Here
|
| 134 |
/* This is used to store the pid of ssh_program */ |
139 |
/* This is used to store the pid of ssh_program */ |
| 135 |
pid_t do_cmd_pid = -1; |
140 |
pid_t do_cmd_pid = -1; |
| 136 |
|
141 |
|
|
|
142 |
#ifdef HAVE_COPYFILE |
| 143 |
int copy_xattr = 0; |
| 144 |
int md_flag = 0; |
| 145 |
#endif |
| 146 |
|
| 147 |
|
| 137 |
static void |
148 |
static void |
| 138 |
killchild(int signo) |
149 |
killchild(int signo) |
| 139 |
{ |
150 |
{ |
|
Lines 313-319
Link Here
|
| 313 |
addargs(&args, "-oClearAllForwardings yes"); |
324 |
addargs(&args, "-oClearAllForwardings yes"); |
| 314 |
|
325 |
|
| 315 |
fflag = tflag = 0; |
326 |
fflag = tflag = 0; |
|
|
327 |
#if HAVE_COPYFILE |
| 328 |
while ((ch = getopt(argc, argv, "dfl:prtvBCEc:i:P:q1246S:o:F:")) != -1) |
| 329 |
#else |
| 316 |
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) |
330 |
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) |
|
|
331 |
#endif |
| 317 |
switch (ch) { |
332 |
switch (ch) { |
| 318 |
/* User-visible flags. */ |
333 |
/* User-visible flags. */ |
| 319 |
case '1': |
334 |
case '1': |
|
Lines 359-364
Link Here
|
| 359 |
showprogress = 0; |
374 |
showprogress = 0; |
| 360 |
break; |
375 |
break; |
| 361 |
|
376 |
|
|
|
377 |
#ifdef HAVE_COPYFILE |
| 378 |
case 'E': |
| 379 |
copy_xattr = 1; |
| 380 |
break; |
| 381 |
#endif |
| 362 |
/* Server options. */ |
382 |
/* Server options. */ |
| 363 |
case 'd': |
383 |
case 'd': |
| 364 |
targetshouldbedirectory = 1; |
384 |
targetshouldbedirectory = 1; |
|
Lines 408-414
Link Here
|
| 408 |
remin = remout = -1; |
428 |
remin = remout = -1; |
| 409 |
do_cmd_pid = -1; |
429 |
do_cmd_pid = -1; |
| 410 |
/* Command to be executed on remote system using "ssh". */ |
430 |
/* Command to be executed on remote system using "ssh". */ |
|
|
431 |
#if HAVE_COPYFILE |
| 432 |
(void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s%s", |
| 433 |
copy_xattr ? " -E" : "", |
| 434 |
#else |
| 411 |
(void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", |
435 |
(void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", |
|
|
436 |
#endif |
| 412 |
verbose_mode ? " -v" : "", |
437 |
verbose_mode ? " -v" : "", |
| 413 |
iamrecursive ? " -r" : "", pflag ? " -p" : "", |
438 |
iamrecursive ? " -r" : "", pflag ? " -p" : "", |
| 414 |
targetshouldbedirectory ? " -d" : ""); |
439 |
targetshouldbedirectory ? " -d" : ""); |
|
Lines 587-592
Link Here
|
| 587 |
int fd = -1, haderr, indx; |
612 |
int fd = -1, haderr, indx; |
| 588 |
char *last, *name, buf[2048], encname[MAXPATHLEN]; |
613 |
char *last, *name, buf[2048], encname[MAXPATHLEN]; |
| 589 |
int len; |
614 |
int len; |
|
|
615 |
#if HAVE_COPYFILE |
| 616 |
char md_name[MAXPATHLEN]; |
| 617 |
char *md_tmp; |
| 618 |
#endif |
| 590 |
|
619 |
|
| 591 |
for (indx = 0; indx < argc; ++indx) { |
620 |
for (indx = 0; indx < argc; ++indx) { |
| 592 |
name = argv[indx]; |
621 |
name = argv[indx]; |
|
Lines 594-605
Link Here
|
| 594 |
len = strlen(name); |
623 |
len = strlen(name); |
| 595 |
while (len > 1 && name[len-1] == '/') |
624 |
while (len > 1 && name[len-1] == '/') |
| 596 |
name[--len] = '\0'; |
625 |
name[--len] = '\0'; |
|
|
626 |
#if HAVE_COPYFILE |
| 627 |
md_next: |
| 628 |
statbytes = 0; |
| 629 |
if (md_flag) { |
| 630 |
fd = open(md_tmp, O_RDONLY, 0); |
| 631 |
unlink(md_tmp); |
| 632 |
free(md_tmp); |
| 633 |
if (fd < 0) |
| 634 |
goto syserr; |
| 635 |
} else { |
| 636 |
#endif |
| 597 |
if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0) |
637 |
if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0) |
| 598 |
goto syserr; |
638 |
goto syserr; |
| 599 |
if (strchr(name, '\n') != NULL) { |
639 |
if (strchr(name, '\n') != NULL) { |
| 600 |
strnvis(encname, name, sizeof(encname), VIS_NL); |
640 |
strnvis(encname, name, sizeof(encname), VIS_NL); |
| 601 |
name = encname; |
641 |
name = encname; |
| 602 |
} |
642 |
} |
|
|
643 |
#if HAVE_COPYFILE |
| 644 |
} |
| 645 |
#endif |
| 603 |
if (fstat(fd, &stb) < 0) { |
646 |
if (fstat(fd, &stb) < 0) { |
| 604 |
syserr: run_err("%s: %s", name, strerror(errno)); |
647 |
syserr: run_err("%s: %s", name, strerror(errno)); |
| 605 |
goto next; |
648 |
goto next; |
|
Lines 688-693
Link Here
|
| 688 |
else |
731 |
else |
| 689 |
run_err("%s: %s", name, strerror(haderr)); |
732 |
run_err("%s: %s", name, strerror(haderr)); |
| 690 |
(void) response(); |
733 |
(void) response(); |
|
|
734 |
#ifdef HAVE_COPYFILE |
| 735 |
if (copy_xattr && md_flag == 0) |
| 736 |
{ |
| 737 |
if (!copyfile(name, NULL, 0, |
| 738 |
COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_CHECK)) |
| 739 |
continue; |
| 740 |
|
| 741 |
/* |
| 742 |
* this file will hold the actual metadata |
| 743 |
* to be transferred |
| 744 |
*/ |
| 745 |
md_tmp = strdup("/tmp/scp.md.XXXXXX"); |
| 746 |
md_tmp = mktemp(md_tmp); |
| 747 |
|
| 748 |
if(copyfile(name, md_tmp, 0, |
| 749 |
COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_PACK) == 0) |
| 750 |
{ |
| 751 |
/* |
| 752 |
* this is the fake name to display |
| 753 |
*/ |
| 754 |
snprintf(md_name, sizeof md_name, "%s/._%s", dirname(name), basename(name)); |
| 755 |
name = md_name; |
| 756 |
md_flag = 1; |
| 757 |
if (verbose_mode) |
| 758 |
fprintf(stderr, "copyfile(%s, %s, PACK)\n", name, md_tmp); |
| 759 |
goto md_next; |
| 760 |
} |
| 761 |
} else |
| 762 |
md_flag = 0; |
| 763 |
#endif |
| 691 |
} |
764 |
} |
| 692 |
} |
765 |
} |
| 693 |
|
766 |
|
|
Lines 836-841
Link Here
|
| 836 |
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) |
909 |
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) |
| 837 |
targisdir = 1; |
910 |
targisdir = 1; |
| 838 |
for (first = 1;; first = 0) { |
911 |
for (first = 1;; first = 0) { |
|
|
912 |
#if HAVE_COPYFILE |
| 913 |
char md_src[MAXPATHLEN]; |
| 914 |
char md_dst[MAXPATHLEN]; |
| 915 |
#endif |
| 839 |
cp = buf; |
916 |
cp = buf; |
| 840 |
if (atomicio(read, remin, cp, 1) != 1) |
917 |
if (atomicio(read, remin, cp, 1) != 1) |
| 841 |
return; |
918 |
return; |
|
Lines 969-974
Link Here
|
| 969 |
} |
1046 |
} |
| 970 |
omode = mode; |
1047 |
omode = mode; |
| 971 |
mode |= S_IWRITE; |
1048 |
mode |= S_IWRITE; |
|
|
1049 |
|
| 1050 |
#if HAVE_COPYFILE |
| 1051 |
if (copy_xattr && !strncmp(basename(curfile), "._", 2)) |
| 1052 |
{ |
| 1053 |
int mdfd; |
| 1054 |
if (targisdir) |
| 1055 |
{ |
| 1056 |
snprintf(md_src, sizeof md_src, "%s.XXXXXX", np); |
| 1057 |
snprintf(md_dst, sizeof md_dst, "%s/%s", |
| 1058 |
dirname(np), basename(np) + 2); |
| 1059 |
if((mdfd = mkstemp(md_src)) < 0) |
| 1060 |
continue; |
| 1061 |
} |
| 1062 |
else |
| 1063 |
{ |
| 1064 |
snprintf(md_src, sizeof md_src, "%s/._%s.XXXXXX", |
| 1065 |
dirname(np), basename(np)); |
| 1066 |
snprintf(md_dst, sizeof md_dst, "%s", np); |
| 1067 |
if((mdfd = mkstemp(md_src)) < 0) |
| 1068 |
continue; |
| 1069 |
} |
| 1070 |
if (mdfd >= 0) |
| 1071 |
close(mdfd); |
| 1072 |
np = md_src; |
| 1073 |
} |
| 1074 |
#endif |
| 972 |
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { |
1075 |
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { |
| 973 |
bad: run_err("%s: %s", np, strerror(errno)); |
1076 |
bad: run_err("%s: %s", np, strerror(errno)); |
| 974 |
continue; |
1077 |
continue; |
|
Lines 1057-1062
Link Here
|
| 1057 |
wrerrno = errno; |
1160 |
wrerrno = errno; |
| 1058 |
} |
1161 |
} |
| 1059 |
(void) response(); |
1162 |
(void) response(); |
|
|
1163 |
#ifdef HAVE_COPYFILE |
| 1164 |
if (copy_xattr && strncmp(basename(np), "._", 2) == 0) |
| 1165 |
{ |
| 1166 |
if (verbose_mode) |
| 1167 |
fprintf(stderr, "copyfile(%s, %s, UNPACK)\n", md_src, md_dst); |
| 1168 |
if(!copyfile(md_src, md_dst, 0, |
| 1169 |
COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_UNPACK) < 0) |
| 1170 |
{ |
| 1171 |
snprintf(md_dst, sizeof md_dst, "%s/._%s", |
| 1172 |
dirname(md_dst), basename(md_dst)); |
| 1173 |
rename(md_src, md_dst); |
| 1174 |
} else |
| 1175 |
unlink(md_src); |
| 1176 |
} else |
| 1177 |
#endif |
| 1060 |
if (setimes && wrerr == NO) { |
1178 |
if (setimes && wrerr == NO) { |
| 1061 |
setimes = 0; |
1179 |
setimes = 0; |
| 1062 |
if (utimes(np, tv) < 0) { |
1180 |
if (utimes(np, tv) < 0) { |
|
Lines 1118-1124
Link Here
|
| 1118 |
usage(void) |
1236 |
usage(void) |
| 1119 |
{ |
1237 |
{ |
| 1120 |
(void) fprintf(stderr, |
1238 |
(void) fprintf(stderr, |
|
|
1239 |
#if HAVE_COPYFILE |
| 1240 |
"usage: scp [-1246BCEpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" |
| 1241 |
#else |
| 1121 |
"usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" |
1242 |
"usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" |
|
|
1243 |
#endif |
| 1122 |
" [-l limit] [-o ssh_option] [-P port] [-S program]\n" |
1244 |
" [-l limit] [-o ssh_option] [-P port] [-S program]\n" |
| 1123 |
" [[user@]host1:]file1 ... [[user@]host2:]file2\n"); |
1245 |
" [[user@]host1:]file1 ... [[user@]host2:]file2\n"); |
| 1124 |
exit(1); |
1246 |
exit(1); |