]> git.pld-linux.org Git - packages/coreutils.git/blob - coreutils-acl-0.8.25.patch
- release 2
[packages/coreutils.git] / coreutils-acl-0.8.25.patch
1 diff -urN coreutils-4.5.10.org/configure.ac coreutils-4.5.10/configure.ac
2 --- coreutils-4.5.10.org/configure.ac   Mon Mar 24 16:29:50 2003
3 +++ coreutils-4.5.10/configure.ac       Mon Mar 24 16:31:35 2003
4 @@ -257,6 +257,8 @@
5  AM_GNU_GETTEXT([external], [need-ngettext])
6  AM_GNU_GETTEXT_VERSION(0.11.5)
7  
8 +ag_POSIX_ACL
9 +
10  # just in case we want PAM
11  AC_SUBST(LIB_PAM)
12  # with PAM su doesn't need libcrypt
13 diff -urN coreutils-4.5.10.org/lib/acl.c coreutils-4.5.10/lib/acl.c
14 --- coreutils-4.5.10.org/lib/acl.c      Mon Mar 24 16:29:46 2003
15 +++ coreutils-4.5.10/lib/acl.c  Mon Mar 24 16:30:58 2003
16 @@ -22,6 +22,13 @@
17  # include <config.h>
18  #endif
19  
20 +#if ENABLE_NLS
21 +# include <libintl.h>
22 +# define _(Text) gettext (Text)
23 +#else
24 +# define _(Text) Text
25 +#endif
26 +
27  #include <sys/stat.h>
28  #ifndef S_ISLNK
29  # define S_ISLNK(Mode) 0
30 @@ -33,6 +40,9 @@
31  #ifndef ENOSYS
32  # define ENOSYS (-1)
33  #endif
34 +#ifndef ENOTSUP
35 +# define ENOTSUP (-1)
36 +#endif
37  
38  #ifndef MIN_ACL_ENTRIES
39  # define MIN_ACL_ENTRIES 4
40 @@ -44,19 +54,201 @@
41  int
42  file_has_acl (char const *path, struct stat const *pathstat)
43  {
44 -  /* FIXME: This implementation should work on recent-enough versions
45 -     of HP-UX, Solaris, and Unixware, but it simply returns 0 with
46 -     POSIX 1003.1e (draft 17 -- abandoned), AIX, GNU/Linux, Irix, and
47 -     Tru64.  Please see Samba's source/lib/sysacls.c file for
48 -     fix-related ideas.  */
49 -
50  #if HAVE_ACL && defined GETACLCNT
51 +  /* This implementation should work on recent-enough versions of HP-UX,
52 +     Solaris, and Unixware.  */
53 +
54    if (! S_ISLNK (pathstat->st_mode))
55      {
56        int n = acl (path, GETACLCNT, 0, NULL);
57        return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n);
58      }
59 +#elif HAVE_ACL_EXTENDED_FILE
60 +
61 +  /* Linux specific.  */
62 +
63 +  if (! S_ISLNK (pathstat->st_mode))
64 +    {
65 +      int ret = acl_extended_file (path);
66 +      if (ret < 0)
67 +       return (errno == ENOSYS || errno == ENOTSUP) ? 0 : -1;
68 +      return ret;
69 +    }
70 +#else
71 +  /* FIXME: Add support for AIX, Irix, and Tru64, FreeBSD, etc.
72 +     Please see Samba's source/lib/sysacls.c file for fix-related ideas.  */
73 +#endif
74 +
75 +  return 0;
76 +}
77 +
78 +/* Copy the permissions from SRC_PATH to DST_PATH, including access control
79 +   lists on systems where this is supported. MODE is the file mode for
80 +   DST_PATH, including the file type.
81 +   Also sets special bits in MODE on DST_PATH.  */
82 +
83 +int
84 +copy_acl (char const *src_path, char const *dst_path, mode_t mode)
85 +{
86 +#if HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && HAVE_ACL_FREE && \
87 +    HAVE_ACL_ENTRIES
88 +
89 +  /* Linux specific. Will work on all POSIX 1003.1e draft 17 (abandoned)
90 +     compliant systems if the acl_entries() function is implemented.  */
91 +
92 +  acl_t acl = acl_get_file (src_path, ACL_TYPE_ACCESS);
93 +  if (acl == NULL)
94 +    {
95 +      if (errno == ENOSYS || errno == ENOTSUP)
96 +       return set_acl (dst_path, mode);
97 +      else
98 +        {
99 +         error (0, errno, "%s", quote (src_path));
100 +         return -1;
101 +       }
102 +    }
103 +
104 +  if (acl_set_file (dst_path, ACL_TYPE_ACCESS, acl))
105 +    {
106 +      int saved_errno = errno;
107 +
108 +      if (errno == ENOSYS || errno == ENOTSUP)
109 +        {
110 +         int n = acl_entries (acl);
111 +
112 +         acl_free (acl);
113 +         if (n == 3)
114 +           {
115 +             if (chmod (dst_path, mode))
116 +               saved_errno = errno;
117 +             else
118 +               return 0;
119 +           }
120 +         else
121 +           chmod (dst_path, mode);
122 +       }
123 +      else
124 +       {
125 +         acl_free (acl);
126 +         chmod (dst_path, mode);
127 +       }
128 +      error (0, saved_errno, _("preserving permissions for %s"),
129 +            quote (dst_path));
130 +      return -1;
131 +    }
132 +  acl_free (acl);
133 +
134 +  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
135 +    {
136 +      /* We did not call chmod so far, so the special bits have not yet
137 +         been set.  */
138 +
139 +      if (chmod (dst_path, mode))
140 +       {
141 +         error (0, errno, _("preserving permissions for %s"),
142 +                quote (dst_path));
143 +         return -1;
144 +       }
145 +    }
146 +
147 +  if (S_ISDIR (mode))
148 +    {
149 +      acl = acl_get_file (src_path, ACL_TYPE_DEFAULT);
150 +      if (acl == NULL)
151 +       {
152 +         error (0, errno, "%s", quote (src_path));
153 +         return -1;
154 +       }
155 +
156 +      if (acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl))
157 +       {
158 +         error (0, errno, _("preserving permissions for %s"),
159 +                quote (dst_path));
160 +         acl_free(acl);
161 +         return -1;
162 +       }
163 +      else
164 +        acl_free(acl);
165 +    }
166 +  return 0;
167 +#else
168 +  int ret = chmod (dst_path, mode);
169 +  if (ret)
170 +    error (0, errno, _("preserving permissions for %s"), quote (dst_path));
171 +  return ret;
172  #endif
173 +}
174 +
175 +/* Set the permissions of PATH, overwriting access control lists, on systems
176 +   where this is supported. MODE is the file mode for PATH, including the
177 +   file type. Also sets special bits in MODE on PATH.  */
178  
179 +int
180 +set_acl (char const *path, mode_t mode)
181 +{
182 +#if HAVE_ACL_FROM_TEXT && HAVE_ACL_SET_FILE && HAVE_ACL_FREE && \
183 +       HAVE_ACL_DELETE_DEF_FILE
184 +  char acl_text[] = "u::---,g::---,o::---";
185 +  acl_t acl;
186 +
187 +  if (mode & S_IRUSR) acl_text[ 3] = 'r';
188 +  if (mode & S_IWUSR) acl_text[ 4] = 'w';
189 +  if (mode & S_IXUSR) acl_text[ 5] = 'x';
190 +  if (mode & S_IRGRP) acl_text[10] = 'r';
191 +  if (mode & S_IWGRP) acl_text[11] = 'w';
192 +  if (mode & S_IXGRP) acl_text[12] = 'x';
193 +  if (mode & S_IROTH) acl_text[17] = 'r';
194 +  if (mode & S_IWOTH) acl_text[18] = 'w';
195 +  if (mode & S_IXOTH) acl_text[19] = 'x';
196 +
197 +  acl = acl_from_text(acl_text);
198 +  if (!acl)
199 +    {
200 +      error (0, errno, "%s", quote (path));
201 +      return -1;
202 +    }
203 +
204 +  if (acl_set_file(path, ACL_TYPE_ACCESS, acl))
205 +    {
206 +      int saved_errno = errno;
207 +      acl_free (acl);
208 +
209 +      if (errno == ENOTSUP || errno == ENOSYS)
210 +       {
211 +         if (chmod (path, mode))
212 +           saved_errno = errno;
213 +         else
214 +           return 0;
215 +       }
216 +      error (0, saved_errno, _("setting permissions for %s"), quote (path));
217 +      return -1;
218 +    }
219 +  acl_free (acl);
220 +
221 +  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
222 +    {
223 +      /* We did not call chmod so far, so the special bits have not yet
224 +         been set.  */
225 +
226 +      if (chmod (path, mode))
227 +       {
228 +         error (0, errno, _("preserving permissions for %s"),
229 +                quote (path));
230 +         return -1;
231 +       }
232 +    }
233 +
234 +  if (S_ISDIR (mode) && acl_delete_def_file (path))
235 +    {
236 +      error (0, errno, _("setting permissions for %s"), quote (path));
237 +      return -1;
238 +    }
239    return 0;
240 +#else
241 +  int ret = chmod (path, mode);
242 +  if (ret)
243 +    error (0, errno, _("setting permissions for %s"), quote (path));
244 +  return ret;
245 +#endif
246  }
247 +
248 diff -urN coreutils-4.5.10.org/lib/acl.h coreutils-4.5.10/lib/acl.h
249 --- coreutils-4.5.10.org/lib/acl.h      Mon Mar 24 16:29:46 2003
250 +++ coreutils-4.5.10/lib/acl.h  Mon Mar 24 16:30:58 2003
251 @@ -18,7 +18,7 @@
252  
253     Written by Paul Eggert.  */
254  
255 -#if HAVE_SYS_ACL_H && HAVE_ACL
256 +#if HAVE_SYS_ACL_H
257  # include <sys/acl.h>
258  #endif
259  #if ! defined GETACLCNT && defined ACL_CNT
260 @@ -26,3 +26,5 @@
261  #endif
262  
263  int file_has_acl (char const *, struct stat const *);
264 +int copy_acl (char const *, char const *, mode_t);
265 +int set_acl (char const *, mode_t);
266 diff -urN coreutils-4.5.10.org/m4/Makefile.am coreutils-4.5.10/m4/Makefile.am
267 --- coreutils-4.5.10.org/m4/Makefile.am Mon Mar 24 16:29:47 2003
268 +++ coreutils-4.5.10/m4/Makefile.am     Mon Mar 24 16:30:58 2003
269 @@ -62,6 +62,7 @@
270  onceonly.m4 \
271  open-max.m4 \
272  perl.m4 \
273 +posix_acl.m4 \
274  prereq.m4 \
275  progtest.m4 \
276  putenv.m4 \
277 diff -urN coreutils-4.5.10.org/m4/posix_acl.m4 coreutils-4.5.10/m4/posix_acl.m4
278 --- coreutils-4.5.10.org/m4/posix_acl.m4        Thu Jan  1 01:00:00 1970
279 +++ coreutils-4.5.10/m4/posix_acl.m4    Mon Mar 24 16:30:58 2003
280 @@ -0,0 +1,19 @@
281 +#serial 1
282 +
283 +dnl Written by Andreas Gruenbacher <a.gruenbacher@computer.org>.
284 +
285 +dnl Posix 1003.1e draft standard 17 (abandoned) and similar
286 +dnl access control list support
287 +AC_DEFUN([ag_POSIX_ACL],
288 +[
289 +  AC_CHECK_HEADERS(sys/acl.h)
290 +  AC_CHECK_LIB(acl, main)
291 +  AC_CHECK_FUNCS(acl_get_file acl_set_file acl_free acl_to_text \
292 +                 acl_from_text acl_delete_def_file)
293 +  # Linux specific extensions:
294 +  AC_CHECK_FUNCS(acl_entries acl_extended_file)
295 +
296 +  if test $ac_cv_header_sys_acl_h = yes; then
297 +    AC_DEFINE(USE_ACL, 1, [Define if you want access control list support.])
298 +  fi
299 +])
300 diff -urN coreutils-4.5.10.org/src/copy.c coreutils-4.5.10/src/copy.c
301 --- coreutils-4.5.10.org/src/copy.c     Mon Mar 24 16:29:46 2003
302 +++ coreutils-4.5.10/src/copy.c Mon Mar 24 16:30:58 2003
303 @@ -99,26 +99,6 @@
304  /* The invocation name of this program.  */
305  extern char *program_name;
306  
307 -/* Encapsulate selection of the file mode to be applied to
308 -   new non-directories.  */
309 -
310 -static mode_t
311 -get_dest_mode (const struct cp_options *option, mode_t mode)
312 -{
313 -  /* In some applications (e.g., install), use precisely the
314 -     specified mode.  */
315 -  if (option->set_mode)
316 -    return option->mode;
317 -
318 -  /* Honor the umask for `cp', but not for `mv' or `cp -p'.
319 -     In addition, `cp' without -p must clear the set-user-ID and set-group-ID
320 -     bits.  POSIX requires it do that when creating new files.  */
321 -  if (!option->move_mode && !option->preserve_mode)
322 -    mode &= (option->umask_kill & ~(S_ISUID | S_ISGID));
323 -
324 -  return mode;
325 -}
326 -
327  /* FIXME: describe */
328  /* FIXME: rewrite this to use a hash table so we avoid the quadratic
329     performance hit that's probably noticeable only on trees deeper
330 @@ -792,13 +772,13 @@
331    struct stat src_sb;
332    struct stat dst_sb;
333    mode_t src_mode;
334 -  mode_t src_type;
335 +  mode_t dst_mode;
336    char *earlier_file = NULL;
337    char *dst_backup = NULL;
338    int backup_succeeded = 0;
339    int delayed_fail;
340    int copied_as_regular = 0;
341 -  int ran_chown = 0;
342 +  int dst_mode_valid = 0;
343    int preserve_metadata;
344  
345    if (x->move_mode && rename_succeeded)
346 @@ -811,11 +791,9 @@
347        return 1;
348      }
349  
350 -  src_type = src_sb.st_mode;
351 -
352    src_mode = src_sb.st_mode;
353  
354 -  if (S_ISDIR (src_type) && !x->recursive)
355 +  if (S_ISDIR (src_mode) && !x->recursive)
356      {
357        error (0, 0, _("omitting directory %s"), quote (src_path));
358        return 1;
359 @@ -870,7 +848,7 @@
360  
361           if (!S_ISDIR (dst_sb.st_mode))
362             {
363 -             if (S_ISDIR (src_type))
364 +             if (S_ISDIR (src_mode))
365                 {
366                   error (0, 0,
367                      _("cannot overwrite non-directory %s with directory %s"),
368 @@ -896,7 +874,7 @@
369                 }
370             }
371  
372 -         if (!S_ISDIR (src_type))
373 +         if (!S_ISDIR (src_mode))
374             {
375               if (S_ISDIR (dst_sb.st_mode))
376                 {
377 @@ -924,7 +902,7 @@
378              This may be due to an interactive `negative' reply to the
379              prompt about the existing file.  It may also be due to the
380              use of the --reply=no option.  */
381 -         if (!S_ISDIR (src_type))
382 +         if (!S_ISDIR (src_mode))
383             {
384               /* cp and mv treat -i and -f differently.  */
385               if (x->move_mode)
386 @@ -1042,7 +1020,7 @@
387    /* If the source is a directory, we don't always create the destination
388       directory.  So --verbose should not announce anything until we're
389       sure we'll create a directory. */
390 -  if (x->verbose && !S_ISDIR (src_type))
391 +  if (x->verbose && !S_ISDIR (src_mode))
392      {
393        printf ("%s -> %s", quote_n (0, src_path), quote_n (1, dst_path));
394        if (backup_succeeded)
395 @@ -1077,7 +1055,7 @@
396            || (command_line_arg
397                && x->dereference == DEREF_COMMAND_LINE_ARGUMENTS)
398            || x->dereference == DEREF_ALWAYS))
399 -      || (x->recursive && S_ISDIR (src_type)))
400 +      || (x->recursive && S_ISDIR (src_mode)))
401      {
402        earlier_file = remember_copied (dst_path, src_sb.st_ino, src_sb.st_dev);
403      }
404 @@ -1090,7 +1068,7 @@
405        /* Avoid damaging the destination filesystem by refusing to preserve
406          hard-linked directories (which are found at least in Netapp snapshot
407          directories).  */
408 -      if (S_ISDIR (src_type))
409 +      if (S_ISDIR (src_mode))
410         {
411           /* If src_path and earlier_file refer to the same directory entry,
412              then warn about copying a directory into itself.  */
413 @@ -1142,7 +1120,7 @@
414      {
415        if (rename (src_path, dst_path) == 0)
416         {
417 -         if (x->verbose && S_ISDIR (src_type))
418 +         if (x->verbose && S_ISDIR (src_mode))
419             printf ("%s -> %s\n", quote_n (0, src_path), quote_n (1, dst_path));
420           if (rename_succeeded)
421             *rename_succeeded = 1;
422 @@ -1255,7 +1233,7 @@
423       In such cases, set this variable to zero.  */
424    preserve_metadata = 1;
425  
426 -  if (S_ISDIR (src_type))
427 +  if (S_ISDIR (src_mode))
428      {
429        struct dir_list *dir;
430  
431 @@ -1280,16 +1258,38 @@
432  
433        if (new_dst || !S_ISDIR (dst_sb.st_mode))
434         {
435 -         /* Create the new directory writable and searchable, so
436 -             we can create new entries in it.  */
437 -
438 -         if (mkdir (dst_path, (src_mode & x->umask_kill) | S_IRWXU))
439 +         if (mkdir (dst_path, src_mode))
440             {
441               error (0, errno, _("cannot create directory %s"),
442                      quote (dst_path));
443               goto un_backup;
444             }
445  
446 +         /* We need search and write permissions to the new directory
447 +            for adding the directory's contents. Check if these permissions
448 +            are already there.  */
449 +
450 +         if (lstat (dst_path, &dst_sb))
451 +           {
452 +             error (0, errno, _("cannot stat %s"), quote (dst_path));
453 +             delayed_fail = 1;
454 +           }
455 +         else if ((dst_sb.st_mode & S_IRWXU) != S_IRWXU)
456 +           {
457 +             /* Make the new directory writable and searchable. The original
458 +                permissions will be restored later.  */
459 +
460 +             dst_mode_valid = 1;
461 +             dst_mode = dst_sb.st_mode;
462 +
463 +             if (chmod (dst_path, dst_mode | S_IRWXU))
464 +               {
465 +                 error (0, errno, _("setting permissions for %s"),
466 +                        quote (dst_path));
467 +                 goto un_backup;
468 +               }
469 +           }
470 +
471           /* Insert the created directory's inode and device
472               numbers into the search structure, so that we can
473               avoid copying it again.  */
474 @@ -1365,10 +1365,10 @@
475           goto un_backup;
476         }
477      }
478 -  else if (S_ISREG (src_type)
479 -          || (x->copy_as_regular && !S_ISDIR (src_type)
480 +  else if (S_ISREG (src_mode)
481 +          || (x->copy_as_regular && !S_ISDIR (src_mode)
482  #ifdef S_ISLNK
483 -              && !S_ISLNK (src_type)
484 +              && !S_ISLNK (src_mode)
485  #endif
486                ))
487      {
488 @@ -1376,15 +1376,14 @@
489        /* POSIX says the permission bits of the source file must be
490          used as the 3rd argument in the open call, but that's not consistent
491          with historical practice.  */
492 -      if (copy_reg (src_path, dst_path, x,
493 -                   get_dest_mode (x, src_mode), &new_dst, &src_sb))
494 +      if (copy_reg (src_path, dst_path, x, src_mode, &new_dst, &src_sb))
495         goto un_backup;
496      }
497    else
498  #ifdef S_ISFIFO
499 -  if (S_ISFIFO (src_type))
500 +  if (S_ISFIFO (src_mode))
501      {
502 -      if (mkfifo (dst_path, get_dest_mode (x, src_mode)))
503 +      if (mkfifo (dst_path, src_mode))
504         {
505           error (0, errno, _("cannot create fifo %s"), quote (dst_path));
506           goto un_backup;
507 @@ -1392,13 +1391,13 @@
508      }
509    else
510  #endif
511 -    if (S_ISBLK (src_type) || S_ISCHR (src_type)
512 +    if (S_ISBLK (src_mode) || S_ISCHR (src_mode)
513  #ifdef S_ISSOCK
514 -       || S_ISSOCK (src_type)
515 +       || S_ISSOCK (src_mode)
516  #endif
517         )
518      {
519 -      if (mknod (dst_path, get_dest_mode (x, src_mode), src_sb.st_rdev))
520 +      if (mknod (dst_path, src_mode, src_sb.st_rdev))
521         {
522           error (0, errno, _("cannot create special file %s"),
523                  quote (dst_path));
524 @@ -1407,7 +1406,7 @@
525      }
526    else
527  #ifdef S_ISLNK
528 -  if (S_ISLNK (src_type))
529 +  if (S_ISLNK (src_mode))
530      {
531        char *src_link_val = xreadlink (src_path);
532        if (src_link_val == NULL)
533 @@ -1513,7 +1512,25 @@
534    if (x->preserve_ownership
535        && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb)))
536      {
537 -      ran_chown = 1;
538 +      /* The chown() system call may clear the SUID and SGID bits, so we
539 +         need to set them again later. (But we don't care if we will
540 +        overwrite the permissions of the destination file anyway.)  */
541 +        
542 +      if ((src_mode & (S_ISUID | S_ISGID))
543 +         && !x->preserve_mode && !x->move_mode && !x->set_mode)
544 +       {
545 +         if (lstat (dst_path, &dst_sb))
546 +           {
547 +             error (0, errno, _("cannot stat %s"), quote (dst_path));
548 +             delayed_fail = 1;
549 +           }
550 +         else
551 +           {
552 +             dst_mode_valid = 1;
553 +             dst_mode = dst_sb.st_mode;
554 +           }
555 +       }
556 +
557        if (DO_CHOWN (chown, dst_path, src_sb.st_uid, src_sb.st_gid))
558         {
559           error (0, errno, _("failed to preserve ownership for %s"),
560 @@ -1534,20 +1551,23 @@
561    }
562  #endif
563  
564 -  /* Permissions of newly-created regular files were set upon `open' in
565 -     copy_reg.  But don't return early if there were any special bits and
566 -     we had to run chown, because the chown must have reset those bits.  */
567 -  if ((new_dst && copied_as_regular)
568 -      && !(ran_chown && (src_mode & ~S_IRWXUGO)))
569 -    return delayed_fail;
570 -
571 -  if ((x->preserve_mode || new_dst)
572 -      && (x->copy_as_regular || S_ISREG (src_type) || S_ISDIR (src_type)))
573 +  if (x->preserve_mode || x->move_mode)
574      {
575 -      if (chmod (dst_path, get_dest_mode (x, src_mode)))
576 -       {
577 -         error (0, errno, _("setting permissions for %s"), quote (dst_path));
578 -         if (x->set_mode || x->require_preserve)
579 +      if (copy_acl (src_path, dst_path, src_mode) && x->require_preserve)
580 +       return 1;
581 +    }
582 +  else if (x->set_mode)
583 +    {
584 +      if (set_acl (dst_path, x->mode) && x->require_preserve)
585 +       return 1;
586 +    }
587 +  else if (dst_mode_valid)
588 +    {
589 +      if (chmod (dst_path, dst_mode))
590 +        {
591 +         error (0, errno, _("preserving permissions for %s"),
592 +                quote (dst_path));
593 +         if (x->require_preserve)
594             return 1;
595         }
596      }
597 diff -urN coreutils-4.5.10.org/src/copy.h coreutils-4.5.10/src/copy.h
598 --- coreutils-4.5.10.org/src/copy.h     Mon Mar 24 16:29:46 2003
599 +++ coreutils-4.5.10/src/copy.h Mon Mar 24 16:30:58 2003
600 @@ -139,9 +139,6 @@
601       Create destination directories as usual. */
602    int symbolic_link;
603  
604 -  /* The bits to preserve in created files' modes. */
605 -  mode_t umask_kill;
606 -
607    /* If nonzero, do not copy a nondirectory that has an existing destination
608       with the same or newer modification time. */
609    int update;
610 diff -urN coreutils-4.5.10.org/src/cp.c coreutils-4.5.10/src/cp.c
611 --- coreutils-4.5.10.org/src/cp.c       Mon Mar 24 16:29:46 2003
612 +++ coreutils-4.5.10/src/cp.c   Mon Mar 24 16:34:26 2003
613 @@ -61,7 +61,8 @@
614     need to be fixed after copying. */
615  struct dir_attr
616  {
617 -  int is_new_dir;
618 +  int mode_valid;
619 +  mode_t mode;
620    int slash_offset;
621    struct dir_attr *next;
622  };
623 @@ -342,9 +343,14 @@
624             }
625         }
626  
627 -      if (x->preserve_mode || p->is_new_dir)
628 +      if (x->preserve_mode)
629         {
630 -         if (chmod (dst_path, src_sb.st_mode & x->umask_kill))
631 +         if (copy_acl (src_path, dst_path, src_sb.st_mode))
632 +             return 1;
633 +       }
634 +      else if (p->mode_valid)
635 +        {
636 +         if (chmod (dst_path, p->mode))
637             {
638               error (0, errno, _("failed to preserve permissions for %s"),
639                      quote (dst_path));
640 @@ -362,8 +368,7 @@
641  
642     SRC_OFFSET is the index in CONST_DIRPATH (which is a destination
643     path) of the beginning of the source directory name.
644 -   Create any leading directories that don't already exist,
645 -   giving them permissions MODE.
646 +   Create any leading directories that don't already exist.
647     If VERBOSE_FMT_STRING is nonzero, use it as a printf format
648     string for printing a message after successfully making a directory.
649     The format should take two string arguments: the names of the
650 @@ -378,15 +383,16 @@
651  /* FIXME: find a way to synch this function with the one in lib/makepath.c. */
652  
653  static int
654 -make_path_private (const char *const_dirpath, int src_offset, int mode,
655 +make_path_private (const char *const_dirpath, int src_offset,
656                    const char *verbose_fmt_string, struct dir_attr **attr_list,
657 -                  int *new_dst, int (*xstat)())
658 +                  int *new_dst, const struct cp_options *x)
659  {
660    struct stat stats;
661    char *dirpath;               /* A copy of CONST_DIRPATH we can change. */
662    char *src;                   /* Source name in `dirpath'. */
663    char *dst_dirname;           /* Leading path of `dirpath'. */
664    size_t dirlen;               /* Length of leading path of `dirpath'. */
665 +  mode_t mode;
666  
667    dirpath = (char *) alloca (strlen (const_dirpath) + 1);
668    strcpy (dirpath, const_dirpath);
669 @@ -400,7 +406,7 @@
670  
671    *attr_list = NULL;
672  
673 -  if ((*xstat) (dst_dirname, &stats))
674 +  if ((*x->xstat) (dst_dirname, &stats))
675      {
676        /* Parent of CONST_DIRNAME does not exist.
677          Make all missing intermediate directories. */
678 @@ -420,15 +426,23 @@
679           *attr_list = new;
680  
681           *slash = '\0';
682 -         if ((*xstat) (dirpath, &stats))
683 +         if ((*x->xstat) (dirpath, &stats))
684             {
685               /* This element of the path does not exist.  We must set
686 -                *new_dst and new->is_new_dir inside this loop because,
687 +                *new_dst inside this loop because,
688                  for example, in the command `cp --parents ../a/../b/c e_dir',
689                  make_path_private creates only e_dir/../a if ./b already
690                  exists. */
691               *new_dst = 1;
692 -             new->is_new_dir = 1;
693 +
694 +             if ((*x->xstat) (src, &stats))
695 +               {
696 +                 error (0, errno, _("failed to get attributes of %s"),
697 +                        quote (src));
698 +                 return 1;
699 +               }
700 +             mode = stats.st_mode;
701 +
702               if (mkdir (dirpath, mode))
703                 {
704                   error (0, errno, _("cannot make directory %s"),
705 @@ -440,6 +454,46 @@
706                   if (verbose_fmt_string != NULL)
707                     printf (verbose_fmt_string, src, dirpath);
708                 }
709 +
710 +             /* We need search and write permissions to the new directory
711 +                for adding the directory's contents. Check if these
712 +                permissions are already there.  */
713 +
714 +             if (lstat (dirpath, &stats))
715 +               {
716 +                 error (0, errno, _("failed to get attributes of %s"),
717 +                        quote (dirpath));
718 +                 return 1;
719 +               }
720 +             else
721 +               {
722 +                 if (x->preserve_mode && mode != stats.st_mode)
723 +                   {
724 +                     new->mode = mode;
725 +                     new->mode_valid = 1;
726 +                   }
727 +                 else
728 +                   new->mode_valid = 0;
729 +
730 +                 if ((stats.st_mode & S_IRWXU) != S_IRWXU)
731 +                   {
732 +                     /* Make the new directory writable and searchable. The
733 +                        original permissions will be restored later.  */
734 +
735 +                     if (!new->mode_valid)
736 +                       {
737 +                         new->mode = stats.st_mode;
738 +                         new->mode_valid = 1;
739 +                       }
740 +
741 +                     if (chmod (dirpath, stats.st_mode | S_IRWXU))
742 +                       {
743 +                         error (0, errno, _("setting permissions for %s"),
744 +                                quote (dirpath));
745 +                         return 1;
746 +                       }
747 +                   }
748 +               }
749             }
750           else if (!S_ISDIR (stats.st_mode))
751             {
752 @@ -449,7 +503,7 @@
753             }
754           else
755             {
756 -             new->is_new_dir = 0;
757 +             new->mode_valid = 0;
758               *new_dst = 0;
759             }
760           *slash++ = '/';
761 @@ -600,11 +654,9 @@
762                  leading directories. */
763               parent_exists = !make_path_private (dst_path,
764                                                   arg_in_concat - dst_path,
765 -                                                 S_IRWXU,
766                                                   (x->verbose
767                                                    ? "%s -> %s\n" : NULL),
768 -                                                 &attr_list, &new_dst,
769 -                                                 x->xstat);
770 +                                                 &attr_list, &new_dst, x);
771             }
772           else
773             {
774 @@ -739,12 +791,6 @@
775    /* Not used.  */
776    x->stdin_tty = 0;
777  
778 -  /* Find out the current file creation mask, to knock the right bits
779 -     when using chmod.  The creation mask is set to be liberal, so
780 -     that created directories can be written, even if it would not
781 -     have been allowed with the mask this process was started with.  */
782 -  x->umask_kill = ~ umask (0);
783 -
784    x->update = 0;
785    x->verbose = 0;
786    x->dest_info = NULL;
787 @@ -1017,9 +1063,6 @@
788                                    version_control_string)
789                    : none);
790  
791 -  if (x.preserve_mode == 1)
792 -    x.umask_kill = ~ (mode_t) 0;
793 -
794    if (x.dereference == DEREF_UNDEFINED)
795      {
796        if (x.recursive)
797 diff -urN coreutils-4.5.10.org/src/install.c coreutils-4.5.10/src/install.c
798 --- coreutils-4.5.10.org/src/install.c  Mon Mar 24 16:29:46 2003
799 +++ coreutils-4.5.10/src/install.c      Mon Mar 24 16:30:58 2003
800 @@ -245,7 +245,6 @@
801    x->mode = S_IRUSR | S_IWUSR;
802    x->stdin_tty = 0;
803  
804 -  x->umask_kill = 0;
805    x->update = 0;
806    x->verbose = 0;
807    x->xstat = stat;
808 diff -urN coreutils-4.5.10.org/src/ls.c coreutils-4.5.10/src/ls.c
809 --- coreutils-4.5.10.org/src/ls.c       Mon Mar 24 16:29:46 2003
810 +++ coreutils-4.5.10/src/ls.c   Mon Mar 24 16:30:58 2003
811 @@ -223,13 +223,13 @@
812  
813      enum filetype filetype;
814  
815 -#if HAVE_ACL
816 +#if HAVE_ACL || USE_ACL
817      /* For long listings, true if the file has an access control list.  */
818      bool have_acl;
819  #endif
820    };
821  
822 -#if HAVE_ACL
823 +#if HAVE_ACL || USE_ACL
824  # define FILE_HAS_ACL(F) ((F)->have_acl)
825  #else
826  # define FILE_HAS_ACL(F) 0
827 @@ -2400,7 +2400,7 @@
828           return 0;
829         }
830  
831 -#if HAVE_ACL
832 +#if HAVE_ACL || USE_ACL
833        if (format == long_format)
834         {
835           int n = file_has_acl (path, &files[files_index].stat);
836 diff -urN coreutils-4.5.10.org/src/mv.c coreutils-4.5.10/src/mv.c
837 --- coreutils-4.5.10.org/src/mv.c       Mon Mar 24 16:29:46 2003
838 +++ coreutils-4.5.10/src/mv.c   Mon Mar 24 16:30:58 2003
839 @@ -137,12 +137,6 @@
840    x->mode = 0;
841    x->stdin_tty = isatty (STDIN_FILENO);
842  
843 -  /* Find out the current file creation mask, to knock the right bits
844 -     when using chmod.  The creation mask is set to be liberal, so
845 -     that created directories can be written, even if it would not
846 -     have been allowed with the mask this process was started with.  */
847 -  x->umask_kill = ~ umask (0);
848 -
849    x->update = 0;
850    x->verbose = 0;
851    x->xstat = lstat;
852 diff -urN coreutils-4.5.10.org/tests/misc/README coreutils-4.5.10/tests/misc/README
853 --- coreutils-4.5.10.org/tests/misc/README      Thu Jan  1 01:00:00 1970
854 +++ coreutils-4.5.10/tests/misc/README  Mon Mar 24 16:30:58 2003
855 @@ -0,0 +1,6 @@
856 +Use the run script to run any of the *.test scripts, e.g.,
857 +
858 +  run cp.test
859 +
860 +The cp.test script can be run as any user; the cp-root
861 +script requires root privileges.
862 diff -urN coreutils-4.5.10.org/tests/misc/acl coreutils-4.5.10/tests/misc/acl
863 --- coreutils-4.5.10.org/tests/misc/acl Thu Jan  1 01:00:00 1970
864 +++ coreutils-4.5.10/tests/misc/acl     Mon Mar 24 16:30:58 2003
865 @@ -0,0 +1,3 @@
866 +#!/bin/sh
867 +
868 +getfacl "$@" | sed -e 's/[     ]*#.*$//' -e '/^$/d'
869 diff -urN coreutils-4.5.10.org/tests/misc/cp-root.test coreutils-4.5.10/tests/misc/cp-root.test
870 --- coreutils-4.5.10.org/tests/misc/cp-root.test        Thu Jan  1 01:00:00 1970
871 +++ coreutils-4.5.10/tests/misc/cp-root.test    Mon Mar 24 16:30:58 2003
872 @@ -0,0 +1,26 @@
873 +! Tests the access control list extensions to cp.
874 +! This script must be run as root.
875 +!
876 +$ rm -rf test
877 +$ mkdir test
878 +$ cd test
879 +$ umask 022
880 +$ touch f
881 +$ chmod u+xs,g+xs f
882 +$ mode f
883 + -rwsr-sr-- f
884 +$ cp -p f g
885 +$ mode g
886 + -rwsr-sr-- g
887 +$ cp f h
888 +$ mode h
889 + -rwsr-sr-- h
890 +$ chown bin h
891 +$ cp h i
892 +$ mode i
893 + -rwsr-sr-- i
894 +!
895 +! cleanup
896 +!
897 +$cd ..
898 +$ rm -rf test
899 diff -urN coreutils-4.5.10.org/tests/misc/cp.test coreutils-4.5.10/tests/misc/cp.test
900 --- coreutils-4.5.10.org/tests/misc/cp.test     Thu Jan  1 01:00:00 1970
901 +++ coreutils-4.5.10/tests/misc/cp.test Mon Mar 24 16:30:58 2003
902 @@ -0,0 +1,86 @@
903 +! Tests the access control list extensions to cp (and also of ls).
904 +! Requires a system with POSIX access control lists and the
905 +! getfacl and setfacl utilities.
906 +!
907 +$ rm -rf test
908 +$ mkdir test
909 +$ cd test
910 +$ umask 022
911 +$ touch f
912 +$ mode . f
913 + drwxr-xr-x .
914 + -rw-r--r-- f
915 +$ setfacl -m u:@OWNER@:rw- f
916 +$ mode f
917 + -rw-rw-r--+ f
918 +$ acl f
919 + user::rw-
920 + user:@OWNER@:rw-
921 + group::r--
922 + mask::rw-
923 + other::r--
924 +!
925 +! cp and cp -p
926 +!
927 +$ cp f g
928 +$ cp -p f h
929 +$ mode g h
930 + -rw-r--r-- g
931 + -rw-rw-r--+ h
932 +$ acl h
933 + user::rw-
934 + user:@OWNER@:rw-
935 + group::r--
936 + mask::rw-
937 + other::r--
938 +$ mkdir d
939 +$ setfacl -d -m u::rwx,u:@OWNER@:r-x,g::---,m::r-x,o::--- d
940 +$ acl d
941 + user::rwx
942 + group::r-x
943 + other::r-x
944 + default:user::rwx
945 + default:user:@OWNER@:r-x
946 + default:group::---
947 + default:mask::r-x
948 + default:other::---
949 +$ touch d/i
950 +$ acl d/i
951 + user::rw-
952 + user:@OWNER@:r-x
953 + group::---
954 + mask::r--
955 + other::---
956 +$ cp f d/f
957 +$ acl d/f
958 + user::rw-
959 + user:@OWNER@:r-x
960 + group::---
961 + mask::r--
962 + other::---
963 +$ chmod go-rwx g
964 +$ cp g d/g
965 +$ acl d/g
966 + user::rw-
967 + user:@OWNER@:r-x
968 + group::---
969 + mask::---
970 + other::---
971 +$ cp -p h d/h
972 +$ acl h
973 + user::rw-
974 + user:@OWNER@:rw-
975 + group::r--
976 + mask::rw-
977 + other::r--
978 +$ touch j
979 +$ cp -p j d/j
980 +$ mode d/j
981 + -rw-r--r-- d/j
982 +$ 
983 +! mv
984 +!
985 +! cleanup
986 +!
987 +$cd ..
988 +$ rm -rf test
989 diff -urN coreutils-4.5.10.org/tests/misc/mode coreutils-4.5.10/tests/misc/mode
990 --- coreutils-4.5.10.org/tests/misc/mode        Thu Jan  1 01:00:00 1970
991 +++ coreutils-4.5.10/tests/misc/mode    Mon Mar 24 16:30:58 2003
992 @@ -0,0 +1,2 @@
993 +#!/bin/sh
994 +ls -dl $* | awk -- '!/^total/ { print $1, $8; }'
995 diff -urN coreutils-4.5.10.org/tests/misc/run coreutils-4.5.10/tests/misc/run
996 --- coreutils-4.5.10.org/tests/misc/run Thu Jan  1 01:00:00 1970
997 +++ coreutils-4.5.10/tests/misc/run     Mon Mar 24 16:30:58 2003
998 @@ -0,0 +1,164 @@
999 +#!/usr/bin/perl
1000 +
1001 +use strict;
1002 +use FileHandle;
1003 +use POSIX qw(geteuid getegid isatty);
1004 +
1005 +my $pwd = `pwd`;
1006 +chomp $pwd;
1007 +$ENV{'PATH'} = $pwd . ":../../src:" . $ENV{'PATH'};
1008 +
1009 +my $owner = getpwuid(geteuid());
1010 +my $group = getgrgid(getegid());
1011 +
1012 +my ($OK, $FAILED) = ("ok", "failed");
1013 +if (isatty(fileno(STDOUT))) {
1014 +       $OK = "\033[32m" . $OK . "\033[m";
1015 +       $FAILED = "\033[31m\033[1m" . $FAILED . "\033[m";
1016 +}
1017 +
1018 +my ($prog, $in, $out) = ([], [], []);
1019 +my $line = 0;
1020 +my $prog_line;
1021 +my ($tests, $failed);
1022 +
1023 +for (;;) {
1024 +  my $script = <>; $line++;
1025 +  $script =~ s/\@OWNER\@/$owner/g;
1026 +  $script =~ s/\@GROUP\@/$group/g;
1027 +  next if (defined($script) && $script =~ /^!/);
1028 +  if (!defined($script) || $script =~ s/^\$ ?//) {
1029 +    if (@$prog) {
1030 +       #print "[$prog_line] \$ ", join(' ', @$prog), " -- ";
1031 +       my $p = [ @$prog ];
1032 +       print "[$prog_line] \$ ", join(' ',
1033 +             map { s/\s/\\$&/g; $_ } @$p), " -- ";
1034 +       my $result = exec_test($prog, $in);
1035 +       my $good = 1;
1036 +       my $nmax = (@$out > @$result) ? @$out : @$result;
1037 +       for (my $n=0; $n < $nmax; $n++) {
1038 +        if (!defined($out->[$n]) || !defined($result->[$n]) ||
1039 +            $out->[$n] ne $result->[$n]) {
1040 +                $good = 0;
1041 +                #chomp $out->[$n];
1042 +                #chomp $result->[$n];
1043 +                #print "$out->[$n] != $result->[$n]";
1044 +        }
1045 +       }
1046 +       $tests++;
1047 +       $failed++ unless $good;
1048 +       print $good ? $OK : $FAILED, "\n";
1049 +       if (!$good) {
1050 +         for (my $n=0; $n < $nmax; $n++) {
1051 +          my $l = defined($out->[$n]) ? $out->[$n] : "~";
1052 +          chomp $l;
1053 +          my $r = defined($result->[$n]) ? $result->[$n] : "~";
1054 +          chomp $r;
1055 +          print sprintf("%-37s | %-39s\n", $l, $r);
1056 +         }
1057 +       }
1058 +    }
1059 +    #$prog = [ split /\s+/, $script ] if $script;
1060 +    $prog = [ map { s/\\(.)/$1/g; $_ } split /(?<!\\)\s+/, $script ] if $script;
1061 +    $prog_line = $line;
1062 +    $in = [];
1063 +    $out = [];
1064 +  } elsif ($script =~ s/^> ?//) {
1065 +    push @$in, $script;
1066 +  } else {
1067 +    $script =~ s/^[ \t]*//;  # ignore leading whitespace
1068 +    push @$out, $script;
1069 +  }
1070 +  last unless defined($script);
1071 +}
1072 +my $status = sprintf("%d commands (%d passed, %d failed)",
1073 +       $tests, $tests-$failed, $failed);
1074 +if (isatty(fileno(STDOUT))) {
1075 +       if ($failed) {
1076 +               $status = "\033[31m\033[1m" . $status . "\033[m";
1077 +       } else {
1078 +               $status = "\033[32m" . $status . "\033[m";
1079 +       }
1080 +}
1081 +print $status, "\n";
1082 +
1083 +sub exec_test($$) {
1084 +  my ($prog, $in) = @_;
1085 +  local (*IN, *IN_DUP, *IN2, *OUT_DUP, *OUT, *OUT2);
1086 +
1087 +  if ($prog->[0] eq "umask") {
1088 +    umask oct $prog->[1];
1089 +    return [];
1090 +  } elsif ($prog->[0] eq "cd") {
1091 +    if (!chdir $prog->[1]) {
1092 +      return [ "chdir: $prog->[1]: $!\n" ];
1093 +    }
1094 +    return [];
1095 +  }
1096 +
1097 +  pipe *IN2, *OUT
1098 +    or die "Can't create pipe for reading: $!";
1099 +  open *IN_DUP, "<&STDIN"
1100 +    or *IN_DUP = undef;
1101 +  open *STDIN, "<&IN2"
1102 +    or die "Can't duplicate pipe for reading: $!";
1103 +  close *IN2;
1104 +
1105 +  open *OUT_DUP, ">&STDOUT"
1106 +    or die "Can't duplicate STDOUT: $!";
1107 +  pipe *IN, *OUT2
1108 +    or die "Can't create pipe for writing: $!";
1109 +  open *STDOUT, ">&OUT2"
1110 +    or die "Can't duplicate pipe for writing: $!";
1111 +  close *OUT2;
1112 +
1113 +  *STDOUT->autoflush();
1114 +  *OUT->autoflush();
1115 +
1116 +  if (fork()) {
1117 +    # Server
1118 +    if (*IN_DUP) {
1119 +      open *STDIN, "<&IN_DUP"
1120 +        or die "Can't duplicate STDIN: $!";
1121 +      close *IN_DUP
1122 +        or die "Can't close STDIN duplicate: $!";
1123 +    }
1124 +    open *STDOUT, ">&OUT_DUP"
1125 +      or die "Can't duplicate STDOUT: $!";
1126 +    close *OUT_DUP
1127 +      or die "Can't close STDOUT duplicate: $!";
1128 +
1129 +    foreach my $line (@$in) {
1130 +      #print "> $line";
1131 +      print OUT $line;
1132 +    }
1133 +    close *OUT
1134 +      or die "Can't close pipe for writing: $!";
1135 +
1136 +    my $result = [];
1137 +    while (<IN>) {
1138 +      #print "< $_";
1139 +      push @$result, $_;
1140 +    }
1141 +    return $result;
1142 +  } else {
1143 +    # Client
1144 +    close IN
1145 +      or die "Can't close read end for input pipe: $!";
1146 +    close OUT
1147 +      or die "Can't close write end for output pipe: $!";
1148 +    close OUT_DUP
1149 +      or die "Can't close STDOUT duplicate: $!";
1150 +    local *ERR_DUP;
1151 +    open ERR_DUP, ">&STDERR"
1152 +      or die "Can't duplicate STDERR: $!";
1153 +    open STDERR, ">&STDOUT"
1154 +      or die "Can't join STDOUT and STDERR: $!";
1155 +
1156 +    #print ERR_DUP "<", join(' ', @$prog), ">\n";
1157 +    exec @$prog;
1158 +    print ERR_DUP $prog->[0], ": $!\n";
1159 +    exit;
1160 +  }
1161 +}
1162 +
This page took 0.119331 seconds and 3 git commands to generate.