|
|
# --- ROCK-COPYRIGHT-NOTE-BEGIN --- # # This copyright note is auto-generated by ./scripts/Create-CopyPatch. # Please add additional copyright information _after_ the line containing # the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by # the ./scripts/Create-CopyPatch script. Do not edit this copyright text! # # ROCK Linux: rock-src/package/base/coreutils/acl-xattr.diff # ROCK Linux is Copyright (C) 1998 - 2005 Clifford Wolf # # This patch file is dual-licensed. It is available under the license the # patched project is licensed under, as long as it is an OpenSource license # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms # of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # # --- ROCK-COPYRIGHT-NOTE-END ---
--- /dev/null 2004-02-23 21:02:56.000000000 +0000
+++ ./m4/posix_acl.m4 2004-03-13 11:50:03.000000000 +0000
@@ -0,0 +1,28 @@
+#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, cu_cv_lacl=yes, cu_cv_lacl=no)
+ if test "$cu_cv_lacl" = yes; then
+ LIBACL=-lacl
+ else
+ LIBACL=
+ fi
+ AC_SUBST(LIBACL)
+ OLDLIBS="$LIBS"
+ LIBS="$LIBS $LIBACL"
+ 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)
+ LIBS="$OLDLIBS"
+
+ if test $ac_cv_header_sys_acl_h = yes; then
+ AC_DEFINE(USE_ACL, 1, [Define if you want access control list support.])
+ fi
+])
--- ./m4/Makefile.am.acl 2004-03-08 09:56:31.000000000 +0000
+++ ./m4/Makefile.am 2004-03-13 11:50:03.000000000 +0000
@@ -108,6 +108,7 @@
EXTRA_DIST += path-concat.m4 EXTRA_DIST += pathmax.m4 EXTRA_DIST += perl.m4 +EXTRA_DIST += posix_acl.m4
EXTRA_DIST += physmem.m4 EXTRA_DIST += po.m4 EXTRA_DIST += posixtm.m4 --- ./lib/acl.h.acl 2004-02-02 08:13:21.000000000 +0000
+++ ./lib/acl.h 2004-03-13 11:50:03.000000000 +0000
@@ -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);
--- ./lib/acl.c.acl 2004-02-02 08:13:21.000000000 +0000
+++ ./lib/acl.c 2004-03-13 11:50:03.000000000 +0000
@@ -22,18 +22,30 @@
# include <config.h> #endif +#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+
#include <sys/types.h> #include <sys/stat.h> #ifndef S_ISLNK # define S_ISLNK(Mode) 0 #endif +#include <stdlib.h>
+
#include "acl.h" #include <errno.h> #ifndef ENOSYS # define ENOSYS (-1) #endif +#ifndef ENOTSUP
+# define ENOTSUP (-1)
+#endif
#ifndef MIN_ACL_ENTRIES # define MIN_ACL_ENTRIES 4 @@ -45,19 +57,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
+}
+
--- ./src/mv.c.acl 2004-02-07 15:41:02.000000000 +0000
+++ ./src/mv.c 2004-03-13 11:50:03.000000000 +0000
@@ -132,12 +132,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->dest_info = NULL; --- ./src/ls.c.acl 2004-03-13 11:50:03.000000000 +0000
+++ ./src/ls.c 2004-03-13 11:50:03.000000000 +0000
@@ -188,13 +188,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 @@ -2409,7 +2409,7 @@
return 0; } -#if HAVE_ACL
+#if HAVE_ACL || USE_ACL
if (format == long_format) { int n = file_has_acl (path, &f->stat); --- ./src/install.c.acl 2004-03-13 11:50:03.000000000 +0000
+++ ./src/install.c 2004-03-13 11:50:03.000000000 +0000
@@ -242,7 +242,6 @@
x->mode = S_IRUSR | S_IWUSR; x->stdin_tty = 0; - x->umask_kill = 0;
x->update = 0; x->verbose = 0; x->dest_info = NULL; --- ./src/cp.c.acl 2004-02-07 15:55:09.000000000 +0000
+++ ./src/cp.c 2004-03-13 11:50:03.000000000 +0000
@@ -58,7 +58,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; }; @@ -333,9 +334,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)); @@ -353,8 +359,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 @@ -369,15 +374,20 @@
/* 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;
+ int (*xstat)() = (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS
+ || x->dereference == DEREF_ALWAYS
+ ? stat
+ : lstat);
ASSIGN_STRDUPA (dirpath, const_dirpath); @@ -412,12 +422,20 @@
if ((*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 ((*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"), @@ -429,6 +447,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)) { @@ -438,7 +496,7 @@
} else { - new->is_new_dir = 0;
+ new->mode_valid = 0;
*new_dst = 0; } *slash++ = '/'; @@ -552,10 +610,6 @@
Copy the files `file1' through `filen' to the existing directory `edir'. */ int i; - int (*xstat)() = (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS
- || x->dereference == DEREF_ALWAYS
- ? stat
- : lstat);
for (i = 0; i < n_files; i++) { @@ -593,11 +647,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,
- xstat);
+ &attr_list, &new_dst, x);
} else { @@ -731,12 +783,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; @@ -1011,9 +1057,6 @@
version_control_string) : none); - if (x.preserve_mode == 1)
- x.umask_kill = ~ (mode_t) 0;
-
if (x.dereference == DEREF_UNDEFINED) { if (x.recursive) --- ./src/copy.h.acl 2004-02-07 16:00:59.000000000 +0000
+++ ./src/copy.h 2004-03-13 11:50:03.000000000 +0000
@@ -143,9 +143,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; --- ./src/copy.c.acl 2004-03-12 11:48:59.000000000 +0000
+++ ./src/copy.c 2004-03-13 11:50:43.000000000 +0000
@@ -95,26 +95,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 @@ -817,13 +797,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; if (x->move_mode && rename_succeeded) @@ -837,11 +817,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; @@ -909,7 +887,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"), @@ -935,7 +913,7 @@
} } - if (!S_ISDIR (src_type))
+ if (!S_ISDIR (src_mode))
{ if (S_ISDIR (dst_sb.st_mode)) { @@ -963,7 +941,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) @@ -1084,7 +1062,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) @@ -1132,7 +1110,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); } @@ -1145,7 +1123,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. */ @@ -1197,7 +1175,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; @@ -1310,7 +1288,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; @@ -1335,16 +1313,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. */ @@ -1420,23 +1420,22 @@
goto un_backup; } } - else if (S_ISREG (src_type)
- || (x->copy_as_regular && !S_ISDIR (src_type)
- && !S_ISLNK (src_type)))
+ else if (S_ISREG (src_mode)
+ || (x->copy_as_regular && !S_ISDIR (src_mode)
+ && !S_ISLNK (src_mode)))
{ copied_as_regular = 1; /* 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; @@ -1444,10 +1443,10 @@
} else #endif - if (S_ISBLK (src_type) || S_ISCHR (src_type)
- || S_ISSOCK (src_type))
+ if (S_ISBLK (src_mode) || S_ISCHR (src_mode)
+ || S_ISSOCK (src_mode))
{ - 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)); @@ -1456,7 +1455,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) @@ -1560,7 +1559,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"), @@ -1587,20 +1604,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; } } --- ./src/Makefile.am.acl 2004-02-02 08:12:57.000000000 +0000
+++ ./src/Makefile.am 2004-03-13 11:50:03.000000000 +0000
@@ -32,10 +32,13 @@
# replacement functions defined in libfetish.a. LDADD = ../lib/libfetish.a $(LIBINTL) ../lib/libfetish.a -dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
-ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
+dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBACL@
+ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBACL@
shred_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) -vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
+vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBACL@
+cp_LDADD = $(LDADD) @LIBACL@
+ginstall_LDADD = $(LDADD) @LIBACL@
+mv_LDADD = $(LDADD) @LIBACL@
## If necessary, add -lm to resolve use of pow in lib/strtod.c. sort_LDADD = $(LDADD) $(POW_LIB) --- ./configure.ac.acl 2004-03-02 22:47:31.000000000 +0000
+++ ./configure.ac 2004-03-13 11:50:03.000000000 +0000
@@ -16,6 +16,9 @@
AC_PROG_RANLIB AC_PROG_LN_S AC_CANONICAL_HOST +AM_C_PROTOTYPES
+AC_PROG_YACC
+AC_SUBST(YACC)
AC_CHECK_FUNCS(uname, @@ -235,6 +238,8 @@
AM_GNU_GETTEXT([external], [need-ngettext]) AM_GNU_GETTEXT_VERSION(0.13.1) +ag_POSIX_ACL
+
AC_CONFIG_FILES( Makefile doc/Makefile --- ./config.hin.acl 2004-03-11 08:59:16.000000000 +0000
+++ ./config.hin 2004-03-13 11:50:03.000000000 +0000
@@ -96,6 +96,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 @@ -489,6 +513,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 @@ -1335,6 +1362,9 @@
<sys/cpustats.h>. */ #undef UMAX4_3 +/* Define if you want access control list support. */
+#undef USE_ACL
+
/* Version number of package */ #undef VERSION
|