Bugzilla – Attachment 1403 Details for
Bug 1409
Mac OS X support for Extended Attributes with scp
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Add the -E option to scp.
DVG-4122722+5277818_new_EA.patch (text/plain), 15.57 KB, created by
Disco Vince Giffin
on 2007-12-21 15:09:25 AEDT
(
hide
)
Description:
Add the -E option to scp.
Filename:
MIME Type:
Creator:
Disco Vince Giffin
Created:
2007-12-21 15:09:25 AEDT
Size:
15.57 KB
patch
obsolete
>diff -ruN ../openssh-4.7p1/config.h.in ./config.h.in >--- ../openssh-4.7p1/config.h.in 2007-09-03 23:50:04.000000000 -0700 >+++ ./config.h.in 2007-10-01 20:02:51.000000000 -0700 >@@ -56,6 +56,18 @@ > /* Define if your snprintf is busted */ > #undef BROKEN_SNPRINTF > >+/* platform uses an in-memory credentials cache */ >+#undef USE_CCAPI >+ >+/* platform has a Security Authorization Session API */ >+#undef USE_SECURITY_SESSION_API >+ >+/* Define to 1 if you have the `copyfile' function. */ >+#undef HAVE_COPYFILE >+ >+/* Define to 1 if you have the <copyfile.h> header file. */ >+#undef HAVE_COPYFILE_H >+ > /* updwtmpx is broken (if present) */ > #undef BROKEN_UPDWTMPX > >diff -ruN ../openssh-4.7p1/configure ./configure >--- ../openssh-4.7p1/configure 2007-09-03 23:50:09.000000000 -0700 >+++ ./configure 2007-10-01 20:02:51.000000000 -0700 >@@ -28390,6 +28390,259 @@ > CFLAGS="$CFLAGS $werror_flags" > > >+for ac_func in copyfile >+do >+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` >+echo "$as_me:$LINENO: checking for $ac_func" >&5 >+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 >+if eval "test \"\${$as_ac_var+set}\" = set"; then >+ echo $ECHO_N "(cached) $ECHO_C" >&6 >+else >+ cat >conftest.$ac_ext <<_ACEOF >+/* confdefs.h. */ >+_ACEOF >+cat confdefs.h >>conftest.$ac_ext >+cat >>conftest.$ac_ext <<_ACEOF >+/* end confdefs.h. */ >+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. >+ For example, HP-UX 11i <limits.h> declares gettimeofday. */ >+#define $ac_func innocuous_$ac_func >+ >+/* System header to define __stub macros and hopefully few prototypes, >+ which can conflict with char $ac_func (); below. >+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since >+ <limits.h> exists even on freestanding compilers. */ >+ >+#ifdef __STDC__ >+# include <limits.h> >+#else >+# include <assert.h> >+#endif >+ >+#undef $ac_func >+ >+/* Override any gcc2 internal prototype to avoid an error. */ >+#ifdef __cplusplus >+extern "C" >+{ >+#endif >+/* We use char because int might match the return type of a gcc2 >+ builtin and then its argument prototype would still apply. */ >+char $ac_func (); >+/* The GNU C library defines this for functions which it implements >+ to always fail with ENOSYS. Some functions are actually named >+ something starting with __ and the normal name is an alias. */ >+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) >+choke me >+#else >+char (*f) () = $ac_func; >+#endif >+#ifdef __cplusplus >+} >+#endif >+ >+int >+main () >+{ >+return f != $ac_func; >+ ; >+ return 0; >+} >+_ACEOF >+rm -f conftest.$ac_objext conftest$ac_exeext >+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 >+ (eval $ac_link) 2>conftest.er1 >+ ac_status=$? >+ grep -v '^ *+' conftest.er1 >conftest.err >+ rm -f conftest.er1 >+ cat conftest.err >&5 >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); } && >+ { ac_try='test -z "$ac_c_werror_flag" >+ || test ! -s conftest.err' >+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 >+ (eval $ac_try) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); }; } && >+ { ac_try='test -s conftest$ac_exeext' >+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 >+ (eval $ac_try) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); }; }; then >+ eval "$as_ac_var=yes" >+else >+ echo "$as_me: failed program was:" >&5 >+sed 's/^/| /' conftest.$ac_ext >&5 >+ >+eval "$as_ac_var=no" >+fi >+rm -f conftest.err conftest.$ac_objext \ >+ conftest$ac_exeext conftest.$ac_ext >+fi >+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 >+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 >+if test `eval echo '${'$as_ac_var'}'` = yes; then >+ cat >>confdefs.h <<_ACEOF >+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 >+_ACEOF >+ >+fi >+done >+ >+ >+for ac_header in copyfile.h >+do >+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` >+if eval "test \"\${$as_ac_Header+set}\" = set"; then >+ echo "$as_me:$LINENO: checking for $ac_header" >&5 >+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 >+if eval "test \"\${$as_ac_Header+set}\" = set"; then >+ echo $ECHO_N "(cached) $ECHO_C" >&6 >+fi >+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 >+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 >+else >+ # Is the header compilable? >+echo "$as_me:$LINENO: checking $ac_header usability" >&5 >+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 >+cat >conftest.$ac_ext <<_ACEOF >+/* confdefs.h. */ >+_ACEOF >+cat confdefs.h >>conftest.$ac_ext >+cat >>conftest.$ac_ext <<_ACEOF >+/* end confdefs.h. */ >+$ac_includes_default >+#include <$ac_header> >+_ACEOF >+rm -f conftest.$ac_objext >+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 >+ (eval $ac_compile) 2>conftest.er1 >+ ac_status=$? >+ grep -v '^ *+' conftest.er1 >conftest.err >+ rm -f conftest.er1 >+ cat conftest.err >&5 >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); } && >+ { ac_try='test -z "$ac_c_werror_flag" >+ || test ! -s conftest.err' >+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 >+ (eval $ac_try) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); }; } && >+ { ac_try='test -s conftest.$ac_objext' >+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 >+ (eval $ac_try) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); }; }; then >+ ac_header_compiler=yes >+else >+ echo "$as_me: failed program was:" >&5 >+sed 's/^/| /' conftest.$ac_ext >&5 >+ >+ac_header_compiler=no >+fi >+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext >+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 >+echo "${ECHO_T}$ac_header_compiler" >&6 >+ >+# Is the header present? >+echo "$as_me:$LINENO: checking $ac_header presence" >&5 >+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 >+cat >conftest.$ac_ext <<_ACEOF >+/* confdefs.h. */ >+_ACEOF >+cat confdefs.h >>conftest.$ac_ext >+cat >>conftest.$ac_ext <<_ACEOF >+/* end confdefs.h. */ >+#include <$ac_header> >+_ACEOF >+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 >+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 >+ ac_status=$? >+ grep -v '^ *+' conftest.er1 >conftest.err >+ rm -f conftest.er1 >+ cat conftest.err >&5 >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); } >/dev/null; then >+ if test -s conftest.err; then >+ ac_cpp_err=$ac_c_preproc_warn_flag >+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag >+ else >+ ac_cpp_err= >+ fi >+else >+ ac_cpp_err=yes >+fi >+if test -z "$ac_cpp_err"; then >+ ac_header_preproc=yes >+else >+ echo "$as_me: failed program was:" >&5 >+sed 's/^/| /' conftest.$ac_ext >&5 >+ >+ ac_header_preproc=no >+fi >+rm -f conftest.err conftest.$ac_ext >+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 >+echo "${ECHO_T}$ac_header_preproc" >&6 >+ >+# So? What about this header? >+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in >+ yes:no: ) >+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 >+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} >+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 >+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} >+ ac_header_preproc=yes >+ ;; >+ no:yes:* ) >+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 >+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} >+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 >+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} >+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 >+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} >+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 >+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} >+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 >+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} >+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 >+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} >+ ( >+ cat <<\_ASBOX >+## ------------------------------------------- ## >+## Report this to openssh-unix-dev@mindrot.org ## >+## ------------------------------------------- ## >+_ASBOX >+ ) | >+ sed "s/^/$as_me: WARNING: /" >&2 >+ ;; >+esac >+echo "$as_me:$LINENO: checking for $ac_header" >&5 >+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 >+if eval "test \"\${$as_ac_Header+set}\" = set"; then >+ echo $ECHO_N "(cached) $ECHO_C" >&6 >+else >+ eval "$as_ac_Header=\$ac_header_preproc" >+fi >+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 >+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 >+ >+fi >+if test `eval echo '${'$as_ac_Header'}'` = yes; then >+ cat >>confdefs.h <<_ACEOF >+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 >+_ACEOF >+ >+fi >+ >+done >+ >+ >+ > ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile scard/Makefile ssh_prng_cmds survey.sh" > > cat >confcache <<\_ACEOF >diff -ruN ../openssh-4.7p1/configure.ac ./configure.ac >--- ../openssh-4.7p1/configure.ac 2007-08-09 21:36:12.000000000 -0700 >+++ ./configure.ac 2007-10-01 20:02:51.000000000 -0700 >@@ -3982,6 +3982,9 @@ > dnl Add now. > CFLAGS="$CFLAGS $werror_flags" > >+AC_CHECK_FUNCS(copyfile) >+AC_CHECK_HEADERS(copyfile.h) >+ > AC_EXEEXT > AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ > openbsd-compat/Makefile openbsd-compat/regress/Makefile \ >diff -ruN ../openssh-4.7p1/scp.1 ./scp.1 >--- ../openssh-4.7p1/scp.1 2007-08-07 21:29:58.000000000 -0700 >+++ ./scp.1 2007-10-01 20:02:51.000000000 -0700 >@@ -20,7 +20,7 @@ > .Sh SYNOPSIS > .Nm scp > .Bk -words >-.Op Fl 1246BCpqrv >+.Op Fl 1246BCEpqrv > .Op Fl c Ar cipher > .Op Fl F Ar ssh_config > .Op Fl i Ar identity_file >@@ -87,6 +87,8 @@ > flag to > .Xr ssh 1 > to enable compression. >+.It Fl E >+Preserves extended attributes, resource forks, and ACLs. Requires both ends to be running Mac OS X 10.4 or later. > .It Fl c Ar cipher > Selects the cipher to use for encrypting the data transfer. > This option is directly passed to >diff -ruN ../openssh-4.7p1/scp.c ./scp.c >--- ../openssh-4.7p1/scp.c 2007-08-07 21:29:58.000000000 -0700 >+++ ./scp.c 2007-10-01 20:29:54.000000000 -0700 >@@ -107,6 +107,11 @@ > #include "misc.h" > #include "progressmeter.h" > >+#ifdef HAVE_COPYFILE_H >+#include <libgen.h> >+#include <copyfile.h> >+#endif >+ > extern char *__progname; > > int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); >@@ -134,6 +139,12 @@ > /* This is used to store the pid of ssh_program */ > pid_t do_cmd_pid = -1; > >+#ifdef HAVE_COPYFILE >+int copy_xattr = 0; >+int md_flag = 0; >+#endif >+ >+ > static void > killchild(int signo) > { >@@ -313,7 +324,11 @@ > addargs(&args, "-oClearAllForwardings yes"); > > fflag = tflag = 0; >+#if HAVE_COPYFILE >+ while ((ch = getopt(argc, argv, "dfl:prtvBCEc:i:P:q1246S:o:F:")) != -1) >+#else > while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) >+#endif > switch (ch) { > /* User-visible flags. */ > case '1': >@@ -359,6 +374,11 @@ > showprogress = 0; > break; > >+#ifdef HAVE_COPYFILE >+ case 'E': >+ copy_xattr = 1; >+ break; >+#endif > /* Server options. */ > case 'd': > targetshouldbedirectory = 1; >@@ -408,7 +428,12 @@ > remin = remout = -1; > do_cmd_pid = -1; > /* Command to be executed on remote system using "ssh". */ >+#if HAVE_COPYFILE >+ (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s%s", >+ copy_xattr ? " -E" : "", >+#else > (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", >+#endif > verbose_mode ? " -v" : "", > iamrecursive ? " -r" : "", pflag ? " -p" : "", > targetshouldbedirectory ? " -d" : ""); >@@ -587,6 +612,10 @@ > int fd = -1, haderr, indx; > char *last, *name, buf[2048], encname[MAXPATHLEN]; > int len; >+#if HAVE_COPYFILE >+ char md_name[MAXPATHLEN]; >+ char *md_tmp; >+#endif > > for (indx = 0; indx < argc; ++indx) { > name = argv[indx]; >@@ -594,12 +623,26 @@ > len = strlen(name); > while (len > 1 && name[len-1] == '/') > name[--len] = '\0'; >+#if HAVE_COPYFILE >+md_next: >+ statbytes = 0; >+ if (md_flag) { >+ fd = open(md_tmp, O_RDONLY, 0); >+ unlink(md_tmp); >+ free(md_tmp); >+ if (fd < 0) >+ goto syserr; >+ } else { >+#endif > if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0) > goto syserr; > if (strchr(name, '\n') != NULL) { > strnvis(encname, name, sizeof(encname), VIS_NL); > name = encname; > } >+#if HAVE_COPYFILE >+ } >+#endif > if (fstat(fd, &stb) < 0) { > syserr: run_err("%s: %s", name, strerror(errno)); > goto next; >@@ -688,6 +731,36 @@ > else > run_err("%s: %s", name, strerror(haderr)); > (void) response(); >+#ifdef HAVE_COPYFILE >+ if (copy_xattr && md_flag == 0) >+ { >+ if (!copyfile(name, NULL, 0, >+ COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_CHECK)) >+ continue; >+ >+ /* >+ * this file will hold the actual metadata >+ * to be transferred >+ */ >+ md_tmp = strdup("/tmp/scp.md.XXXXXX"); >+ md_tmp = mktemp(md_tmp); >+ >+ if(copyfile(name, md_tmp, 0, >+ COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_PACK) == 0) >+ { >+ /* >+ * this is the fake name to display >+ */ >+ snprintf(md_name, sizeof md_name, "%s/._%s", dirname(name), basename(name)); >+ name = md_name; >+ md_flag = 1; >+ if (verbose_mode) >+ fprintf(stderr, "copyfile(%s, %s, PACK)\n", name, md_tmp); >+ goto md_next; >+ } >+ } else >+ md_flag = 0; >+#endif > } > } > >@@ -836,6 +909,10 @@ > if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) > targisdir = 1; > for (first = 1;; first = 0) { >+#if HAVE_COPYFILE >+ char md_src[MAXPATHLEN]; >+ char md_dst[MAXPATHLEN]; >+#endif > cp = buf; > if (atomicio(read, remin, cp, 1) != 1) > return; >@@ -969,6 +1046,32 @@ > } > omode = mode; > mode |= S_IWRITE; >+ >+#if HAVE_COPYFILE >+ if (copy_xattr && !strncmp(basename(curfile), "._", 2)) >+ { >+ int mdfd; >+ if (targisdir) >+ { >+ snprintf(md_src, sizeof md_src, "%s.XXXXXX", np); >+ snprintf(md_dst, sizeof md_dst, "%s/%s", >+ dirname(np), basename(np) + 2); >+ if((mdfd = mkstemp(md_src)) < 0) >+ continue; >+ } >+ else >+ { >+ snprintf(md_src, sizeof md_src, "%s/._%s.XXXXXX", >+ dirname(np), basename(np)); >+ snprintf(md_dst, sizeof md_dst, "%s", np); >+ if((mdfd = mkstemp(md_src)) < 0) >+ continue; >+ } >+ if (mdfd >= 0) >+ close(mdfd); >+ np = md_src; >+ } >+#endif > if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { > bad: run_err("%s: %s", np, strerror(errno)); > continue; >@@ -1057,6 +1160,21 @@ > wrerrno = errno; > } > (void) response(); >+#ifdef HAVE_COPYFILE >+ if (copy_xattr && strncmp(basename(np), "._", 2) == 0) >+ { >+ if (verbose_mode) >+ fprintf(stderr, "copyfile(%s, %s, UNPACK)\n", md_src, md_dst); >+ if(!copyfile(md_src, md_dst, 0, >+ COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_UNPACK) < 0) >+ { >+ snprintf(md_dst, sizeof md_dst, "%s/._%s", >+ dirname(md_dst), basename(md_dst)); >+ rename(md_src, md_dst); >+ } else >+ unlink(md_src); >+ } else >+#endif > if (setimes && wrerr == NO) { > setimes = 0; > if (utimes(np, tv) < 0) { >@@ -1118,7 +1236,11 @@ > usage(void) > { > (void) fprintf(stderr, >+#if HAVE_COPYFILE >+ "usage: scp [-1246BCEpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" >+#else > "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" >+#endif > " [-l limit] [-o ssh_option] [-P port] [-S program]\n" > " [[user@]host1:]file1 ... [[user@]host2:]file2\n"); > exit(1);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1409
: 1403 |
1404