EA.patch   [plain text]


diff -Naurdp ../openssh.sacl/configure ./configure
--- ../openssh.sacl/configure	2005-09-28 16:11:11.000000000 -0700
+++ ./configure	2005-09-28 16:39:28.000000000 -0700
@@ -25580,6 +25580,259 @@ fi
 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 openbsd-compat/Makefile scard/Makefile ssh_prng_cmds survey.sh"
 
 cat >confcache <<\_ACEOF
diff -Naurdp ../openssh.sacl/configure.ac ./configure.ac
--- ../openssh.sacl/configure.ac	2005-09-28 16:11:11.000000000 -0700
+++ ./configure.ac	2005-09-28 16:38:55.000000000 -0700
@@ -3429,6 +3429,9 @@ dnl Adding -Werror to CFLAGS early preve
 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 openbsd-compat/Makefile \
 	scard/Makefile ssh_prng_cmds survey.sh])
diff -Naurdp ../openssh.sacl/scp.1 ./scp.1
--- ../openssh.sacl/scp.1	2005-09-28 16:11:11.000000000 -0700
+++ ./scp.1	2005-09-28 16:38:55.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 @@ Passes the
 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 -Naurdp ../openssh.sacl/scp.c ./scp.c
--- ../openssh.sacl/scp.c	2005-09-28 16:11:11.000000000 -0700
+++ ./scp.c	2005-09-28 16:38:55.000000000 -0700
@@ -80,6 +80,11 @@ RCSID("$OpenBSD: scp.c,v 1.125 2005/07/2
 #include "misc.h"
 #include "progressmeter.h"
 
+#ifdef HAVE_COPYFILE_H
+#include <libgen.h>
+#include <copyfile.h>
+#endif
+
 extern char *__progname;
 
 void bwlimit(int);
@@ -105,6 +110,12 @@ char *ssh_program = _PATH_SSH_PROGRAM;
 /* 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)
 {
@@ -231,7 +242,11 @@ main(int argc, char **argv)
 	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':
@@ -277,6 +292,11 @@ main(int argc, char **argv)
 			showprogress = 0;
 			break;
 
+#ifdef HAVE_COPYFILE
+		case 'E':
+			copy_xattr = 1;
+			break;
+#endif
 		/* Server options. */
 		case 'd':
 			targetshouldbedirectory = 1;
@@ -326,7 +346,12 @@ main(int argc, char **argv)
 	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" : "");
@@ -509,6 +534,11 @@ source(int argc, char **argv)
 	int fd = -1, haderr, indx;
 	char *last, *name, buf[2048];
 	int len;
+#if HAVE_COPYFILE
+	char md_name[MAXPATHLEN];
+	char *md_tmp;
+#endif
+
 
 	for (indx = 0; indx < argc; ++indx) {
 		name = argv[indx];
@@ -521,6 +551,17 @@ source(int argc, char **argv)
 			    name);
 			goto next;
 		}
+#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, 0)) < 0)
 			goto syserr;
 		if (fstat(fd, &stb) < 0) {
@@ -604,6 +645,36 @@ next:			(void) close(fd);
 		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
 	}
 }
 
@@ -751,6 +822,10 @@ sink(int argc, char **argv)
 	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;
@@ -884,6 +959,29 @@ sink(int argc, char **argv)
 		}
 		omode = mode;
 		mode |= S_IWRITE;
+
+#if HAVE_COPYFILE
+		if (copy_xattr && !strncmp(basename(curfile), "._", 2))
+		{
+			if (targisdir)
+			{
+			    snprintf(md_src, sizeof md_src, "%s.XXX", np);
+			    snprintf(md_dst, sizeof md_dst, "%s/%s",
+				    dirname(np), basename(np) + 2);
+			    if(mkstemp(md_src) < 0)
+				continue;
+			}
+			else
+			{
+			    snprintf(md_src, sizeof md_src, "%s/._%s.XXX",
+				    dirname(np), basename(np));
+			    snprintf(md_dst, sizeof md_dst, "%s", np);
+			    if(mkstemp(md_src) < 0)
+				continue;
+			}
+			np = md_src;
+		}
+#endif
 		if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
 bad:			run_err("%s: %s", np, strerror(errno));
 			continue;
@@ -971,6 +1069,21 @@ bad:			run_err("%s: %s", np, strerror(er
 			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) {
@@ -1032,7 +1145,11 @@ void
 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);
--- config.h.in 2005-02-22 13:45:22.000000000 -0800
+++ config.h.in 2005-02-22 14:03:52.000000000 -0800
@@ -354,6 +353,18 @@
 /* getaddrinfo is broken (if present) */
 #undef BROKEN_GETADDRINFO
 
+/* 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