--- pym/portage.py (revision 2821) +++ pym/portage.py (working copy) @@ -86,7 +86,7 @@ MOVE_BINARY, PRELINK_BINARY, WORLD_FILE, MAKE_CONF_FILE, MAKE_DEFAULTS_FILE, \ DEPRECATED_PROFILE_FILE, USER_VIRTUALS_FILE, EBUILD_SH_ENV_FILE, \ INVALID_ENV_FILE, CUSTOM_MIRRORS_FILE, CONFIG_MEMORY_FILE,\ - INCREMENTALS, STICKIES, EAPI + INCREMENTALS, STICKIES, EAPI, MISC_SH_BINARY from portage_data import ostype, lchown, userland, secpass, uid, wheelgid, \ portage_uid, portage_gid @@ -2746,7 +2746,20 @@ logfile=None if mydo in ["help","clean","setup"]: return spawn(EBUILD_SH_BINARY+" "+mydo,mysettings,debug=debug,free=1,logfile=logfile) - elif mydo in ["prerm","postrm","preinst","postinst","config"]: + elif mydo == "preinst": + if mysettings.has_key("EMERGE_FROM") and "binary" == mysettings["EMERGE_FROM"]: + mysettings["IMAGE"] = os.path.join(mysettings["PKG_TMPDIR"], mysettings["PF"], "bin") + else: + mysettings["IMAGE"] = mysettings["D"] + phase_retval = spawn(" ".join((EBUILD_SH_BINARY, mydo)), mysettings, debug=debug, free=1, logfile=logfile) + if phase_retval == os.EX_OK: + # Post phase logic and tasks that have been factored out of ebuild.sh. + myargs = [MISC_SH_BINARY, "preinst_mask", "preinst_sfperms", + "preinst_selinux_labels", "preinst_suid_scan"] + spawn(" ".join(myargs), mysettings, debug=debug, free=1, logfile=logfile) + del mysettings["IMAGE"] + return phase_retval + elif mydo in ["prerm","postrm","postinst","config"]: mysettings.load_infodir(pkg_dir) return spawn(EBUILD_SH_BINARY+" "+mydo,mysettings,debug=debug,free=1,logfile=logfile) --- pym/portage_const.py (revision 2821) +++ pym/portage_const.py (working copy) @@ -24,6 +24,7 @@ LOCALE_DATA_PATH = PORTAGE_BASE_PATH+"/locale" EBUILD_SH_BINARY = PORTAGE_BIN_PATH+"/ebuild.sh" +MISC_SH_BINARY = PORTAGE_BIN_PATH + "/misc-functions.sh" SANDBOX_BINARY = "/usr/bin/sandbox" BASH_BINARY = "/bin/bash" MOVE_BINARY = "/bin/mv" --- bin/misc-functions.sh (revision 0) +++ bin/misc-functions.sh (revision 0) @@ -0,0 +1,161 @@ +#!/bin/bash +# Copyright 1999-2006 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header$ +# +# Miscellaneous shell functions that make use of the ebuild env but don't need +# to be included directly in ebuild.sh. +# +# We're sourcing ebuild.sh here so that we inherit all of it's goodness, +# including bashrc trickery. This approach allows us to do our miscellaneous +# shell work withing the same env that ebuild.sh has, but without polluting +# ebuild.sh itself with unneeded logic and shell code. +# +# XXX hack: clear the args so ebuild.sh doesn't see them +MISC_FUNCTIONS_ARGS="$@" +shift $# +source /usr/lib/portage/bin/ebuild.sh + +install_mask() { + local root="$1" + shift + local install_mask="$*" + + # we don't want globbing for initial expansion, but afterwards, we do + local shopts=$- + set -o noglob + for no_inst in ${install_mask}; do + set +o noglob + einfo "Removing ${no_inst}" + # normal stuff + rm -Rf ${root}/${no_inst} >&/dev/null + + # we also need to handle globs (*.a, *.h, etc) + find "${root}" -name ${no_inst} -exec rm -fR {} \; >/dev/null + done + # set everything back the way we found it + set +o noglob + set -${shopts} +} + +preinst_mask() { + if [ -z "$IMAGE" ]; then + eerror "${FUNCNAME}: IMAGE is unset" + return 1 + fi + # remove man pages, info pages, docs if requested + for f in man info doc; do + if hasq no${f} $FEATURES; then + INSTALL_MASK="${INSTALL_MASK} /usr/share/${f}" + fi + done + + install_mask "${IMAGE}" ${INSTALL_MASK} + + # remove share dir if unnessesary + if hasq nodoc $FEATURES -o hasq noman $FEATURES -o hasq noinfo $FEATURES; then + rmdir "${IMAGE}/usr/share" &> /dev/null + fi +} + +preinst_sfperms() { + if [ -z "$IMAGE" ]; then + eerror "${FUNCNAME}: IMAGE is unset" + return 1 + fi + # Smart FileSystem Permissions + if hasq sfperms $FEATURES; then + for i in $(find ${IMAGE}/ -type f -perm -4000); do + ebegin ">>> SetUID: [chmod go-r] $i " + chmod go-r "$i" + eend $? + done + for i in $(find ${IMAGE}/ -type f -perm -2000); do + ebegin ">>> SetGID: [chmod o-r] $i " + chmod o-r "$i" + eend $? + done + fi +} + +preinst_suid_scan() { + if [ -z "$IMAGE" ]; then + eerror "${FUNCNAME}: IMAGE is unset" + return 1 + fi + # total suid control. + if hasq suidctl $FEATURES; then + sfconf=/etc/portage/suidctl.conf + echo ">>> Preforming suid scan in ${IMAGE}" + for i in $(find ${IMAGE}/ -type f \( -perm -4000 -o -perm -2000 \) ); do + if [ -s "${sfconf}" ]; then + suid="`grep ^${i/${IMAGE}/}$ ${sfconf}`" + if [ "${suid}" = "${i/${IMAGE}/}" ]; then + echo "- ${i/${IMAGE}/} is an approved suid file" + else + echo ">>> Removing sbit on non registered ${i/${IMAGE}/}" + for x in 5 4 3 2 1 0; do echo -ne "\a"; sleep 0.25 ; done + echo -ne "\a" + chmod ugo-s "${i}" + grep ^#${i/${IMAGE}/}$ ${sfconf} > /dev/null || { + # sandbox prevents us from writing directly + # to files outside of the sandbox, but this + # can easly be bypassed using the addwrite() function + addwrite "${sfconf}" + echo ">>> Appending commented out entry to ${sfconf} for ${PF}" + ls_ret=`ls -ldh "${i}"` + echo "## ${ls_ret%${IMAGE}*}${ls_ret#*${IMAGE}}" >> ${sfconf} + echo "#${i/${IMAGE}/}" >> ${sfconf} + # no delwrite() eh? + # delwrite ${sconf} + } + fi + else + echo "suidctl feature set but you are lacking a ${sfconf}" + fi + done + fi +} + +preinst_selinux_labels() { + if [ -z "$IMAGE" ]; then + eerror "${FUNCNAME}: IMAGE is unset" + return 1 + fi + if hasq selinux ${FEATURES}; then + # SELinux file labeling (needs to always be last in dyn_preinst) + # only attempt to label if setfiles is executable + # and 'context' is available on selinuxfs. + if [ -f /selinux/context -a -x /usr/sbin/setfiles -a -x /usr/sbin/selinuxconfig ]; then + echo ">>> Setting SELinux security labels" + ( + eval "$(/usr/sbin/selinuxconfig)" || \ + die "Failed to determine SELinux policy paths."; + + addwrite /selinux/context; + + /usr/sbin/setfiles "${file_contexts_path}" -r "${IMAGE}" "${IMAGE}"; + ) || die "Failed to set SELinux security labels." + else + # nonfatal, since merging can happen outside a SE kernel + # like during a recovery situation + echo "!!! Unable to set SELinux security labels" + fi + fi +} + +abort_signal() { + trap SIGINT SIGQUIT + exit 1 +} + +if [ -n "${MISC_FUNCTIONS_ARGS}" ]; then + [ "$PORTAGE_DEBUG" == "1" ] && set -x + trap "abort_signal" SIGINT SIGQUIT + for x in ${MISC_FUNCTIONS_ARGS}; do + ${x} + done + trap SIGINT SIGQUIT +fi + +true --- bin/ebuild.sh (revision 2821) +++ bin/ebuild.sh (working copy) @@ -1299,111 +1299,16 @@ } dyn_preinst() { - # set IMAGE depending if this is a binary or compile merge - [ "${EMERGE_FROM}" == "binary" ] && IMAGE=${PKG_TMPDIR}/${PF}/bin \ - || IMAGE=${D} + if [ -z "$IMAGE" ]; then + eerror "${FUNCNAME}: IMAGE is unset" + return 1 + fi [ "$(type -t pre_pkg_preinst)" == "function" ] && pre_pkg_preinst declare -r D=${IMAGE} pkg_preinst - # remove man pages, info pages, docs if requested - for f in man info doc; do - if hasq no${f} $FEATURES; then - INSTALL_MASK="${INSTALL_MASK} /usr/share/${f}" - fi - done - - # we don't want globbing for initial expansion, but afterwards, we do - local shopts=$- - set -o noglob - for no_inst in ${INSTALL_MASK}; do - set +o noglob - einfo "Removing ${no_inst}" - # normal stuff - rm -Rf ${IMAGE}/${no_inst} >&/dev/null - - # we also need to handle globs (*.a, *.h, etc) - find "${IMAGE}" -name ${no_inst} -exec rm -fR {} \; >&/dev/null - done - # set everything back the way we found it - set +o noglob - set -${shopts} - - # remove share dir if unnessesary - if hasq nodoc $FEATURES -o hasq noman $FEATURES -o hasq noinfo $FEATURES; then - rmdir "${IMAGE}/usr/share" &> /dev/null - fi - - # Smart FileSystem Permissions - if hasq sfperms $FEATURES; then - for i in $(find ${IMAGE}/ -type f -perm -4000); do - ebegin ">>> SetUID: [chmod go-r] $i " - chmod go-r "$i" - eend $? - done - for i in $(find ${IMAGE}/ -type f -perm -2000); do - ebegin ">>> SetGID: [chmod o-r] $i " - chmod o-r "$i" - eend $? - done - fi - - # total suid control. - if hasq suidctl $FEATURES > /dev/null ; then - sfconf=/etc/portage/suidctl.conf - echo ">>> Preforming suid scan in ${IMAGE}" - for i in $(find ${IMAGE}/ -type f \( -perm -4000 -o -perm -2000 \) ); do - if [ -s "${sfconf}" ]; then - suid="`grep ^${i/${IMAGE}/}$ ${sfconf}`" - if [ "${suid}" = "${i/${IMAGE}/}" ]; then - echo "- ${i/${IMAGE}/} is an approved suid file" - else - echo ">>> Removing sbit on non registered ${i/${IMAGE}/}" - for x in 5 4 3 2 1 0; do echo -ne "\a"; sleep 0.25 ; done - echo -ne "\a" - chmod ugo-s "${i}" - grep ^#${i/${IMAGE}/}$ ${sfconf} > /dev/null || { - # sandbox prevents us from writing directly - # to files outside of the sandbox, but this - # can easly be bypassed using the addwrite() function - addwrite "${sfconf}" - echo ">>> Appending commented out entry to ${sfconf} for ${PF}" - ls_ret=`ls -ldh "${i}"` - echo "## ${ls_ret%${IMAGE}*}${ls_ret#*${IMAGE}}" >> ${sfconf} - echo "#${i/${IMAGE}/}" >> ${sfconf} - # no delwrite() eh? - # delwrite ${sconf} - } - fi - else - echo "suidctl feature set but you are lacking a ${sfconf}" - fi - done - fi - - # SELinux file labeling (needs to always be last in dyn_preinst) - if hasq selinux ${FEATURES} ; then - # only attempt to label if setfiles is executable - # and 'context' is available on selinuxfs. - if [ -f /selinux/context -a -x /usr/sbin/setfiles -a -x /usr/sbin/selinuxconfig ]; then - echo ">>> Setting SELinux security labels" - ( - eval "$(/usr/sbin/selinuxconfig)" || \ - die "Failed to determine SELinux policy paths."; - - addwrite /selinux/context; - - /usr/sbin/setfiles "${file_contexts_path}" -r "${IMAGE}" "${IMAGE}"; - ) || die "Failed to set SELinux security labels." - else - # nonfatal, since merging can happen outside a SE kernel - # like during a recovery situation - echo "!!! Unable to set SELinux security labels" - fi - fi - [ "$(type -t post_pkg_preinst)" == "function" ] && post_pkg_preinst trap SIGINT SIGQUIT @@ -2030,7 +1935,8 @@ #fi done -if [ "$myarg" != "clean" ]; then +# Save the env only for relevant phases. +if [ -n "$myarg" ] && [ "$myarg" != "clean" ]; then # Save current environment and touch a success file. (echo for success) umask 002 set | egrep -v "^SANDBOX_" > "${T}/environment" 2>/dev/null @@ -2038,4 +1944,5 @@ chmod g+w "${T}/environment" &>/dev/null fi -exit 0 +# Do not exit when ebuild.sh is sourced by other scripts. +true