aboutsummaryrefslogtreecommitdiff
path: root/0.8.0/ebuild/utils
diff options
context:
space:
mode:
Diffstat (limited to '0.8.0/ebuild/utils')
-rw-r--r--0.8.0/ebuild/utils/Makefile.am111
-rwxr-xr-x0.8.0/ebuild/utils/canonicalise6
-rwxr-xr-x0.8.0/ebuild/utils/dobin48
-rw-r--r--0.8.0/ebuild/utils/dobin_TEST.bash70
-rw-r--r--0.8.0/ebuild/utils/doconfd32
-rw-r--r--0.8.0/ebuild/utils/dodir34
-rw-r--r--0.8.0/ebuild/utils/dodoc55
-rw-r--r--0.8.0/ebuild/utils/doenvd32
-rw-r--r--0.8.0/ebuild/utils/doexe58
-rw-r--r--0.8.0/ebuild/utils/dohard34
-rw-r--r--0.8.0/ebuild/utils/dohtml122
-rw-r--r--0.8.0/ebuild/utils/doinfo55
-rw-r--r--0.8.0/ebuild/utils/doinitd32
-rw-r--r--0.8.0/ebuild/utils/doins89
-rw-r--r--0.8.0/ebuild/utils/dolib62
-rw-r--r--0.8.0/ebuild/utils/dolib.a.in27
-rw-r--r--0.8.0/ebuild/utils/dolib.so.in26
-rw-r--r--0.8.0/ebuild/utils/doman84
-rw-r--r--0.8.0/ebuild/utils/domo54
-rw-r--r--0.8.0/ebuild/utils/donewins40
-rw-r--r--0.8.0/ebuild/utils/dosbin45
-rw-r--r--0.8.0/ebuild/utils/dosed52
-rw-r--r--0.8.0/ebuild/utils/dosym42
-rwxr-xr-x0.8.0/ebuild/utils/dounpack108
-rwxr-xr-x0.8.0/ebuild/utils/emake22
-rw-r--r--0.8.0/ebuild/utils/fowners24
-rw-r--r--0.8.0/ebuild/utils/fperms24
-rwxr-xr-x0.8.0/ebuild/utils/getmtime5
-rw-r--r--0.8.0/ebuild/utils/merge.cc396
-rw-r--r--0.8.0/ebuild/utils/merge_TEST.bash223
-rwxr-xr-x0.8.0/ebuild/utils/merge_TEST_cleanup.sh10
-rwxr-xr-x0.8.0/ebuild/utils/merge_TEST_setup.sh74
-rw-r--r--0.8.0/ebuild/utils/merge_common.cc99
-rw-r--r--0.8.0/ebuild/utils/merge_common.hh50
-rw-r--r--0.8.0/ebuild/utils/newbin38
-rw-r--r--0.8.0/ebuild/utils/newconfd38
-rw-r--r--0.8.0/ebuild/utils/newdoc38
-rw-r--r--0.8.0/ebuild/utils/newenvd38
-rw-r--r--0.8.0/ebuild/utils/newexe38
-rw-r--r--0.8.0/ebuild/utils/newinitd38
-rw-r--r--0.8.0/ebuild/utils/newins38
-rw-r--r--0.8.0/ebuild/utils/newlib.a.in38
-rw-r--r--0.8.0/ebuild/utils/newlib.so.in38
-rw-r--r--0.8.0/ebuild/utils/newman38
-rw-r--r--0.8.0/ebuild/utils/newsbin38
-rw-r--r--0.8.0/ebuild/utils/prep.in21
-rw-r--r--0.8.0/ebuild/utils/run_test.bash62
-rwxr-xr-x0.8.0/ebuild/utils/sed.in2
-rw-r--r--0.8.0/ebuild/utils/unmerge.cc235
-rw-r--r--0.8.0/ebuild/utils/unmerge_TEST.bash66
-rwxr-xr-x0.8.0/ebuild/utils/unmerge_TEST_cleanup.sh11
-rwxr-xr-x0.8.0/ebuild/utils/unmerge_TEST_setup.sh8
52 files changed, 3068 insertions, 0 deletions
diff --git a/0.8.0/ebuild/utils/Makefile.am b/0.8.0/ebuild/utils/Makefile.am
new file mode 100644
index 0000000..1fde885
--- /dev/null
+++ b/0.8.0/ebuild/utils/Makefile.am
@@ -0,0 +1,111 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+libexecprogdir = $(libexecdir)/paludis/utils
+
+if NEED_SED_WRAPPER
+libexecprog_SCRIPTS_extra = sed
+endif
+
+libexecprog_SCRIPTS = \
+ canonicalise \
+ dobin \
+ doconfd \
+ dodir \
+ dodoc \
+ doenvd \
+ doexe \
+ dohard \
+ dohtml \
+ doinfo \
+ doinitd \
+ doins \
+ dolib \
+ dolib.a \
+ dolib.so \
+ doman \
+ domo \
+ donewins \
+ dosbin \
+ dosed \
+ dosym \
+ dounpack \
+ emake \
+ fowners \
+ fperms \
+ getmtime \
+ newbin \
+ newconfd \
+ newdoc \
+ newenvd \
+ newexe \
+ newinitd \
+ newins \
+ newlib.a \
+ newlib.so \
+ newman \
+ newsbin \
+ prepall \
+ prepallstrip \
+ prepstrip \
+ prepallman \
+ prepman \
+ prepallinfo \
+ prepinfo \
+ prepdocs \
+ prepalldocs \
+ $(libexecprog_SCRIPTS_extra)
+
+libexecprog_PROGRAMS = merge unmerge
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@
+
+merge_SOURCES = merge.cc merge_common.cc merge_common.hh
+merge_LDADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/digests/libpaludisdigests.la \
+ $(top_builddir)/paludis/selinux/libpaludisselinux.la \
+ $(DYNAMIC_LD_LIBS)
+
+unmerge_SOURCES = unmerge.cc merge_common.cc merge_common.hh
+unmerge_LDADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/digests/libpaludisdigests.la
+
+TESTS_ENVIRONMENT = env \
+ PALUDIS_EBUILD_DIR="`$(top_srcdir)/ebuild/utils/canonicalise $(top_srcdir)/ebuild/`" \
+ TOP_BUILD_DIR="`$(top_srcdir)/ebuild/utils/canonicalise $(top_builddir)/`" \
+ PALUDIS_EBUILD_LOG_LEVEL="silent" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ bash $(top_srcdir)/ebuild/utils/run_test.bash
+
+TESTS = merge_TEST.bash dobin_TEST.bash unmerge_TEST.bash
+check_SCRIPTS = $(TESTS) \
+ merge_TEST_setup.sh merge_TEST_cleanup.sh \
+ unmerge_TEST_setup.sh unmerge_TEST_cleanup.sh
+
+prep_scripts = prepall prepallstrip prepallman prepallinfo prepstrip prepman prepinfo prepdocs prepalldocs
+
+EXTRA_DIST = $(libexecprog_SCRIPTS) $(check_SCRIPTS) run_test.bash \
+ newlib.so.in newlib.a.in dolib.so.in dolib.a.in prep.in
+
+CLEANFILES = *~ newlib.so newlib.a dolib.so dolib.a sed $(prep_scripts)
+
+newlib.a : newlib.a.in
+ cat $< > $@
+
+newlib.so : newlib.so.in
+ cat $< > $@
+
+dolib.so : dolib.so.in
+ cat $< > $@
+
+dolib.a : dolib.a.in
+ cat $< > $@
+
+sed : sed.in
+ cat $< > $@
+
+$(prep_scripts) : prep.in
+ cat $< > $@
+
+check_PROGRAMS =
+
diff --git a/0.8.0/ebuild/utils/canonicalise b/0.8.0/ebuild/utils/canonicalise
new file mode 100755
index 0000000..d070f34
--- /dev/null
+++ b/0.8.0/ebuild/utils/canonicalise
@@ -0,0 +1,6 @@
+#!/bin/bash
+case $(uname -s) in
+ FreeBSD) realpath $@ ;;
+ *) readlink -f $@ ;;
+esac
+
diff --git a/0.8.0/ebuild/utils/dobin b/0.8.0/ebuild/utils/dobin
new file mode 100755
index 0000000..506f50f
--- /dev/null
+++ b/0.8.0/ebuild/utils/dobin
@@ -0,0 +1,48 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dobin from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+if [[ ! -d "${D}${DESTTREE}/bin" ]]; then
+ install -d "${D}${DESTTREE}/bin" || exit 3
+fi
+
+ret=0
+for x in "$@" ; do
+ if [[ -x "${x}" ]]; then
+ install "${x}" "${D}${DESTTREE}/bin" || ret=2
+ else
+ echo ">>> ${0}: making ${x} executable..."
+ install -m0755 -o root -g 0 "${x}" "${D}${DESTTREE}/bin" || ret=2
+ fi
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/dobin_TEST.bash b/0.8.0/ebuild/utils/dobin_TEST.bash
new file mode 100644
index 0000000..1af7700
--- /dev/null
+++ b/0.8.0/ebuild/utils/dobin_TEST.bash
@@ -0,0 +1,70 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+#
+# 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
+# Public License version 2, as published by the Free Software Foundation.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+source ${PALUDIS_EBUILD_DIR}/install_functions.bash
+
+dobin_TEST()
+{
+ mkdir -p dobin_TEST_dir/src dobin_TEST_dir/dst ; test_return_code
+
+ echo "one contents" > dobin_TEST_dir/src/one ; test_return_code
+ chmod +x dobin_TEST_dir/src/one ; test_return_code
+
+ echo "two contents" > dobin_TEST_dir/src/two ; test_return_code
+ chmod +x dobin_TEST_dir/src/two ; test_return_code
+
+ echo "three contents" > dobin_TEST_dir/src/three ; test_return_code
+ chmod +x dobin_TEST_dir/src/three ; test_return_code
+
+ export D=dobin_TEST_dir/dst
+ ${PALUDIS_EBUILD_DIR}/utils/dobin dobin_TEST_dir/src/one &>/dev/null ; test_return_code
+ ${PALUDIS_EBUILD_DIR}/utils/dobin dobin_TEST_dir/src/two dobin_TEST_dir/src/three &>/dev/null ; test_return_code
+
+ [[ -f dobin_TEST_dir/dst/usr/bin/one ]] ; test_return_code
+ [[ -f dobin_TEST_dir/dst/usr/bin/two ]] ; test_return_code
+ [[ -f dobin_TEST_dir/dst/usr/bin/three ]] ; test_return_code
+
+ test_equality "$(< dobin_TEST_dir/dst/usr/bin/one)" "one contents"
+ test_equality "$(< dobin_TEST_dir/dst/usr/bin/two)" "two contents"
+ test_equality "$(< dobin_TEST_dir/dst/usr/bin/three)" "three contents"
+
+ rm -fr dobin_TEST_dir
+}
+
+dobin_fail_TEST()
+{
+ mkdir -p dobin_TEST_dir/src dobin_TEST_dir/dst ; test_return_code
+ echo "one contents" > dobin_TEST_dir/src/one ; test_return_code
+ echo "two contents" > dobin_TEST_dir/src/two ; test_return_code
+ echo "three contents" > dobin_TEST_dir/src/three ; test_return_code
+
+ export D=dobin_TEST_dir/dst
+ ! ${PALUDIS_EBUILD_DIR}/utils/dobin dobin_TEST_dir/src/four &>/dev/null ; test_return_code
+ ! ${PALUDIS_EBUILD_DIR}/utils/dobin dobin_TEST_dir/src/one dobin_TEST_dir/src/seven &>/dev/null ; test_return_code
+ ! ${PALUDIS_EBUILD_DIR}/utils/dobin dobin_TEST_dir/src/eight dobin_TEST_dir/src/one &>/dev/null ; test_return_code
+
+ [[ -f dobin_TEST_dir/dst/usr/bin/one ]] ; test_return_code
+ ! [[ -f dobin_TEST_dir/dst/usr/bin/four ]] ; test_return_code
+ ! [[ -f dobin_TEST_dir/dst/usr/bin/five ]] ; test_return_code
+ ! [[ -f dobin_TEST_dir/dst/usr/bin/six ]] ; test_return_code
+
+ test_equality "$(< dobin_TEST_dir/dst/usr/bin/one)" "one contents"
+
+ rm -fr dobin_TEST_dir
+}
+
diff --git a/0.8.0/ebuild/utils/doconfd b/0.8.0/ebuild/utils/doconfd
new file mode 100644
index 0000000..37c453c
--- /dev/null
+++ b/0.8.0/ebuild/utils/doconfd
@@ -0,0 +1,32 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon doconfd from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [ ${#} -lt 1 ]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+INSDESTTREE=/etc/conf.d/
+doins "$@" || exit 2
diff --git a/0.8.0/ebuild/utils/dodir b/0.8.0/ebuild/utils/dodir
new file mode 100644
index 0000000..52b7c20
--- /dev/null
+++ b/0.8.0/ebuild/utils/dodir
@@ -0,0 +1,34 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dodir from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+ret=0
+for x in "$@"; do
+ install -d ${DIROPTIONS} "${D}${x}" || ret=2
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/dodoc b/0.8.0/ebuild/utils/dodoc
new file mode 100644
index 0000000..bfff299
--- /dev/null
+++ b/0.8.0/ebuild/utils/dodoc
@@ -0,0 +1,55 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dodoc from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ $# -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+if [[ -z ${PALUDIS_COMPRESS} ]]; then
+ PALUDIS_COMPRESS="gzip -f -9"
+fi
+
+dir="${D}usr/share/doc/${PF}/${DOCDESTTREE}"
+if [[ ! -d "${dir}" ]]; then
+ install -d "${dir}" || exit 3
+fi
+
+ret=0
+
+for x in "$@"; do
+ if [[ -s "${x}" ]]; then
+ install -m0644 "${x}" "${dir}"
+ ${PALUDIS_COMPRESS} "${dir}/${x##*/}"
+ elif [[ ! -e "${x}" ]]; then
+ echo "${0}: ${x} does not exist" >&2
+ ret=2
+ fi
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/doenvd b/0.8.0/ebuild/utils/doenvd
new file mode 100644
index 0000000..7299776
--- /dev/null
+++ b/0.8.0/ebuild/utils/doenvd
@@ -0,0 +1,32 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon doenvd from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+export INSDESTTREE=/etc/env.d/
+doins "$@"
diff --git a/0.8.0/ebuild/utils/doexe b/0.8.0/ebuild/utils/doexe
new file mode 100644
index 0000000..a67166b
--- /dev/null
+++ b/0.8.0/ebuild/utils/doexe
@@ -0,0 +1,58 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon doexe from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed"
+ exit 1
+fi
+
+if [[ ! -d "${D}${EXEDESTTREE}" ]]; then
+ install -d "${D}${EXEDESTTREE}" || exit 3
+fi
+
+ret=0
+
+for x in "$@"; do
+ if [[ -L ${x} ]]; then
+ cp "${x}" "${T}"
+ mysrc="${T}/$(/usr/bin/basename "${x}")"
+ elif [[ -d ${x} ]]; then
+ echo "${0}: skipping directory ${x}" >&2
+ continue
+ else
+ mysrc="${x}"
+ fi
+ install ${EXEOPTIONS} "${mysrc}" "${D}${EXEDESTTREE}" || ret=2
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/dohard b/0.8.0/ebuild/utils/dohard
new file mode 100644
index 0000000..b0758e5
--- /dev/null
+++ b/0.8.0/ebuild/utils/dohard
@@ -0,0 +1,34 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dohard from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+ln -f "${D}${1}" "${D}${2}"
diff --git a/0.8.0/ebuild/utils/dohtml b/0.8.0/ebuild/utils/dohtml
new file mode 100644
index 0000000..09743c9
--- /dev/null
+++ b/0.8.0/ebuild/utils/dohtml
@@ -0,0 +1,122 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dohtml from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+source ${PALUDIS_EBUILD_DIR}/list_functions.bash
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+allowed_exts="png gif html htm jpg css jps"
+disallowed_dirs=""
+allowed_files=""
+recurse=0
+args=( )
+
+split_names() {
+ list=$1
+ if [[ ${list} == *,* ]]; then
+ echo -n "${list%%,*} "
+ split_names ${list#*,}
+ else
+ echo ${list}
+ fi
+}
+
+parse_args() {
+ while [[ ${#} -gt 0 ]]; do
+ case $1 in
+ -r)
+ recurse=1 ;;
+ -V)
+ verbose=1 ;;
+ -A)
+ allowed_exts="${allowed_exts} $(split_names $2)"
+ shift
+ ;;
+ -a)
+ allowed_exts="$(split_names $2)"
+ shift
+ ;;
+ -f)
+ allowed_files="$(split_names $2)"
+ shift
+ ;;
+ -x)
+ disallowed_dirs="$(split_names $2)"
+ shift
+ ;;
+ *)
+ args=( "${args[@]}" "$1" ) ;;
+ esac
+ shift
+ done
+}
+
+install_file() {
+ local bn=${1}
+ local dn=${2}
+ local prefix=${3}
+ local ret=0
+
+ path=${bn}
+ [[ -n ${prefix} ]] && path="${prefix}/${path}"
+ [[ -n ${dn} ]] && path="${dn}/${path}"
+
+ [[ -z ${DOCDESTTREE} ]] && DOCDESTTREE="html"
+
+ dir="${D}usr/share/doc/${PF}/${DOCDESTTREE}/${prefix}"
+
+ if [[ -f ${path} ]]; then
+ ext="$(basename ${path})"
+ ext="${ext##*.}"
+ if ([[ -n ${ext} ]] && has $ext $allowed_exts) || has $bn $allowed_files
+ then
+ [[ ! -d ${dir} ]] && install -d "${dir}"
+ echo "install -m0644 ${path} ${dir}"
+ install -m0644 "${path}" "${dir}/${bn}"
+ fi
+ elif [[ $recurse == 1 && -d ${path} ]] &&
+ ! has "${bn}" ${disallowed_dirs}; then
+ for f in ${path}/*; do
+ pfx=${bn}
+ [[ -n ${prefix} ]] && pfx="${prefix}/${pfx}"
+ install_file "$(basename "${f}")" "${dn}" "${pfx}"
+ (( ret += $? ))
+ done
+ else
+ (( ++ret ))
+ fi
+ return ${ret}
+}
+
+parse_args "$@"
+
+retval=0
+for i in "${args[@]}"; do
+ install_file "$(basename "${i}")" "$(dirname "${i}")"
+ (( retval += $? ))
+done
+
+exit $retval
diff --git a/0.8.0/ebuild/utils/doinfo b/0.8.0/ebuild/utils/doinfo
new file mode 100644
index 0000000..746812c
--- /dev/null
+++ b/0.8.0/ebuild/utils/doinfo
@@ -0,0 +1,55 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon doinfo from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 1
+fi
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+if [[ ! -d "${D}usr/share/info" ]]; then
+ install -d "${D}usr/share/info" || exit 3
+fi
+
+if [[ -z ${PALUDIS_COMPRESS} ]]; then
+ PALUDIS_COMPRESS="gzip -f -9"
+fi
+
+ret=0
+
+for x in "$@"; do
+ if [[ -e "${x}" ]]; then
+ install -m0644 "${x}" "${D}usr/share/info"
+ ${PALUDIS_COMPRESS} "${D}usr/share/info/$(basename "${x}")"
+ else
+ echo "${0}: ${x} does not exist"
+ ret=2
+ fi
+done
+
+exit ${ret}
+
diff --git a/0.8.0/ebuild/utils/doinitd b/0.8.0/ebuild/utils/doinitd
new file mode 100644
index 0000000..8fc7080
--- /dev/null
+++ b/0.8.0/ebuild/utils/doinitd
@@ -0,0 +1,32 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon doinitd from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+EXEDESTTREE=/etc/init.d
+doexe "$@"
diff --git a/0.8.0/ebuild/utils/doins b/0.8.0/ebuild/utils/doins
new file mode 100644
index 0000000..2d70f5a
--- /dev/null
+++ b/0.8.0/ebuild/utils/doins
@@ -0,0 +1,89 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon doins from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+if [[ ${1} == "-r" ]]; then
+ DOINSRECUR=y
+ shift
+else
+ DOINSRECUR=n
+fi
+
+if [[ -z "${INSDEPTH}" ]]; then
+ declare -i INSDEPTH=0
+fi
+
+if [[ ${INSDESTTREE} == ${D}* ]]; then
+ echo "-------------------------------------------------------" >&2
+ echo "You should not use \${D} with helpers." >&2
+ echo " --> ${INSDESTTREE}" >&2
+ echo "-------------------------------------------------------" >&2
+ exit 248
+fi
+
+if [[ ! -d "${D}${INSDESTTREE}" ]]; then
+ dodir "${INSDESTTREE}"
+fi
+
+ret=0
+
+for x in "$@"; do
+ if [[ -L ${x} ]]; then
+ cp "${x}" "${T}"
+ mysrc="${T}/$(basename "${x}")"
+ elif [[ -d ${x} ]]; then
+ if [[ ${DOINSRECUR} == "n" ]]; then
+ continue
+ fi
+
+ mydir="${INSDESTTREE}/$(basename "${x}")"
+ find "${x}" -mindepth 1 -maxdepth 1 -exec \
+ env \
+ INSDESTTREE="${mydir}" \
+ INSDEPTH=$((INSDEPTH+1)) \
+ ${0} -r {} \;
+ continue
+ else
+ mysrc="${x}"
+ fi
+
+ install ${INSOPTIONS} "${mysrc}" "${D}${INSDESTTREE}" || ret=2
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/dolib b/0.8.0/ebuild/utils/dolib
new file mode 100644
index 0000000..c35b202
--- /dev/null
+++ b/0.8.0/ebuild/utils/dolib
@@ -0,0 +1,62 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dolib from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ! -d ${PALUDIS_EBUILD_MODULES_DIR} ]]; then
+ echo "${0}: \${PALUDIS_EBUILD_MODULES_DIR} not valid; aborting" >&2
+ exit 1
+fi
+
+source "${PALUDIS_EBUILD_MODULES_DIR}/multilib_functions.bash"
+
+libdir="${D}${DESTTREE}/$(ebuild_get_libdir)"
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed"
+ exit 1
+fi
+
+if [[ ! -d ${libdir} ]]; then
+ install -d "${libdir}" || exit 3
+fi
+
+ret=0
+
+for x in "$@"; do
+ if [[ -e ${x} ]]; then
+ if [[ ! -L ${x} ]]; then
+ install ${LIBOPTIONS} "${x}" "${libdir}" || ret=2
+ else
+ ln -s "$(readlink "${x}")" "${libdir}/$(basename "${x}")" || ret=2
+ fi
+ else
+ echo "${0}: ${x} does not exist"
+ ret=2
+ fi
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/dolib.a.in b/0.8.0/ebuild/utils/dolib.a.in
new file mode 100644
index 0000000..e766554
--- /dev/null
+++ b/0.8.0/ebuild/utils/dolib.a.in
@@ -0,0 +1,27 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dolib.a from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+LIBOPTIONS="-m0644" dolib "$@"
+
diff --git a/0.8.0/ebuild/utils/dolib.so.in b/0.8.0/ebuild/utils/dolib.so.in
new file mode 100644
index 0000000..d4dcb4a
--- /dev/null
+++ b/0.8.0/ebuild/utils/dolib.so.in
@@ -0,0 +1,26 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dolib.so from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+LIBOPTIONS="-m0755" dolib "$@"
diff --git a/0.8.0/ebuild/utils/doman b/0.8.0/ebuild/utils/doman
new file mode 100644
index 0000000..db13a18
--- /dev/null
+++ b/0.8.0/ebuild/utils/doman
@@ -0,0 +1,84 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon doman from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+if [[ -z ${PALUDIS_COMPRESS} ]]; then
+ PALUDIS_COMPRESS="gzip -f -9"
+fi
+
+BASE="/usr/share"
+i18n=""
+
+for x in "$@"; do
+ if [[ ${x:0:6} == "-i18n=" ]]; then
+ i18n="${x:6}/"
+ continue
+ fi
+ if [[ ${x} == .keep ]]; then
+ continue
+ fi
+
+ suffix=${x##*.}
+
+ if [[ ${suffix} == "gz" ]]; then
+ compressed="gz"
+ realname=${x%.*}
+ suffix=${realname##*.}
+ else
+ realname=${x}
+ compressed=""
+ fi
+
+ mandir="${i18n}man${suffix:0:1}"
+
+ if [[ ${mandir} =~ 'man[0-9n](|f|p|pm)$' ]]; then
+ if [[ -s ${x} ]]; then
+ if [[ ! -d "${D}${BASE}/man/${mandir}" ]]; then
+ install -d "${D}${BASE}/man/${mandir}"
+ fi
+
+ install -m0644 "${x}" "${D}${BASE}/man/${mandir}" || ret=2
+
+ if [[ -z ${compressed} ]]; then
+ ${PALUDIS_COMPRESS} "${D}${BASE}/man/${mandir}/$(basename "${x}")"
+ fi
+ else
+ echo "${0}: ${x} does not exist" >&2
+ ret=2
+ fi
+ else
+ echo "${0}: '${x}' is probably not a man page; skipping" >&2
+ ret=2
+ fi
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/domo b/0.8.0/ebuild/utils/domo
new file mode 100644
index 0000000..b7a0dd4
--- /dev/null
+++ b/0.8.0/ebuild/utils/domo
@@ -0,0 +1,54 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon domo from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+if [[ ! -d "${D}${DESTTREE}/share/locale" ]]; then
+ install -d "${D}${DESTTREE}/share/locale" || exit 3
+fi
+
+ret=0
+
+for x in "$@"; do
+ if [[ -e ${x} ]]; then
+ mytiny="$(basename "${x}")"
+ mydir="${D}${DESTTREE}/share/local/${mytiny%.*}/LC_MESSAGES"
+ if [[ ! -d ${mydir} ]]; then
+ install -d "${mydir}"
+ fi
+ install -m0644 "${x}" "${mydir}/${MOPREFIX}.mo" || ret=2
+ else
+ echo "${0}: ${x} does not exist" >&2
+ ret=2
+ fi
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/donewins b/0.8.0/ebuild/utils/donewins
new file mode 100644
index 0000000..90f0377
--- /dev/null
+++ b/0.8.0/ebuild/utils/donewins
@@ -0,0 +1,40 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon donewins from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed." >&2
+ exit 1
+fi
+
+ebuild_notice "qa" "${0} is retarded. Don't use it; use newins instead."
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doins "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/dosbin b/0.8.0/ebuild/utils/dosbin
new file mode 100644
index 0000000..25c6258
--- /dev/null
+++ b/0.8.0/ebuild/utils/dosbin
@@ -0,0 +1,45 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dosbin from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+if [[ ! -d "${D}${DESTTREE}/sbin" ]]; then
+ install -d "${D}${DESTTREE}/sbin" || exit 3
+fi
+
+for x in "$@"; do
+ if [[ -x ${x} ]]; then
+ install -m0755 "${x}" "${D}${DESTTREE}/sbin" || exit 2
+ else
+ echo ">>> dosbin: making ${x} executable..."
+ install -m0755 -o root -g 0 "${x}" "${D}${DESTTREE}/sbin" || exit 2
+ fi
+done
diff --git a/0.8.0/ebuild/utils/dosed b/0.8.0/ebuild/utils/dosed
new file mode 100644
index 0000000..ca9dc04
--- /dev/null
+++ b/0.8.0/ebuild/utils/dosed
@@ -0,0 +1,52 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dosed from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -lt 1 ]]; then
+ echo "${0}: at least one argument needed" >&2
+ exit 1
+fi
+
+mysed="s:${D}::g"
+
+ret=0
+
+for x in "$@"; do
+ y="${D}${x}"
+ if [[ -e ${y} ]]; then
+ if [[ -f "${y}" ]]; then
+ sed -i -e "${mysed}" "${y}" || ret=2
+ else
+ echo "${0}: ${y} is not a regular file"
+ ret=2
+ fi
+ else
+ mysed="${x}"
+ fi
+done
+
+exit ${ret}
diff --git a/0.8.0/ebuild/utils/dosym b/0.8.0/ebuild/utils/dosym
new file mode 100644
index 0000000..818ef1a
--- /dev/null
+++ b/0.8.0/ebuild/utils/dosym
@@ -0,0 +1,42 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon dosym from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+source ${PALUDIS_EBUILD_DIR}/echo_functions.bash
+
+if [[ ! -d ${D} ]]; then
+ echo "${0}: \${D} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+if [[ ! -d $(dirname "${D}$2") ]]; then
+ ebuild_notice "qa" "$0: target directory ${D}$2 does not exist; creating. Please fix the ebuild to create it explicitly."
+ dodir $(dirname $2)
+fi
+
+ln -snf "${1}" "${D}${2}"
diff --git a/0.8.0/ebuild/utils/dounpack b/0.8.0/ebuild/utils/dounpack
new file mode 100755
index 0000000..896bfa2
--- /dev/null
+++ b/0.8.0/ebuild/utils/dounpack
@@ -0,0 +1,108 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+#
+# Based in part upon ebuild.sh from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+die()
+{
+ echo "dounpack: error: $@" 1>&2
+ exit 123
+}
+
+unpack_one()
+{
+ [[ -z "$1" ]] && die "Bad argument for unpack_one"
+ [[ -e "$1" ]] || die "${1} doesn't exist"
+
+ case "${x}" in
+ *.tar)
+ echo tar xf "${1}" 1>&2
+ tar xf "${1}" || die "Couldn't unpack ${1}"
+ ;;
+
+ *.tar.gz|*.tgz|*.tar.Z)
+ echo tar zxf "${1}" 1>&2
+ tar zxf "${1}" || die "Couldn't unpack ${1}"
+ ;;
+
+ *.tar.bz2|*.tbz2)
+ echo tar jxf "${1}" 1>&2
+ tar jxf "${1}" || die "Couldn't unpack ${1}"
+ ;;
+
+ *.zip|*.ZIP|*.jar)
+ echo unzip -qo "${1}" 1>&2
+ unzip -qo "${1}" || die "Couldn't unpack ${1}"
+ ;;
+
+ *.gz|*.Z|*.z)
+ echo gzip -dc "${1}" > ${UNPACKTODIR}/$(basename "${1%.*}" ) 1>&2
+ gzip -dc "${1}" > ${UNPACKTODIR}/$(basename "${1%.*}" ) || die "Couldn't unpack ${1}"
+ ;;
+
+ *.bz2)
+ echo bzip2 -dc "${1}" > ${UNPACKTODIR}/$(basename "${1%.*}" ) 1>&2
+ bzip2 -dc "${1}" > ${UNPACKTODIR}/$(basename "${1%.*}" ) || die "Couldn't unpack ${1}"
+ ;;
+
+ *.rar|*.RAR)
+ echo unrar x -idq "${1}" 1>&2
+ unrar x -idq "${1}" || die "Couldn't unpack ${1}"
+ ;;
+
+ *.LHa|*.LHA|*.lha|*.lzh)
+ echo lha xqf "${1}" 1>&2
+ lha xqf "${1}" || die "Couldn't unpack ${1}"
+ ;;
+
+ *.a|*.deb)
+ echo ar x "${1}" 1&>2
+ ar x "${1}" 1>&2
+ ;;
+
+ *)
+ echo "Skipping unpack for ${1}"
+ ;;
+ esac
+
+}
+
+export UNPACKFROMDIR="${DISTDIR}"
+export UNPACKTODIR="${PWD}"
+
+if [[ "${1}" == "--binary" ]] ; then
+ export UNPACKFROMDIR="${PKGDIR}"
+ export UNPACKTODIR="${IMAGE}"
+ shift
+fi
+
+[[ -z "$@" ]] && die "No arguments given to unpack"
+
+for x in "$@" ; do
+ x=$(echo $x )
+ echo ">>> Unpacking ${x} to ${UNPACKTODIR}"
+ [[ "${x:0:2}" == "./" ]] || x="${UNPACKFROMDIR}/${x}"
+ mkdir -p ${UNPACKTODIR}
+ cd ${UNPACKTODIR}
+ unpack_one "${x}"
+done
+
+
diff --git a/0.8.0/ebuild/utils/emake b/0.8.0/ebuild/utils/emake
new file mode 100755
index 0000000..57ffa4c
--- /dev/null
+++ b/0.8.0/ebuild/utils/emake
@@ -0,0 +1,22 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+echo ${EMAKE_WRAPPER} ${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} "$@" 1>&2
+${EMAKE_WRAPPER} ${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} "$@"
+
diff --git a/0.8.0/ebuild/utils/fowners b/0.8.0/ebuild/utils/fowners
new file mode 100644
index 0000000..4eb208c
--- /dev/null
+++ b/0.8.0/ebuild/utils/fowners
@@ -0,0 +1,24 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon fowners from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+chown "${@/#\//${D}/}"
diff --git a/0.8.0/ebuild/utils/fperms b/0.8.0/ebuild/utils/fperms
new file mode 100644
index 0000000..04c5db7
--- /dev/null
+++ b/0.8.0/ebuild/utils/fperms
@@ -0,0 +1,24 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon fperms from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+chmod "${@/#\//${D}/}"
diff --git a/0.8.0/ebuild/utils/getmtime b/0.8.0/ebuild/utils/getmtime
new file mode 100755
index 0000000..81a78e4
--- /dev/null
+++ b/0.8.0/ebuild/utils/getmtime
@@ -0,0 +1,5 @@
+#!/bin/bash
+case $(uname -s) in
+ FreeBSD) stat -f '%m' $@ ;;
+ *) stat -c '%Y' $@ ;;
+esac
diff --git a/0.8.0/ebuild/utils/merge.cc b/0.8.0/ebuild/utils/merge.cc
new file mode 100644
index 0000000..10ae7e8
--- /dev/null
+++ b/0.8.0/ebuild/utils/merge.cc
@@ -0,0 +1,396 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "merge_common.hh"
+
+#include <paludis/digests/md5.hh>
+#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/fd_output_stream.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/pstream.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/strip.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/tokeniser.hh>
+#include <paludis/util/fd_holder.hh>
+#include <paludis/selinux/security_context.hh>
+
+#include <algorithm>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <string>
+#include <vector>
+
+#include <cstdlib>
+#include <errno.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "config.h"
+
+using namespace paludis;
+using namespace merge;
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::ifstream;
+using std::ofstream;
+using std::istreambuf_iterator;
+using std::ostreambuf_iterator;
+
+namespace
+{
+ int exit_status;
+
+ FSEntry
+ make_config_protect_name(const FSEntry & name, const FSEntry & file_to_install)
+ {
+ int n(0);
+ std::string file_to_install_name(stringify(file_to_install));
+
+ ifstream our_md5_file(file_to_install_name.c_str());
+ if (! our_md5_file)
+ throw Failure("Could not get md5 for '" + file_to_install_name + "'");
+ MD5 our_md5(our_md5_file);
+
+ FSEntry result(name);
+ std::string result_name(stringify(name));
+ while (true)
+ {
+ if (! result.exists())
+ return result;
+ else if (result.is_regular_file())
+ {
+ ifstream other_md5_file(result_name.c_str());
+ if (! other_md5_file)
+ throw Failure("Could not get md5 for '" + result_name + "'");
+ MD5 other_md5(other_md5_file);
+
+ if (our_md5.hexsum() == other_md5.hexsum())
+ return result;
+ }
+
+ std::stringstream s;
+ s << std::setw(4) << std::setfill('0') << std::right << n++;
+ result = FSEntry(stringify(name.dirname() / ("._cfg" + s.str() + "_"
+ + name.basename())));
+ result_name = stringify(result);
+ }
+ }
+
+ void
+ do_dir(const FSEntry & root, const FSEntry & src_dir,
+ const FSEntry & dst_dir, ofstream * const contents)
+ {
+ std::string root_str(stringify(root)), dst_dir_str(stringify(dst_dir.dirname()));
+
+ Context context("Installing directory in root '" + root_str + "' from '"
+ + stringify(src_dir) + "' to '" + stringify(dst_dir) + "':");
+
+ if (root_str == "/")
+ root_str.clear();
+ if (0 != dst_dir_str.compare(0, root_str.length(), root_str))
+ throw Failure("do_dir confused: '" + root_str + "' '" + dst_dir_str + "'");
+
+ cout << ">>> " << std::setw(5) << std::left << "[dir]" << " " <<
+ dst_dir_str.substr(root_str.length()) << "/" << dst_dir.basename() << endl;
+
+ if (dst_dir.is_directory())
+ /* nothing */;
+ else if (dst_dir.is_symbolic_link() && dst_dir.realpath().is_directory())
+ Log::get_instance()->message(ll_qa, lc_no_context, "Expected '" + stringify(dst_dir) +
+ "' to be a directory or non-existent, but found a symlink to a directory");
+ else if (dst_dir.exists())
+ throw Failure("Expected '" + stringify(dst_dir) +
+ "' to be a directory or non-existent, but found a file");
+ else
+ {
+ mode_t mode(src_dir.permissions());
+
+#ifdef HAVE_SELINUX
+ CountedPtr<FSCreateCon, count_policy::ExternalCountTag> createcon(0);
+ if (MatchPathCon::get_instance()->good())
+ {
+ FSCreateCon *p = new FSCreateCon(MatchPathCon::get_instance()->match(dst_dir_str.substr(root_str.length()),
+ mode));
+ createcon.assign(p);
+ }
+#endif
+
+ FSEntry dst_dir_copy(dst_dir);
+ dst_dir_copy.mkdir(mode);
+ dst_dir_copy.chown(src_dir.owner(), src_dir.group());
+ /* the chmod is needed to pick up fancy set*id bits */
+ dst_dir_copy.chmod(src_dir.permissions());
+ }
+
+ *contents << "dir " << dst_dir_str.substr(root_str.length()) << "/" <<
+ dst_dir.basename() << endl;
+ }
+
+ void
+ copy_file_contents(int input_fd, int fd)
+ {
+ char buf[4096];
+ ssize_t count;
+ while ((count = read(input_fd, buf, 4096)) > 0)
+ write(fd, buf, count);
+ }
+
+ void
+ do_obj(const FSEntry & root, const FSEntry & src,
+ const FSEntry & dst, ofstream * const contents)
+ {
+ std::string root_str(stringify(root)), dst_dir_str(stringify(dst.dirname())),
+ src_str(stringify(src));
+
+ Context context("Installing object in root '" + root_str + "' from '"
+ + stringify(src) + "' to '" + stringify(dst) + "':");
+
+ if (root_str == "/")
+ root_str.clear();
+ if (0 != dst_dir_str.compare(0, root_str.length(), root_str))
+ throw Failure("do_obj confused: '" + root_str + "' '" + dst_dir_str + "'");
+
+ cout << ">>> " << std::setw(5) << std::left << "[obj]" << " " <<
+ dst_dir_str.substr(root_str.length()) << "/" << dst.basename();
+
+ if (dst.is_directory())
+ throw Failure("Cannot overwrite directory '" + stringify(dst) + "' with a file");
+ else
+ {
+ FSEntry real_dst(dst);
+
+ FDHolder input_fd(::open(src_str.c_str(), O_RDONLY), false);
+ if (-1 == input_fd)
+ throw Failure("Cannot read '" + src_str + "'");
+
+ if (dst.exists())
+ {
+ if (is_config_protected(root, dst))
+ {
+ real_dst = make_config_protect_name(dst, src);
+ if (dst != real_dst)
+ cout << " -> " << real_dst << endl;
+ else
+ cout << endl;
+ }
+ else
+ {
+ FSEntry(dst).unlink();
+ cout << endl;
+ }
+ }
+ else
+ cout << endl;
+
+ /* FDHolder must be destroyed before we do the md5 thing, or the
+ * disk write may not have synced. */
+ {
+#ifdef HAVE_SELINUX
+ CountedPtr<FSCreateCon, count_policy::ExternalCountTag> createcon(0);
+ if (MatchPathCon::get_instance()->good())
+ createcon.assign(new
+ FSCreateCon(MatchPathCon::get_instance()->match(dst_dir_str.substr(root_str.length()) + "/"
+ + dst.basename(), src.permissions())));
+#endif
+ FDHolder fd(::open(stringify(real_dst).c_str(), O_WRONLY | O_CREAT, src.permissions()));
+ if (-1 == fd)
+ throw Failure("Cannot open '" + stringify(real_dst) + "' for write");
+
+ if (0 != ::fchown(fd, src.owner(), src.group()))
+ throw Failure("Cannot fchown '" + stringify(real_dst) + "': " +
+ stringify(::strerror(errno)));
+
+ /* the chmod is needed for set*id bits, which are dropped by
+ * umask in the ::open */
+ if (0 != ::fchmod(fd, src.permissions()))
+ throw Failure("Cannot fchmod '" + stringify(real_dst) + "': " +
+ stringify(::strerror(errno)));
+
+ copy_file_contents(input_fd, fd);
+ }
+
+ ifstream dst_file(stringify(dst).c_str());
+ if (! dst_file)
+ throw Failure("Could not get md5 for '" + stringify(dst_file) + "'");
+ MD5 md5(dst_file);
+
+ *contents << "obj " << dst_dir_str.substr(root_str.length()) << "/" <<
+ dst.basename() << " " << md5.hexsum() << " " <<
+ FSEntry(stringify(dst)).mtime() << endl;
+ }
+ }
+
+ void
+ do_sym(const FSEntry & root, const FSEntry & src,
+ const FSEntry & dst, ofstream * const contents)
+ {
+ std::string root_str(stringify(root)), dst_dir_str(stringify(dst.dirname()));
+
+ Context context("Installing symlink in root '" + root_str + "' from '"
+ + stringify(src) + "' to '" + stringify(dst) + "':");
+
+ if (root_str == "/")
+ root_str.clear();
+ if (0 != dst_dir_str.compare(0, root_str.length(), root_str))
+ throw Failure("do_sym confused: '" + root_str + "' '" + dst_dir_str + "'");
+
+ cout << ">>> " << std::setw(5) << std::left << "[sym]" << " " <<
+ dst_dir_str.substr(root_str.length()) << "/" << dst.basename() << endl;
+
+ if (dst.exists())
+ {
+ if (dst.is_directory())
+ throw Failure("Can't overwrite directory '" + stringify(dst) +
+ "' with symlink to '" + src.readlink() + "'");
+ else
+ FSEntry(dst).unlink();
+ }
+
+#ifdef HAVE_SELINUX
+ // permissions() on a symlink does weird things, but matchpathcon only cares about the file type,
+ // so just pass S_IFLNK.
+ CountedPtr<FSCreateCon, count_policy::ExternalCountTag> createcon(0);
+ if (MatchPathCon::get_instance()->good())
+ createcon.assign(new
+ FSCreateCon(MatchPathCon::get_instance()->match(dst_dir_str.substr(root_str.length()) + "/"
+ + dst.basename(), S_IFLNK)));
+#endif
+
+ if (0 != ::symlink(src.readlink().c_str(), stringify(dst).c_str()))
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context, "Couldn't create symlink '"
+ + src.readlink() + "' at '" + stringify(dst) + "'");
+ exit_status |= 2;
+ }
+
+ *contents << "sym " << dst_dir_str.substr(root_str.length()) << "/" <<
+ dst.basename() << " -> " << dst.readlink() << " " <<
+ FSEntry(stringify(dst)).mtime() << endl;
+ }
+
+ void
+ merge_this(const FSEntry & root, const FSEntry & src_dir, const FSEntry & dst_dir,
+ ofstream * const contents)
+ {
+ Context context("Merging under root '" + stringify(root) + "' from '"
+ + stringify(src_dir) + "' to '" + stringify(dst_dir) + "':");
+
+ if (! root.is_directory())
+ throw Failure("merge_this called with bad root '" + stringify(root) + "'");
+ if (! src_dir.is_directory())
+ throw Failure("merge_this called with bad src_dir '" + stringify(src_dir) + "'");
+ if (! dst_dir.is_directory())
+ throw Failure("merge_this called with bad dst_dir '" + stringify(dst_dir) + "'");
+
+ for (DirIterator d(src_dir, false), d_end ; d != d_end ; ++d)
+ {
+ if (d->is_regular_file())
+ do_obj(root, src_dir / d->basename(), dst_dir / d->basename(), contents);
+ else if (d->is_symbolic_link())
+ do_sym(root, src_dir / d->basename(), dst_dir / d->basename(), contents);
+ else if (d->is_directory())
+ {
+ do_dir(root, src_dir / d->basename(), dst_dir / d->basename(), contents);
+ merge_this(root, (src_dir / d->basename()).realpath(), (dst_dir / d->basename()).realpath(), contents);
+ }
+ else
+ throw Failure("Don't know how to merge '" + stringify(*d) + "'");
+ }
+ }
+}
+
+int
+main(int argc, char * argv[])
+{
+ Context context("In main program:");
+
+#ifdef HAVE_SELINUX
+ // If the MatchPathCon initialisation fails, don't attempt to match contexts when merging.
+ if (! MatchPathCon::get_instance()->good())
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "matchpathcon_init failed; not setting security contexts");
+#endif
+
+ exit_status = 0;
+ try
+ {
+ if (argc != 4)
+ throw Failure("Usage: " + stringify(argv[0]) + " src dst contents");
+
+ Log::get_instance()->set_program_name(argv[0]);
+ std::string log_level(getenv_with_default("PALUDIS_EBUILD_LOG_LEVEL", "qa"));
+
+ if (log_level == "debug")
+ Log::get_instance()->set_log_level(ll_debug);
+ else if (log_level == "qa")
+ Log::get_instance()->set_log_level(ll_qa);
+ else if (log_level == "warning")
+ Log::get_instance()->set_log_level(ll_warning);
+ else if (log_level == "silent")
+ Log::get_instance()->set_log_level(ll_silent);
+ else
+ throw Failure("bad value for log level");
+
+ Log::get_instance()->message(ll_debug, lc_no_context,
+ "CONFIG_PROTECT is " + getenv_with_default("CONFIG_PROTECT", "(unset)"));
+ Log::get_instance()->message(ll_debug, lc_no_context,
+ "CONFIG_PROTECT_MASK is " + getenv_with_default("CONFIG_PROTECT_MASK", "(unset)"));
+
+ FSEntry src(argv[1]), dst(argv[2]), contents(argv[3]);
+
+ if (! ((src = src.realpath())).is_directory())
+ throw Failure(stringify(argv[1]) + ": not a directory");
+ if (! ((dst = dst.realpath())).is_directory())
+ throw Failure(stringify(argv[2]) + ": not a directory");
+
+ ofstream contents_file(stringify(contents).c_str());
+ if (! contents_file)
+ throw Failure(stringify(contents) + ": not writeable");
+
+ ::umask(0000);
+ merge_this(dst, src, dst, &contents_file);
+ return exit_status;
+ }
+ catch (const Failure & f)
+ {
+ cerr << argv[0] << ": fatal error: " << f.message << endl;
+ return EXIT_FAILURE;
+ }
+ catch (const Exception & e)
+ {
+ cerr << argv[0] << ": fatal error:" << endl
+ << " * " << e.backtrace("\n * ") << e.message()
+ << " (" << e.what() << ")" << endl;
+ return EXIT_FAILURE;
+ }
+ catch (const std::exception & e)
+ {
+ cerr << argv[0] << ": fatal error: " << e.what() << endl;
+ return EXIT_FAILURE;
+ }
+}
+
diff --git a/0.8.0/ebuild/utils/merge_TEST.bash b/0.8.0/ebuild/utils/merge_TEST.bash
new file mode 100644
index 0000000..07a10d1
--- /dev/null
+++ b/0.8.0/ebuild/utils/merge_TEST.bash
@@ -0,0 +1,223 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+#
+# 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
+# Public License version 2, as published by the Free Software Foundation.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+merge_empty_TEST()
+{
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/empty_src" \
+ "merge_TEST_dir/empty_dst" \
+ "merge_TEST_dir/empty_contents" 1>/dev/null
+ test_return_code
+}
+
+merge_files_TEST()
+{
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/files_src" \
+ "merge_TEST_dir/files_dst" \
+ "merge_TEST_dir/files_contents" 1>/dev/null
+ test_return_code
+
+ [[ -f "merge_TEST_dir/files_dst/one" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/files_dst/one)" "contents of one"
+
+ [[ -f "merge_TEST_dir/files_dst/two" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/files_dst/two)" "contents of two"
+}
+
+merge_dirs_TEST()
+{
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/dirs_src" \
+ "merge_TEST_dir/dirs_dst" \
+ "merge_TEST_dir/dirs_contents" 1>/dev/null
+ test_return_code
+
+ [[ -d "merge_TEST_dir/dirs_dst/dir_one" ]] ; test_return_code
+ [[ -d "merge_TEST_dir/dirs_dst/dir_two" ]] ; test_return_code
+ [[ -d "merge_TEST_dir/dirs_dst/dir_two/dir_three" ]] ; test_return_code
+
+ [[ -f "merge_TEST_dir/dirs_dst/dir_one/one" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/dirs_dst/dir_one/one)" "contents of one"
+
+ [[ -f "merge_TEST_dir/dirs_dst/dir_two/two" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/dirs_dst/dir_two/two)" "contents of two"
+
+ [[ -f "merge_TEST_dir/dirs_dst/dir_two/dir_three/three" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/dirs_dst/dir_two/dir_three/three)" "contents of three"
+}
+
+merge_dirs_over_TEST()
+{
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/dirs_over_src" \
+ "merge_TEST_dir/dirs_over_dst" \
+ "merge_TEST_dir/dirs_over_contents" 1>/dev/null
+ test_return_code
+
+ [[ -d "merge_TEST_dir/dirs_over_dst/dir_one/" ]] ; test_return_code
+ [[ -d "merge_TEST_dir/dirs_over_dst/dir_two/" ]] ; test_return_code
+ [[ -d "merge_TEST_dir/dirs_over_dst/dir_two/dir_three/" ]] ; test_return_code
+
+ [[ -f "merge_TEST_dir/dirs_over_dst/dir_one/one" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/dirs_over_dst/dir_one/one)" "contents of one"
+
+ [[ -f "merge_TEST_dir/dirs_over_dst/dir_two/two" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/dirs_over_dst/dir_two/two)" "contents of two"
+
+ [[ -f "merge_TEST_dir/dirs_over_dst/dir_two/dir_three/three" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/dirs_over_dst/dir_two/dir_three/three)" "contents of three"
+}
+
+merge_links_TEST()
+{
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/links_src" \
+ "merge_TEST_dir/links_dst" \
+ "merge_TEST_dir/links_contents" 1>/dev/null
+ test_return_code
+
+ [[ -f "merge_TEST_dir/links_dst/one" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/links_dst/one)" "contents of one"
+
+ [[ -f "merge_TEST_dir/links_dst/two" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/links_dst/two)" "contents of two"
+
+ [[ -f "merge_TEST_dir/links_dst/link_to_two" ]] ; test_return_code
+ [[ -L "merge_TEST_dir/links_dst/link_to_two" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/links_dst/link_to_two)" "contents of two"
+}
+
+merge_links_over_TEST()
+{
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/links_over_src" \
+ "merge_TEST_dir/links_over_dst" \
+ "merge_TEST_dir/links_over_contents" 1>/dev/null
+ test_return_code
+
+ [[ -f "merge_TEST_dir/links_over_dst/one" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/links_over_dst/one)" "contents of one"
+
+ [[ -f "merge_TEST_dir/links_over_dst/two" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/links_over_dst/two)" "contents of two"
+
+ [[ -f "merge_TEST_dir/links_over_dst/link_to_two" ]] ; test_return_code
+ [[ -L "merge_TEST_dir/links_over_dst/link_to_two" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/links_over_dst/link_to_two)" "contents of two"
+
+ [[ -f "merge_TEST_dir/links_over_dst/link_to_three" ]] ; test_return_code
+ [[ -L "merge_TEST_dir/links_over_dst/link_to_three" ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/links_over_dst/link_to_three)" "contents of three"
+}
+
+merge_links_over_dir_TEST()
+{
+ ! ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/links_over_dir_src" \
+ "merge_TEST_dir/links_over_dir_dst" \
+ "merge_TEST_dir/links_over_dir_contents" &>/dev/null
+ test_return_code
+}
+
+merge_config_protect_TEST()
+{
+ export CONFIG_PROTECT=/dir
+
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/config_pro_src" \
+ "merge_TEST_dir/config_pro_dst" \
+ "merge_TEST_dir/config_pro_contents" 1>/dev/null
+ test_return_code
+
+ echo -n "[one]"
+
+ [[ -f merge_TEST_dir/config_pro_dst/dir/one ]] ; test_return_code
+ [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0000_one ]] ; test_return_code
+ ! [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0001_one ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/one)" "i am a fish"
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/._cfg0000_one)" "contents of one"
+
+ echo -n "[two]"
+
+ [[ -f merge_TEST_dir/config_pro_dst/dir/two ]] ; test_return_code
+ ! [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0000_two ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/two)" "contents of two"
+
+ echo -n "[three]"
+
+ [[ -f merge_TEST_dir/config_pro_dst/dir/three ]] ; test_return_code
+ [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0000_three ]] ; test_return_code
+ [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0001_three ]] ; test_return_code
+ [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0002_three ]] ; test_return_code
+ ! [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0003_three ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/three)" "i am a fish"
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/._cfg0000_three)" "i am a dish"
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/._cfg0001_three)" "i am a fist"
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/._cfg0002_three)" "contents of three"
+
+ echo -n "[four]"
+
+ [[ -f merge_TEST_dir/config_pro_dst/dir/four ]] ; test_return_code
+ [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0000_four ]] ; test_return_code
+ [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0001_four ]] ; test_return_code
+ ! [[ -f merge_TEST_dir/config_pro_dst/dir/._cfg0002_four ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/four)" "i am a fish"
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/._cfg0000_four)" "contents of four"
+ test_equality "$(< merge_TEST_dir/config_pro_dst/dir/._cfg0001_four)" "i am a fist"
+}
+
+merge_config_protect_noroot_TEST()
+{
+ export CONFIG_PROTECT=$(${PALUDIS_EBUILD_DIR}/utils/canonicalise `pwd` )/merge_TEST_dir/noroot_dst/dir
+
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "merge_TEST_dir/config_pro_noroot_src" \
+ "/" \
+ "merge_TEST_dir/config_pro_slash_root_contents" 1>/dev/null
+ test_return_code
+
+ echo -n "[one]"
+
+ [[ -f merge_TEST_dir/noroot_dst/dir/one ]] ; test_return_code
+ [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0000_one ]] ; test_return_code
+ ! [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0001_one ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/one)" "i am a fish"
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/._cfg0000_one)" "contents of one"
+
+ echo -n "[two]"
+
+ [[ -f merge_TEST_dir/noroot_dst/dir/two ]] ; test_return_code
+ ! [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0000_two ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/two)" "contents of two"
+
+ echo -n "[three]"
+
+ [[ -f merge_TEST_dir/noroot_dst/dir/three ]] ; test_return_code
+ [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0000_three ]] ; test_return_code
+ [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0001_three ]] ; test_return_code
+ [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0002_three ]] ; test_return_code
+ ! [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0003_three ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/three)" "i am a fish"
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/._cfg0000_three)" "i am a dish"
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/._cfg0001_three)" "i am a fist"
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/._cfg0002_three)" "contents of three"
+
+ echo -n "[four]"
+
+ [[ -f merge_TEST_dir/noroot_dst/dir/four ]] ; test_return_code
+ [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0000_four ]] ; test_return_code
+ [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0001_four ]] ; test_return_code
+ ! [[ -f merge_TEST_dir/noroot_dst/dir/._cfg0002_four ]] ; test_return_code
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/four)" "i am a fish"
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/._cfg0000_four)" "contents of four"
+ test_equality "$(< merge_TEST_dir/noroot_dst/dir/._cfg0001_four)" "i am a fist"
+
+}
+
diff --git a/0.8.0/ebuild/utils/merge_TEST_cleanup.sh b/0.8.0/ebuild/utils/merge_TEST_cleanup.sh
new file mode 100755
index 0000000..4b40b8f
--- /dev/null
+++ b/0.8.0/ebuild/utils/merge_TEST_cleanup.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d merge_TEST_dir ] ; then
+ rm -fr merge_TEST_dir
+else
+ true
+fi
+
+
diff --git a/0.8.0/ebuild/utils/merge_TEST_setup.sh b/0.8.0/ebuild/utils/merge_TEST_setup.sh
new file mode 100755
index 0000000..4af857d
--- /dev/null
+++ b/0.8.0/ebuild/utils/merge_TEST_setup.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir -p merge_TEST_dir/{empty_src,empty_dst} || exit 2
+
+mkdir -p merge_TEST_dir/{files_src,files_dst} || exit 2
+echo "contents of one" > merge_TEST_dir/files_src/one
+echo "contents of two" > merge_TEST_dir/files_src/two
+
+mkdir -p merge_TEST_dir/{dirs_src/{dir_one,dir_two/dir_three},dirs_dst} || exit 3
+echo "contents of one" > merge_TEST_dir/dirs_src/dir_one/one
+echo "contents of two" > merge_TEST_dir/dirs_src/dir_two/two
+echo "contents of three" > merge_TEST_dir/dirs_src/dir_two/dir_three/three
+
+mkdir -p merge_TEST_dir/{dirs_over_src/{dir_one,dir_two/dir_three},dirs_over_dst} || exit 4
+mkdir -p merge_TEST_dir/dirs_over_dst/{one,real}
+ln -s real merge_TEST_dir/dirs_over_dst/two
+echo "contents of one" > merge_TEST_dir/dirs_over_src/dir_one/one
+echo "contents of two" > merge_TEST_dir/dirs_over_src/dir_two/two
+echo "contents of three" > merge_TEST_dir/dirs_over_src/dir_two/dir_three/three
+
+mkdir -p merge_TEST_dir/{links_src,links_dst} || exit 5
+echo "contents of one" > merge_TEST_dir/links_src/one
+echo "contents of two" > merge_TEST_dir/links_src/two
+ln -s two merge_TEST_dir/links_src/link_to_two
+
+mkdir -p merge_TEST_dir/{links_over_src,links_over_dst} || exit 5
+echo "contents of one" > merge_TEST_dir/links_over_src/one
+echo "contents of two" > merge_TEST_dir/links_over_src/two
+echo "contents of three" > merge_TEST_dir/links_over_src/three
+ln -s two merge_TEST_dir/links_over_src/link_to_two
+ln -s three merge_TEST_dir/links_over_src/link_to_three
+echo "existing file" > merge_TEST_dir/link_to_two
+ln -s ../ merge_TEST_dir/links_over_dst/link_to_three
+
+mkdir -p merge_TEST_dir/{links_over_dir_src,links_over_dir_dst} || exit 5
+echo "contents of one" > merge_TEST_dir/links_over_dir_src/one
+echo "contents of two" > merge_TEST_dir/links_over_dir_src/two
+echo "contents of three" > merge_TEST_dir/links_over_dir_src/three
+ln -s two merge_TEST_dir/links_over_dir_src/link_to_two
+ln -s three merge_TEST_dir/links_over_dir_src/link_to_three
+mkdir merge_TEST_dir/links_over_dir_dst/link_to_two
+echo "existing file" > merge_TEST_dir/links_over_dir_dst/link_to_three
+
+mkdir -p merge_TEST_dir/{config_pro_src/dir,config_pro_dst/dir} || exit 6
+echo "contents of one" > merge_TEST_dir/config_pro_src/dir/one
+echo "contents of two" > merge_TEST_dir/config_pro_src/dir/two
+echo "contents of three" > merge_TEST_dir/config_pro_src/dir/three
+echo "contents of four" > merge_TEST_dir/config_pro_src/dir/four
+echo "i am a fish" > merge_TEST_dir/config_pro_dst/dir/one
+echo "contents of two" > merge_TEST_dir/config_pro_dst/dir/two
+echo "i am a fish" > merge_TEST_dir/config_pro_dst/dir/three
+echo "i am a dish" > merge_TEST_dir/config_pro_dst/dir/._cfg0000_three
+echo "i am a fist" > merge_TEST_dir/config_pro_dst/dir/._cfg0001_three
+echo "i am a fish" > merge_TEST_dir/config_pro_dst/dir/four
+echo "contents of four" > merge_TEST_dir/config_pro_dst/dir/._cfg0000_four
+echo "i am a fist" > merge_TEST_dir/config_pro_dst/dir/._cfg0001_four
+
+d=merge_TEST_dir/config_pro_noroot_src/$(${PALUDIS_EBUILD_DIR}/utils/canonicalise `pwd` )/merge_TEST_dir/noroot_dst/dir
+mkdir -p "${d}" || exit 7
+mkdir -p merge_TEST_dir/noroot_dst/dir || exit 7
+echo "contents of one" > ${d}/one
+echo "contents of two" > ${d}/two
+echo "contents of three" > ${d}/three
+echo "contents of four" > ${d}/four
+echo "i am a fish" > merge_TEST_dir/noroot_dst/dir/one
+echo "contents of two" > merge_TEST_dir/noroot_dst/dir/two
+echo "i am a fish" > merge_TEST_dir/noroot_dst/dir/three
+echo "i am a dish" > merge_TEST_dir/noroot_dst/dir/._cfg0000_three
+echo "i am a fist" > merge_TEST_dir/noroot_dst/dir/._cfg0001_three
+echo "i am a fish" > merge_TEST_dir/noroot_dst/dir/four
+echo "contents of four" > merge_TEST_dir/noroot_dst/dir/._cfg0000_four
+echo "i am a fist" > merge_TEST_dir/noroot_dst/dir/._cfg0001_four
+
diff --git a/0.8.0/ebuild/utils/merge_common.cc b/0.8.0/ebuild/utils/merge_common.cc
new file mode 100644
index 0000000..27b9e11
--- /dev/null
+++ b/0.8.0/ebuild/utils/merge_common.cc
@@ -0,0 +1,99 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "merge_common.hh"
+
+#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/pstream.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/strip.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/tokeniser.hh>
+
+#include <algorithm>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <string>
+#include <vector>
+
+#include <cstdlib>
+#include <errno.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+using namespace paludis;
+
+std::vector<std::string>
+merge::get_config_var(const std::string & var)
+{
+ std::vector<std::string> result, preresult;
+ WhitespaceTokeniser::get_instance()->tokenise(getenv_with_default(var, ""),
+ std::back_inserter(preresult));
+ result.reserve(preresult.size());
+
+ for (std::vector<std::string>::const_iterator i(preresult.begin()), i_end(preresult.end()) ;
+ i != i_end ; ++i)
+ {
+ if (i->empty())
+ continue;
+ if ("-*" == *i)
+ result.clear();
+ else if ('-' == i->at(0))
+ result.erase(std::remove(result.begin(), result.end(), i->substr(1)), result.end());
+ else
+ result.push_back(*i);
+ }
+ return result;
+}
+
+bool
+merge::is_config_protected(const FSEntry & root, const FSEntry & file)
+{
+ static std::vector<std::string> cfg_pro(get_config_var("CONFIG_PROTECT")),
+ cfg_pro_mask(get_config_var("CONFIG_PROTECT_MASK"));
+
+ std::string file_str(stringify(file)), root_str(stringify(root));
+ if (0 != file_str.compare(0, root_str.length(), root_str))
+ throw Failure("is_config_protected confused: '" + root_str + "' '" + file_str + "'");
+ file_str.erase(0, root_str.length());
+ if (file_str.empty())
+ file_str = "/";
+ if ('/' != file_str.at(0))
+ file_str = "/" + file_str;
+
+ bool result(false);
+ for (std::vector<std::string>::const_iterator c(cfg_pro.begin()),
+ c_end(cfg_pro.end()) ; c != c_end && ! result ; ++c)
+ if (0 == fnmatch((*c + "/*").c_str(), file_str.c_str(), 0))
+ result = true;
+
+ for (std::vector<std::string>::const_iterator c(cfg_pro_mask.begin()),
+ c_end(cfg_pro_mask.end()) ; c != c_end && result ; ++c)
+ if (0 == fnmatch((*c + "/*").c_str(), file_str.c_str(), 0))
+ result = false;
+
+ return result;
+}
+
diff --git a/0.8.0/ebuild/utils/merge_common.hh b/0.8.0/ebuild/utils/merge_common.hh
new file mode 100644
index 0000000..6f06648
--- /dev/null
+++ b/0.8.0/ebuild/utils/merge_common.hh
@@ -0,0 +1,50 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_EBUILD_UTILS_MERGE_COMMON_HH
+#define PALUDIS_GUARD_EBUILD_UTILS_MERGE_COMMON_HH 1
+
+#include <string>
+#include <vector>
+
+namespace paludis
+{
+ class FSEntry;
+}
+
+namespace merge
+{
+ struct Failure
+ {
+ std::string message;
+
+ Failure(const std::string & m) :
+ message(m)
+ {
+ };
+ };
+
+ std::vector<std::string>
+ get_config_var(const std::string & var);
+
+ bool
+ is_config_protected(const paludis::FSEntry & root, const paludis::FSEntry & file);
+}
+
+#endif
diff --git a/0.8.0/ebuild/utils/newbin b/0.8.0/ebuild/utils/newbin
new file mode 100644
index 0000000..21792c6
--- /dev/null
+++ b/0.8.0/ebuild/utils/newbin
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newbin from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dobin "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newconfd b/0.8.0/ebuild/utils/newconfd
new file mode 100644
index 0000000..7783865
--- /dev/null
+++ b/0.8.0/ebuild/utils/newconfd
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newconfd from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doconfd "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newdoc b/0.8.0/ebuild/utils/newdoc
new file mode 100644
index 0000000..b4cb507
--- /dev/null
+++ b/0.8.0/ebuild/utils/newdoc
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newdoc from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dodoc "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newenvd b/0.8.0/ebuild/utils/newenvd
new file mode 100644
index 0000000..76f0a7f
--- /dev/null
+++ b/0.8.0/ebuild/utils/newenvd
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newenvd from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doenvd "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newexe b/0.8.0/ebuild/utils/newexe
new file mode 100644
index 0000000..9a5cb35
--- /dev/null
+++ b/0.8.0/ebuild/utils/newexe
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newexe from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doexe "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newinitd b/0.8.0/ebuild/utils/newinitd
new file mode 100644
index 0000000..01ca12b
--- /dev/null
+++ b/0.8.0/ebuild/utils/newinitd
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newinitd from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doinitd "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newins b/0.8.0/ebuild/utils/newins
new file mode 100644
index 0000000..2b692ad
--- /dev/null
+++ b/0.8.0/ebuild/utils/newins
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newins from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doins "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newlib.a.in b/0.8.0/ebuild/utils/newlib.a.in
new file mode 100644
index 0000000..415a057
--- /dev/null
+++ b/0.8.0/ebuild/utils/newlib.a.in
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newlib.a from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dolib.a "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newlib.so.in b/0.8.0/ebuild/utils/newlib.so.in
new file mode 100644
index 0000000..0701351
--- /dev/null
+++ b/0.8.0/ebuild/utils/newlib.so.in
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newlib.so from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dolib.so "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newman b/0.8.0/ebuild/utils/newman
new file mode 100644
index 0000000..0dab5fc
--- /dev/null
+++ b/0.8.0/ebuild/utils/newman
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newman from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doman "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/newsbin b/0.8.0/ebuild/utils/newsbin
new file mode 100644
index 0000000..da94577
--- /dev/null
+++ b/0.8.0/ebuild/utils/newsbin
@@ -0,0 +1,38 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# Based in part upon newsbin from Portage, which is Copyright 1995-2005
+# Gentoo Foundation and distributed under the terms of the GNU General
+# Public License v2.
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+export PATH="${PALUDIS_EBUILD_DIR:+${PALUDIS_EBUILD_DIR}/utils:}${PATH}"
+
+if [[ ! -d ${T} ]]; then
+ echo "${0}: \${T} not valid; aborting" >&2
+ exit 247
+fi
+
+if [[ ${#} -ne 2 ]]; then
+ echo "${0}: exactly two arguments needed" >&2
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dosbin "${T}/${2}"
diff --git a/0.8.0/ebuild/utils/prep.in b/0.8.0/ebuild/utils/prep.in
new file mode 100644
index 0000000..fcb6495
--- /dev/null
+++ b/0.8.0/ebuild/utils/prep.in
@@ -0,0 +1,21 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+#
+# 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
+# Public License as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+ebuild_notice "qa" "Ebuilds shouldn't be calling $0 manually."
+
diff --git a/0.8.0/ebuild/utils/run_test.bash b/0.8.0/ebuild/utils/run_test.bash
new file mode 100644
index 0000000..1f9db4e
--- /dev/null
+++ b/0.8.0/ebuild/utils/run_test.bash
@@ -0,0 +1,62 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+shopt -s expand_aliases
+shopt -s extglob
+set +o posix
+
+export TEST_STATUS=
+export PALUDIS_IN_TEST_FRAMEWORK="yes"
+
+test_return_code()
+{
+ local r="$?"
+ if [[ "0" == "${r}" ]] ; then
+ echo -n "."
+ else
+ echo -n "!{retcode: ${r}}"
+ export local_test_status="fail"
+ export TEST_STATUS="fail"
+ fi
+}
+
+test_equality()
+{
+ if [[ "${1}" == "${2}" ]] ; then
+ echo -n "."
+ else
+ echo -n "!{'${1}' not equal to '${2}'}"
+ export local_test_status="fail"
+ export TEST_STATUS="fail"
+ fi
+}
+
+if test -f "$TEST_SCRIPT_DIR""${1%.bash}"_"setup.sh" ; then
+ echo ">>> setup for test ${1%.bash}"
+ if ! "$TEST_SCRIPT_DIR""${1%.bash}"_"setup.sh" ; then
+ echo ">>> exiting with error for test ${1%.bash}"
+ exit 255
+ fi
+fi
+
+echo "Test program ${1%.bash}:"
+source "${1}" || exit 200
+
+for testname in $(set | grep '_TEST *() *$' ) ; do
+ [[ ${testname/()} != ${testname} ]] && continue
+ echo -n "* ${testname%_TEST}: "
+ export local_test_status=""
+ ${testname}
+ [[ -z "$local_test_status" ]] && echo " OK" || echo " FAIL"
+done
+
+if test -f "$TEST_SCRIPT_DIR""${1%.bash}"_"cleanup.sh" ; then
+ echo ">>> cleanup for test ${1%.bash}"
+ if ! "$TEST_SCRIPT_DIR""${1%.bash}"_"cleanup.sh" ; then
+ echo ">>> exiting with error for test ${1%.bash}"
+ exit 255
+ fi
+fi
+
+[[ -z "$TEST_STATUS" ]]
+
diff --git a/0.8.0/ebuild/utils/sed.in b/0.8.0/ebuild/utils/sed.in
new file mode 100755
index 0000000..8be311a
--- /dev/null
+++ b/0.8.0/ebuild/utils/sed.in
@@ -0,0 +1,2 @@
+#!/bin/bash
+gsed $@
diff --git a/0.8.0/ebuild/utils/unmerge.cc b/0.8.0/ebuild/utils/unmerge.cc
new file mode 100644
index 0000000..fa55d41
--- /dev/null
+++ b/0.8.0/ebuild/utils/unmerge.cc
@@ -0,0 +1,235 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "merge_common.hh"
+
+#include <paludis/digests/md5.hh>
+
+#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/pstream.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/strip.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/tokeniser.hh>
+
+#include <algorithm>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <string>
+#include <vector>
+#include <list>
+
+#include <cstdlib>
+#include <errno.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+using namespace paludis;
+using namespace merge;
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::ifstream;
+
+namespace
+{
+ int exit_status;
+
+ template <typename Iter_>
+ void unmerge_contents(const FSEntry & root, const Iter_ begin, const Iter_ end)
+ {
+ using std::istreambuf_iterator;
+
+ for (Iter_ cur(begin) ; cur != end ; ++cur)
+ {
+ std::vector<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(*cur, std::back_inserter(tokens));
+ if (tokens.empty())
+ continue;
+
+ if ("obj" == tokens.at(0))
+ {
+ if (tokens.size() != 4)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Malformed VDB entry '" + *cur + "'");
+ exit_status |= 4;
+ }
+ else if (! (root / tokens.at(1)).is_regular_file())
+ cout << "--- [!type] " << tokens.at(1) << endl;
+ else if (stringify((root / tokens.at(1)).mtime()) != tokens.at(3))
+ cout << "--- [!time] " << tokens.at(1) << endl;
+ else
+ {
+ ifstream md5_file(stringify(root / tokens.at(1)).c_str());
+ if (! md5_file)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Couldn't get md5 for '" + stringify(root / tokens.at(1)) + "'");
+ cout << "--- [!md5?] " << tokens.at(1) << endl;
+ }
+ else if (MD5(md5_file).hexsum() != tokens.at(2))
+ cout << "--- [!md5 ] " << tokens.at(1) << endl;
+ else if (is_config_protected(root, root / tokens.at(1)))
+ cout << "--- [cfgpr] " << tokens.at(1) << endl;
+ else
+ {
+ cout << "<<< " << tokens.at(1) << endl;
+ (root / tokens.at(1)).unlink();
+ }
+ }
+ }
+ else if ("sym" == tokens.at(0))
+ {
+ if (tokens.size() != 5)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Malformed VDB entry '" + *cur + "'");
+ exit_status |= 4;
+ }
+ else if (! (root / tokens.at(1)).is_symbolic_link())
+ cout << "--- [!type] " << tokens.at(1) << endl;
+ else if (stringify((root / tokens.at(1)).mtime()) != tokens.at(4))
+ cout << "--- [!time] " << tokens.at(1) << endl;
+ else if ((root / tokens.at(1)).readlink() != tokens.at(3))
+ cout << "--- [!dest] " << tokens.at(1) << endl;
+ else
+ {
+ cout << "<<< " << tokens.at(1) << endl;
+ (root / tokens.at(1)).unlink();
+ }
+ }
+ else if ("misc" == tokens.at(0))
+ {
+
+ }
+ else if ("dir" == tokens.at(0))
+ /* nothing */ ;
+ else
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Skipping unknown VDB entry '" + *cur + "'");
+ exit_status |= 2;
+ }
+ }
+ }
+
+ template <typename Iter_>
+ void unmerge_directories(const FSEntry & root, const Iter_ begin, const Iter_ end)
+ {
+ using std::istreambuf_iterator;
+
+ for (Iter_ cur(begin) ; cur != end ; ++cur)
+ {
+ std::vector<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(*cur, std::back_inserter(tokens));
+ if (tokens.empty())
+ continue;
+
+ if ("dir" == tokens.at(0))
+ {
+ if (tokens.size() != 2)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Malformed VDB entry '" + *cur + "'");
+ exit_status |= 8;
+ }
+ else if (! (root / tokens.at(1)).is_directory())
+ cout << "--- [!type] " << tokens.at(1) << endl;
+ else if (DirIterator((root / tokens.at(1)), false) != DirIterator())
+ cout << "--- [!empt] " << tokens.at(1) << endl;
+ else
+ {
+ cout << "<<< " << tokens.at(1) << endl;
+ (root / tokens.at(1)).rmdir();
+ }
+ }
+ }
+ }
+}
+
+int
+main(int argc, char * argv[])
+{
+ Context context("In main program:");
+ exit_status = 0;
+ try
+ {
+ if (argc != 3)
+ throw Failure("Usage: " + stringify(argv[0]) + " root contents");
+
+ Log::get_instance()->set_program_name(argv[0]);
+ std::string log_level(getenv_with_default("PALUDIS_EBUILD_LOG_LEVEL", "qa"));
+
+ if (log_level == "debug")
+ Log::get_instance()->set_log_level(ll_debug);
+ else if (log_level == "qa")
+ Log::get_instance()->set_log_level(ll_qa);
+ else if (log_level == "warning")
+ Log::get_instance()->set_log_level(ll_warning);
+ else if (log_level == "silent")
+ Log::get_instance()->set_log_level(ll_silent);
+ else
+ throw Failure("bad value for log level");
+
+ FSEntry root(argv[1]), contents(argv[2]);
+
+ if (! ((root = root.realpath())).is_directory())
+ throw Failure(stringify(argv[1]) + ": not a directory");
+
+ ifstream contents_file(stringify(contents).c_str());
+ if (! contents_file)
+ throw Failure(stringify(contents) + ": not readable");
+
+ std::list<std::string> lines;
+ std::string line;
+ while (std::getline(contents_file, line))
+ lines.push_back(line);
+
+ unmerge_contents(root, lines.begin(), lines.end());
+ unmerge_directories(root, lines.rbegin(), lines.rend());
+ return exit_status;
+ }
+ catch (const Failure & f)
+ {
+ cerr << argv[0] << ": fatal error: " << f.message << endl;
+ return EXIT_FAILURE;
+ }
+ catch (const Exception & e)
+ {
+ cerr << argv[0] << ": fatal error:" << endl
+ << " * " << e.backtrace("\n * ") << e.message()
+ << " (" << e.what() << ")" << endl;
+ return EXIT_FAILURE;
+ }
+ catch (const std::exception & e)
+ {
+ cerr << argv[0] << ": fatal error: " << e.what() << endl;
+ return EXIT_FAILURE;
+ }
+}
+
+
diff --git a/0.8.0/ebuild/utils/unmerge_TEST.bash b/0.8.0/ebuild/utils/unmerge_TEST.bash
new file mode 100644
index 0000000..8efc7d6
--- /dev/null
+++ b/0.8.0/ebuild/utils/unmerge_TEST.bash
@@ -0,0 +1,66 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+# Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+#
+# 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
+# Public License version 2, as published by the Free Software Foundation.
+#
+# Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+unmerge_empty_TEST()
+{
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "unmerge_TEST_dir/empty_src" \
+ "unmerge_TEST_dir/empty_dst" \
+ "unmerge_TEST_dir/empty_contents" 1>/dev/null
+ test_return_code
+
+ ${TOP_BUILD_DIR}/ebuild/utils/unmerge "unmerge_TEST_dir/empty_dst" \
+ "unmerge_TEST_dir/empty_contents" 1>/dev/null
+ test_return_code
+
+ ok=
+ for a in unmerge_TEST_dir/empty_dst/* ; do
+ [[ -e "$a" ]] || continue
+ test_equality "$a" ""
+ ok=no
+ done
+ test_equality "$ok" ""
+}
+
+unmerge_files_TEST()
+{
+ ${TOP_BUILD_DIR}/ebuild/utils/merge "unmerge_TEST_dir/files_src" \
+ "unmerge_TEST_dir/files_dst" \
+ "unmerge_TEST_dir/files_contents" 1>/dev/null
+ test_return_code
+
+ ok=
+ for a in unmerge_TEST_dir/files_dst/* ; do
+ [[ -e "$a" ]] || continue
+ ok=yes
+ break
+ done
+ test_equality "$ok" "yes"
+
+ ${TOP_BUILD_DIR}/ebuild/utils/unmerge "unmerge_TEST_dir/files_dst" \
+ "unmerge_TEST_dir/files_contents" 1>/dev/null
+ test_return_code
+
+ ok=
+ for a in unmerge_TEST_dir/files_dst/* ; do
+ [[ -e "$a" ]] || continue
+ test_equality "$a" ""
+ ok=no
+ done
+ test_equality "$ok" ""
+}
+
diff --git a/0.8.0/ebuild/utils/unmerge_TEST_cleanup.sh b/0.8.0/ebuild/utils/unmerge_TEST_cleanup.sh
new file mode 100755
index 0000000..e0f01b6
--- /dev/null
+++ b/0.8.0/ebuild/utils/unmerge_TEST_cleanup.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d unmerge_TEST_dir ] ; then
+ rm -fr unmerge_TEST_dir
+else
+ true
+fi
+
+
+
diff --git a/0.8.0/ebuild/utils/unmerge_TEST_setup.sh b/0.8.0/ebuild/utils/unmerge_TEST_setup.sh
new file mode 100755
index 0000000..158e2ae
--- /dev/null
+++ b/0.8.0/ebuild/utils/unmerge_TEST_setup.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir -p unmerge_TEST_dir/{empty_src,empty_dst} || exit 2
+
+mkdir -p unmerge_TEST_dir/{files_src,files_dst} || exit 3
+echo "file one" > unmerge_TEST_dir/files_src/one
+echo "file two" > unmerge_TEST_dir/files_src/two