aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2008-01-16 16:37:36 +0000
committerAvatar David Leverton <levertond@googlemail.com> 2008-01-16 16:37:36 +0000
commit564b9d2d300b9718d3d474d115524565403c9890 (patch)
tree1cd02f2e3f9bd3d8e568ec13fb02f75d39e7c936
parentaa261ee83c6787a0b5daf35ee4dfafb209231749 (diff)
downloadpaludis-564b9d2d300b9718d3d474d115524565403c9890.tar.gz
paludis-564b9d2d300b9718d3d474d115524565403c9890.tar.xz
Fix symlink ownership in the merger.
-rw-r--r--paludis/merger.cc12
-rw-r--r--paludis/util/fs_entry.cc8
-rw-r--r--paludis/util/fs_entry.hh9
3 files changed, 25 insertions, 4 deletions
diff --git a/paludis/merger.cc b/paludis/merger.cc
index 7da0e92..79dfee1 100644
--- a/paludis/merger.cc
+++ b/paludis/merger.cc
@@ -506,8 +506,8 @@ Merger::on_dir_over_nothing(bool is_check, const FSEntry & src, const FSEntry &
if (is_check)
return;
- install_dir(src, dst);
record_install_dir(src, dst);
+ install_dir(src, dst);
}
void
@@ -727,7 +727,6 @@ Merger::rewrite_symlink_as_needed(const FSEntry & src, const FSEntry & dst_dir)
void
Merger::record_renamed_dir_recursive(const FSEntry & dst)
{
- record_install_dir(dst, dst.dirname());
for (DirIterator d(dst, false), d_end ; d != d_end ; ++d)
{
if (! _options.no_chown)
@@ -737,7 +736,7 @@ Merger::record_renamed_dir_recursive(const FSEntry & dst)
if (uid_t(-1) != new_uid || gid_t(-1) != new_gid)
{
FSEntry f(*d);
- f.chown(new_uid, new_gid);
+ f.lchown(new_uid, new_gid);
if (et_dir == entry_type(*d))
{
@@ -764,6 +763,7 @@ Merger::record_renamed_dir_recursive(const FSEntry & dst)
continue;
case et_dir:
+ record_install_dir(*d, d->dirname());
record_renamed_dir_recursive(*d);
continue;
@@ -875,6 +875,9 @@ Merger::install_sym(const FSEntry & src, const FSEntry & dst_dir)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' pre hooks returned non-zero");
+ uid_t dest_uid(src.owner() == _options.environment->reduced_uid() ? 0 : src.owner());
+ gid_t dest_gid(src.group() == _options.environment->reduced_gid() ? 0 : src.group());
+
if (symlink_needs_rewriting(src))
rewrite_symlink_as_needed(src, dst_dir);
else
@@ -885,6 +888,9 @@ Merger::install_sym(const FSEntry & src, const FSEntry & dst_dir)
+ stringify(::strerror(errno)));
}
+ if (! _options.no_chown)
+ FSEntry(dst_dir / src.basename()).lchown(dest_uid, dest_gid);
+
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_sym_post")
("INSTALL_SOURCE", stringify(src))
diff --git a/paludis/util/fs_entry.cc b/paludis/util/fs_entry.cc
index 3c04949..6fcc3b1 100644
--- a/paludis/util/fs_entry.cc
+++ b/paludis/util/fs_entry.cc
@@ -608,6 +608,14 @@ FSEntry::chown(const uid_t new_owner, const gid_t new_group)
}
void
+FSEntry::lchown(const uid_t new_owner, const gid_t new_group)
+{
+ if (0 != ::lchown(_imp->path.c_str(), new_owner, new_group))
+ throw FSError("lchown '" + _imp->path + "' to '" + stringify(new_owner) + "', '"
+ + stringify(new_group) + "' failed: " + ::strerror(errno));
+}
+
+void
FSEntry::chmod(const mode_t mode)
{
if (0 != ::chmod(_imp->path.c_str(), mode))
diff --git a/paludis/util/fs_entry.hh b/paludis/util/fs_entry.hh
index 3d3ae45..244463b 100644
--- a/paludis/util/fs_entry.hh
+++ b/paludis/util/fs_entry.hh
@@ -351,13 +351,20 @@ namespace paludis
bool utime(const struct ::utimbuf * buf = 0);
/**
- * Change our permissions.
+ * Change our ownership, following symlinks.
*
* \exception FSError If the chown failed.
*/
void chown(const uid_t owner, const gid_t group = static_cast<gid_t>(-1));
/**
+ * Change our ownership, not following symlinks.
+ *
+ * \exception FSError If the lchown failed.
+ */
+ void lchown(const uid_t owner, const gid_t group = static_cast<gid_t>(-1));
+
+ /**
* Change our permissions.
*
* \exception FSError If the chmod failed.