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.

957 lines
27 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 - 2004 Clifford Wolf
  10. #
  11. # This patch file is dual-licensed. It is available under the license the
  12. # patched project is licensed under, as long as it is an OpenSource license
  13. # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
  14. # of the GNU General Public License as published by the Free Software
  15. # Foundation; either version 2 of the License, or (at your option) any later
  16. # version.
  17. #
  18. # --- ROCK-COPYRIGHT-NOTE-END ---
  19. --- /dev/null 2004-02-23 21:02:56.000000000 +0000
  20. +++ ./m4/posix_acl.m4 2004-03-13 11:50:03.000000000 +0000
  21. @@ -0,0 +1,28 @@
  22. +#serial 1
  23. +
  24. +dnl Written by Andreas Gruenbacher <a.gruenbacher@computer.org>.
  25. +
  26. +dnl Posix 1003.1e draft standard 17 (abandoned) and similar
  27. +dnl access control list support
  28. +AC_DEFUN([ag_POSIX_ACL],
  29. +[
  30. + AC_CHECK_HEADERS(sys/acl.h)
  31. + AC_CHECK_LIB(acl, main, cu_cv_lacl=yes, cu_cv_lacl=no)
  32. + if test "$cu_cv_lacl" = yes; then
  33. + LIBACL=-lacl
  34. + else
  35. + LIBACL=
  36. + fi
  37. + AC_SUBST(LIBACL)
  38. + OLDLIBS="$LIBS"
  39. + LIBS="$LIBS $LIBACL"
  40. + AC_CHECK_FUNCS(acl_get_file acl_set_file acl_free acl_to_text \
  41. + acl_from_text acl_delete_def_file)
  42. + # Linux specific extensions:
  43. + AC_CHECK_FUNCS(acl_entries acl_extended_file)
  44. + LIBS="$OLDLIBS"
  45. +
  46. + if test $ac_cv_header_sys_acl_h = yes; then
  47. + AC_DEFINE(USE_ACL, 1, [Define if you want access control list support.])
  48. + fi
  49. +])
  50. --- ./m4/Makefile.am.acl 2004-03-08 09:56:31.000000000 +0000
  51. +++ ./m4/Makefile.am 2004-03-13 11:50:03.000000000 +0000
  52. @@ -108,6 +108,7 @@
  53. EXTRA_DIST += path-concat.m4
  54. EXTRA_DIST += pathmax.m4
  55. EXTRA_DIST += perl.m4
  56. +EXTRA_DIST += posix_acl.m4
  57. EXTRA_DIST += physmem.m4
  58. EXTRA_DIST += po.m4
  59. EXTRA_DIST += posixtm.m4
  60. --- ./lib/acl.h.acl 2004-02-02 08:13:21.000000000 +0000
  61. +++ ./lib/acl.h 2004-03-13 11:50:03.000000000 +0000
  62. @@ -18,11 +18,16 @@
  63. Written by Paul Eggert. */
  64. -#if HAVE_SYS_ACL_H && HAVE_ACL
  65. +#if HAVE_SYS_ACL_H
  66. # include <sys/acl.h>
  67. #endif
  68. +#if HAVE_SYS_TYPES_H
  69. +# include <sys/types.h>
  70. +#endif
  71. #if ! defined GETACLCNT && defined ACL_CNT
  72. # define GETACLCNT ACL_CNT
  73. #endif
  74. int file_has_acl (char const *, struct stat const *);
  75. +int copy_acl (char const *, char const *, mode_t);
  76. +int set_acl (char const *, mode_t);
  77. --- ./lib/acl.c.acl 2004-02-02 08:13:21.000000000 +0000
  78. +++ ./lib/acl.c 2004-03-13 11:50:03.000000000 +0000
  79. @@ -22,18 +22,30 @@
  80. # include <config.h>
  81. #endif
  82. +#if ENABLE_NLS
  83. +# include <libintl.h>
  84. +# define _(Text) gettext (Text)
  85. +#else
  86. +# define _(Text) Text
  87. +#endif
  88. +
  89. #include <sys/types.h>
  90. #include <sys/stat.h>
  91. #ifndef S_ISLNK
  92. # define S_ISLNK(Mode) 0
  93. #endif
  94. +#include <stdlib.h>
  95. +
  96. #include "acl.h"
  97. #include <errno.h>
  98. #ifndef ENOSYS
  99. # define ENOSYS (-1)
  100. #endif
  101. +#ifndef ENOTSUP
  102. +# define ENOTSUP (-1)
  103. +#endif
  104. #ifndef MIN_ACL_ENTRIES
  105. # define MIN_ACL_ENTRIES 4
  106. @@ -45,19 +57,201 @@
  107. int
  108. file_has_acl (char const *path, struct stat const *pathstat)
  109. {
  110. - /* FIXME: This implementation should work on recent-enough versions
  111. - of HP-UX, Solaris, and Unixware, but it simply returns 0 with
  112. - POSIX 1003.1e (draft 17 -- abandoned), AIX, GNU/Linux, Irix, and
  113. - Tru64. Please see Samba's source/lib/sysacls.c file for
  114. - fix-related ideas. */
  115. -
  116. #if HAVE_ACL && defined GETACLCNT
  117. + /* This implementation should work on recent-enough versions of HP-UX,
  118. + Solaris, and Unixware. */
  119. +
  120. if (! S_ISLNK (pathstat->st_mode))
  121. {
  122. int n = acl (path, GETACLCNT, 0, NULL);
  123. return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n);
  124. }
  125. +#elif HAVE_ACL_EXTENDED_FILE
  126. +
  127. + /* Linux specific. */
  128. +
  129. + if (! S_ISLNK (pathstat->st_mode))
  130. + {
  131. + int ret = acl_extended_file (path);
  132. + if (ret < 0)
  133. + return (errno == ENOSYS || errno == ENOTSUP) ? 0 : -1;
  134. + return ret;
  135. + }
  136. +#else
  137. + /* FIXME: Add support for AIX, Irix, and Tru64, FreeBSD, etc.
  138. + Please see Samba's source/lib/sysacls.c file for fix-related ideas. */
  139. #endif
  140. return 0;
  141. }
  142. +
  143. +/* Copy the permissions from SRC_PATH to DST_PATH, including access control
  144. + lists on systems where this is supported. MODE is the file mode for
  145. + DST_PATH, including the file type.
  146. + Also sets special bits in MODE on DST_PATH. */
  147. +
  148. +int
  149. +copy_acl (char const *src_path, char const *dst_path, mode_t mode)
  150. +{
  151. +#if HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && HAVE_ACL_FREE && \
  152. + HAVE_ACL_ENTRIES
  153. +
  154. + /* Linux specific. Will work on all POSIX 1003.1e draft 17 (abandoned)
  155. + compliant systems if the acl_entries() function is implemented. */
  156. +
  157. + acl_t acl = acl_get_file (src_path, ACL_TYPE_ACCESS);
  158. + if (acl == NULL)
  159. + {
  160. + if (errno == ENOSYS || errno == ENOTSUP)
  161. + return set_acl (dst_path, mode);
  162. + else
  163. + {
  164. + error (0, errno, "%s", quote (src_path));
  165. + return -1;
  166. + }
  167. + }
  168. +
  169. + if (acl_set_file (dst_path, ACL_TYPE_ACCESS, acl))
  170. + {
  171. + int saved_errno = errno;
  172. +
  173. + if (errno == ENOSYS || errno == ENOTSUP)
  174. + {
  175. + int n = acl_entries (acl);
  176. +
  177. + acl_free (acl);
  178. + if (n == 3)
  179. + {
  180. + if (chmod (dst_path, mode))
  181. + saved_errno = errno;
  182. + else
  183. + return 0;
  184. + }
  185. + else
  186. + chmod (dst_path, mode);
  187. + }
  188. + else
  189. + {
  190. + acl_free (acl);
  191. + chmod (dst_path, mode);
  192. + }
  193. + error (0, saved_errno, _("preserving permissions for %s"),
  194. + quote (dst_path));
  195. + return -1;
  196. + }
  197. + acl_free (acl);
  198. +
  199. + if (mode & (S_ISUID | S_ISGID | S_ISVTX))
  200. + {
  201. + /* We did not call chmod so far, so the special bits have not yet
  202. + been set. */
  203. +
  204. + if (chmod (dst_path, mode))
  205. + {
  206. + error (0, errno, _("preserving permissions for %s"),
  207. + quote (dst_path));
  208. + return -1;
  209. + }
  210. + }
  211. +
  212. + if (S_ISDIR (mode))
  213. + {
  214. + acl = acl_get_file (src_path, ACL_TYPE_DEFAULT);
  215. + if (acl == NULL)
  216. + {
  217. + error (0, errno, "%s", quote (src_path));
  218. + return -1;
  219. + }
  220. +
  221. + if (acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl))
  222. + {
  223. + error (0, errno, _("preserving permissions for %s"),
  224. + quote (dst_path));
  225. + acl_free(acl);
  226. + return -1;
  227. + }
  228. + else
  229. + acl_free(acl);
  230. + }
  231. + return 0;
  232. +#else
  233. + int ret = chmod (dst_path, mode);
  234. + if (ret)
  235. + error (0, errno, _("preserving permissions for %s"), quote (dst_path));
  236. + return ret;
  237. +#endif
  238. +}
  239. +
  240. +/* Set the permissions of PATH, overwriting access control lists, on systems
  241. + where this is supported. MODE is the file mode for PATH, including the
  242. + file type. Also sets special bits in MODE on PATH. */
  243. +
  244. +int
  245. +set_acl (char const *path, mode_t mode)
  246. +{
  247. +#if HAVE_ACL_FROM_TEXT && HAVE_ACL_SET_FILE && HAVE_ACL_FREE && \
  248. + HAVE_ACL_DELETE_DEF_FILE
  249. + char acl_text[] = "u::---,g::---,o::---";
  250. + acl_t acl;
  251. +
  252. + if (mode & S_IRUSR) acl_text[ 3] = 'r';
  253. + if (mode & S_IWUSR) acl_text[ 4] = 'w';
  254. + if (mode & S_IXUSR) acl_text[ 5] = 'x';
  255. + if (mode & S_IRGRP) acl_text[10] = 'r';
  256. + if (mode & S_IWGRP) acl_text[11] = 'w';
  257. + if (mode & S_IXGRP) acl_text[12] = 'x';
  258. + if (mode & S_IROTH) acl_text[17] = 'r';
  259. + if (mode & S_IWOTH) acl_text[18] = 'w';
  260. + if (mode & S_IXOTH) acl_text[19] = 'x';
  261. +
  262. + acl = acl_from_text(acl_text);
  263. + if (!acl)
  264. + {
  265. + error (0, errno, "%s", quote (path));
  266. + return -1;
  267. + }
  268. +
  269. + if (acl_set_file(path, ACL_TYPE_ACCESS, acl))
  270. + {
  271. + int saved_errno = errno;
  272. + acl_free (acl);
  273. +
  274. + if (errno == ENOTSUP || errno == ENOSYS)
  275. + {
  276. + if (chmod (path, mode))
  277. + saved_errno = errno;
  278. + else
  279. + return 0;
  280. + }
  281. + error (0, saved_errno, _("setting permissions for %s"), quote (path));
  282. + return -1;
  283. + }
  284. + acl_free (acl);
  285. +
  286. + if (mode & (S_ISUID | S_ISGID | S_ISVTX))
  287. + {
  288. + /* We did not call chmod so far, so the special bits have not yet
  289. + been set. */
  290. +
  291. + if (chmod (path, mode))
  292. + {
  293. + error (0, errno, _("preserving permissions for %s"),
  294. + quote (path));
  295. + return -1;
  296. + }
  297. + }
  298. +
  299. + if (S_ISDIR (mode) && acl_delete_def_file (path))
  300. + {
  301. + error (0, errno, _("setting permissions for %s"), quote (path));
  302. + return -1;
  303. + }
  304. + return 0;
  305. +#else
  306. + int ret = chmod (path, mode);
  307. + if (ret)
  308. + error (0, errno, _("setting permissions for %s"), quote (path));
  309. + return ret;
  310. +#endif
  311. +}
  312. +
  313. --- ./src/mv.c.acl 2004-02-07 15:41:02.000000000 +0000
  314. +++ ./src/mv.c 2004-03-13 11:50:03.000000000 +0000
  315. @@ -132,12 +132,6 @@
  316. x->mode = 0;
  317. x->stdin_tty = isatty (STDIN_FILENO);
  318. - /* Find out the current file creation mask, to knock the right bits
  319. - when using chmod. The creation mask is set to be liberal, so
  320. - that created directories can be written, even if it would not
  321. - have been allowed with the mask this process was started with. */
  322. - x->umask_kill = ~ umask (0);
  323. -
  324. x->update = 0;
  325. x->verbose = 0;
  326. x->dest_info = NULL;
  327. --- ./src/ls.c.acl 2004-03-13 11:50:03.000000000 +0000
  328. +++ ./src/ls.c 2004-03-13 11:50:03.000000000 +0000
  329. @@ -188,13 +188,13 @@
  330. enum filetype filetype;
  331. -#if HAVE_ACL
  332. +#if HAVE_ACL || USE_ACL
  333. /* For long listings, true if the file has an access control list. */
  334. bool have_acl;
  335. #endif
  336. };
  337. -#if HAVE_ACL
  338. +#if HAVE_ACL || USE_ACL
  339. # define FILE_HAS_ACL(F) ((F)->have_acl)
  340. #else
  341. # define FILE_HAS_ACL(F) 0
  342. @@ -2409,7 +2409,7 @@
  343. return 0;
  344. }
  345. -#if HAVE_ACL
  346. +#if HAVE_ACL || USE_ACL
  347. if (format == long_format)
  348. {
  349. int n = file_has_acl (path, &f->stat);
  350. --- ./src/install.c.acl 2004-03-13 11:50:03.000000000 +0000
  351. +++ ./src/install.c 2004-03-13 11:50:03.000000000 +0000
  352. @@ -242,7 +242,6 @@
  353. x->mode = S_IRUSR | S_IWUSR;
  354. x->stdin_tty = 0;
  355. - x->umask_kill = 0;
  356. x->update = 0;
  357. x->verbose = 0;
  358. x->dest_info = NULL;
  359. --- ./src/cp.c.acl 2004-02-07 15:55:09.000000000 +0000
  360. +++ ./src/cp.c 2004-03-13 11:50:03.000000000 +0000
  361. @@ -58,7 +58,8 @@
  362. need to be fixed after copying. */
  363. struct dir_attr
  364. {
  365. - int is_new_dir;
  366. + int mode_valid;
  367. + mode_t mode;
  368. int slash_offset;
  369. struct dir_attr *next;
  370. };
  371. @@ -333,9 +334,14 @@
  372. }
  373. }
  374. - if (x->preserve_mode || p->is_new_dir)
  375. - {
  376. - if (chmod (dst_path, src_sb.st_mode & x->umask_kill))
  377. + if (x->preserve_mode)
  378. + {
  379. + if (copy_acl (src_path, dst_path, src_sb.st_mode))
  380. + return 1;
  381. + }
  382. + else if (p->mode_valid)
  383. + {
  384. + if (chmod (dst_path, p->mode))
  385. {
  386. error (0, errno, _("failed to preserve permissions for %s"),
  387. quote (dst_path));
  388. @@ -353,8 +359,7 @@
  389. SRC_OFFSET is the index in CONST_DIRPATH (which is a destination
  390. path) of the beginning of the source directory name.
  391. - Create any leading directories that don't already exist,
  392. - giving them permissions MODE.
  393. + Create any leading directories that don't already exist.
  394. If VERBOSE_FMT_STRING is nonzero, use it as a printf format
  395. string for printing a message after successfully making a directory.
  396. The format should take two string arguments: the names of the
  397. @@ -369,15 +374,20 @@
  398. /* FIXME: find a way to synch this function with the one in lib/makepath.c. */
  399. static int
  400. -make_path_private (const char *const_dirpath, int src_offset, int mode,
  401. +make_path_private (const char *const_dirpath, int src_offset,
  402. const char *verbose_fmt_string, struct dir_attr **attr_list,
  403. - int *new_dst, int (*xstat)())
  404. + int *new_dst, const struct cp_options *x)
  405. {
  406. struct stat stats;
  407. char *dirpath; /* A copy of CONST_DIRPATH we can change. */
  408. char *src; /* Source name in `dirpath'. */
  409. char *dst_dirname; /* Leading path of `dirpath'. */
  410. size_t dirlen; /* Length of leading path of `dirpath'. */
  411. + mode_t mode;
  412. + int (*xstat)() = (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS
  413. + || x->dereference == DEREF_ALWAYS
  414. + ? stat
  415. + : lstat);
  416. ASSIGN_STRDUPA (dirpath, const_dirpath);
  417. @@ -412,12 +422,20 @@
  418. if ((*xstat) (dirpath, &stats))
  419. {
  420. /* This element of the path does not exist. We must set
  421. - *new_dst and new->is_new_dir inside this loop because,
  422. + *new_dst inside this loop because,
  423. for example, in the command `cp --parents ../a/../b/c e_dir',
  424. make_path_private creates only e_dir/../a if ./b already
  425. exists. */
  426. *new_dst = 1;
  427. - new->is_new_dir = 1;
  428. +
  429. + if ((*xstat) (src, &stats))
  430. + {
  431. + error (0, errno, _("failed to get attributes of %s"),
  432. + quote (src));
  433. + return 1;
  434. + }
  435. + mode = stats.st_mode;
  436. +
  437. if (mkdir (dirpath, mode))
  438. {
  439. error (0, errno, _("cannot make directory %s"),
  440. @@ -429,6 +447,46 @@
  441. if (verbose_fmt_string != NULL)
  442. printf (verbose_fmt_string, src, dirpath);
  443. }
  444. +
  445. + /* We need search and write permissions to the new directory
  446. + for adding the directory's contents. Check if these
  447. + permissions are already there. */
  448. +
  449. + if (lstat (dirpath, &stats))
  450. + {
  451. + error (0, errno, _("failed to get attributes of %s"),
  452. + quote (dirpath));
  453. + return 1;
  454. + }
  455. + else
  456. + {
  457. + if (x->preserve_mode && mode != stats.st_mode)
  458. + {
  459. + new->mode = mode;
  460. + new->mode_valid = 1;
  461. + }
  462. + else
  463. + new->mode_valid = 0;
  464. +
  465. + if ((stats.st_mode & S_IRWXU) != S_IRWXU)
  466. + {
  467. + /* Make the new directory writable and searchable. The
  468. + original permissions will be restored later. */
  469. +
  470. + if (!new->mode_valid)
  471. + {
  472. + new->mode = stats.st_mode;
  473. + new->mode_valid = 1;
  474. + }
  475. +
  476. + if (chmod (dirpath, stats.st_mode | S_IRWXU))
  477. + {
  478. + error (0, errno, _("setting permissions for %s"),
  479. + quote (dirpath));
  480. + return 1;
  481. + }
  482. + }
  483. + }
  484. }
  485. else if (!S_ISDIR (stats.st_mode))
  486. {
  487. @@ -438,7 +496,7 @@
  488. }
  489. else
  490. {
  491. - new->is_new_dir = 0;
  492. + new->mode_valid = 0;
  493. *new_dst = 0;
  494. }
  495. *slash++ = '/';
  496. @@ -552,10 +610,6 @@
  497. Copy the files `file1' through `filen'
  498. to the existing directory `edir'. */
  499. int i;
  500. - int (*xstat)() = (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS
  501. - || x->dereference == DEREF_ALWAYS
  502. - ? stat
  503. - : lstat);
  504. for (i = 0; i < n_files; i++)
  505. {
  506. @@ -593,11 +647,9 @@
  507. leading directories. */
  508. parent_exists = !make_path_private (dst_path,
  509. arg_in_concat - dst_path,
  510. - S_IRWXU,
  511. (x->verbose
  512. ? "%s -> %s\n" : NULL),
  513. - &attr_list, &new_dst,
  514. - xstat);
  515. + &attr_list, &new_dst, x);
  516. }
  517. else
  518. {
  519. @@ -731,12 +783,6 @@
  520. /* Not used. */
  521. x->stdin_tty = 0;
  522. - /* Find out the current file creation mask, to knock the right bits
  523. - when using chmod. The creation mask is set to be liberal, so
  524. - that created directories can be written, even if it would not
  525. - have been allowed with the mask this process was started with. */
  526. - x->umask_kill = ~ umask (0);
  527. -
  528. x->update = 0;
  529. x->verbose = 0;
  530. x->dest_info = NULL;
  531. @@ -1011,9 +1057,6 @@
  532. version_control_string)
  533. : none);
  534. - if (x.preserve_mode == 1)
  535. - x.umask_kill = ~ (mode_t) 0;
  536. -
  537. if (x.dereference == DEREF_UNDEFINED)
  538. {
  539. if (x.recursive)
  540. --- ./src/copy.h.acl 2004-02-07 16:00:59.000000000 +0000
  541. +++ ./src/copy.h 2004-03-13 11:50:03.000000000 +0000
  542. @@ -143,9 +143,6 @@
  543. Create destination directories as usual. */
  544. int symbolic_link;
  545. - /* The bits to preserve in created files' modes. */
  546. - mode_t umask_kill;
  547. -
  548. /* If nonzero, do not copy a nondirectory that has an existing destination
  549. with the same or newer modification time. */
  550. int update;
  551. --- ./src/copy.c.acl 2004-03-12 11:48:59.000000000 +0000
  552. +++ ./src/copy.c 2004-03-13 11:50:43.000000000 +0000
  553. @@ -95,26 +95,6 @@
  554. /* The invocation name of this program. */
  555. extern char *program_name;
  556. -/* Encapsulate selection of the file mode to be applied to
  557. - new non-directories. */
  558. -
  559. -static mode_t
  560. -get_dest_mode (const struct cp_options *option, mode_t mode)
  561. -{
  562. - /* In some applications (e.g., install), use precisely the
  563. - specified mode. */
  564. - if (option->set_mode)
  565. - return option->mode;
  566. -
  567. - /* Honor the umask for `cp', but not for `mv' or `cp -p'.
  568. - In addition, `cp' without -p must clear the set-user-ID and set-group-ID
  569. - bits. POSIX requires it do that when creating new files. */
  570. - if (!option->move_mode && !option->preserve_mode)
  571. - mode &= (option->umask_kill & ~(S_ISUID | S_ISGID));
  572. -
  573. - return mode;
  574. -}
  575. -
  576. /* FIXME: describe */
  577. /* FIXME: rewrite this to use a hash table so we avoid the quadratic
  578. performance hit that's probably noticeable only on trees deeper
  579. @@ -817,13 +797,13 @@
  580. struct stat src_sb;
  581. struct stat dst_sb;
  582. mode_t src_mode;
  583. - mode_t src_type;
  584. + mode_t dst_mode;
  585. char *earlier_file = NULL;
  586. char *dst_backup = NULL;
  587. int backup_succeeded = 0;
  588. int delayed_fail;
  589. int copied_as_regular = 0;
  590. - int ran_chown = 0;
  591. + int dst_mode_valid = 0;
  592. int preserve_metadata;
  593. if (x->move_mode && rename_succeeded)
  594. @@ -837,11 +817,9 @@
  595. return 1;
  596. }
  597. - src_type = src_sb.st_mode;
  598. -
  599. src_mode = src_sb.st_mode;
  600. - if (S_ISDIR (src_type) && !x->recursive)
  601. + if (S_ISDIR (src_mode) && !x->recursive)
  602. {
  603. error (0, 0, _("omitting directory %s"), quote (src_path));
  604. return 1;
  605. @@ -909,7 +887,7 @@
  606. if (!S_ISDIR (dst_sb.st_mode))
  607. {
  608. - if (S_ISDIR (src_type))
  609. + if (S_ISDIR (src_mode))
  610. {
  611. error (0, 0,
  612. _("cannot overwrite non-directory %s with directory %s"),
  613. @@ -935,7 +913,7 @@
  614. }
  615. }
  616. - if (!S_ISDIR (src_type))
  617. + if (!S_ISDIR (src_mode))
  618. {
  619. if (S_ISDIR (dst_sb.st_mode))
  620. {
  621. @@ -963,7 +941,7 @@
  622. This may be due to an interactive `negative' reply to the
  623. prompt about the existing file. It may also be due to the
  624. use of the --reply=no option. */
  625. - if (!S_ISDIR (src_type))
  626. + if (!S_ISDIR (src_mode))
  627. {
  628. /* cp and mv treat -i and -f differently. */
  629. if (x->move_mode)
  630. @@ -1084,7 +1062,7 @@
  631. /* If the source is a directory, we don't always create the destination
  632. directory. So --verbose should not announce anything until we're
  633. sure we'll create a directory. */
  634. - if (x->verbose && !S_ISDIR (src_type))
  635. + if (x->verbose && !S_ISDIR (src_mode))
  636. {
  637. printf ("%s -> %s", quote_n (0, src_path), quote_n (1, dst_path));
  638. if (backup_succeeded)
  639. @@ -1132,7 +1110,7 @@
  640. || (command_line_arg
  641. && x->dereference == DEREF_COMMAND_LINE_ARGUMENTS)
  642. || x->dereference == DEREF_ALWAYS))
  643. - || (x->recursive && S_ISDIR (src_type)))
  644. + || (x->recursive && S_ISDIR (src_mode)))
  645. {
  646. earlier_file = remember_copied (dst_path, src_sb.st_ino, src_sb.st_dev);
  647. }
  648. @@ -1145,7 +1123,7 @@
  649. /* Avoid damaging the destination filesystem by refusing to preserve
  650. hard-linked directories (which are found at least in Netapp snapshot
  651. directories). */
  652. - if (S_ISDIR (src_type))
  653. + if (S_ISDIR (src_mode))
  654. {
  655. /* If src_path and earlier_file refer to the same directory entry,
  656. then warn about copying a directory into itself. */
  657. @@ -1197,7 +1175,7 @@
  658. {
  659. if (rename (src_path, dst_path) == 0)
  660. {
  661. - if (x->verbose && S_ISDIR (src_type))
  662. + if (x->verbose && S_ISDIR (src_mode))
  663. printf ("%s -> %s\n", quote_n (0, src_path), quote_n (1, dst_path));
  664. if (rename_succeeded)
  665. *rename_succeeded = 1;
  666. @@ -1310,7 +1288,7 @@
  667. In such cases, set this variable to zero. */
  668. preserve_metadata = 1;
  669. - if (S_ISDIR (src_type))
  670. + if (S_ISDIR (src_mode))
  671. {
  672. struct dir_list *dir;
  673. @@ -1335,16 +1313,38 @@
  674. if (new_dst || !S_ISDIR (dst_sb.st_mode))
  675. {
  676. - /* Create the new directory writable and searchable, so
  677. - we can create new entries in it. */
  678. -
  679. - if (mkdir (dst_path, (src_mode & x->umask_kill) | S_IRWXU))
  680. + if (mkdir (dst_path, src_mode))
  681. {
  682. error (0, errno, _("cannot create directory %s"),
  683. quote (dst_path));
  684. goto un_backup;
  685. }
  686. + /* We need search and write permissions to the new directory
  687. + for adding the directory's contents. Check if these permissions
  688. + are already there. */
  689. +
  690. + if (lstat (dst_path, &dst_sb))
  691. + {
  692. + error (0, errno, _("cannot stat %s"), quote (dst_path));
  693. + delayed_fail = 1;
  694. + }
  695. + else if ((dst_sb.st_mode & S_IRWXU) != S_IRWXU)
  696. + {
  697. + /* Make the new directory writable and searchable. The original
  698. + permissions will be restored later. */
  699. +
  700. + dst_mode_valid = 1;
  701. + dst_mode = dst_sb.st_mode;
  702. +
  703. + if (chmod (dst_path, dst_mode | S_IRWXU))
  704. + {
  705. + error (0, errno, _("setting permissions for %s"),
  706. + quote (dst_path));
  707. + goto un_backup;
  708. + }
  709. + }
  710. +
  711. /* Insert the created directory's inode and device
  712. numbers into the search structure, so that we can
  713. avoid copying it again. */
  714. @@ -1420,23 +1420,22 @@
  715. goto un_backup;
  716. }
  717. }
  718. - else if (S_ISREG (src_type)
  719. - || (x->copy_as_regular && !S_ISDIR (src_type)
  720. - && !S_ISLNK (src_type)))
  721. + else if (S_ISREG (src_mode)
  722. + || (x->copy_as_regular && !S_ISDIR (src_mode)
  723. + && !S_ISLNK (src_mode)))
  724. {
  725. copied_as_regular = 1;
  726. /* POSIX says the permission bits of the source file must be
  727. used as the 3rd argument in the open call, but that's not consistent
  728. with historical practice. */
  729. - if (copy_reg (src_path, dst_path, x,
  730. - get_dest_mode (x, src_mode), &new_dst, &src_sb))
  731. + if (copy_reg (src_path, dst_path, x, src_mode, &new_dst, &src_sb))
  732. goto un_backup;
  733. }
  734. else
  735. #ifdef S_ISFIFO
  736. - if (S_ISFIFO (src_type))
  737. + if (S_ISFIFO (src_mode))
  738. {
  739. - if (mkfifo (dst_path, get_dest_mode (x, src_mode)))
  740. + if (mkfifo (dst_path, src_mode))
  741. {
  742. error (0, errno, _("cannot create fifo %s"), quote (dst_path));
  743. goto un_backup;
  744. @@ -1444,10 +1443,10 @@
  745. }
  746. else
  747. #endif
  748. - if (S_ISBLK (src_type) || S_ISCHR (src_type)
  749. - || S_ISSOCK (src_type))
  750. + if (S_ISBLK (src_mode) || S_ISCHR (src_mode)
  751. + || S_ISSOCK (src_mode))
  752. {
  753. - if (mknod (dst_path, get_dest_mode (x, src_mode), src_sb.st_rdev))
  754. + if (mknod (dst_path, src_mode, src_sb.st_rdev))
  755. {
  756. error (0, errno, _("cannot create special file %s"),
  757. quote (dst_path));
  758. @@ -1456,7 +1455,7 @@
  759. }
  760. else
  761. #ifdef S_ISLNK
  762. - if (S_ISLNK (src_type))
  763. + if (S_ISLNK (src_mode))
  764. {
  765. char *src_link_val = xreadlink (src_path);
  766. if (src_link_val == NULL)
  767. @@ -1560,7 +1559,25 @@
  768. if (x->preserve_ownership
  769. && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb)))
  770. {
  771. - ran_chown = 1;
  772. + /* The chown() system call may clear the SUID and SGID bits, so we
  773. + need to set them again later. (But we don't care if we will
  774. + overwrite the permissions of the destination file anyway.) */
  775. +
  776. + if ((src_mode & (S_ISUID | S_ISGID))
  777. + && !x->preserve_mode && !x->move_mode && !x->set_mode)
  778. + {
  779. + if (lstat (dst_path, &dst_sb))
  780. + {
  781. + error (0, errno, _("cannot stat %s"), quote (dst_path));
  782. + delayed_fail = 1;
  783. + }
  784. + else
  785. + {
  786. + dst_mode_valid = 1;
  787. + dst_mode = dst_sb.st_mode;
  788. + }
  789. + }
  790. +
  791. if (DO_CHOWN (chown, dst_path, src_sb.st_uid, src_sb.st_gid))
  792. {
  793. error (0, errno, _("failed to preserve ownership for %s"),
  794. @@ -1587,20 +1604,23 @@
  795. }
  796. #endif
  797. - /* Permissions of newly-created regular files were set upon `open' in
  798. - copy_reg. But don't return early if there were any special bits and
  799. - we had to run chown, because the chown must have reset those bits. */
  800. - if ((new_dst && copied_as_regular)
  801. - && !(ran_chown && (src_mode & ~S_IRWXUGO)))
  802. - return delayed_fail;
  803. -
  804. - if ((x->preserve_mode || new_dst)
  805. - && (x->copy_as_regular || S_ISREG (src_type) || S_ISDIR (src_type)))
  806. + if (x->preserve_mode || x->move_mode)
  807. {
  808. - if (chmod (dst_path, get_dest_mode (x, src_mode)))
  809. - {
  810. - error (0, errno, _("setting permissions for %s"), quote (dst_path));
  811. - if (x->set_mode || x->require_preserve)
  812. + if (copy_acl (src_path, dst_path, src_mode) && x->require_preserve)
  813. + return 1;
  814. + }
  815. + else if (x->set_mode)
  816. + {
  817. + if (set_acl (dst_path, x->mode) && x->require_preserve)
  818. + return 1;
  819. + }
  820. + else if (dst_mode_valid)
  821. + {
  822. + if (chmod (dst_path, dst_mode))
  823. + {
  824. + error (0, errno, _("preserving permissions for %s"),
  825. + quote (dst_path));
  826. + if (x->require_preserve)
  827. return 1;
  828. }
  829. }
  830. --- ./src/Makefile.am.acl 2004-02-02 08:12:57.000000000 +0000
  831. +++ ./src/Makefile.am 2004-03-13 11:50:03.000000000 +0000
  832. @@ -32,10 +32,13 @@
  833. # replacement functions defined in libfetish.a.
  834. LDADD = ../lib/libfetish.a $(LIBINTL) ../lib/libfetish.a
  835. -dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
  836. -ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
  837. +dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBACL@
  838. +ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBACL@
  839. shred_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
  840. -vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
  841. +vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBACL@
  842. +cp_LDADD = $(LDADD) @LIBACL@
  843. +ginstall_LDADD = $(LDADD) @LIBACL@
  844. +mv_LDADD = $(LDADD) @LIBACL@
  845. ## If necessary, add -lm to resolve use of pow in lib/strtod.c.
  846. sort_LDADD = $(LDADD) $(POW_LIB)
  847. --- ./configure.ac.acl 2004-03-02 22:47:31.000000000 +0000
  848. +++ ./configure.ac 2004-03-13 11:50:03.000000000 +0000
  849. @@ -16,6 +16,9 @@
  850. AC_PROG_RANLIB
  851. AC_PROG_LN_S
  852. AC_CANONICAL_HOST
  853. +AM_C_PROTOTYPES
  854. +AC_PROG_YACC
  855. +AC_SUBST(YACC)
  856. AC_CHECK_FUNCS(uname,
  857. @@ -235,6 +238,8 @@
  858. AM_GNU_GETTEXT([external], [need-ngettext])
  859. AM_GNU_GETTEXT_VERSION(0.13.1)
  860. +ag_POSIX_ACL
  861. +
  862. AC_CONFIG_FILES(
  863. Makefile
  864. doc/Makefile
  865. --- ./config.hin.acl 2004-03-11 08:59:16.000000000 +0000
  866. +++ ./config.hin 2004-03-13 11:50:03.000000000 +0000
  867. @@ -96,6 +96,30 @@
  868. /* Define to 1 if you have the `acl' function. */
  869. #undef HAVE_ACL
  870. +/* Define to 1 if you have the `acl_delete_def_file' function. */
  871. +#undef HAVE_ACL_DELETE_DEF_FILE
  872. +
  873. +/* Define to 1 if you have the `acl_entries' function. */
  874. +#undef HAVE_ACL_ENTRIES
  875. +
  876. +/* Define to 1 if you have the `acl_extended_file' function. */
  877. +#undef HAVE_ACL_EXTENDED_FILE
  878. +
  879. +/* Define to 1 if you have the `acl_free' function. */
  880. +#undef HAVE_ACL_FREE
  881. +
  882. +/* Define to 1 if you have the `acl_from_text' function. */
  883. +#undef HAVE_ACL_FROM_TEXT
  884. +
  885. +/* Define to 1 if you have the `acl_get_file' function. */
  886. +#undef HAVE_ACL_GET_FILE
  887. +
  888. +/* Define to 1 if you have the `acl_set_file' function. */
  889. +#undef HAVE_ACL_SET_FILE
  890. +
  891. +/* Define to 1 if you have the `acl_to_text' function. */
  892. +#undef HAVE_ACL_TO_TEXT
  893. +
  894. /* Define to 1 if you have the `alarm' function. */
  895. #undef HAVE_ALARM
  896. @@ -489,6 +513,9 @@
  897. /* Define to 1 if you have the `lchown' function. */
  898. #undef HAVE_LCHOWN
  899. +/* Define to 1 if you have the `acl' library (-lacl). */
  900. +#undef HAVE_LIBACL
  901. +
  902. /* Define to 1 if you have the `dgc' library (-ldgc). */
  903. #undef HAVE_LIBDGC
  904. @@ -1335,6 +1362,9 @@
  905. <sys/cpustats.h>. */
  906. #undef UMAX4_3
  907. +/* Define if you want access control list support. */
  908. +#undef USE_ACL
  909. +
  910. /* Version number of package */
  911. #undef VERSION