--- fileutils-4.1.9/lib/acl.c.acl	2002-02-26 15:53:52.000000000 +0100
+++ fileutils-4.1.9/lib/acl.c	2002-07-01 12:10:50.000000000 +0200
@@ -22,6 +22,13 @@
 # include <config.h>
 #endif
 
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+
 #include <sys/stat.h>
 #ifndef S_ISLNK
 # define S_ISLNK(Mode) 0
@@ -33,6 +40,9 @@
 #ifndef ENOSYS
 # define ENOSYS (-1)
 #endif
+#ifndef ENOTSUP
+# define ENOTSUP (-1)
+#endif
 
 #ifndef MIN_ACL_ENTRIES
 # define MIN_ACL_ENTRIES 4
@@ -44,19 +54,201 @@
 int
 file_has_acl (char const *path, struct stat const *pathstat)
 {
-  /* FIXME: This implementation should work on recent-enough versions
-     of HP-UX, Solaris, and Unixware, but it simply returns 0 with
-     POSIX 1003.1e (draft 17 -- abandoned), AIX, GNU/Linux, Irix, and
-     Tru64.  Please see Samba's source/lib/sysacls.c file for
-     fix-related ideas.  */
-
 #if HAVE_ACL && defined GETACLCNT
+  /* This implementation should work on recent-enough versions of HP-UX,
+     Solaris, and Unixware.  */
+
   if (! S_ISLNK (pathstat->st_mode))
     {
       int n = acl (path, GETACLCNT, 0, NULL);
       return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n);
     }
+#elif HAVE_ACL_EXTENDED_FILE
+
+  /* Linux specific.  */
+
+  if (! S_ISLNK (pathstat->st_mode))
+    {
+      int ret = acl_extended_file (path);
+      if (ret < 0)
+	return (errno == ENOSYS || errno == ENOTSUP) ? 0 : -1;
+      return ret;
+    }
+#else
+  /* FIXME: Add support for AIX, Irix, and Tru64, FreeBSD, etc.
+     Please see Samba's source/lib/sysacls.c file for fix-related ideas.  */
+#endif
+
+  return 0;
+}
+
+/* Copy the permissions from SRC_PATH to DST_PATH, including access control
+   lists on systems where this is supported. MODE is the file mode for
+   DST_PATH, including the file type.
+   Also sets special bits in MODE on DST_PATH.  */
+
+int
+copy_acl (char const *src_path, char const *dst_path, mode_t mode)
+{
+#if HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && HAVE_ACL_FREE && \
+    HAVE_ACL_ENTRIES
+
+  /* Linux specific. Will work on all POSIX 1003.1e draft 17 (abandoned)
+     compliant systems if the acl_entries() function is implemented.  */
+
+  acl_t acl = acl_get_file (src_path, ACL_TYPE_ACCESS);
+  if (acl == NULL)
+    {
+      if (errno == ENOSYS || errno == ENOTSUP)
+	return set_acl (dst_path, mode);
+      else
+        {
+	  error (0, errno, "%s", quote (src_path));
+	  return -1;
+	}
+    }
+
+  if (acl_set_file (dst_path, ACL_TYPE_ACCESS, acl))
+    {
+      int saved_errno = errno;
+
+      if (errno == ENOSYS || errno == ENOTSUP)
+        {
+	  int n = acl_entries (acl);
+
+	  acl_free (acl);
+	  if (n == 3)
+	    {
+	      if (chmod (dst_path, mode))
+		saved_errno = errno;
+	      else
+		return 0;
+	    }
+	  else
+	    chmod (dst_path, mode);
+	}
+      else
+	{
+	  acl_free (acl);
+	  chmod (dst_path, mode);
+	}
+      error (0, saved_errno, _("preserving permissions for %s"),
+	     quote (dst_path));
+      return -1;
+    }
+  acl_free (acl);
+
+  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
+    {
+      /* We did not call chmod so far, so the special bits have not yet
+         been set.  */
+
+      if (chmod (dst_path, mode))
+	{
+	  error (0, errno, _("preserving permissions for %s"),
+	  	 quote (dst_path));
+	  return -1;
+	}
+    }
+
+  if (S_ISDIR (mode))
+    {
+      acl = acl_get_file (src_path, ACL_TYPE_DEFAULT);
+      if (acl == NULL)
+	{
+	  error (0, errno, "%s", quote (src_path));
+	  return -1;
+	}
+
+      if (acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl))
+	{
+	  error (0, errno, _("preserving permissions for %s"),
+		 quote (dst_path));
+	  acl_free(acl);
+	  return -1;
+	}
+      else
+        acl_free(acl);
+    }
+  return 0;
+#else
+  int ret = chmod (dst_path, mode);
+  if (ret)
+    error (0, errno, _("preserving permissions for %s"), quote (dst_path));
+  return ret;
 #endif
