? diff Index: Makefile =================================================================== RCS file: /home/ncvs/src/bin/cp/Makefile,v retrieving revision 1.8 diff -u -r1.8 Makefile --- Makefile 4 Dec 2001 01:57:38 -0000 1.8 +++ Makefile 4 Feb 2002 02:18:46 -0000 @@ -6,4 +6,8 @@ CFLAGS+= -DVM_AND_BUFFER_CACHE_SYNCHRONIZED WARNS= 0 +.if !defined(RELEASE_CRUNCH) +CFLAGS+=-DWANT_ACL +.endif + .include Index: cp.1 =================================================================== RCS file: /home/ncvs/src/bin/cp/cp.1,v retrieving revision 1.22 diff -u -r1.22 cp.1 --- cp.1 15 Aug 2001 09:09:34 -0000 1.22 +++ cp.1 4 Feb 2002 02:18:46 -0000 @@ -141,7 +141,8 @@ Cause .Nm to preserve in the copy as many of the modification time, access time, -file flags, file mode, user ID, and group ID as allowed by permissions. +file flags, file mode, user ID, group ID, and extended ACL entries as +allowed by permissions. .Pp If the user ID and group ID cannot be preserved, no error message is displayed and the exit value is not altered. @@ -231,6 +232,7 @@ .Xr mv 1 , .Xr rcp 1 , .Xr umask 2 , +.Xr acl 3 , .Xr fts 3 , .Xr symlink 7 .Sh STANDARDS Index: cp.c =================================================================== RCS file: /home/ncvs/src/bin/cp/cp.c,v retrieving revision 1.31 diff -u -r1.31 cp.c --- cp.c 2 Feb 2002 06:15:22 -0000 1.31 +++ cp.c 4 Feb 2002 02:18:46 -0000 @@ -238,6 +238,9 @@ int copy(char *argv[], enum op type, int fts_options) { +#ifdef WANT_ACL + acl_t *acl; +#endif struct stat to_stat; FTS *ftsp; FTSENT *curr; @@ -341,9 +344,19 @@ * honour setuid, setgid and sticky bits, but we * normally want to preserve them on directories. */ - if (pflag) - rval = setfile(curr->fts_statp, 0); - else { + if (pflag) { +#ifdef WANT_ACL + acl = getacls(curr); + rval = setfile(curr->fts_statp, acl, 0); + if (acl[0] != NULL) + acl_free(acl[0]); + if (acl[1] != NULL) + acl_free(acl[1]); + free(acl); +#else + rval = setfile(curr->fts_statp, NULL, 0); +#endif /* WANT_ACL */ + } else { mode = curr->fts_statp->st_mode; if ((mode & (S_ISUID | S_ISGID | S_ISTXT)) || ((mode | S_IRWXU) & mask) != (mode & mask)) Index: extern.h =================================================================== RCS file: /home/ncvs/src/bin/cp/extern.h,v retrieving revision 1.12 diff -u -r1.12 extern.h --- extern.h 2 Feb 2002 06:15:22 -0000 1.12 +++ extern.h 4 Feb 2002 02:18:46 -0000 @@ -43,13 +43,23 @@ extern PATH_T to; extern int iflag, pflag, fflag, vflag; +#ifdef WANT_ACL +#include +#include +#else #include +#endif __BEGIN_DECLS int copy_fifo(struct stat *, int); int copy_file(FTSENT *, int); int copy_link(FTSENT *, int); int copy_special(struct stat *, int); +#ifdef WANT_ACL +acl_t *getacls (FTSENT *); +int setfile (struct stat *, acl_t *, int); +#else int setfile(struct stat *, int); +#endif void usage(void); __END_DECLS Index: utils.c =================================================================== RCS file: /home/ncvs/src/bin/cp/utils.c,v retrieving revision 1.33 diff -u -r1.33 utils.c --- utils.c 2 Feb 2002 06:15:22 -0000 1.33 +++ utils.c 4 Feb 2002 02:18:46 -0000 @@ -58,9 +58,41 @@ #include "extern.h" +#ifdef WANT_ACL +acl_t * +getacls(entp) + FTSENT *entp; +{ + acl_t *acl; + + acl = malloc(sizeof(acl_t) * 2); + if (acl == NULL) + err(1, "malloc"); + + acl[0] = NULL; + acl[1] = NULL; + + /* retrieve the access ACL */ + acl[0] = acl_get_file(entp->fts_path, ACL_TYPE_ACCESS); + if (acl[0] == NULL && errno != EOPNOTSUPP) + warn("%s", entp->fts_path); + if (S_ISDIR(entp->fts_statp->st_mode)) { + /* retrieve the default ACL */ + acl[1] = acl_get_file(entp->fts_path, ACL_TYPE_DEFAULT); + if (acl[1] == NULL && errno != EOPNOTSUPP) + warn("%s", entp->fts_path); + } + + return (acl); +} +#endif + int copy_file(FTSENT *entp, int dne) { +#ifdef WANT_ACL + acl_t *acl; +#endif static char buf[MAXBSIZE]; struct stat *fs; int ch, checkch, from_fd, rcount, rval, to_fd, wcount, wresid; @@ -76,6 +108,11 @@ fs = entp->fts_statp; +#ifdef WANT_ACL + /* retrieve the ACL entries */ + acl = getacls(entp); +#endif + /* * If the file exists and we're interactive, verify with the user. * If the file DNE, set the mode to be the from file, minus setuid @@ -177,13 +214,24 @@ * to remove it if we created it and its length is 0. */ - if (pflag && setfile(fs, to_fd)) +#ifdef WANT_ACL + if (pflag && setfile(fs, acl, to_fd)) +#else + if (pflag && setfile(fs, NULL, to_fd)) +#endif rval = 1; (void)close(from_fd); if (close(to_fd)) { warn("%s", to.p_path); rval = 1; } +#ifdef WANT_ACL + if (acl[0] != NULL) + acl_free(acl[0]); + if (acl[1] != NULL) + acl_free(acl[1]); + free(acl); +#endif return (rval); } @@ -220,7 +268,7 @@ warn("mkfifo: %s", to.p_path); return (1); } - return (pflag ? setfile(from_stat, 0) : 0); + return (pflag ? setfile(from_stat, NULL, 0) : 0); } int @@ -234,14 +282,18 @@ warn("mknod: %s", to.p_path); return (1); } - return (pflag ? setfile(from_stat, 0) : 0); + return (pflag ? setfile(from_stat, NULL, 0) : 0); } #define RETAINBITS \ (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) int -setfile(struct stat *fs, int fd) +#ifdef WANT_ACL +setfile(struct stat *fs, acl_t *acl, int fd) +#else +setfile(struct stat *fs, void *acl, int fd) +#endif { static struct timeval tv[2]; struct stat ts; @@ -280,6 +332,23 @@ } fs->st_mode &= ~(S_ISUID | S_ISGID); } + +#ifdef WANT_ACL + if (acl != NULL && acl[0] != NULL) { + if (acl_set_file(to.p_path, ACL_TYPE_ACCESS, acl[0]) == -1 && + errno != EOPNOTSUPP) { + warn("acl_set_file(): %s", to.p_path); + rval = 1; + } + } + if (acl != NULL && acl[1] != NULL) { + if (acl_set_file(to.p_path, ACL_TYPE_ACCESS, acl[1]) == -1 && + errno != EOPNOTSUPP) { + warn("acl_set_file(): %s", to.p_path); + rval = 1; + } + } +#endif if (!gotstat || fs->st_mode != ts.st_mode) if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {