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