+}
+
+/* Set the permissions of PATH, overwriting access control lists, on systems
+   where this is supported. MODE is the file mode for PATH, including the
+   file type. Also sets special bits in MODE on PATH.  */
 
+int
+set_acl (char const *path, mode_t mode)
+{
+#if HAVE_ACL_FROM_TEXT && HAVE_ACL_SET_FILE && HAVE_ACL_FREE && \
+       HAVE_ACL_DELETE_DEF_FILE
+  char acl_text[] = "u::---,g::---,o::---";
+  acl_t acl;
+
+  if (mode & S_IRUSR) acl_text[ 3] = 'r';
+  if (mode & S_IWUSR) acl_text[ 4] = 'w';
+  if (mode & S_IXUSR) acl_text[ 5] = 'x';
+  if (mode & S_IRGRP) acl_text[10] = 'r';
+  if (mode & S_IWGRP) acl_text[11] = 'w';
+  if (mode & S_IXGRP) acl_text[12] = 'x';
+  if (mode & S_IROTH) acl_text[17] = 'r';
+  if (mode & S_IWOTH) acl_text[18] = 'w';
+  if (mode & S_IXOTH) acl_text[19] = 'x';
+
+  acl = acl_from_text(acl_text);
+  if (!acl)
+    {
+      error (0, errno, "%s", quote (path));
+      return -1;
+    }
+
+  if (acl_set_file(path, ACL_TYPE_ACCESS, acl))
+    {
+      int saved_errno = errno;
+      acl_free (acl);
+
+      if (errno == ENOTSUP || errno == ENOSYS)
+	{
+	  if (chmod (path, mode))
+	    saved_errno = errno;
+	  else
+	    return 0;
+	}
+      error (0, saved_errno, _("setting permissions for %s"), quote (path));
+      return -1;
+    }
+  acl_free (acl);
+
+  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
+    {
+      /* We did not call chmod so far, so the special bits have not yet
+         been set.  */
+
+      if (chmod (path, mode))
+	{
+	  error (0, errno, _("preserving permissions for %s"),
+	  	 quote (path));
+	  return -1;
+	}
+    }
+
+  if (S_ISDIR (mode) && acl_delete_def_file (path))
+    {
+      error (0, errno, _("setting permissions for %s"), quote (path));
+      return -1;
+    }
   return 0;
+#else
+  int ret = chmod (path, mode);
+  if (ret)
+    error (0, errno, _("setting permissions for %s"), quote (path));
+  return ret;
+#endif
 }
+
--- fileutils-4.1.9/lib/acl.h.acl	2002-02-26 15:54:01.000000000 +0100
+++ fileutils-4.1.9/lib/acl.h	2002-07-01 12:10:50.000000000 +0200
@@ -18,11 +18,16 @@
 
    Written by Paul Eggert.  */
 
-#if HAVE_SYS_ACL_H && HAVE_ACL
+#if HAVE_SYS_ACL_H
 # include <sys/acl.h>
 #endif
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
 #if ! defined GETACLCNT && defined ACL_CNT
 # define GETACLCNT ACL_CNT
 #endif
 
 int file_has_acl (char const *, struct stat const *);
+int copy_acl (char const *, char const *, mode_t);
+int set_acl (char const *, mode_t);
--- fileutils-4.1.9/src/copy.c.acl	2002-06-21 14:07:40.000000000 +0200
+++ fileutils-4.1.9/src/copy.c	2002-07-01 12:10:50.000000000 +0200
@@ -99,26 +99,6 @@
 /* The invocation name of this program.  */
 extern char *program_name;
 
