mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1118 lines
33 KiB

  1. # --- ROCK-COPYRIGHT-NOTE-BEGIN ---
  2. #
  3. # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  4. # Please add additional copyright information _after_ the line containing
  5. # the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
  6. # the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
  7. #
  8. # ROCK Linux: rock-src/package/base/coreutils/acl-xattr.diff
  9. # ROCK Linux is Copyright (C) 1998 - 2003 Clifford Wolf
  10. #
  11. # This program is free software; you can redistribute it and/or modify
  12. # it under the terms of the GNU General Public License as published by
  13. # the Free Software Foundation; either version 2 of the License, or
  14. # (at your option) any later version. A copy of the GNU General Public
  15. # License can be found at Documentation/COPYING.
  16. #
  17. # Many people helped and are helping developing ROCK Linux. Please
  18. # have a look at http://www.rocklinux.org/ and the Documentation/TEAM
  19. # file for details.
  20. #
  21. # --- ROCK-COPYRIGHT-NOTE-END ---
  22. 2003-04-09 Clifford Wolf <clifford@clifford.at>
  23. * This patch is created using combinediff based on some patches from
  24. the linux acl homepage at http://acl.bestbits.at/.
  25. * Fixed some includes (lib/acl.c and src/copy.c)
  26. 2002-08-15 Andreas Gruenbacher <agruen@suse.de>
  27. * lib/acl.h: Add copy_acl() and set_acl(). Fix for POSIX/Linux ACLs.
  28. * lib/acl.c: Add dummy copy_acl() and set_acl() implementations.
  29. * src/copy.[hc]: Remove umask_kill; this makes no sense with POSIX
  30. ACLs. Use copy_acl() instead of chmod(). Fix the logic for
  31. POSIX ACLs.
  32. * src/ls.c: Switch back from HAVE_ACL to USE_ACL: The acl() syscall
  33. is no requirement for ACL support.
  34. * src/cp.c: Remove umask_kill. Fix logic in make_path_private() for
  35. POSIX ACLs.
  36. * src/cp.c, src/mv.c, src/install.c: Remove umask_kill.
  37. * m4/acl.m4: Add POSIX/Linux ACL tests.
  38. * lib/acl.c: Add POSIX/Linux ACL support.
  39. --- coreutils-4.5.6/lib/acl.c 2003-02-13 21:39:29.000000000 +0100
  40. +++ coreutils-4.5.6/lib/acl.c 2003-02-13 21:42:45.000000000 +0100
  41. @@ -27,12 +27,29 @@
  42. # define S_ISLNK(Mode) 0
  43. #endif
  44. +#include <unistd.h>
  45. +#include "error.h"
  46. +#include "quote.h"
  47. #include "acl.h"
  48. +#ifdef HAVE_ACL_LIBACL_H
  49. +# include <acl/libacl.h>
  50. +#endif
  51. +
  52. #include <errno.h>
  53. #ifndef ENOSYS
  54. # define ENOSYS (-1)
  55. #endif
  56. +#ifndef ENOTSUP
  57. +# define ENOTSUP (-1)
  58. +#endif
  59. +
  60. +#if ENABLE_NLS
  61. +# include <libintl.h>
  62. +# define _(Text) gettext (Text)
  63. +#else
  64. +# define _(Text) Text
  65. +#endif
  66. #ifndef MIN_ACL_ENTRIES
  67. # define MIN_ACL_ENTRIES 4
  68. @@ -46,17 +62,196 @@
  69. {
  70. - /* FIXME: This implementation should work on recent-enough versions
  71. - of HP-UX, Solaris, and Unixware, but it simply returns 0 with
  72. - POSIX 1003.1e (draft 17 -- abandoned), AIX, GNU/Linux, Irix, and
  73. - Tru64. Please see Samba's source/lib/sysacls.c file for
  74. - fix-related ideas. */
  75. +#if USE_ACL && HAVE_ACL && defined GETACLCNT
  76. + /* This implementation should work on recent-enough versions of HP-UX,
  77. + Solaris, and Unixware. */
  78. -#if HAVE_ACL && defined GETACLCNT
  79. if (! S_ISLNK (pathstat->st_mode))
  80. {
  81. int n = acl (path, GETACLCNT, 0, NULL);
  82. return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n);
  83. }
  84. +#elif USE_ACL && HAVE_ACL_EXTENDED_FILE
  85. + /* Linux specific version. */
  86. +
  87. + if (! S_ISLNK (pathstat->st_mode))
  88. + {
  89. + int ret = acl_extended_file (path);
  90. + if (ret < 0)
  91. + return (errno == ENOSYS || errno == ENOTSUP) ? 0 : -1;
  92. + return ret;
  93. + }
  94. +#endif
  95. +
  96. + /* FIXME: Add support for POSIX 1003.1e (draft 17 -- abandoned), AIX, Irix,
  97. + and Tru64. Please see Samba's source/lib/sysacls.c file for fix-related
  98. + ideas. */
  99. +
  100. + return 0;
  101. +}
  102. +
  103. +/* Copy the access control list of src_path to dst_path. Fall back to
  104. + src_st.st_mode if access control lists are not supported for either
  105. + file. */
  106. +int
  107. +copy_acl (char const *src_path, char const *dst_path, mode_t mode)
  108. +{
  109. +#if USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && \
  110. + HAVE_ACL_FREE && HAVE_ACL_ENTRIES
  111. + /* Linux specific. Will work on all POSIX 1003.1e draft 17 (abandoned)
  112. + systems if the Linux specific acl_entries() function is substituted. */
  113. +
  114. + acl_t acl = acl_get_file (src_path, ACL_TYPE_ACCESS);
  115. + if (acl == NULL)
  116. + {
  117. + if (errno == ENOSYS || errno == ENOTSUP)
  118. + return set_acl (dst_path, mode);
  119. + else
  120. + {
  121. + error (0, errno, "%s", quote (src_path));
  122. + return -1;
  123. + }
  124. + }
  125. +
  126. + if (acl_set_file (dst_path, ACL_TYPE_ACCESS, acl))
  127. + {
  128. + int saved_errno = errno;
  129. +
  130. + if (errno == ENOSYS || errno == ENOTSUP)
  131. + {
  132. + int n = acl_entries (acl);
  133. +
  134. + acl_free (acl);
  135. + if (n == 3)
  136. + {
  137. + if (chmod (dst_path, mode))
  138. + saved_errno = errno;
  139. + else
  140. + return 0;
  141. + }
  142. + else
  143. + chmod (dst_path, mode);
  144. + }
  145. + else
  146. + {
  147. + acl_free (acl);
  148. + chmod (dst_path, mode);
  149. + }
  150. + error (0, saved_errno, _("preserving permissions for %s"),
  151. + quote (dst_path));
  152. + return -1;
  153. + }
  154. + else
  155. + acl_free (acl);
  156. +
  157. + if (mode & (S_ISUID | S_ISGID | S_ISVTX))
  158. + {
  159. + /* We did not call chmod so far, so the special bits have not yet
  160. + been set. */
  161. +
  162. + if (chmod (dst_path, mode))
  163. + {
  164. + error (0, errno, _("preserving permissions for %s"),
  165. + quote (dst_path));
  166. + return -1;
  167. + }
  168. + }
  169. +
  170. + if (S_ISDIR (mode))
  171. + {
  172. + acl = acl_get_file (src_path, ACL_TYPE_DEFAULT);
  173. + if (acl == NULL)
  174. + {
  175. + error (0, errno, "%s", quote (src_path));
  176. + return -1;
  177. + }
  178. +
  179. + if (acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl))
  180. + {
  181. + error (0, errno, _("preserving permissions for %s"),
  182. + quote (dst_path));
  183. + acl_free(acl);
  184. + return -1;
  185. + }
  186. + else
  187. + acl_free(acl);
  188. + }
  189. + return 0;
  190. +#else
  191. + int ret = chmod (dst_path, mode);
  192. + if (ret)
  193. + error (0, errno, _("preserving permissions for %s"), quote (dst_path));
  194. + return ret;
  195. #endif
  196. +}
  197. +
  198. +/* Set the access control list of path to the permissions defined by mode. */
  199. +int
  200. +set_acl (char const *path, mode_t mode)
  201. +{
  202. +#if USE_ACL && HAVE_ACL_FROM_TEXT && HAVE_ACL_SET_FILE && HAVE_ACL_FREE && \
  203. + HAVE_ACL_DELETE_DEF_FILE
  204. + /* POSIX 1003.1e draft 17 (abandoned) specific version. */
  205. + char acl_text[] = "u::---,g::---,o::---";
  206. + acl_t acl;
  207. +
  208. + if (mode & S_IRUSR) acl_text[ 3] = 'r';
  209. + if (mode & S_IWUSR) acl_text[ 4] = 'w';
  210. + if (mode & S_IXUSR) acl_text[ 5] = 'x';
  211. + if (mode & S_IRGRP) acl_text[10] = 'r';
  212. + if (mode & S_IWGRP) acl_text[11] = 'w';
  213. + if (mode & S_IXGRP) acl_text[12] = 'x';
  214. + if (mode & S_IROTH) acl_text[17] = 'r';
  215. + if (mode & S_IWOTH) acl_text[18] = 'w';
  216. + if (mode & S_IXOTH) acl_text[19] = 'x';
  217. +
  218. + acl = acl_from_text(acl_text);
  219. + if (!acl)
  220. + {
  221. + error (0, errno, "%s", quote (path));
  222. + return -1;
  223. + }
  224. +
  225. + if (acl_set_file(path, ACL_TYPE_ACCESS, acl))
  226. + {
  227. + int saved_errno = errno;
  228. + acl_free (acl);
  229. +
  230. + if (errno == ENOTSUP || errno == ENOSYS)
  231. + {
  232. + if (chmod (path, mode))
  233. + saved_errno = errno;
  234. + else
  235. + return 0;
  236. + }
  237. + error (0, saved_errno, _("setting permissions for %s"), quote (path));
  238. + return -1;
  239. + }
  240. + else
  241. + acl_free (acl);
  242. +
  243. + if (mode & (S_ISUID | S_ISGID | S_ISVTX))
  244. + {
  245. + /* We did not call chmod so far, so the special bits have not yet
  246. + been set. */
  247. +
  248. + if (chmod (path, mode))
  249. + {
  250. + error (0, errno, _("preserving permissions for %s"),
  251. + quote (path));
  252. + return -1;
  253. + }
  254. + }
  255. +
  256. + if (S_ISDIR (mode) && acl_delete_def_file (path))
  257. + {
  258. + error (0, errno, _("setting permissions for %s"), quote (path));
  259. + return -1;
  260. + }
  261. return 0;
  262. +#else
  263. + int ret = chmod (path, mode);
  264. + if (ret)
  265. + error (0, errno, _("setting permissions for %s"), quote (path));
  266. + return ret;
  267. +#endif
  268. }
  269. --- coreutils-4.5.6~coreutils-acl/lib/acl.h 2003-02-13 21:15:48.000000000 +0100
  270. +++ coreutils-4.5.6/lib/acl.h 2003-02-13 21:28:21.000000000 +0100
  271. @@ -18,11 +18,13 @@
  272. Written by Paul Eggert. */
  273. -#if HAVE_SYS_ACL_H && HAVE_ACL
  274. +#if HAVE_SYS_ACL_H
  275. # include <sys/acl.h>
  276. #endif
  277. -#if ! defined GETACLCNT && defined ACL_CNT
  278. +#if defined HAVE_ACL && ! defined GETACLCNT && defined ACL_CNT
  279. # define GETACLCNT ACL_CNT
  280. #endif
  281. int file_has_acl (char const *, struct stat const *);
  282. +int copy_acl(char const *, char const *, mode_t);
  283. +int set_acl(char const *, mode_t);
  284. --- coreutils-4.5.6~coreutils-acl/src/copy.c 2003-02-13 21:15:48.000000000 +0100
  285. +++ coreutils-4.5.6/src/copy.c 2003-02-13 21:39:46.000000000 +0100
  286. @@ -45,6 +45,7 @@
  287. #include "quote.h"
  288. #include "same.h"
  289. #include "xreadlink.h"
  290. +#include "acl.h"
  291. #define DO_CHOWN(Chown, File, New_uid, New_gid) \
  292. (Chown (File, New_uid, New_gid) \
  293. @@ -99,26 +100,6 @@
  294. /* The invocation name of this program. */
  295. extern char *program_name;
  296. -/* Encapsulate selection of the file mode to be applied to
  297. - new non-directories. */
  298. -
  299. -static mode_t
  300. -get_dest_mode (const struct cp_options *option, mode_t mode)
  301. -{
  302. - /* In some applications (e.g., install), use precisely the
  303. - specified mode. */
  304. - if (option->set_mode)
  305. - return option->mode;
  306. -
  307. - /* Honor the umask for `cp', but not for `mv' or `cp -p'.
  308. - In addition, `cp' without -p must clear the set-user-ID and set-group-ID
  309. - bits. POSIX requires it do that when creating new files. */
  310. - if (!option->move_mode && !option->preserve_mode)
  311. - mode &= (option->umask_kill & ~(S_ISUID | S_ISGID));
  312. -
  313. - return mode;
  314. -}
  315. -
  316. /* FIXME: describe */
  317. /* FIXME: rewrite this to use a hash table so we avoid the quadratic
  318. performance hit that's probably noticeable only on trees deeper
  319. @@ -793,12 +774,13 @@
  320. struct stat dst_sb;
  321. mode_t src_mode;
  322. mode_t src_type;
  323. + mode_t dst_mode IF_LINT(= 0);
  324. + int dst_mode_valid = 0;
  325. char *earlier_file = NULL;
  326. char *dst_backup = NULL;
  327. int backup_succeeded = 0;
  328. int delayed_fail;
  329. int copied_as_regular = 0;
  330. - int ran_chown = 0;
  331. int preserve_metadata;
  332. if (x->move_mode && rename_succeeded)
  333. @@ -1262,15 +1244,36 @@
  334. if (new_dst || !S_ISDIR (dst_sb.st_mode))
  335. {
  336. - /* Create the new directory writable and searchable, so
  337. - we can create new entries in it. */
  338. -
  339. - if (mkdir (dst_path, (src_mode & x->umask_kill) | S_IRWXU))
  340. + if (mkdir (dst_path, src_mode))
  341. {
  342. error (0, errno, _("cannot create directory %s"),
  343. quote (dst_path));
  344. goto un_backup;
  345. }
  346. + /* We need search and write permissions to the new directory
  347. + for writing the directory's contents. Check if these
  348. + permissions are there. */
  349. +
  350. + if (lstat (dst_path, &dst_sb))
  351. + {
  352. + error (0, errno, _("cannot stat %s"), quote (dst_path));
  353. + delayed_fail = 1;
  354. + }
  355. + else if ((dst_sb.st_mode & S_IRWXU) != S_IRWXU)
  356. + {
  357. + /* Make the new directory searchable and writable. The
  358. + original permissions will be restored later. */
  359. +
  360. + dst_mode = dst_sb.st_mode;
  361. + dst_mode_valid = 1;
  362. +
  363. + if (chmod (dst_path, dst_mode | S_IRWXU))
  364. + {
  365. + error (0, errno, _("setting permissions for %s"),
  366. + quote (dst_path));
  367. + goto un_backup;
  368. + }
  369. + }
  370. /* Insert the created directory's inode and device
  371. numbers into the search structure, so that we can
  372. @@ -1358,15 +1361,14 @@
  373. /* POSIX says the permission bits of the source file must be
  374. used as the 3rd argument in the open call, but that's not consistent
  375. with historical practice. */
  376. - if (copy_reg (src_path, dst_path, x,
  377. - get_dest_mode (x, src_mode), &new_dst, &src_sb))
  378. + if (copy_reg (src_path, dst_path, x, src_mode, &new_dst, &src_sb))
  379. goto un_backup;
  380. }
  381. else
  382. #ifdef S_ISFIFO
  383. if (S_ISFIFO (src_type))
  384. {
  385. - if (mkfifo (dst_path, get_dest_mode (x, src_mode)))
  386. + if (mkfifo (dst_path, src_mode))
  387. {
  388. error (0, errno, _("cannot create fifo %s"), quote (dst_path));
  389. goto un_backup;
  390. @@ -1380,7 +1382,7 @@
  391. #endif
  392. )
  393. {
  394. - if (mknod (dst_path, get_dest_mode (x, src_mode), src_sb.st_rdev))
  395. + if (mknod (dst_path, src_mode, src_sb.st_rdev))
  396. {
  397. error (0, errno, _("cannot create special file %s"),
  398. quote (dst_path));
  399. @@ -1495,7 +1497,8 @@
  400. if (x->preserve_ownership
  401. && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb)))
  402. {
  403. - ran_chown = 1;
  404. + /* The chown() system call may clear the SUID and SGID bits, so we
  405. + may need to set them again later. */
  406. if (DO_CHOWN (chown, dst_path, src_sb.st_uid, src_sb.st_gid))
  407. {
  408. error (0, errno, _("failed to preserve ownership for %s"),
  409. @@ -1516,20 +1519,27 @@
  410. }
  411. #endif
  412. - /* Permissions of newly-created regular files were set upon `open' in
  413. - copy_reg. But don't return early if there were any special bits and
  414. - we had to run chown, because the chown must have reset those bits. */
  415. - if ((new_dst && copied_as_regular)
  416. - && !(ran_chown && (src_mode & ~S_IRWXUGO)))
  417. - return delayed_fail;
  418. -
  419. - if ((x->preserve_mode || new_dst)
  420. - && (x->copy_as_regular || S_ISREG (src_type) || S_ISDIR (src_type)))
  421. + if (x->preserve_mode || x->move_mode)
  422. + {
  423. + if (copy_acl (src_path, dst_path, src_mode) && x->require_preserve)
  424. + return 1;
  425. + }
  426. + else if (x->set_mode)
  427. + {
  428. + if (chmod (dst_path, x->mode))
  429. + {
  430. + error (0, errno, _("preserving permissions for %s"),
  431. + quote (dst_path));
  432. + if (x->require_preserve)
  433. + return 1;
  434. + }
  435. + }
  436. + else if (dst_mode_valid)
  437. {
  438. - if (chmod (dst_path, get_dest_mode (x, src_mode)))
  439. + if (chmod (dst_path, dst_mode))
  440. {
  441. - error (0, errno, _("setting permissions for %s"), quote (dst_path));
  442. - if (x->set_mode || x->require_preserve)
  443. + error (0, errno, _("setting permissions for %s"), quote(dst_path));
  444. + if (x->require_preserve)
  445. return 1;
  446. }
  447. }
  448. --- coreutils-4.5.6~coreutils-acl/src/copy.h 2003-02-13 21:15:48.000000000 +0100
  449. +++ coreutils-4.5.6/src/copy.h 2003-02-13 21:28:21.000000000 +0100
  450. @@ -139,9 +139,6 @@
  451. Create destination directories as usual. */
  452. int symbolic_link;
  453. - /* The bits to preserve in created files' modes. */
  454. - mode_t umask_kill;
  455. -
  456. /* If nonzero, do not copy a nondirectory that has an existing destination
  457. with the same or newer modification time. */
  458. int update;
  459. --- coreutils-4.5.6~coreutils-acl/src/cp.c 2003-02-13 21:15:48.000000000 +0100
  460. +++ coreutils-4.5.6/src/cp.c 2003-02-13 21:35:58.000000000 +0100
  461. @@ -36,6 +36,7 @@
  462. #include "dirname.h"
  463. #include "path-concat.h"
  464. #include "quote.h"
  465. +#include "acl.h"
  466. #define ASSIGN_BASENAME_STRDUPA(Dest, File_name) \
  467. do \
  468. @@ -61,7 +62,8 @@
  469. need to be fixed after copying. */
  470. struct dir_attr
  471. {
  472. - int is_new_dir;
  473. + mode_t mode;
  474. + int mode_valid;
  475. int slash_offset;
  476. struct dir_attr *next;
  477. };
  478. @@ -287,6 +289,7 @@
  479. char *dst_path; /* A copy of CONST_DST_PATH we can change. */
  480. char *src_path; /* The source name in `dst_path'. */
  481. uid_t myeuid = geteuid ();
  482. + mode_t umask_kill = ~umask (0);
  483. dst_path = (char *) alloca (strlen (const_dst_path) + 1);
  484. strcpy (dst_path, const_dst_path);
  485. @@ -342,9 +345,14 @@
  486. }
  487. }
  488. - if (x->preserve_mode || p->is_new_dir)
  489. + if (x->preserve_mode)
  490. {
  491. - if (chmod (dst_path, src_sb.st_mode & x->umask_kill))
  492. + if (copy_acl (src_path, dst_path, src_sb.st_mode))
  493. + return 1;
  494. + }
  495. + else if (p->mode_valid)
  496. + {
  497. + if (chmod (dst_path, p->mode))
  498. {
  499. error (0, errno, _("failed to preserve permissions for %s"),
  500. quote (dst_path));
  501. @@ -362,8 +370,7 @@
  502. SRC_OFFSET is the index in CONST_DIRPATH (which is a destination
  503. path) of the beginning of the source directory name.
  504. - Create any leading directories that don't already exist,
  505. - giving them permissions MODE.
  506. + Create any leading directories that don't already exist.
  507. If VERBOSE_FMT_STRING is nonzero, use it as a printf format
  508. string for printing a message after successfully making a directory.
  509. The format should take two string arguments: the names of the
  510. @@ -378,9 +385,9 @@
  511. /* FIXME: find a way to synch this function with the one in lib/makepath.c. */
  512. static int
  513. -make_path_private (const char *const_dirpath, int src_offset, int mode,
  514. +make_path_private (const char *const_dirpath, int src_offset,
  515. const char *verbose_fmt_string, struct dir_attr **attr_list,
  516. - int *new_dst, int (*xstat)())
  517. + int *new_dst, struct cp_options const *x)
  518. {
  519. struct stat stats;
  520. char *dirpath; /* A copy of CONST_DIRPATH we can change. */
  521. @@ -400,7 +407,7 @@
  522. *attr_list = NULL;
  523. - if ((*xstat) (dst_dirname, &stats))
  524. + if ((*x->xstat) (dst_dirname, &stats))
  525. {
  526. /* Parent of CONST_DIRNAME does not exist.
  527. Make all missing intermediate directories. */
  528. @@ -420,16 +427,26 @@
  529. *attr_list = new;
  530. *slash = '\0';
  531. - if ((*xstat) (dirpath, &stats))
  532. + if ((*x->xstat) (dirpath, &stats))
  533. {
  534. + mode_t src_mode;
  535. +
  536. /* This element of the path does not exist. We must set
  537. - *new_dst and new->is_new_dir inside this loop because,
  538. + *new_dst and new->mode inside this loop because,
  539. for example, in the command `cp --parents ../a/../b/c e_dir',
  540. make_path_private creates only e_dir/../a if ./b already
  541. exists. */
  542. *new_dst = 1;
  543. - new->is_new_dir = 1;
  544. - if (mkdir (dirpath, mode))
  545. +
  546. + if ((*x->xstat) (src, &stats))
  547. + {
  548. + error (0, errno, _("failed to get attributes of %s"),
  549. + quote (src));
  550. + return 1;
  551. + }
  552. + src_mode = stats.st_mode;
  553. +
  554. + if (mkdir (dirpath, src_mode))
  555. {
  556. error (0, errno, _("cannot make directory %s"),
  557. quote (dirpath));
  558. @@ -440,6 +457,42 @@
  559. if (verbose_fmt_string != NULL)
  560. printf (verbose_fmt_string, src, dirpath);
  561. }
  562. +
  563. + /* We need search and write permissions to the new directory
  564. + for writing the directory's contents. Check if these
  565. + permissions are there. */
  566. +
  567. + if (lstat (dirpath, &stats))
  568. + {
  569. + error (0, errno, _("failed to get attributes of %s"),
  570. + quote (dirpath));
  571. + return 1;
  572. + }
  573. + else
  574. + {
  575. + if (x->preserve_mode) {
  576. + new->mode = src_mode;
  577. + new->mode_valid = (src_mode != stats.st_mode);
  578. + } else {
  579. + new->mode = stats.st_mode;
  580. + new->mode_valid = 0;
  581. + }
  582. +
  583. + if ((stats.st_mode & S_IRWXU) != S_IRWXU)
  584. + {
  585. + /* Make the new directory searchable and writable. The
  586. + original permissions will be restored later. */
  587. +
  588. + new->mode_valid = 1;
  589. +
  590. + if (chmod (dirpath, stats.st_mode | S_IRWXU))
  591. + {
  592. + error (0, errno, _("setting permissions for %s"),
  593. + quote (dirpath));
  594. + return 1;
  595. + }
  596. + }
  597. + }
  598. }
  599. else if (!S_ISDIR (stats.st_mode))
  600. {
  601. @@ -449,7 +502,7 @@
  602. }
  603. else
  604. {
  605. - new->is_new_dir = 0;
  606. + new->mode_valid = 0;
  607. *new_dst = 0;
  608. }
  609. *slash++ = '/';
  610. @@ -600,11 +653,9 @@
  611. leading directories. */
  612. parent_exists = !make_path_private (dst_path,
  613. arg_in_concat - dst_path,
  614. - S_IRWXU,
  615. (x->verbose
  616. ? "%s -> %s\n" : NULL),
  617. - &attr_list, &new_dst,
  618. - x->xstat);
  619. + &attr_list, &new_dst, x);
  620. }
  621. else
  622. {
  623. @@ -739,12 +790,6 @@
  624. /* Not used. */
  625. x->stdin_tty = 0;
  626. - /* Find out the current file creation mask, to knock the right bits
  627. - when using chmod. The creation mask is set to be liberal, so
  628. - that created directories can be written, even if it would not
  629. - have been allowed with the mask this process was started with. */
  630. - x->umask_kill = ~ umask (0);
  631. -
  632. x->update = 0;
  633. x->verbose = 0;
  634. x->dest_info = NULL;
  635. @@ -1017,9 +1062,6 @@
  636. version_control_string)
  637. : none);
  638. - if (x.preserve_mode == 1)
  639. - x.umask_kill = ~ (mode_t) 0;
  640. -
  641. if (x.dereference == DEREF_UNDEFINED)
  642. {
  643. if (x.recursive)
  644. --- coreutils-4.5.6~coreutils-acl/src/install.c 2003-02-13 21:15:48.000000000 +0100
  645. +++ coreutils-4.5.6/src/install.c 2003-02-13 21:28:21.000000000 +0100
  646. @@ -165,7 +165,6 @@
  647. x->mode = S_IRUSR | S_IWUSR;
  648. x->stdin_tty = 0;
  649. - x->umask_kill = 0;
  650. x->update = 0;
  651. x->verbose = 0;
  652. x->xstat = stat;
  653. --- coreutils-4.5.6~coreutils-acl/src/ls.c 2003-02-13 21:15:48.000000000 +0100
  654. +++ coreutils-4.5.6/src/ls.c 2003-02-13 21:28:21.000000000 +0100
  655. @@ -223,13 +223,13 @@
  656. enum filetype filetype;
  657. -#if HAVE_ACL
  658. +#if USE_ACL
  659. /* For long listings, true if the file has an access control list. */
  660. bool have_acl;
  661. #endif
  662. };
  663. -#if HAVE_ACL
  664. +#if USE_ACL
  665. # define FILE_HAS_ACL(F) ((F)->have_acl)
  666. #else
  667. # define FILE_HAS_ACL(F) 0
  668. @@ -2400,7 +2400,7 @@
  669. return 0;
  670. }
  671. -#if HAVE_ACL
  672. +#if USE_ACL
  673. if (format == long_format)
  674. {
  675. int n = file_has_acl (path, &files[files_index].stat);
  676. --- coreutils-4.5.6~coreutils-acl/src/mv.c 2003-02-13 21:15:48.000000000 +0100
  677. +++ coreutils-4.5.6/src/mv.c 2003-02-13 21:28:21.000000000 +0100
  678. @@ -137,12 +137,6 @@
  679. x->mode = 0;
  680. x->stdin_tty = isatty (STDIN_FILENO);
  681. - /* Find out the current file creation mask, to knock the right bits
  682. - when using chmod. The creation mask is set to be liberal, so
  683. - that created directories can be written, even if it would not
  684. - have been allowed with the mask this process was started with. */
  685. - x->umask_kill = ~ umask (0);
  686. -
  687. x->update = 0;
  688. x->verbose = 0;
  689. x->xstat = lstat;
  690. --- coreutils-4.5.6~coreutils-acl+posix/m4/acl.m4 2003-02-13 21:39:29.000000000 +0100
  691. +++ coreutils-4.5.6/m4/acl.m4 2003-02-13 21:49:04.000000000 +0100
  692. @@ -20,4 +20,22 @@
  693. AC_DEFUN([AC_FUNC_ACL],
  694. [AC_CHECK_HEADERS(sys/acl.h)
  695. - AC_CHECK_FUNCS(acl)])
  696. + if test "$ac_cv_header_sys_acl_h" = yes; then
  697. + use_acl=1
  698. + else
  699. + use_acl=0
  700. + fi
  701. + AC_DEFINE_UNQUOTED(USE_ACL, $use_acl,
  702. + [Define if you want access control list support.])
  703. + AC_CHECK_FUNCS(acl)
  704. + ac_save_LIBS="$LIBS"
  705. + AC_SEARCH_LIBS(acl_get_file, acl)
  706. + LIB_ACL=`echo "$LIBS" | \
  707. + awk -- "{ print substr(\\$_, length(\"$ac_save_LIBS\")+1)}"`
  708. + AC_SUBST(LIB_ACL)
  709. + AC_CHECK_HEADERS(acl/libacl.h)
  710. + AC_CHECK_FUNCS(acl_get_file acl_set_file acl_free acl_to_text \
  711. + acl_from_text acl_delete_def_file \
  712. + acl_entries acl_extended_file)
  713. + LIBS="$ac_save_LIBS"
  714. + ])
  715. --- coreutils-4.5.6~coreutils-acl+posix/src/Makefile.am 2003-02-13 21:39:29.000000000 +0100
  716. +++ coreutils-4.5.6/src/Makefile.am 2003-02-13 21:40:44.000000000 +0100
  717. @@ -34,10 +34,13 @@
  718. # replacement functions defined in libfetish.a.
  719. LDADD = ../lib/libfetish.a @LIBINTL@ ../lib/libfetish.a
  720. -dir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
  721. -ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
  722. +dir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ @LIB_ACL@
  723. +ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ @LIB_ACL@
  724. shred_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
  725. -vdir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
  726. +vdir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ @LIB_ACL@
  727. +cp_LDADD = $(LDADD) @LIB_ACL@
  728. +mv_LDADD = $(LDADD) @LIB_ACL@
  729. +ginstall_LDADD = $(LDADD) @LIB_ACL@
  730. ## If necessary, add -lm to resolve use of pow in lib/strtod.c.
  731. sort_LDADD = $(LDADD) @POW_LIB@
  732. --- coreutils-4.5.8/configure.ac
  733. +++ coreutils-4.5.8/configure.ac
  734. @@ -245,6 +245,9 @@
  735. # For src/kill.c.
  736. AC_CHECK_DECLS([strsignal, strtoimax, sys_siglist, _sys_siglist])
  737. +# Extended attribute copying.
  738. +AC_FUNC_XATTR
  739. +
  740. jm_LIB_CHECK
  741. AM_GNU_GETTEXT([external], [need-ngettext])
  742. --- coreutils-4.5.8/doc/coreutils.texi
  743. +++ coreutils-4.5.8/doc/coreutils.texi
  744. @@ -5859,6 +5859,19 @@
  745. directory in a different order).
  746. Equivalent to @option{-dpPR}.
  747. +@itemx @w{@kbd{--attributes}=@var{regex}}
  748. +@opindex --attributes
  749. +Preserve extended attributes whose names match the specified regular
  750. +expression. The default behavior or @command{cp} if no
  751. +@option{--attributes} option is given is to preserve all extended
  752. +attributes except file permissions. If @var{regex} is ``@samp{-}'', no
  753. +extended attributes are preserved.
  754. +
  755. +This option does not affect the preservation of discretionary file
  756. +permissions (i.e., file mode permission bits and access control lists).
  757. +To control the preservation of file permissions, the @option{-p} or
  758. +@option{--preserve=mode} options are used.
  759. +
  760. @item -b
  761. @itemx @w{@kbd{--backup}[=@var{method}]}
  762. @opindex -b
  763. @@ -5962,7 +5975,7 @@
  764. @table @samp
  765. @itemx mode
  766. -Preserve the permission attributes.
  767. +Preserve the permission attributes, including access control lists.
  768. @itemx ownership
  769. Preserve the owner and group. On most modern systems,
  770. only the super-user may change the owner of a file, and regular users
  771. @@ -5978,7 +5991,6 @@
  772. @itemx all
  773. Preserve all file attributes.
  774. Equivalent to specifying all of the above.
  775. -@c Mention ACLs here.
  776. @end table
  777. Using @option{--preserve} with no @var{attribute_list} is equivalent
  778. --- coreutils-4.5.8/m4/xattr.m4
  779. +++ coreutils-4.5.8/m4/xattr.m4
  780. @@ -0,0 +1,38 @@
  781. +# xattr.m4 - check for Extended Attributes (Linux)
  782. +
  783. +# Copyright (C) 2003 Free Software Foundation, Inc.
  784. +
  785. +# This program is free software; you can redistribute it and/or modify
  786. +# it under the terms of the GNU General Public License as published by
  787. +# the Free Software Foundation; either version 2, or (at your option)
  788. +# any later version.
  789. +
  790. +# This program is distributed in the hope that it will be useful,
  791. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  792. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  793. +# GNU General Public License for more details.
  794. +
  795. +# You should have received a copy of the GNU General Public License
  796. +# along with this program; if not, write to the Free Software Foundation,
  797. +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  798. +
  799. +# Written by Andreas Gruenbacher.
  800. +
  801. +AC_DEFUN([AC_FUNC_XATTR],
  802. +[
  803. + AC_CHECK_HEADERS(attr/error_context.h attr/libattr.h)
  804. + if test "$ac_cv_header_attr_libattr_h" = yes \
  805. + && test "$ac_cv_header_attr_error_context_h" = yes; then
  806. + use_xattr=1
  807. + else
  808. + use_xattr=0
  809. + fi
  810. + AC_DEFINE_UNQUOTED(USE_XATTR, $use_xattr,
  811. + [Define if you want extended attribute support.])
  812. + xattr_saved_LIBS=$LIBS
  813. + AC_SEARCH_LIBS(attr_copy_file, attr,
  814. + [LIB_XATTR=$ac_cv_search_attr_copy_file])
  815. + AC_SUBST(LIB_XATTR)
  816. + AC_CHECK_FUNCS(attr_copy_file)
  817. + LIBS=$xattr_saved_LIBS
  818. +])
  819. --- coreutils-4.5.8/man/cp.1
  820. +++ coreutils-4.5.8/man/cp.1
  821. @@ -60,6 +60,14 @@
  822. mode,ownership,timestamps), if possible
  823. additional attributes: links, all
  824. .TP
  825. +\fB\-\-attributes\fR=\fIregex\fR
  826. +preserve extended attributes whose name
  827. +matches the specified regular expression
  828. +(defaults to preserving all extended
  829. +.IP
  830. +attributes except file permissions;
  831. +regex=`-' preserves no extended attributes).
  832. +.TP
  833. \fB\-\-no\-preserve\fR=\fIATTR_LIST\fR
  834. don't preserve the specified attributes
  835. .TP
  836. --- coreutils-4.5.8/src/Makefile.am
  837. +++ coreutils-4.5.8/src/Makefile.am
  838. @@ -38,9 +38,9 @@
  839. ls_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ @LIB_ACL@
  840. shred_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@
  841. vdir_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ @LIB_ACL@
  842. -cp_LDADD = $(LDADD) @LIB_ACL@
  843. -mv_LDADD = $(LDADD) @LIB_ACL@
  844. -ginstall_LDADD = $(LDADD) @LIB_ACL@
  845. +cp_LDADD = $(LDADD) @LIB_ACL@ @LIB_XATTR@
  846. +mv_LDADD = $(LDADD) @LIB_ACL@ @LIB_XATTR@
  847. +ginstall_LDADD = $(LDADD) @LIB_ACL@ @LIB_XATTR@
  848. ## If necessary, add -lm to resolve use of pow in lib/strtod.c.
  849. sort_LDADD = $(LDADD) @POW_LIB@
  850. --- coreutils-4.5.8/src/copy.c
  851. +++ coreutils-4.5.8/src/copy.c
  852. @@ -47,6 +47,14 @@
  853. #include "xreadlink.h"
  854. #include "acl.h"
  855. +#ifdef USE_XATTR
  856. +# include "regex.h"
  857. +# include <stdarg.h>
  858. +# include <attr/attributes.h>
  859. +# include <attr/xattr.h>
  860. +# include <attr/error_context.h>
  861. +#endif
  862. +
  863. #define DO_CHOWN(Chown, File, New_uid, New_gid) \
  864. (Chown (File, New_uid, New_gid) \
  865. /* If non-root uses -p, it's ok if we can't preserve ownership. \
  866. @@ -117,6 +124,104 @@
  867. return 0;
  868. }
  869. +#if USE_XATTR
  870. +static void
  871. +copy_attr_error (struct error_context *ctx, const char *fmt, ...)
  872. +{
  873. + int err = errno;
  874. + va_list ap;
  875. + int len;
  876. + char *buffer;
  877. +
  878. + /* There is no error function that takes a va_list argument,
  879. + so we print the message in a buffer first. */
  880. +
  881. + va_start (ap, fmt);
  882. + len = vsnprintf (NULL, 0, fmt, ap);
  883. + if (len > 0)
  884. + {
  885. + buffer = xmalloc (len + 1);
  886. + vsnprintf (buffer, len + 1, fmt, ap);
  887. + error (0, err, "%s", buffer);
  888. + free (buffer);
  889. + }
  890. + va_end (ap);
  891. +}
  892. +
  893. +static const char *
  894. +copy_attr_quote (struct error_context *ctx, const char *str)
  895. +{
  896. + return xstrdup (quote (str));
  897. +}
  898. +
  899. +static void
  900. +copy_attr_free (struct error_context *ctx, const char *str)
  901. +{
  902. + free ((void *) str);
  903. +}
  904. +
  905. +struct copy_attr_context
  906. + {
  907. + struct error_context ctx;
  908. + const char *re_pattern;
  909. + struct re_pattern_buffer re_compiled;
  910. + } copy_attr_ctx = {
  911. + { copy_attr_error,
  912. + copy_attr_quote,
  913. + copy_attr_free }
  914. + };
  915. +
  916. +static int
  917. +copy_attr_filter (const char *name, struct error_context *ctx)
  918. +{
  919. + struct copy_attr_context *copy_ctx = (struct copy_attr_context *) ctx;
  920. +
  921. + return (attr_copy_check_permissions (name, ctx)
  922. + && copy_ctx->re_pattern != NULL
  923. + && re_search (&copy_ctx->re_compiled, name, strlen (name), 0,
  924. + strlen (name), NULL) >= 0);
  925. +}
  926. +#endif /* USE_XATTR */
  927. +
  928. +static int
  929. +copy_extended_attributes (const char *src_path, const char *dst_path,
  930. + const struct cp_options *x)
  931. +{
  932. +#if USE_XATTR
  933. + if (x->attr_pattern == NULL)
  934. + return 0;
  935. +
  936. + if (copy_attr_ctx.re_pattern != x->attr_pattern)
  937. + {
  938. + struct re_pattern_buffer *c = &copy_attr_ctx.re_compiled;
  939. + size_t len = strlen (x->attr_pattern);
  940. + const char *err;
  941. +
  942. + free (c->fastmap);
  943. + free (c->buffer);
  944. +
  945. + copy_attr_ctx.re_pattern = x->attr_pattern;
  946. + c->allocated = 2 * len;
  947. + c->buffer = xmalloc (c->allocated);
  948. + c->fastmap = xmalloc (256);
  949. + c->translate = 0;
  950. + err = re_compile_pattern (x->attr_pattern, len, c);
  951. + if (err)
  952. + {
  953. + free (c->fastmap);
  954. + free (c->buffer);
  955. + copy_attr_ctx.re_pattern = NULL;
  956. + error (EXIT_FAILURE, 0, _("%s: invalid regular expression: %s"),
  957. + x->attr_pattern, err);
  958. + }
  959. + }
  960. + return attr_copy_file (src_path, dst_path,
  961. + copy_attr_filter, &copy_attr_ctx.ctx);
  962. +#else /* USE_XATTR */
  963. + return 0;
  964. +#endif /* USE_XATTR */
  965. +}
  966. +
  967. /* Read the contents of the directory SRC_PATH_IN, and recursively
  968. copy the contents to DST_PATH_IN. NEW_DST is nonzero if
  969. DST_PATH_IN is a directory that was created previously in the
  970. @@ -1519,6 +1624,9 @@
  971. }
  972. #endif
  973. + if (copy_extended_attributes (src_path, dst_path, x))
  974. + delayed_fail = 1;
  975. +
  976. if (x->preserve_mode || x->move_mode)
  977. {
  978. if (copy_acl (src_path, dst_path, src_mode) && x->require_preserve)
  979. --- coreutils-4.5.8/src/copy.h
  980. +++ coreutils-4.5.8/src/copy.h
  981. @@ -102,6 +102,10 @@
  982. int preserve_mode;
  983. int preserve_timestamps;
  984. + /* Regular expression pattern that specifies which extended attributes to
  985. + copy. NULL stands for copying no extended attributes. */
  986. + const char *attr_pattern;
  987. +
  988. /* Enabled for mv, and for cp by the --preserve=links option.
  989. If nonzero, attempt to preserve in the destination files any
  990. logical hard links between the source files. If used with cp's
  991. --- coreutils-4.5.8/src/cp.c
  992. +++ coreutils-4.5.8/src/cp.c
  993. @@ -81,7 +81,8 @@
  994. SPARSE_OPTION,
  995. STRIP_TRAILING_SLASHES_OPTION,
  996. TARGET_DIRECTORY_OPTION,
  997. - UNLINK_DEST_BEFORE_OPENING
  998. + UNLINK_DEST_BEFORE_OPENING,
  999. + PRESERVE_XATTRS_OPTION
  1000. };
  1001. /* Initial number of entries in each hash table entry's table of inodes. */
  1002. @@ -137,6 +138,7 @@
  1003. {"parents", no_argument, NULL, PARENTS_OPTION},
  1004. {"path", no_argument, NULL, PARENTS_OPTION}, /* Deprecated. */
  1005. {"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION},
  1006. + {"attributes", required_argument, NULL, PRESERVE_XATTRS_OPTION},
  1007. {"recursive", no_argument, NULL, 'R'},
  1008. {"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING},
  1009. {"reply", required_argument, NULL, REPLY_OPTION},
  1010. @@ -225,6 +227,13 @@
  1011. -v, --verbose explain what is being done\n\
  1012. -x, --one-file-system stay on this file system\n\
  1013. "), stdout);
  1014. + fputs(_("\n\
  1015. + --attributes=regex preserve extended attributes whose name\n\
  1016. + matches the specified regular expression\n\
  1017. + (defaults to preserving all extended\n\
  1018. + attributes except file permissions;\n\
  1019. + regex=`-' preserves no extended attributes).\n\
  1020. +"), stdout);
  1021. fputs (HELP_OPTION_DESCRIPTION, stdout);
  1022. fputs (VERSION_OPTION_DESCRIPTION, stdout);
  1023. fputs (_("\
  1024. @@ -792,6 +801,8 @@
  1025. x->verbose = 0;
  1026. x->dest_info = NULL;
  1027. x->src_info = NULL;
  1028. +
  1029. + x->attr_pattern = ""; /* all extended attributes */
  1030. }
  1031. /* Given a string, ARG, containing a comma-separated list of arguments
  1032. @@ -1004,6 +1015,13 @@
  1033. x.require_preserve = 1;
  1034. break;
  1035. + case PRESERVE_XATTRS_OPTION:
  1036. + if (strcmp (optarg, "-") == 0)
  1037. + x.attr_pattern = NULL;
  1038. + else
  1039. + x.attr_pattern = optarg;
  1040. + break;
  1041. +
  1042. case PARENTS_OPTION:
  1043. flag_path = 1;
  1044. break;
  1045. --- coreutils-4.5.8/src/install.c
  1046. +++ coreutils-4.5.8/src/install.c
  1047. @@ -170,6 +170,8 @@
  1048. x->xstat = stat;
  1049. x->dest_info = NULL;
  1050. x->src_info = NULL;
  1051. +
  1052. + x->attr_pattern = NULL; /* no extended attributes */
  1053. }
  1054. int
  1055. --- coreutils-4.5.8/src/mv.c
  1056. +++ coreutils-4.5.8/src/mv.c
  1057. @@ -142,6 +142,8 @@
  1058. x->xstat = lstat;
  1059. x->dest_info = NULL;
  1060. x->src_info = NULL;
  1061. +
  1062. + x->attr_pattern = ""; /* all extended attributes */
  1063. }
  1064. /* If PATH is an existing directory, return nonzero, else 0. */