aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-01-22 12:46:23 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-01-22 12:46:23 +0000
commit24457af06d3b1e2d3367e869ddc52b1feb694b29 (patch)
tree84472a1ef83a273a8813e249d5cf88299e889890
parent5d58495bb95b3432aad6f5cb6445906f78845764 (diff)
downloadpaludis-24457af06d3b1e2d3367e869ddc52b1feb694b29.tar.gz
paludis-24457af06d3b1e2d3367e869ddc52b1feb694b29.tar.xz
Work around Linux clobbering set*id bits on a rename. Display more information about how we did a merge.
-rw-r--r--paludis/files.m42
-rw-r--r--paludis/merger.cc91
-rw-r--r--paludis/merger.hh24
-rw-r--r--paludis/merger.se24
-rw-r--r--paludis/merger.sr1
-rw-r--r--paludis/merger_TEST.cc8
-rw-r--r--paludis/repositories/e/vdb_merger.cc60
-rw-r--r--paludis/repositories/e/vdb_merger.hh9
-rw-r--r--paludis/repositories/unpackaged/ndbam_merger.cc61
-rw-r--r--paludis/repositories/unpackaged/ndbam_merger.hh9
10 files changed, 221 insertions, 68 deletions
diff --git a/paludis/files.m4 b/paludis/files.m4
index b1b9426..573c84b 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -36,7 +36,7 @@ add(`install_task', `hh', `cc', `se')
add(`literal_metadata_key', `hh', `cc')
add(`mask', `hh', `cc', `fwd', `sr')
add(`match_package', `hh', `cc')
-add(`merger', `hh', `cc', `sr', `test', `testscript')
+add(`merger', `hh', `cc', `se', `sr', `test', `testscript')
add(`merger_entry_type', `hh', `cc', `se')
add(`metadata_key', `hh', `cc', `se', `fwd')
add(`name', `hh', `cc', `fwd', `test', `sr', `se')
diff --git a/paludis/merger.cc b/paludis/merger.cc
index 79dfee1..c478d29 100644
--- a/paludis/merger.cc
+++ b/paludis/merger.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 Ciaran McCreesh
* Copyright (c) 2008 Fernando J. Pereda
*
* This file is part of the Paludis package manager. Paludis is free software;
@@ -23,6 +23,7 @@
#include <paludis/util/stringify.hh>
#include <paludis/util/fd_holder.hh>
#include <paludis/util/log.hh>
+#include <paludis/util/options.hh>
#include <paludis/selinux/security_context.hh>
#include <paludis/environment.hh>
#include <paludis/hook.hh>
@@ -447,8 +448,7 @@ Merger::on_file_over_nothing(bool is_check, const FSEntry & src, const FSEntry &
if (is_check)
return;
- install_file(src, dst, src.basename());
- record_install_file(src, dst, src.basename());
+ record_install_file(src, dst, src.basename(), install_file(src, dst, src.basename()));
}
void
@@ -460,14 +460,12 @@ Merger::on_file_over_file(bool is_check, const FSEntry & src, const FSEntry & ds
if (config_protected(src, dst))
{
std::string cfgpro_name(make_config_protect_name(src, dst));
- install_file(src, dst, cfgpro_name);
- record_install_file(src, dst, cfgpro_name);
+ record_install_file(src, dst, cfgpro_name, install_file(src, dst, cfgpro_name));
}
else
{
unlink_file(dst / src.basename());
- install_file(src, dst, src.basename());
- record_install_file(src, dst, src.basename());
+ record_install_file(src, dst, src.basename(), install_file(src, dst, src.basename()) + msi_unlinked_first);
}
}
@@ -485,8 +483,7 @@ Merger::on_file_over_sym(bool is_check, const FSEntry & src, const FSEntry & dst
return;
unlink_sym(dst / src.basename());
- install_file(src, dst, src.basename());
- record_install_file(src, dst, src.basename());
+ record_install_file(src, dst, src.basename(), install_file(src, dst, src.basename()) + msi_unlinked_first);
}
void
@@ -496,8 +493,7 @@ Merger::on_file_over_misc(bool is_check, const FSEntry & src, const FSEntry & ds
return;
unlink_misc(dst / src.basename());
- install_file(src, dst, src.basename());
- record_install_file(src, dst, src.basename());
+ record_install_file(src, dst, src.basename(), install_file(src, dst, src.basename()) + msi_unlinked_first);
}
void
@@ -506,8 +502,7 @@ Merger::on_dir_over_nothing(bool is_check, const FSEntry & src, const FSEntry &
if (is_check)
return;
- record_install_dir(src, dst);
- install_dir(src, dst);
+ record_install_dir(src, dst, install_dir(src, dst));
}
void
@@ -523,7 +518,7 @@ Merger::on_dir_over_dir(bool is_check, const FSEntry & src, const FSEntry & dst)
if (is_check)
return;
- record_install_dir(src, dst);
+ record_install_dir(src, dst, MergeStatusFlags() + msi_used_existing);
}
void
@@ -544,7 +539,7 @@ Merger::on_dir_over_sym(bool is_check, const FSEntry & src, const FSEntry & dst)
on_warn(is_check, "Expected '" + stringify(dst / src.basename()) +
"' to be a directory but found a symlink to a directory");
if (! is_check)
- record_install_dir(src, dst);
+ record_install_dir(src, dst, MergeStatusFlags() + msi_used_existing);
}
else
on_error(is_check, "Expected '" + stringify(dst / src.basename()) +
@@ -558,8 +553,7 @@ Merger::on_dir_over_misc(bool is_check, const FSEntry & src, const FSEntry & dst
return;
unlink_misc(dst / src.basename());
- install_dir(src, dst);
- record_install_dir(src, dst);
+ record_install_dir(src, dst, install_dir(src, dst) + msi_unlinked_first);
}
void
@@ -568,8 +562,7 @@ Merger::on_sym_over_nothing(bool is_check, const FSEntry & src, const FSEntry &
if (is_check)
return;
- install_sym(src, dst);
- record_install_sym(src, dst);
+ record_install_sym(src, dst, install_sym(src, dst));
}
void
@@ -579,8 +572,7 @@ Merger::on_sym_over_file(bool is_check, const FSEntry & src, const FSEntry & dst
return;
unlink_file(dst / src.basename());
- install_sym(src, dst);
- record_install_sym(src, dst);
+ record_install_sym(src, dst, install_sym(src, dst) + msi_unlinked_first);
}
void
@@ -597,8 +589,7 @@ Merger::on_sym_over_sym(bool is_check, const FSEntry & src, const FSEntry & dst)
return;
unlink_sym(dst / src.basename());
- install_sym(src, dst);
- record_install_sym(src, dst);
+ record_install_sym(src, dst, install_sym(src, dst) + msi_unlinked_first);
}
void
@@ -608,15 +599,15 @@ Merger::on_sym_over_misc(bool is_check, const FSEntry & src, const FSEntry & dst
return;
unlink_misc(dst / src.basename());
- install_sym(src, dst);
- record_install_sym(src, dst);
+ record_install_sym(src, dst, install_sym(src, dst) + msi_unlinked_first);
}
-void
+MergeStatusFlags
Merger::install_file(const FSEntry & src, const FSEntry & dst_dir, const std::string & dst_name)
{
Context context("When installing file '" + stringify(src) + "' to '" + stringify(dst_dir) + "' with protection '"
+ stringify(dst_name) + "':");
+ MergeStatusFlags result;
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_file_pre")
@@ -634,6 +625,10 @@ Merger::install_file(const FSEntry & src, const FSEntry & dst_dir, const std::st
throw MergerError("Could not set SELinux context on '"
+ stringify(src) + "': " + stringify(::strerror(errno)));
+ mode_t src_perms(src.permissions());
+ if (0 != (src_perms & (S_ISVTX | S_ISUID | S_ISGID)))
+ result += msi_setid_bits;
+
uid_t dest_uid(src.owner());
gid_t dest_gid(src.group());
@@ -642,15 +637,22 @@ Merger::install_file(const FSEntry & src, const FSEntry & dst_dir, const std::st
uid_t new_uid(dest_uid == _options.environment->reduced_uid() ? 0 : -1);
gid_t new_gid(dest_gid == _options.environment->reduced_gid() ? 0 : -1);
if (uid_t(-1) != new_uid || gid_t(-1) != new_gid)
+ {
FSEntry(src).chown(new_uid, new_gid);
+ result += msi_fixed_ownership;
+ }
dest_uid = new_uid == 0 ? 0 : dest_uid;
dest_gid = new_gid == 0 ? 0 : dest_gid;
}
if (0 == ::rename(stringify(src).c_str(), stringify(dst_real).c_str()))
{
+ result += msi_rename;
if (! dst_real.utime())
throw MergerError("utime(" + stringify(dst_real) + ", 0) failed: " + stringify(::strerror(errno)));
+
+ /* set*id bits get partially clobbered on a rename on linux */
+ dst_real.chmod(src_perms);
}
else
{
@@ -661,8 +663,7 @@ Merger::install_file(const FSEntry & src, const FSEntry & dst_dir, const std::st
if (-1 == input_fd)
throw MergerError("Cannot read '" + stringify(src) + "': " + stringify(::strerror(errno)));
- FDHolder output_fd(::open(stringify(dst).c_str(), O_WRONLY | O_CREAT,
- src.permissions()), false);
+ FDHolder output_fd(::open(stringify(dst).c_str(), O_WRONLY | O_CREAT, src_perms), false);
if (-1 == output_fd)
throw MergerError("Cannot write '" + stringify(dst) + "': " + stringify(::strerror(errno)));
@@ -671,7 +672,7 @@ Merger::install_file(const FSEntry & src, const FSEntry & dst_dir, const std::st
throw MergerError("Cannot fchown '" + stringify(dst) + "': " + stringify(::strerror(errno)));
/* set*id bits */
- if (0 != ::fchmod(output_fd, src.permissions()))
+ if (0 != ::fchmod(output_fd, src_perms))
throw MergerError("Cannot fchmod '" + stringify(dst) + "': " + stringify(::strerror(errno)));
char buf[4096];
@@ -693,6 +694,8 @@ Merger::install_file(const FSEntry & src, const FSEntry & dst_dir, const std::st
("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' post hooks returned non-zero");
+
+ return result;
}
bool
@@ -755,15 +758,15 @@ Merger::record_renamed_dir_recursive(const FSEntry & dst)
{
case et_sym:
rewrite_symlink_as_needed(*d, dst);
- record_install_sym(*d, dst);
+ record_install_sym(*d, dst, MergeStatusFlags() + msi_parent_rename);
continue;
case et_file:
- record_install_file(*d, dst, stringify(d->basename()));
+ record_install_file(*d, dst, stringify(d->basename()), MergeStatusFlags() + msi_parent_rename);
continue;
case et_dir:
- record_install_dir(*d, d->dirname());
+ record_install_dir(*d, d->dirname(), MergeStatusFlags() + msi_parent_rename);
record_renamed_dir_recursive(*d);
continue;
@@ -796,11 +799,13 @@ Merger::relabel_dir_recursive(const FSEntry & src, const FSEntry & dst)
}
}
-void
+MergeStatusFlags
Merger::install_dir(const FSEntry & src, const FSEntry & dst_dir)
{
Context context("When installing dir '" + stringify(src) + "' to '" + stringify(dst_dir) + "':");
+ MergeStatusFlags result;
+
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_dir_pre")
("INSTALL_SOURCE", stringify(src))
@@ -812,6 +817,9 @@ Merger::install_dir(const FSEntry & src, const FSEntry & dst_dir)
uid_t dest_uid(src.owner());
gid_t dest_gid(src.group());
+ if (0 != (mode & (S_ISVTX | S_ISUID | S_ISGID)))
+ result += msi_setid_bits;
+
if (! _options.no_chown)
{
uid_t new_uid(dest_uid == _options.environment->reduced_uid() ? 0 : -1);
@@ -822,6 +830,7 @@ Merger::install_dir(const FSEntry & src, const FSEntry & dst_dir)
mode &= ~S_ISGID;
if (uid_t(-1) != new_uid || gid_t(-1) != new_gid)
{
+ result += msi_fixed_ownership;
FSEntry f(src);
f.chown(new_uid, new_gid);
f.chmod(mode);
@@ -842,6 +851,7 @@ Merger::install_dir(const FSEntry & src, const FSEntry & dst_dir)
if (0 == ::rename(stringify(src).c_str(), stringify(dst).c_str()))
{
+ result += msi_rename;
record_renamed_dir_recursive(dst);
_skip_dir = true;
}
@@ -861,13 +871,17 @@ Merger::install_dir(const FSEntry & src, const FSEntry & dst_dir)
("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' post hooks returned non-zero");
+
+ return result;
}
-void
+MergeStatusFlags
Merger::install_sym(const FSEntry & src, const FSEntry & dst_dir)
{
Context context("When installing sym '" + stringify(src) + "' to '" + stringify(dst_dir) + "':");
+ MergeStatusFlags result;
+
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_sym_pre")
("INSTALL_SOURCE", stringify(src))
@@ -878,6 +892,9 @@ Merger::install_sym(const FSEntry & src, const FSEntry & dst_dir)
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 (0 != (src.permissions() & (S_ISVTX | S_ISUID | S_ISGID)))
+ result += msi_setid_bits;
+
if (symlink_needs_rewriting(src))
rewrite_symlink_as_needed(src, dst_dir);
else
@@ -889,7 +906,11 @@ Merger::install_sym(const FSEntry & src, const FSEntry & dst_dir)
}
if (! _options.no_chown)
+ {
+ if (src.owner() != dest_uid || src.group() != dest_gid)
+ result += msi_fixed_ownership;
FSEntry(dst_dir / src.basename()).lchown(dest_uid, dest_gid);
+ }
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_sym_post")
@@ -897,6 +918,8 @@ Merger::install_sym(const FSEntry & src, const FSEntry & dst_dir)
("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' post hooks returned non-zero");
+
+ return result;
}
void
diff --git a/paludis/merger.hh b/paludis/merger.hh
index a98d289..2f05913 100644
--- a/paludis/merger.hh
+++ b/paludis/merger.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -23,6 +23,7 @@
#include <paludis/util/sr.hh>
#include <paludis/util/fs_entry.hh>
#include <paludis/util/exception.hh>
+#include <paludis/util/options-fwd.hh>
#include <paludis/merger_entry_type.hh>
#include <iosfwd>
@@ -42,9 +43,18 @@ namespace paludis
class Environment;
class Hook;
+#include <paludis/merger-se.hh>
#include <paludis/merger-sr.hh>
/**
+ * Status flags for Merger.
+ *
+ * \ingroup g_repository
+ * \since 0.26
+ */
+ typedef Options<MergeStatusFlag> MergeStatusFlags;
+
+ /**
* Thrown if an error occurs during a Merger operation.
*
* \ingroup g_repository
@@ -129,9 +139,9 @@ namespace paludis
virtual void on_file_over_sym(bool is_check, const FSEntry &, const FSEntry &);
virtual void on_file_over_misc(bool is_check, const FSEntry &, const FSEntry &);
- virtual void install_file(const FSEntry &, const FSEntry &, const std::string &);
+ virtual MergeStatusFlags install_file(const FSEntry &, const FSEntry &, const std::string &) PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void unlink_file(FSEntry);
- virtual void record_install_file(const FSEntry &, const FSEntry &, const std::string &) = 0;
+ virtual void record_install_file(const FSEntry &, const FSEntry &, const std::string &, const MergeStatusFlags &) = 0;
virtual void on_dir(bool is_check, const FSEntry &, const FSEntry &);
virtual void on_dir_over_nothing(bool is_check, const FSEntry &, const FSEntry &);
@@ -140,9 +150,9 @@ namespace paludis
virtual void on_dir_over_sym(bool is_check, const FSEntry &, const FSEntry &);
virtual void on_dir_over_misc(bool is_check, const FSEntry &, const FSEntry &);
- virtual void install_dir(const FSEntry &, const FSEntry &);
+ virtual MergeStatusFlags install_dir(const FSEntry &, const FSEntry &) PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void unlink_dir(FSEntry);
- virtual void record_install_dir(const FSEntry &, const FSEntry &) = 0;
+ virtual void record_install_dir(const FSEntry &, const FSEntry &, const MergeStatusFlags &) = 0;
virtual void on_sym(bool is_check, const FSEntry &, const FSEntry &);
virtual void on_sym_over_nothing(bool is_check, const FSEntry &, const FSEntry &);
@@ -151,9 +161,9 @@ namespace paludis
virtual void on_sym_over_sym(bool is_check, const FSEntry &, const FSEntry &);
virtual void on_sym_over_misc(bool is_check, const FSEntry &, const FSEntry &);
- virtual void install_sym(const FSEntry &, const FSEntry &);
+ virtual MergeStatusFlags install_sym(const FSEntry &, const FSEntry &) PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void unlink_sym(FSEntry);
- virtual void record_install_sym(const FSEntry &, const FSEntry &) = 0;
+ virtual void record_install_sym(const FSEntry &, const FSEntry &, const MergeStatusFlags &) = 0;
virtual void unlink_misc(FSEntry);
virtual void on_misc(bool is_check, const FSEntry &, const FSEntry &);
diff --git a/paludis/merger.se b/paludis/merger.se
new file mode 100644
index 0000000..0ed5dc2
--- /dev/null
+++ b/paludis/merger.se
@@ -0,0 +1,24 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_MergeStatusFlag()
+{
+ prefix msi
+
+ key msi_unlinked_first "We unlinked before the merge"
+ key msi_rename "We renamed rather than copied"
+ key msi_parent_rename "A parent directory was renamed, so we weren't copied"
+ key msi_used_existing "We used the existing entry (e.g. dir over dir)"
+ key msi_fixed_ownership "We fixed owner or group from the reduced id"
+ key msi_setid_bits "The source file had set*id bits"
+
+ doxygen_comment << "END"
+ /**
+ * Status flags for Merger, used by MergeStatusFlags
+ *
+ * \ingroup g_repository
+ * \since 0.26
+ */
+END
+}
+
diff --git a/paludis/merger.sr b/paludis/merger.sr
index 9554bdd..ca9cbd1 100644
--- a/paludis/merger.sr
+++ b/paludis/merger.sr
@@ -20,6 +20,7 @@ make_class_MergerOptions()
* \see Merger
* \ingroup g_repository
* \nosubgrouping
+ * \since 0.26
*/
END
}
diff --git a/paludis/merger_TEST.cc b/paludis/merger_TEST.cc
index 3120949..1162286 100644
--- a/paludis/merger_TEST.cc
+++ b/paludis/merger_TEST.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -85,15 +85,15 @@ namespace
{
}
- void record_install_file(const FSEntry &, const FSEntry &, const std::string &)
+ void record_install_file(const FSEntry &, const FSEntry &, const std::string &, const MergeStatusFlags &)
{
}
- void record_install_dir(const FSEntry &, const FSEntry &)
+ void record_install_dir(const FSEntry &, const FSEntry &, const MergeStatusFlags &)
{
}
- void record_install_sym(const FSEntry &, const FSEntry &)
+ void record_install_sym(const FSEntry &, const FSEntry &, const MergeStatusFlags &)
{
}
diff --git a/paludis/repositories/e/vdb_merger.cc b/paludis/repositories/e/vdb_merger.cc
index 796e9cf..b6882ae 100644
--- a/paludis/repositories/e/vdb_merger.cc
+++ b/paludis/repositories/e/vdb_merger.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -27,6 +27,7 @@
#include <paludis/util/sequence.hh>
#include <paludis/util/fs_entry.hh>
#include <paludis/util/strip.hh>
+#include <paludis/util/options.hh>
#include <paludis/hook.hh>
#include <paludis/package_id.hh>
#include <paludis/util/md5.hh>
@@ -112,7 +113,7 @@ VDBMerger::extend_hook(const Hook & h)
}
void
-VDBMerger::record_install_file(const FSEntry & src, const FSEntry & dst_dir, const std::string & dst_name)
+VDBMerger::record_install_file(const FSEntry & src, const FSEntry & dst_dir, const std::string & dst_name, const MergeStatusFlags & flags)
{
std::string tidy(stringify((dst_dir / dst_name).strip_leading(_imp->realroot))),
tidy_real(stringify((dst_dir / src.basename()).strip_leading(_imp->realroot)));
@@ -124,7 +125,7 @@ VDBMerger::record_install_file(const FSEntry & src, const FSEntry & dst_dir, con
MD5 md5(infile);
- std::string line(">>> [obj] " + tidy_real);
+ std::string line(make_arrows(flags) + " [obj] " + tidy_real);
if (tidy_real != tidy)
line.append(" (" + FSEntry(tidy).basename() + ")");
display_override(line);
@@ -133,22 +134,22 @@ VDBMerger::record_install_file(const FSEntry & src, const FSEntry & dst_dir, con
}
void
-VDBMerger::record_install_dir(const FSEntry & src, const FSEntry & dst_dir)
+VDBMerger::record_install_dir(const FSEntry & src, const FSEntry & dst_dir, const MergeStatusFlags & flags)
{
std::string tidy(stringify((dst_dir / src.basename()).strip_leading(_imp->realroot)));
- display_override(">>> [dir] " + tidy);
+ display_override(make_arrows(flags) + " [dir] " + tidy);
*_imp->contents_file << "dir " << tidy << std::endl;
}
void
-VDBMerger::record_install_sym(const FSEntry & src, const FSEntry & dst_dir)
+VDBMerger::record_install_sym(const FSEntry & src, const FSEntry & dst_dir, const MergeStatusFlags & flags)
{
std::string tidy(stringify((dst_dir / src.basename()).strip_leading(_imp->realroot)));
std::string target((dst_dir / src.basename()).readlink());
time_t timestamp((dst_dir / src.basename()).mtime());
- display_override(">>> [sym] " + tidy);
+ display_override(make_arrows(flags) + " [sym] " + tidy);
*_imp->contents_file << "sym " << tidy << " -> " << target << " " << timestamp << std::endl;
}
@@ -295,3 +296,48 @@ VDBMerger::display_override(const std::string & message) const
std::cout << message << std::endl;
}
+std::string
+VDBMerger::make_arrows(const MergeStatusFlags & flags) const
+{
+ std::string result(">>>");
+ for (MergeStatusFlag m(static_cast<MergeStatusFlag>(0)), m_end(last_msi) ; m != m_end ;
+ m = static_cast<MergeStatusFlag>(static_cast<long>(m) + 1))
+ {
+ if (! flags[m])
+ continue;
+
+ switch (m)
+ {
+ case msi_unlinked_first:
+ result[0] = '<';
+ continue;
+
+ case msi_used_existing:
+ result[0] = '=';
+ continue;
+
+ case msi_parent_rename:
+ result[1] = '^';
+ continue;
+
+ case msi_rename:
+ result[1] = '-';
+ continue;
+
+ case msi_fixed_ownership:
+ result[2] = '~';
+ continue;
+
+ case msi_setid_bits:
+ result[2] = '*';
+ continue;
+
+ case last_msi:
+ break;
+ }
+ throw InternalError(PALUDIS_HERE, "Unhandled MergeStatusFlag '" + stringify(static_cast<long>(m)) + "'");
+ }
+
+ return result;
+}
+
diff --git a/paludis/repositories/e/vdb_merger.hh b/paludis/repositories/e/vdb_merger.hh
index b5a5896..e8bf53b 100644
--- a/paludis/repositories/e/vdb_merger.hh
+++ b/paludis/repositories/e/vdb_merger.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -42,6 +42,7 @@ namespace paludis
{
private:
void display_override(const std::string &) const;
+ std::string make_arrows(const MergeStatusFlags &) const;
public:
///\name Basic operations
@@ -54,9 +55,9 @@ namespace paludis
virtual Hook extend_hook(const Hook &);
- virtual void record_install_file(const FSEntry &, const FSEntry &, const std::string &);
- virtual void record_install_dir(const FSEntry &, const FSEntry &);
- virtual void record_install_sym(const FSEntry &, const FSEntry &);
+ virtual void record_install_file(const FSEntry &, const FSEntry &, const std::string &, const MergeStatusFlags &);
+ virtual void record_install_dir(const FSEntry &, const FSEntry &, const MergeStatusFlags &);
+ virtual void record_install_sym(const FSEntry &, const FSEntry &, const MergeStatusFlags &);
virtual void on_error(bool is_check, const std::string &);
virtual void on_warn(bool is_check, const std::string &);
diff --git a/paludis/repositories/unpackaged/ndbam_merger.cc b/paludis/repositories/unpackaged/ndbam_merger.cc
index a72e96c..e214847 100644
--- a/paludis/repositories/unpackaged/ndbam_merger.cc
+++ b/paludis/repositories/unpackaged/ndbam_merger.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -27,6 +27,7 @@
#include <paludis/util/fs_entry.hh>
#include <paludis/util/strip.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/options.hh>
#include <paludis/hook.hh>
#include <paludis/package_id.hh>
#include <paludis/util/md5.hh>
@@ -138,7 +139,7 @@ namespace
}
void
-NDBAMMerger::record_install_file(const FSEntry & src, const FSEntry & dst_dir, const std::string & dst_name)
+NDBAMMerger::record_install_file(const FSEntry & src, const FSEntry & dst_dir, const std::string & dst_name, const MergeStatusFlags & flags)
{
std::string tidy(stringify((dst_dir / dst_name).strip_leading(_imp->realroot))),
tidy_real(stringify((dst_dir / src.basename()).strip_leading(_imp->realroot)));
@@ -150,7 +151,7 @@ NDBAMMerger::record_install_file(const FSEntry & src, const FSEntry & dst_dir, c
MD5 md5(infile);
- std::string line(">>> [obj] " + tidy_real);
+ std::string line(make_arrows(flags) + " [obj] " + tidy_real);
if (tidy_real != tidy)
line.append(" (" + FSEntry(tidy).basename() + ")");
display_override(line);
@@ -163,22 +164,22 @@ NDBAMMerger::record_install_file(const FSEntry & src, const FSEntry & dst_dir, c
}
void
-NDBAMMerger::record_install_dir(const FSEntry & src, const FSEntry & dst_dir)
+NDBAMMerger::record_install_dir(const FSEntry & src, const FSEntry & dst_dir, const MergeStatusFlags & flags)
{
std::string tidy(stringify((dst_dir / src.basename()).strip_leading(_imp->realroot)));
- display_override(">>> [dir] " + tidy);
+ display_override(make_arrows(flags) + " [dir] " + tidy);
*_imp->contents_file << "type=dir path=" << escape(tidy) << std::endl;
}
void
-NDBAMMerger::record_install_sym(const FSEntry & src, const FSEntry & dst_dir)
+NDBAMMerger::record_install_sym(const FSEntry & src, const FSEntry & dst_dir, const MergeStatusFlags & flags)
{
std::string tidy(stringify((dst_dir / src.basename()).strip_leading(_imp->realroot)));
std::string target((dst_dir / src.basename()).readlink());
time_t timestamp((dst_dir / src.basename()).mtime());
- display_override(">>> [sym] " + tidy);
+ display_override(make_arrows(flags) + " [sym] " + tidy);
*_imp->contents_file << "type=sym path=" << escape(tidy);
*_imp->contents_file << " target=" << escape(target);
@@ -263,6 +264,52 @@ NDBAMMerger::make_config_protect_name(const FSEntry & src, const FSEntry & dst)
return result_name;
}
+std::string
+NDBAMMerger::make_arrows(const MergeStatusFlags & flags) const
+{
+ std::string result(">>>");
+ for (MergeStatusFlag m(static_cast<MergeStatusFlag>(0)), m_end(last_msi) ; m != m_end ;
+ m = static_cast<MergeStatusFlag>(static_cast<long>(m) + 1))
+ {
+ if (! flags[m])
+ continue;
+
+ switch (m)
+ {
+ case msi_unlinked_first:
+ result[0] = '<';
+ continue;
+
+ case msi_used_existing:
+ result[0] = '=';
+ continue;
+
+ case msi_parent_rename:
+ result[1] = '^';
+ continue;
+
+ case msi_rename:
+ result[1] = '-';
+ continue;
+
+ case msi_fixed_ownership:
+ result[2] = '~';
+ continue;
+
+ case msi_setid_bits:
+ result[2] = '*';
+ continue;
+
+ case last_msi:
+ break;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Unhandled MergeStatusFlag '" + stringify(static_cast<long>(m)) + "'");
+ }
+
+ return result;
+}
+
void
NDBAMMerger::merge()
{
diff --git a/paludis/repositories/unpackaged/ndbam_merger.hh b/paludis/repositories/unpackaged/ndbam_merger.hh
index 1c5e023..8ef0551 100644
--- a/paludis/repositories/unpackaged/ndbam_merger.hh
+++ b/paludis/repositories/unpackaged/ndbam_merger.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -35,6 +35,7 @@ namespace paludis
{
private:
void display_override(const std::string &) const;
+ std::string make_arrows(const MergeStatusFlags &) const;
public:
NDBAMMerger(const NDBAMMergerOptions &);
@@ -42,9 +43,9 @@ namespace paludis
virtual Hook extend_hook(const Hook &);
- virtual void record_install_file(const FSEntry &, const FSEntry &, const std::string &);
- virtual void record_install_dir(const FSEntry &, const FSEntry &);
- virtual void record_install_sym(const FSEntry &, const FSEntry &);
+ virtual void record_install_file(const FSEntry &, const FSEntry &, const std::string &, const MergeStatusFlags &);
+ virtual void record_install_dir(const FSEntry &, const FSEntry &, const MergeStatusFlags &);
+ virtual void record_install_sym(const FSEntry &, const FSEntry &, const MergeStatusFlags &);
virtual void on_error(bool is_check, const std::string &);
virtual void on_warn(bool is_check, const std::string &);