-/* Encapsulate selection of the file mode to be applied to
-   new non-directories.  */
-
-static mode_t
-get_dest_mode (const struct cp_options *option, mode_t mode)
-{
-  /* In some applications (e.g., install), use precisely the
-     specified mode.  */
-  if (option->set_mode)
-    return option->mode;
-
-  /* Honor the umask for `cp', but not for `mv' or `cp -p'.
-     In addition, `cp' without -p must clear the set-user-ID and set-group-ID
-     bits.  POSIX requires it do that when creating new files.  */
-  if (!option->move_mode && !option->preserve_mode)
-    mode &= (option->umask_kill & ~(S_ISUID | S_ISGID));
-
-  return mode;
-}
-
 /* FIXME: describe */
 /* FIXME: rewrite this to use a hash table so we avoid the quadratic
    performance hit that's probably noticeable only on trees deeper
@@ -792,13 +772,13 @@
   struct stat src_sb;
   struct stat dst_sb;
   mode_t src_mode;
-  mode_t src_type;
+  mode_t dst_mode;
   char *earlier_file = NULL;
   char *dst_backup = NULL;
   int backup_succeeded = 0;
   int delayed_fail;
   int copied_as_regular = 0;
-  int ran_chown = 0;
+  int dst_mode_valid = 0;
   int preserve_metadata;
 
   /* move_mode is set to the value from the `options' parameter for the
@@ -818,11 +798,9 @@
       return 1;
     }
 
-  src_type = src_sb.st_mode;
-
   src_mode = src_sb.st_mode;
 
-  if (S_ISDIR (src_type) && !x->recursive)
+  if (S_ISDIR (src_mode) && !x->recursive)
     {
       error (0, 0, _("omitting directory %s"), quote (src_path));
       return 1;
@@ -877,7 +855,7 @@
 
 	  if (!S_ISDIR (dst_sb.st_mode))
 	    {
-	      if (S_ISDIR (src_type))
+	      if (S_ISDIR (src_mode))
 		{
 		  error (0, 0,
 		     _("cannot overwrite non-directory %s with directory %s"),
@@ -903,7 +881,7 @@
 		}
 	    }
 
-	  if (!S_ISDIR (src_type))
+	  if (!S_ISDIR (src_mode))
 	    {
 	      if (S_ISDIR (dst_sb.st_mode))
 		{
@@ -931,7 +909,7 @@
 	     This may be due to an interactive `negative' reply to the
 	     prompt about the existing file.  It may also be due to the
 	     use of the --reply=no option.  */
-	  if (!S_ISDIR (src_type))
+	  if (!S_ISDIR (src_mode))
 	    {
 	      /* cp and mv treat -i and -f differently.  */
 	      if (x->move_mode)
@@ -1049,7 +1027,7 @@
   /* If the source is a directory, we don't always create the destination
      directory.  So --verbose should not announce anything until we're
      sure we'll create a directory. */
-  if (x->verbose && !S_ISDIR (src_type))
+  if (x->verbose && !S_ISDIR (src_mode))
     {
       printf ("%s -> %s", quote_n (0, src_path), quote_n (1, dst_path));
       if (backup_succeeded)
@@ -1084,7 +1062,7 @@
 	   || (command_line_arg
 	       && x->dereference == DEREF_COMMAND_LINE_ARGUMENTS)
 	   || x->dereference == DEREF_ALWAYS))
-      || (x->recursive && S_ISDIR (src_type)))
+      || (x->recursive && S_ISDIR (src_mode)))
     {
       earlier_file = remember_copied (dst_path, src_sb.st_ino, src_sb.st_dev);
     }
@@ -1097,7 +1075,7 @@
       /* Avoid damaging the destination filesystem by refusing to preserve
 	 hard-linked directories (which are found at least in Netapp snapshot
 	 directories).  */
