]> git.pld-linux.org Git - packages/coreutils.git/blame - coreutils-acl-0.8.25.patch
- release 2
[packages/coreutils.git] / coreutils-acl-0.8.25.patch
CommitLineData
e570ca16
AM
1diff -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
13diff -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+
248diff -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);
266diff -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 \
277diff -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+])
300diff -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 }
597diff -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;
610diff -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)
797diff -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;
808diff -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);
836diff -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;
852diff -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.
862diff -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'
869diff -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
899diff -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
989diff -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; }'
995diff -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.206061 seconds and 4 git commands to generate.