-      if (S_ISDIR (src_type))
+      if (S_ISDIR (src_mode))
 	{
 	  /* If src_path and earlier_file refer to the same directory entry,
 	     then warn about copying a directory into itself.  */
@@ -1133,7 +1111,7 @@
     {
       if (rename (src_path, dst_path) == 0)
 	{
-	  if (x->verbose && S_ISDIR (src_type))
+	  if (x->verbose && S_ISDIR (src_mode))
 	    printf ("%s -> %s\n", quote_n (0, src_path), quote_n (1, dst_path));
 	  if (rename_succeeded)
 	    *rename_succeeded = 1;
@@ -1246,7 +1224,7 @@
      In such cases, set this variable to zero.  */
   preserve_metadata = 1;
 
-  if (S_ISDIR (src_type))
+  if (S_ISDIR (src_mode))
     {
       struct dir_list *dir;
 
@@ -1271,16 +1249,38 @@
 
       if (new_dst || !S_ISDIR (dst_sb.st_mode))
 	{
-	  /* Create the new directory writable and searchable, so
-             we can create new entries in it.  */
-
-	  if (mkdir (dst_path, (src_mode & x->umask_kill) | S_IRWXU))
+	  if (mkdir (dst_path, src_mode))
 	    {
 	      error (0, errno, _("cannot create directory %s"),
 		     quote (dst_path));
 	      goto un_backup;
 	    }
 
+	  /* We need search and write permissions to the new directory
+	     for adding the directory's contents. Check if these permissions
+	     are already there.  */
+
+	  if (lstat (dst_path, &dst_sb))
+	    {
+	      error (0, errno, _("cannot stat %s"), quote (dst_path));
+	      delayed_fail = 1;
+	    }
+	  else if ((dst_sb.st_mode & S_IRWXU) != S_IRWXU)
+	    {
+	      /* Make the new directory writable and searchable. The original
+	         permissions will be restored later.  */
+
+	      dst_mode_valid = 1;
+	      dst_mode = dst_sb.st_mode;
+
+	      if (chmod (dst_path, dst_mode | S_IRWXU))
+	        {
+		  error (0, errno, _("setting permissions for %s"),
+		         quote (dst_path));
+		  goto un_backup;
+		}
+	    }
+
 	  /* Insert the created directory's inode and device
              numbers into the search structure, so that we can
              avoid copying it again.  */
@@ -1356,10 +1356,10 @@
 	  goto un_backup;
 	}
     }
-  else if (S_ISREG (src_type)
-	   || (x->copy_as_regular && !S_ISDIR (src_type)
+  else if (S_ISREG (src_mode)
+	   || (x->copy_as_regular && !S_ISDIR (src_mode)
 #ifdef S_ISLNK
-	       && !S_ISLNK (src_type)
+	       && !S_ISLNK (src_mode)
 #endif
 	       ))
     {
@@ -1367,15 +1367,14 @@
       /* POSIX says the permission bits of the source file must be
 	 used as the 3rd argument in the open call, but that's not consistent
 	 with historical practice.  */
-      if (copy_reg (src_path, dst_path, x,
-		    get_dest_mode (x, src_mode), &new_dst, &src_sb))
+      if (copy_reg (src_path, dst_path, x, src_mode, &new_dst, &src_sb))
 	goto un_backup;
     }
   else
 #ifdef S_ISFIFO
-  if (S_ISFIFO (src_type))
+  if (S_ISFIFO (src_mode))
     {
-      if (mkfifo (dst_path, get_dest_mode (x, src_mode)))
+      if (mkfifo (dst_path, src_mode))
 	{
 	  error (0, errno, _("cannot create fifo %s"), quote (dst_path));
 	  goto un_backup;
@@ -1383,13 +1382,13 @@
     }
   else
 #endif
-    if (S_ISBLK (src_type) || S_ISCHR (src_type)
+    if (S_ISBLK (src_mode) || S_ISCHR (src_mode)
 #ifdef S_ISSOCK
-	|| S_ISSOCK (src_type)
+	|| S_ISSOCK (src_mode)
 #endif
 	)
     {
-      if (mknod (dst_path, get_dest_mode (x, src_mode), src_sb.st_rdev))
+      if (mknod (dst_path, src_mode, src_sb.st_rdev))
 	{
 	  error (0, errno, _("cannot create special file %s"),
 		 quote (dst_path));
@@ -1398,7 +1397,7 @@
     }
   else
 #ifdef S_ISLNK
-  if (S_ISLNK (src_type))
+  if (S_ISLNK (src_mode))
     {
       char *src_link_val = xreadlink (src_path);
       if (src_link_val == NULL)
@@ -1504,7 +1503,25 @@
   if (x->preserve_ownership
       && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb)))
     {
-      ran_chown = 1;
+      /* The chown() system call may clear the SUID and SGID bits, so we
+         need to set them again later. (But we don't care if we will
+	 overwrite the permissions of the destination file anyway.)  */
+	 
+      if ((src_mode & (S_ISUID | S_ISGID))
+	  && !x->preserve_mode && !x->move_mode && !x->set_mode)
+	{
+	  if (lstat (dst_path, &dst_sb))
+	    {
+	      error (0, errno, _("cannot stat %s"), quote (dst_path));
+	      delayed_fail = 1;
+	    }
+	  else
+	    {
+	      dst_mode_valid = 1;
+	      dst_mode = dst_sb.st_mode;
+	    }
+	}
+
       if (DO_CHOWN (chown, dst_path, src_sb.st_uid, src_sb.st_gid))
 	{
 	  error (0, errno, _("failed to preserve ownership for %s"),
@@ -1525,20 +1542,23 @@
   }
 #endif
 
-  /* Permissions of newly-created regular files were set upon `open' in
-     copy_reg.  But don't return early if there were any special bits and
-     we had to run chown, because the chown must have reset those bits.  */
-  if ((new_dst && copied_as_regular)
-      && !(ran_chown && (src_mode & ~S_IRWXUGO)))
-    return delayed_fail;
-
-  if ((x->preserve_mode || new_dst)
-      && (x->copy_as_regular || S_ISREG (src_type) || S_ISDIR (src_type)))
+  if (x->preserve_mode || x->move_mode)
     {
-      if (chmod (dst_path, get_dest_mode (x, src_mode)))
-	{
-	  error (0, errno, _("setting permissions for %s"), quote (dst_path));
-	  if (x->set_mode || x->require_preserve)
+      if (copy_acl (src_path, dst_path, src_mode) && x->require_preserve)
+	return 1;
+    }
+  else if (x->set_mode)
+    {
+      if (set_acl (dst_path, x->mode) && x->require_preserve)
+	return 1;
+    }
+  else if (dst_mode_valid)
+    {
+      if (chmod (dst_path, dst_mode))
+        {
+	  error (0, errno, _("preserving permissions for %s"),
+	         quote (dst_path));
+	  if (x->require_preserve)
 	    return 1;
 	}
     }
--- fileutils-4.1.9/src/copy.h.acl	2001-11-22 16:23:00.000000000 +0100
+++ fileutils-4.1.9/src/copy.h	2002-07-01 12:10:50.000000000 +0200
@@ -139,9 +139,6 @@
      Create destination directories as usual. */
   int symbolic_link;
 
-  /* The bits to preserve in created files' modes. */
-  mode_t umask_kill;
-
   /* If nonzero, do not copy a nondirectory that has an existing destination
      with the same or newer modification time. */
   int update;
--- fileutils-4.1.9/src/cp.c.acl	2002-06-22 12:18:41.000000000 +0200
+++ fileutils-4.1.9/src/cp.c	2002-07-01 12:19:35.000000000 +0200
@@ -61,7 +61,8 @@
    need to be fixed after copying. */
 struct dir_attr
 {
-  int is_new_dir;
+  int mode_valid;
+  mode_t mode;
   int slash_offset;
   struct dir_attr *next;
 };
@@ -342,9 +343,14 @@
 	    }
 	}
 
-      if (x->preserve_mode || p->is_new_dir)
-	{
-	  if (chmod (dst_path, src_sb.st_mode & x->umask_kill))
+      if (x->preserve_mode)
+        {
+          if (copy_acl (src_path, dst_path, src_sb.st_mode))
+            return 1;
+        }
+      else if (p->mode_valid)
+        {
+          if (chmod (dst_path, p->mode))
 	    {
 	      error (0, errno, _("failed to preserve permissions for %s"),
 		     quote (dst_path));
@@ -362,8 +368,7 @@
 
    SRC_OFFSET is the index in CONST_DIRPATH (which is a destination
    path) of the beginning of the source directory name.
-   Create any leading directories that don't already exist,
-   giving them permissions MODE.
+   Create any leading directories that don't already exist.
    If VERBOSE_FMT_STRING is nonzero, use it as a printf format
    string for printing a message after successfully making a directory.
    The format should take two string arguments: the names of the
@@ -378,15 +383,16 @@
 /* FIXME: find a way to synch this function with the one in lib/makepath.c. */
 
 static int
-make_path_private (const char *const_dirpath, int src_offset, int mode,
+make_path_private (const char *const_dirpath, int src_offset,
 		   const char *verbose_fmt_string, struct dir_attr **attr_list,
-		   int *new_dst, int (*xstat)())
+		   int *new_dst, const struct cp_options *x)
 {
   struct stat stats;
   char *dirpath;		/* A copy of CONST_DIRPATH we can change. */
   char *src;			/* Source name in `dirpath'. */
   char *dst_dirname;		/* Leading path of `dirpath'. */
   size_t dirlen;		/* Length of leading path of `dirpath'. */
+  mode_t mode;
 
   dirpath = (char *) alloca (strlen (const_dirpath) + 1);
   strcpy (dirpath, const_dirpath);
@@ -400,7 +406,7 @@
 
   *attr_list = NULL;
 
-  if ((*xstat) (dst_dirname, &stats))
+  if ((*x->xstat) (dst_dirname, &stats))
     {
       /* Parent of CONST_DIRNAME does not exist.
 	 Make all missing intermediate directories. */
@@ -420,15 +426,23 @@
 	  *attr_list = new;
 
 	  *slash = '\0';
-	  if ((*xstat) (dirpath, &stats))
+	  if ((*x->xstat) (dirpath, &stats))
 	    {
 	      /* This element of the path does not exist.  We must set
-		 *new_dst and new->is_new_dir inside this loop because,
+		 *new_dst inside this loop because,
 		 for example, in the command `cp --parents ../a/../b/c e_dir',
 		 make_path_private creates only e_dir/../a if ./b already
 		 exists. */
 	      *new_dst = 1;
-	      new->is_new_dir = 1;
+
+	      if ((*x->xstat) (src, &stats))
+		{
+		  error (0, errno, _("failed to get attributes of %s"),
+			 quote (src));
+		  return 1;
+		}
+	      mode = stats.st_mode;
+
 	      if (mkdir (dirpath, mode))
 		{
 		  error (0, errno, _("cannot make directory %s"),
@@ -440,6 +454,46 @@
 		  if (verbose_fmt_string != NULL)
 		    printf (verbose_fmt_string, src, dirpath);
 		}
+
+	      /* We need search and write permissions to the new directory
+	         for adding the directory's contents. Check if these
+		 permissions are already there.  */
+
+	      if (lstat (dirpath, &stats))
+	        {
+		  error (0, errno, _("failed to get attributes of %s"),
+		         quote (dirpath));
+		  return 1;
+		}
+	      else
+		{
+		  if (x->preserve_mode && mode != stats.st_mode)
+		    {
+		      new->mode = mode;
+		      new->mode_valid = 1;
+		    }
+		  else
+		    new->mode_valid = 0;
+
+		  if ((stats.st_mode & S_IRWXU) != S_IRWXU)
+		    {
+		      /* Make the new directory writable and searchable. The
+		         original permissions will be restored later.  */
+
+		      if (!new->mode_valid)
+			{
+			  new->mode = stats.st_mode;
+			  new->mode_valid = 1;
+			}
+
+		      if (chmod (dirpath, stats.st_mode | S_IRWXU))
+			{
+			  error (0, errno, _("setting permissions for %s"),
+			         quote (dirpath));
+			  return 1;
+			}
+		    }
+		}
 	    }
 	  else if (!S_ISDIR (stats.st_mode))
 	    {
@@ -449,7 +503,7 @@
 	    }
 	  else
 	    {
-	      new->is_new_dir = 0;
+	      new->mode_valid = 0;
 	      *new_dst = 0;
 	    }
 	  *slash++ = '/';
@@ -600,11 +654,9 @@
 	         leading directories. */
 	      parent_exists = !make_path_private (dst_path,
 						  arg_in_concat - dst_path,
-						  S_IRWXU,
 						  (x->verbose
 						   ? "%s -> %s\n" : NULL),
-						  &attr_list, &new_dst,
-						  x->xstat);
+						  &attr_list, &new_dst, x);
 	    }
   	  else
   	    {
@@ -739,12 +791,6 @@
   /* Not used.  */
   x->stdin_tty = 0;
 
-  /* Find out the current file creation mask, to knock the right bits
-     when using chmod.  The creation mask is set to be liberal, so
-     that created directories can be written, even if it would not
-     have been allowed with the mask this process was started with.  */
-  x->umask_kill = ~ umask (0);
-
   x->update = 0;
   x->verbose = 0;
   x->dest_info = NULL;
@@ -1016,9 +1062,6 @@
 				   version_control_string)
 		   : none);
 
-  if (x.preserve_mode == 1)
-    x.umask_kill = ~ (mode_t) 0;
-
   if (x.dereference == DEREF_UNDEFINED)
     {
       if (x.recursive)
--- fileutils-4.1.9/src/install.c.acl	2002-07-01 12:10:50.000000000 +0200
+++ fileutils-4.1.9/src/install.c	2002-07-01 12:10:50.000000000 +0200
@@ -249,7 +249,6 @@
   x->mode = S_IRUSR | S_IWUSR;
   x->stdin_tty = 0;
 
-  x->umask_kill = 0;
   x->update = 0;
   x->verbose = 0;
   x->xstat = stat;
--- fileutils-4.1.9/src/ls.c.acl	2002-07-01 12:10:50.000000000 +0200
+++ fileutils-4.1.9/src/ls.c	2002-07-01 12:10:50.000000000 +0200
@@ -230,13 +230,13 @@
 
     enum filetype filetype;
 
-#if HAVE_ACL
+#if HAVE_ACL || USE_ACL
     /* For long listings, true if the file has an access control list.  */
     bool have_acl;
 #endif
   };
 
-#if HAVE_ACL
+#if HAVE_ACL || USE_ACL
 # define FILE_HAS_ACL(F) ((F)->have_acl)
 #else
 # define FILE_HAS_ACL(F) 0
@@ -2261,7 +2261,7 @@
 	  return 0;
 	}
 
-#if HAVE_ACL
+#if HAVE_ACL || USE_ACL
       if (format == long_format)
 	{
 	  int n = file_has_acl (path, &files[files_index].stat);
--- fileutils-4.1.9/src/mv.c.acl	2002-06-12 09:36:06.000000000 +0200
+++ fileutils-4.1.9/src/mv.c	2002-07-01 12:10:50.000000000 +0200
@@ -139,12 +139,6 @@
   x->mode = 0;
   x->stdin_tty = isatty (STDIN_FILENO);
 
-  /* Find out the current file creation mask, to knock the right bits
-     when using chmod.  The creation mask is set to be liberal, so
-     that created directories can be written, even if it would not
-     have been allowed with the mask this process was started with.  */
-  x->umask_kill = ~ umask (0);
-
   x->update = 0;
   x->verbose = 0;
   x->xstat = lstat;
--- fileutils-4.1.9/m4/Makefile.am.acl	2002-06-22 10:58:05.000000000 +0200
+++ fileutils-4.1.9/m4/Makefile.am	2002-07-01 12:10:50.000000000 +0200
@@ -60,6 +60,7 @@
 mkstemp.m4 \
 nanosleep.m4 \
 perl.m4 \
+posix_acl.m4 \
 prereq.m4 \
 progtest.m4 \
 putenv.m4 \
--- fileutils-4.1.9/m4/posix_acl.m4.acl	2002-07-01 12:10:50.000000000 +0200
+++ fileutils-4.1.9/m4/posix_acl.m4	2002-07-01 12:10:50.000000000 +0200
@@ -0,0 +1,19 @@
+#serial 1
+
+dnl Written by Andreas Gruenbacher <a.gruenbacher@computer.org>.
+
+dnl Posix 1003.1e draft standard 17 (abandoned) and similar
+dnl access control list support
+AC_DEFUN([ag_POSIX_ACL],
+[
+  AC_CHECK_HEADERS(sys/acl.h)
+  AC_CHECK_LIB(acl, main)
+  AC_CHECK_FUNCS(acl_get_file acl_set_file acl_free acl_to_text \
+                 acl_from_text acl_delete_def_file)
+  # Linux specific extensions:
+  AC_CHECK_FUNCS(acl_entries acl_extended_file)
+
+  if test $ac_cv_header_sys_acl_h = yes; then
+    AC_DEFINE(USE_ACL, 1, [Define if you want access control list support.])
+  fi
+])
--- fileutils-4.1.9/ChangeLog.acl	2002-06-22 12:09:31.000000000 +0200
+++ fileutils-4.1.9/ChangeLog	2002-07-01 12:15:54.000000000 +0200
@@ -0,0 +1,45 @@
+2002-07-01  Bernhard Rosenkraenzer <bero@bero.org>
+	* Port the following patch to 4.1.9:
+
+2002-04-10  Andreas Gruenbacher  <a.gruenbacher@computer.org>
+
+	* Version 4.1.8acl.
+
+	* src/copy.c (get_dest_mode): Remove.
+	* src/copy.c (copy_internal): Merge src_mode and src_type.
+	* src/copy.c (copy_internal): Add dst_mode and dst_mode_valid,
+	which are set when the destination file mode is changed temporarily.
+	* src/copy.c (copy_internal): Check effective permissions after
+	mkdir(). Add S_IRWXU only after saving the default permissions, so
+	the default permissions can be restored. This is needed with
+	default ACLs on some systems.
+	* src/copy.c (copy_internal): Use dst_mode and dst_mode_valid for
+	ran_chown. Save the current permissions if needed before chown().
+	* src/copy.c (copy_internal): Clean up the final permission setting
+	code and prepare for copy/set ACL support.
+	* src/cp.c, src/install.c, src/mv.c, src/copy.h: Remove umask_kill,
+	and never change the startup umask. The functions creating files need
+	the original umask to be active to create the correct permissions
+	inside directories with default ACLs; umask_kill no longer works.
+	* src/cp.c (struct dir_attr, re_protect, make_path_private): Remove
+	is_new_dir and add mode and mode_valid instead.
+	* src/cp.c (make_path_private): Remove the mode parameter. Pass in
+	cp_options, instead of cp_options->xstat only. Stat the source dir,
+	and create the destination dir with the source dir's mode as create
+	mode (see analog change to src/copy.c (copy_internal)). Check if the
+	effective permissions include S_IRWXU. Remember the original code only
+	if needed later.
+	* lib/acl.h, lib/acl.c (copy_acl, set_acl): Add these functions,
+	initially with the bare non-ACL functionality.
+	* src/copy.c (copy_internal): Use copy_acl and set_acl instead of chmod.
+	* src/cp.c (re_protect): Use copy_acl instead of chmod.
+	* m4/posix_acl.m4, configure.ac (ag_POSIX_ACL): Add POSIX ACL tests.
+	* lib/acl.h: Remove HAVE_ACL symbol; <sys/acl.h> is needed for POSIX
+	ACLs even if there is no acl system call.
+	* lib/acl.c (ENOTSUP): Provide default value.
+	* lib/acl.c (file_has_acl, copy_acl, set_acl): Add Linux ACL
+	implementations.
+	* src/ls.c: change `HAVE_ACL' to `HAVE_ACL || USE_ACL' for POSIX ACLs:
+	there is no acl system call for POSIX ACLs.
+	* tests/misc: Add my own small test suite so it doesn't get lost.
+
--- fileutils-4.1.9/NEWS.acl	2002-06-21 17:29:27.000000000 +0200
+++ fileutils-4.1.9/NEWS	2002-07-01 12:12:56.000000000 +0200
@@ -1,3 +1,6 @@
+[4.1.9acl]
+* ACL framework and Linux ACL support.
+* `cp -p' and `mv' now preserve ACLs
 [4.1.9]
 * rm can now remove very deep hierarchies, in spite of any limit on stack size
 * new programs: link, unlink, and stat
--- fileutils-4.1.9/config.hin.acl	2002-06-23 07:55:33.000000000 +0200
+++ fileutils-4.1.9/config.hin	2002-07-01 12:10:50.000000000 +0200
@@ -80,6 +80,30 @@
 /* Define to 1 if you have the `acl' function. */
 #undef HAVE_ACL
 
+/* Define to 1 if you have the `acl_delete_def_file' function. */
+#undef HAVE_ACL_DELETE_DEF_FILE
+
+/* Define to 1 if you have the `acl_entries' function. */
+#undef HAVE_ACL_ENTRIES
+
+/* Define to 1 if you have the `acl_extended_file' function. */
+#undef HAVE_ACL_EXTENDED_FILE
+
+/* Define to 1 if you have the `acl_free' function. */
+#undef HAVE_ACL_FREE
+
+/* Define to 1 if you have the `acl_from_text' function. */
+#undef HAVE_ACL_FROM_TEXT
+
+/* Define to 1 if you have the `acl_get_file' function. */
+#undef HAVE_ACL_GET_FILE
+
+/* Define to 1 if you have the `acl_set_file' function. */
+#undef HAVE_ACL_SET_FILE
+
+/* Define to 1 if you have the `acl_to_text' function. */
+#undef HAVE_ACL_TO_TEXT
+
 /* Define to 1 if you have the `alarm' function. */
 #undef HAVE_ALARM
 
@@ -500,6 +524,9 @@
 /* Define to 1 if you have the `lchown' function. */
 #undef HAVE_LCHOWN
 
+/* Define to 1 if you have the `acl' library (-lacl). */
+#undef HAVE_LIBACL
+
 /* Define to 1 if you have the `dgc' library (-ldgc). */
 #undef HAVE_LIBDGC
 
@@ -1238,6 +1265,9 @@
    <sys/cpustats.h>. */
 #undef UMAX4_3
 
+/* Define if you want access control list support. */
+#undef USE_ACL
+
 /* Version number of package */
 #undef VERSION
 
--- fileutils-4.1.9/configure.ac.acl	2002-06-22 10:42:46.000000000 +0200
+++ fileutils-4.1.9/configure.ac	2002-07-01 12:10:50.000000000 +0200
@@ -16,6 +16,9 @@
 AC_PROG_RANLIB
 AC_AIX
 AC_MINIX
+AM_C_PROTOTYPES
+AC_PROG_YACC
+AC_SUBST(YACC)
 
 jm_MACROS
 
@@ -50,6 +53,8 @@
 
 AM_GNU_GETTEXT([external])
 
+ag_POSIX_ACL
+
 AC_CONFIG_FILES(
   Makefile
   doc/Makefile
