From: Kito Date: Sat, 11 Mar 2006 18:09:19 +0000 (-0000) Subject: Merge with trunk rev 2795:2851 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=fba850cea3f6eb13d13be61088ca3081033799cc;p=portage.git Merge with trunk rev 2795:2851 svn path=/main/branches/prefix/; revision=2852 --- diff --git a/bin/dobin b/bin/dobin index bd57cb340..65ca298af 100755 --- a/bin/dobin +++ b/bin/dobin @@ -16,7 +16,7 @@ ret=0 for x in "$@" ; do if [[ -e ${x} ]] ; then - install -m 0755 -o @rootuser@ -g @wheelgroup@ "${x}" "${D}${DESTTREE}/bin" + install -m 0755 -o ${PORTAGE_INST_UID} -g ${PORTAGE_INST_GID} "${x}" "${D}${DESTTREE}/bin" else echo "!!! ${0##*/}: ${x} does not exist" 1>&2 false diff --git a/bin/dosbin b/bin/dosbin index 811e51031..0c3d52639 100755 --- a/bin/dosbin +++ b/bin/dosbin @@ -16,7 +16,7 @@ ret=0 for x in "$@" ; do if [[ -e ${x} ]] ; then - install -m 0755 -o @rootuser@ -g @wheelgroup@ "${x}" "${D}${DESTTREE}/sbin" + install -m 0755 -o ${PORTAGE_INST_UID} -g ${PORTAGE_INST_GID} "${x}" "${D}${DESTTREE}/sbin" else echo "!!! ${0##*/}: ${x} does not exist" 1>&2 false diff --git a/bin/ebuild.sh b/bin/ebuild.sh index a3b252973..07b91aa31 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -440,7 +440,7 @@ dump_trace() { # Display function arguments args= if [[ -n "${BASH_ARGV[@]}" ]]; then - for (( j = 0 ; j < ${BASH_ARGC[${n} - 1]} ; ++j )); do + for (( j = 1 ; j <= ${BASH_ARGC[${n} - 1]} ; ++j )); do newarg=${BASH_ARGV[$(( p - j - 1 ))]} args="${args:+${args} }'${newarg}'" done @@ -861,6 +861,11 @@ dyn_unpack() { } dyn_clean() { + if [ -z "${PORTAGE_BUILDDIR}" ]; then + echo "Aborting clean phase because PORTAGE_BUILDDIR is unset!" + return 1 + fi + if [ "$USERLAND" == "BSD" ] && type -p chflags &>/dev/null; then chflags -R noschg,nouchg,nosappnd,nouappnd,nosunlnk,nouunlnk \ "${PORTAGE_BUILDDIR}" @@ -892,12 +897,14 @@ dyn_clean() { find "${PORTAGE_BUILDDIR}" -type d ! -regex "^${WORKDIR}" | sort -r | tr "\n" "\0" | $XARGS -0 rmdir &>/dev/null fi - if [ -z "$(find "${PORTAGE_BUILDDIR}" -mindepth 1 -maxdepth 1)" ]; then - rmdir "${PORTAGE_BUILDDIR}" - fi # do not bind this to doebuild defined DISTDIR; don't trust doebuild, and if mistakes are made it'll # result in it wiping the users distfiles directory (bad). rm -rf "${PORTAGE_BUILDDIR}/distdir" + + if [ -z "$(find "${PORTAGE_BUILDDIR}" -mindepth 1 -maxdepth 1)" ]; then + rmdir "${PORTAGE_BUILDDIR}" + fi + true } @@ -1020,13 +1027,6 @@ abort_unpack() { exit 1 } -abort_package() { - abort_handler "dyn_package" $1 - rm -f "${PORTAGE_BUILDDIR}/.packaged" - rm -f "${PKGDIR}"/All/${PF}.t* - exit 1 -} - abort_test() { abort_handler "dyn_test" $1 rm -f "${PORTAGE_BUILDDIR}/.tested" @@ -1127,26 +1127,6 @@ dyn_compile() { trap SIGINT SIGQUIT } -dyn_package() { - trap "abort_package" SIGINT SIGQUIT - cd "${PORTAGE_BUILDDIR}/image" - tar cpvf - ./ | bzip2 -f > ../bin.tar.bz2 || die "Failed to create tarball" - cd .. - xpak build-info inf.xpak - tbz2tool join bin.tar.bz2 inf.xpak "${PF}.tbz2" - mv "${PF}.tbz2" "${PKGDIR}/All" || die "Failed to move tbz2 to ${PKGDIR}/All" - rm -f inf.xpak bin.tar.bz2 - if [ ! -d "${PKGDIR}/${CATEGORY}" ]; then - install -d "${PKGDIR}/${CATEGORY}" - fi - ln -sf "../All/${PF}.tbz2" "${PKGDIR}/${CATEGORY}/${PF}.tbz2" || die "Failed to create symlink in ${PKGDIR}/${CATEGORY}" - echo ">>> Done." - cd "${PORTAGE_BUILDDIR}" - touch .packaged || die "Failed to 'touch .packaged' in ${PORTAGE_BUILDDIR}" - trap SIGINT SIGQUIT -} - - dyn_test() { [ "$(type -t pre_src_test)" == "function" ] && pre_src_test if [ "${PORTAGE_BUILDDIR}/.tested" -nt "${WORKDIR}" ]; then @@ -1173,8 +1153,8 @@ dyn_test() { trap SIGINT SIGQUIT } - dyn_install() { + [ -z "$PORTAGE_BUILDDIR" ] && die "${FUNCNAME}: PORTAGE_BUILDDIR is unset" trap "abort_install" SIGINT SIGQUIT [ "$(type -t pre_src_install)" == "function" ] && pre_src_install rm -rf "${PORTAGE_BUILDDIR}/image" @@ -1191,219 +1171,6 @@ dyn_install() { #our libtool to create problematic .la files export PWORKDIR="$WORKDIR" src_install - #|| abort_install "fail" - prepall - cd "${D}" - - declare -i UNSAFE=0 - for i in $(find "${D}/" -type f -perm -2002); do - ((UNSAFE++)) - echo "UNSAFE SetGID: $i" - chmod -s,o-w "$i" - done - for i in $(find "${D}/" -type f -perm -4002); do - ((UNSAFE++)) - echo "UNSAFE SetUID: $i" - chmod -s,o-w "$i" - done - - # Now we look for all world writable files. - for i in $(find "${D}/" -type f -perm -2); do - echo -ne '\a' - echo "QA Security Notice:" - echo "- ${i:${#D}:${#i}} will be a world writable file." - echo "- This may or may not be a security problem, most of the time it is one." - echo "- Please double check that $PF really needs a world writeable bit and file bugs accordingly." - sleep 1 - done - - if type -p scanelf > /dev/null ; then - local insecure_rpath=0 - - # Make sure we disallow insecure RUNPATH/RPATH's - # Don't want paths that point to the tree where the package was built - # (older, broken libtools would do this). Also check for null paths - # because the loader will search $PWD when it finds null paths. - f=$(scanelf -qyRF '%r %p' "${D}" | grep -E "(${PORTAGE_BUILDDIR}|: |::|^:|^ )") - if [[ -n ${f} ]] ; then - echo -ne '\a\n' - echo "QA Notice: the following files contain insecure RUNPATH's" - echo " Please file a bug about this at http://bugs.gentoo.org/" - echo " For more information on this issue, kindly review:" - echo " http://bugs.gentoo.org/81745" - echo "${f}" - echo -ne '\a\n' - insecure_rpath=1 - fi - - # Check for setid binaries but are not built with BIND_NOW - f=$(scanelf -qyRF '%b %p' "${D}") - if [[ -n ${f} ]] ; then - echo -ne '\a\n' - echo "QA Notice: the following files are setXid, dyn linked, and using lazy bindings" - echo " This combination is generally discouraged. Try re-emerging the package:" - echo " LDFLAGS='-Wl,-z,now' emerge ${PN}" - echo "${f}" - echo -ne '\a\n' - die_msg="${die_msg} setXid lazy bindings," - sleep 1 - fi - - # TEXTREL's are baaaaaaaad - f=$(scanelf -qyRF '%t %p' "${D}") - if [[ -n ${f} ]] ; then - scanelf -qyRF '%T %p' "${WORKDIR}"/ &> "${T}"/scanelf-textrel.log - echo -ne '\a\n' - echo "QA Notice: the following files contain runtime text relocations" - echo " Text relocations force the dynamic linker to perform extra" - echo " work at startup, waste system resources, and may pose a security" - echo " risk. On some architectures, the code may not even function" - echo " properly, if at all." - echo " Please include this file in your report:" - echo " ${T}/scanelf-textrel.log" - echo "${f}" - echo -ne '\a\n' - die_msg="${die_msg} textrels," - sleep 1 - fi - - # Check for files with executable stacks, but only on arches which - # are supported at the moment. Keep this list in sync with - # http://hardened.gentoo.org/gnu-stack.xml (Arch Status) - case ${CTARGET:-${CHOST}} in - i?86*|ia64*|m68k*|powerpc64*|s390*|x86_64*) - f=$(scanelf -qyRF '%e %p' "${D}") ;; - *) - f="" ;; - esac - if [[ -n ${f} ]] ; then - # One more pass to help devs track down the source - scanelf -qyRF '%e %p' "${WORKDIR}"/ &> "${T}"/scanelf-exec.log - echo -ne '\a\n' - echo "QA Notice: the following files contain executable stacks" - echo " Files with executable stacks will not work properly (or at all!)" - echo " on some architectures/operating systems. A bug should be filed" - echo " at http://bugs.gentoo.org/ to make sure the file is fixed." - echo " Please include this file in your report:" - echo " ${T}/scanelf-exec.log" - echo "${f}" - echo -ne '\a\n' - die_msg="${die_msg} execstacks" - sleep 1 - fi - - # Save NEEDED information - scanelf -qyRF '%p %n' "${D}" | sed -e 's:^:/:' > "${PORTAGE_BUILDDIR}"/build-info/NEEDED - - if [[ ${insecure_rpath} -eq 1 ]] ; then - die "Aborting due to serious QA concerns with RUNPATH/RPATH" - elif [[ ${die_msg} != "" ]] && has stricter ${FEATURES} && ! has stricter ${RESTRICT} ; then - die "Aborting due to QA concerns: ${die_msg}" - fi - fi - - if [[ ${UNSAFE} > 0 ]] ; then - die "There are ${UNSAFE} unsafe files. Portage will not install them." - fi - - if [[ -d ${D}/${D} ]] ; then - declare -i INSTALLTOD=0 - for i in $(find "${D}/${D}/"); do - echo "QA Notice: /${i##${D}/${D}} installed in \${D}/\${D}" - ((INSTALLTOD++)) - done - die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D}/${D}" - unset INSTALLTOD - fi - - # dumps perms to stdout. if error, no perms dumped. - function stat_perms() { - local f - # only define do_stat if it hasn't been already - if ! type -p do_stat &> /dev/null; then - if ! type -p stat &>/dev/null; then - do_stat() { - # Generic version -- Octal result - python -c "import os,stat; print '%o' % os.stat('$1')[stat.ST_MODE]" - } - else - if [ "${USERLAND}" == "BSD" ]; then - do_stat() { - # BSD version -- Octal result - $(type -p stat) -f '%p' "$1" - } - else - do_stat() { - # Linux version -- Hex result converted to Octal - f=$($(type -p stat) -c '%f' "$1") || return $? - printf '%o' "0x$f" - } - fi - fi - fi - - f=$(do_stat "$@") || return - f="${f:2:4}" - echo $f - } - - local file s - local count=0 - find "${D}/" -user @portageuser@ | while read file; do - count=$(( $count + 1 )) - if [ -L "${file}" ]; then - lchown @rootuser@ "${file}" - else - s=$(stat_perms "$file") - if [ -z "${s}" ]; then - ewarn "failed stat_perm'ing $file. User intervention during install isn't wise..." - continue - fi - chown @rootuser@ "$file" - chmod "$s" "$file" - fi - done - if (( $count > 0 )); then - ewarn "$count files were installed with user portage!" - fi - - count=0 - find "${D}/" -group @portagegroup@ | while read file; do - count=$(( $count + 1 )) - if [ -L "${file}" ]; then - lchgrp @wheelgroup@ "${file}" - else - s=$(stat_perms "$file") - if [ -z "${s}" ]; then - echo "failed stat_perm'ing '$file' . User intervention during install isn't wise..." - continue - fi - chgrp @wheelgroup@ "$file" - chmod "$s" "$file" - fi - done - if (( $count > 0 )); then - ewarn "$count files were installed with group portage!" - fi - - unset -f stat_perms - - # Portage regenerates this on the installed system. - if [ -f "${D}/usr/share/info/dir.gz" ]; then - rm -f "${D}/usr/share/info/dir.gz" - fi - - if hasq multilib-strict ${FEATURES} && [ -x file -a -x find -a \ - -n "${MULTILIB_STRICT_DIRS}" -a -n "${MULTILIB_STRICT_DENY}" ]; then - MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT:-"(perl5|gcc|gcc-lib|debug|portage)"} | sed -e 's:\([(|)]\):\\\1:g') - for dir in ${MULTILIB_STRICT_DIRS}; do - [ -d "${D}/${dir}" ] || continue - for file in $(find ${D}/${dir} -type f | grep -v "^${D}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do - file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" && die "File ${file} matches a file type that is not allowed in ${dir}" - done - done - fi - touch "${PORTAGE_BUILDDIR}/.installed" echo ">>> Completed installing ${PF} into ${D}" echo @@ -1413,152 +1180,17 @@ dyn_install() { } 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 ${PREFIX}/usr/sbin/setfiles -a -x ${PREFIX}/usr/sbin/selinuxconfig ]; then - echo ">>> Setting SELinux security labels" - ( - eval "$(${PREFIX}/usr/sbin/selinuxconfig)" || \ - die "Failed to determine SELinux policy paths."; - - addwrite /selinux/context; - - ${PREFIX}/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 -} - -dyn_spec() { - tar czf "${PREFIX}/usr/src/redhat/SOURCES/${PF}.tar.gz" "${O}/${PF}.ebuild" "${O}/files" || die "Failed to create base rpm tarball." - - cat <<__END1__ > ${PF}.spec -Summary: ${DESCRIPTION} -Name: ${PN} -Version: ${PV} -Release: ${PR} -Copyright: GPL -Group: portage/${CATEGORY} -Source: ${PF}.tar.gz -Buildroot: ${D} -%description -${DESCRIPTION} - -${HOMEPAGE} - -%prep -%setup -c - -%build - -%install - -%clean - -%files -/ -__END1__ - -} - -dyn_rpm() { - dyn_spec - rpmbuild -bb "${PF}.spec" || die "Failed to integrate rpm spec file" - install -D "/usr/src/redhat/RPMS/i386/${PN}-${PV}-${PR}.i386.rpm" "${RPMDIR}/${CATEGORY}/${PN}-${PV}-${PR}.rpm" || die "Failed to move rpm" } dyn_help() { @@ -2079,16 +1711,6 @@ for myarg in $*; do set +x fi ;; - package|rpm) - export SANDBOX_ON="0" - if [ "$PORTAGE_DEBUG" != "1" ]; then - dyn_${myarg} - else - set -x - dyn_${myarg} - set +x - fi - ;; depend) export SANDBOX_ON="0" set -f @@ -2144,7 +1766,11 @@ for myarg in $*; do #fi done -if [ "$myarg" != "clean" ]; then +# Save the env only for relevant phases. +if [ -n "$myarg" ] && [ "$myarg" != "clean" ]; then + # Do not save myarg in the env, or else the above [ -n "$myarg" ] test will + # give a false positive when ebuild.sh is sourced. + unset myarg # Save current environment and touch a success file. (echo for success) umask 002 set | @EGREP@ -v "^SANDBOX_" > "${T}/environment" 2>/dev/null @@ -2152,4 +1778,5 @@ if [ "$myarg" != "clean" ]; then chmod g+w "${T}/environment" &>/dev/null fi -exit 0 +# Do not exit when ebuild.sh is sourced by other scripts. +true diff --git a/bin/emaint b/bin/emaint index c56912a99..05cc45a0a 100755 --- a/bin/emaint +++ b/bin/emaint @@ -16,9 +16,10 @@ class WorldHandler(object): self.invalid = [] self.not_installed = [] self.okay = [] - self.found = os.access(portage_const.WORLD_FILE, os.R_OK) + self.world_file = os.path.join("/", portage_const.WORLD_FILE) + self.found = os.access(self.world_file, os.R_OK) - for atom in open(portage_const.WORLD_FILE).read().split(): + for atom in open(self.world_file).read().split(): if not portage.isvalidatom(atom): self.invalid.append(atom) elif not portage.db["/"]["vartree"].dbapi.match(atom): @@ -36,15 +37,15 @@ class WorldHandler(object): if self.masked: errors += "Masked ebuilds can be manually unmasked with package.keywords or package.unmask" else: - errors.append(portage_const.WORLD_FILE + " could not be opened for reading") + errors.append(self.world_file + " could not be opened for reading") return errors def fix(self): errors = [] try: - portage.write_atomic(portage_const.WORLD_FILE,"\n".join(self.okay)) + portage.write_atomic(self.world_file, "\n".join(self.okay)) except OSError: - errors.append(portage_const.WORLD_FILE + " could not be opened for writing") + errors.append(self.world_file + " could not be opened for writing") return errors class VdbKeyHandler(object): diff --git a/bin/emerge b/bin/emerge index 799c4c493..16abcb32d 100755 --- a/bin/emerge +++ b/bin/emerge @@ -411,8 +411,9 @@ if ("--resume" in myopts): if ("--nocolor" in myopts) and (sys.stdout.isatty()): nocolor() -if not sys.stdout.isatty() or ("--nospinner" in myopts): - update_spinner = update_basic_spinner +if not ("--quiet" in myopts): + if not sys.stdout.isatty() or ("--nospinner" in myopts): + update_spinner = update_basic_spinner CLEAN_DELAY = 5 EMERGE_WARNING_DELAY = 10 @@ -836,7 +837,7 @@ def getlist(mode): mylines=portage.settings.packages elif mode=="world": try: - myfile=open(portage.root+portage.WORLD_FILE,"r") + myfile = open(os.path.join(portage.root, portage.WORLD_FILE), "r") mylines=myfile.readlines() myfile.close() except OSError: @@ -1569,7 +1570,7 @@ class depgraph: if "--changelog" in myopts: changelogs.extend(self.calc_changelog( portage.portdb.findname(x[2]), - portage.db["/"]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])), + portage.db[x[1]]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])), x[2] )) else: @@ -1596,8 +1597,8 @@ class depgraph: pkg = myoldbest else: pkg = x[2] - if portage.db["/"]["vartree"].dbapi.cpv_exists(pkg): - (old_iuse, old_use) = portage.db["/"]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"]) + if portage.db[x[1]]["vartree"].dbapi.cpv_exists(pkg): + (old_iuse, old_use) = portage.db[x[1]]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"]) old_iuse = portage.unique_array(old_iuse.split()) old_iuse.sort() old_use = old_use.split() @@ -1846,7 +1847,7 @@ class depgraph: print red("!!! the merge operation manually.") sys.exit(1) else: - myfavs=portage.grabfile(portage.root+portage.WORLD_FILE) + myfavs = portage.grabfile(os.path.join(portage.root, portage.WORLD_FILE)) myfavdict=genericdict(myfavs) for x in range(len(mylist)): if mylist[x][3]!="nomerge": @@ -1864,7 +1865,9 @@ class depgraph: myfavdict[myfavkey]=myfavkey print ">>> Recording",myfavkey,"in \"world\" favorites file..." if not "--fetchonly" in myopts: - portage.write_atomic(os.path.join(portage.root,portage.WORLD_FILE),"\n".join(myfavdict.values())) + portage.write_atomic( + os.path.join(portage.root, portage.WORLD_FILE), + "\n".join(myfavdict.values())) portage.mtimedb["resume"]["mergelist"]=mymergelist[:] @@ -1891,6 +1894,7 @@ class depgraph: sys.stdin.close() sys.stdout.close() sys.stderr.close() + time.sleep(3) # allow the parent to have first fetch sys.stdout = open("/dev/null","w") sys.stderr = open("/dev/null","w") os.dup2(sys.stdout.fileno(), 1) @@ -2026,7 +2030,7 @@ class depgraph: portage.db[x[1]]["vartree"].inject(x[2]) myfavkey=portage.cpv_getkey(x[2]) if "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts and myfavkey in favorites: - myfavs=portage.grabfile(myroot+portage.WORLD_FILE) + myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE)) myfavdict=genericdict(myfavs) mysysdict=genericdict(syslist) #don't record if already in system profile or already recorded @@ -2035,17 +2039,9 @@ class depgraph: myfavdict[myfavkey]=myfavkey print ">>> Recording",myfavkey,"in \"world\" favorites file..." emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")") - portage.write_atomic(os.path.join(myroot,portage.WORLD_FILE),"\n".join(myfavdict.values())) - - if ("noclean" not in portage.features) and (x[0] != "binary"): - short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean Post" - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Post-Build Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) - retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree") - if (retval == None): - portage_util.writemsg("Unable to run required binary.\n") - sys.exit(127) - if retval: - sys.exit(retval) + portage.write_atomic( + os.path.join(myroot, portage.WORLD_FILE), + "\n".join(myfavdict.values())) if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts): # Clean the old package that we have merged over top of it. @@ -2077,6 +2073,11 @@ class depgraph: os.execv(mynewargv[0], mynewargv) if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts): + if "noclean" not in portage.features: + short_msg = "emerge: (%s of %s) %s Clean Post" % \ + (mergecount, len(mymergelist), x[pkgindex]) + emergelog(" === (%s of %s) Post-Build Cleaning (%s::%s)" % \ + (mergecount, len(mymergelist), x[pkgindex], y), short_msg=short_msg) emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1]) # Unsafe for parallel merges @@ -2299,6 +2300,9 @@ def unmerge(unmerge_action, unmerge_files): else: print "none", print + + if portage.settings["ROOT"]: + print string.rjust("ROOT:", 12) + " " + white(portage.settings["ROOT"]) print "\n>>>",red("'Selected'"),"packages are slated for removal." print ">>>",green("'Protected'"),"and",green("'omitted'"),"packages will not be removed.\n" @@ -3146,7 +3150,13 @@ else: print darkgreen("These are the packages that would be %s, in order:") % action print - if ("--resume" in myopts) and portage.mtimedb.has_key("resume"): + if "--resume" in myopts and \ + ("resume" in portage.mtimedb or + "resume_backup" in portage.mtimedb): + if "resume" not in portage.mtimedb: + portage.mtimedb["resume"] = portage.mtimedb["resume_backup"] + del portage.mtimedb["resume_backup"] + portage.commit_mtimedb() myresumeopts=portage.mtimedb["resume"]["myopts"][:] for opt in ("--skipfirst", "--ask", "--verbose"): @@ -3253,6 +3263,11 @@ else: favorites=portage.mtimedb["resume"]["favorites"] mydepgraph.merge(portage.mtimedb["resume"]["mergelist"]) else: + if "resume" in portage.mtimedb and \ + len(portage.mtimedb["resume"]["mergelist"]) > 1: + portage.mtimedb["resume_backup"] = portage.mtimedb["resume"] + del portage.mtimedb["resume"] + portage.commit_mtimedb() portage.mtimedb["resume"]={} portage.mtimedb["resume"]["myopts"]=myopts portage.mtimedb["resume"]["favorites"]=favorites diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync index 25286a6c9..8df407cb7 100755 --- a/bin/emerge-webrsync +++ b/bin/emerge-webrsync @@ -5,13 +5,11 @@ # Author: Karl Trygve Kalleberg # Rewritten from the old, Perl-based emerge-webrsync script -if [ -z "$PULLED_NICENESS" ]; then - PULLED_NICENESS="$(@PORTAGE_BASE@/bin/portageq envvar PORTAGE_NICENESS)" - if [ -n "$PULLED_NICENESS" ]; then - export PULLED_NICENESS - exec nice -n $PORTAGE_NICENESS "$0" "$@" - echo "failed pulling PORTAGE_NICENESS, disabling" - fi +# If PORTAGE_NICENESS is overriden via the env then it will +# still pass through the portageq call and override properly. +PORTAGE_NICENESS="$(@PORTAGE_BASE@/bin/portageq envvar PORTAGE_NICENESS)" +if [ -n "${PORTAGE_NICENESS}" ]; then + renice $PORTAGE_NICENESS $$ > /dev/null fi GENTOO_MIRRORS="${GENTOO_MIRRORS} $(@PORTAGE_BASE@/bin/portageq gentoo_mirrors)" PORTDIR="$(@PORTAGE_BASE@/bin/portageq portdir)" diff --git a/bin/env-update b/bin/env-update index 4c3531828..d5e5e04d2 100755 --- a/bin/env-update +++ b/bin/env-update @@ -8,7 +8,7 @@ os.environ["PORTAGE_CALLER"] = "env-update" sys.path = ["@PORTAGE_BASE@/pym"]+sys.path def usage(status): - print "Usage: env-update" + print "Usage: env-update [--no-ldconfig]" print "" print "See the env-update(1) man page for more info" sys.exit(status) diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh new file mode 100644 index 000000000..8ae5149fe --- /dev/null +++ b/bin/misc-functions.sh @@ -0,0 +1,472 @@ +#!/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_qa_check() { + + prepall + cd "${D}" + + declare -i UNSAFE=0 + for i in $(find "${D}/" -type f -perm -2002); do + ((UNSAFE++)) + echo "UNSAFE SetGID: $i" + chmod -s,o-w "$i" + done + for i in $(find "${D}/" -type f -perm -4002); do + ((UNSAFE++)) + echo "UNSAFE SetUID: $i" + chmod -s,o-w "$i" + done + + # Now we look for all world writable files. + for i in $(find "${D}/" -type f -perm -2); do + echo -ne '\a' + echo "QA Security Notice:" + echo "- ${i:${#D}:${#i}} will be a world writable file." + echo "- This may or may not be a security problem, most of the time it is one." + echo "- Please double check that $PF really needs a world writeable bit and file bugs accordingly." + sleep 1 + done + + if type -p scanelf > /dev/null ; then + local qa_var insecure_rpath=0 + + # Make sure we disallow insecure RUNPATH/RPATH's + # Don't want paths that point to the tree where the package was built + # (older, broken libtools would do this). Also check for null paths + # because the loader will search $PWD when it finds null paths. + f=$(scanelf -qyRF '%r %p' "${D}" | grep -E "(${PORTAGE_BUILDDIR}|: |::|^:|^ )") + if [[ -n ${f} ]] ; then + echo -ne '\a\n' + echo "QA Notice: the following files contain insecure RUNPATH's" + echo " Please file a bug about this at http://bugs.gentoo.org/" + echo " with the maintaining herd of the package." + echo " Summary: $CATEGORY/$PN: insecure RPATH ${f}" + echo "${f}" + echo -ne '\a\n' + if has stricter ${FEATURES}; then + insecure_rpath=1 + else + echo "Auto fixing rpaths for ${f}" + TMPDIR=${PORTAGE_BUILDDIR} scanelf -BXr ${f} -o /dev/null + fi + fi + + # Check for setid binaries but are not built with BIND_NOW + f=$(scanelf -qyRF '%b %p' "${D}") + if [[ -n ${f} ]] ; then + echo -ne '\a\n' + echo "QA Notice: the following files are setXid, dyn linked, and using lazy bindings" + echo " This combination is generally discouraged. Try re-emerging the package:" + echo " LDFLAGS='-Wl,-z,now' emerge ${PN}" + echo "${f}" + echo -ne '\a\n' + die_msg="${die_msg} setXid lazy bindings," + sleep 1 + fi + + # TEXTREL's are baaaaaaaad + # Allow devs to mark things as ignorable ... e.g. things that are + # binary-only and upstream isn't cooperating (nvidia-glx) ... we + # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ... + # the former overrides the latter ... regexes allowed ! :) + qa_var="QA_TEXTRELS_${ARCH}" + [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var} + [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS="" + f=$(scanelf -qyRF '%t %p' "${D}" | grep -v ' usr/lib/debug/' | \ + gawk ' + BEGIN { split("'"${QA_TEXTRELS}"'", ignore); } + { for (idx in ignore) + if ($NF ~ "^"ignore[idx]"$") + next; + print; + }') + if [[ -n ${f} ]] ; then + scanelf -qyRF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log + echo -ne '\a\n' + echo "QA Notice: the following files contain runtime text relocations" + echo " Text relocations force the dynamic linker to perform extra" + echo " work at startup, waste system resources, and may pose a security" + echo " risk. On some architectures, the code may not even function" + echo " properly, if at all." + echo " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml" + echo " Please include this file in your report:" + echo " ${T}/scanelf-textrel.log" + echo "${f}" + echo -ne '\a\n' + die_msg="${die_msg} textrels," + sleep 1 + fi + + # Also, executable stacks only matter on linux (and just glibc atm ...) + case ${CTARGET:-${CHOST}} in + *-linux-gnu*) + # Check for files with executable stacks, but only on arches which + # are supported at the moment. Keep this list in sync with + # http://hardened.gentoo.org/gnu-stack.xml (Arch Status) + case ${CTARGET:-${CHOST}} in + i?86*|ia64*|m68k*|powerpc64*|s390*|x86_64*) + # Allow devs to mark things as ignorable ... e.g. things + # that are binary-only and upstream isn't cooperating ... + # we allow ebuild authors to set QA_EXECSTACK_arch and + # QA_EXECSTACK ... the former overrides the latter ... + # regexes allowed ! :) + + qa_var="QA_EXECSTACK_${ARCH}" + [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var} + [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK="" + f=$(scanelf -qyRF '%e %p' "${D}" | grep -v ' usr/lib/debug/' | \ + gawk ' + BEGIN { split("'"${QA_EXECSTACK}"'", ignore); } + { for (idx in ignore) + if ($NF ~ "^"ignore[idx]"$") + next; + print; + }') + ;; + *) f="" ;; + esac + ;; + esac + if [[ -n ${f} ]] ; then + # One more pass to help devs track down the source + scanelf -qyRF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log + echo -ne '\a\n' + echo "QA Notice: the following files contain executable stacks" + echo " Files with executable stacks will not work properly (or at all!)" + echo " on some architectures/operating systems. A bug should be filed" + echo " at http://bugs.gentoo.org/ to make sure the file is fixed." + echo " For more information, see http://hardened.gentoo.org/gnu-stack.xml" + echo " Please include this file in your report:" + echo " ${T}/scanelf-execstack.log" + echo "${f}" + echo -ne '\a\n' + die_msg="${die_msg} execstacks" + sleep 1 + fi + + # Save NEEDED information + scanelf -qyRF '%p %n' "${D}" | sed -e 's:^:/:' > "${PORTAGE_BUILDDIR}"/build-info/NEEDED + + if [[ ${insecure_rpath} -eq 1 ]] ; then + die "Aborting due to serious QA concerns with RUNPATH/RPATH" + elif [[ ${die_msg} != "" ]] && has stricter ${FEATURES} && ! has stricter ${RESTRICT} ; then + die "Aborting due to QA concerns: ${die_msg}" + fi + fi + + if [[ ${UNSAFE} > 0 ]] ; then + die "There are ${UNSAFE} unsafe files. Portage will not install them." + fi + + if [[ -d ${D}/${D} ]] ; then + declare -i INSTALLTOD=0 + for i in $(find "${D}/${D}/"); do + echo "QA Notice: /${i##${D}/${D}} installed in \${D}/\${D}" + ((INSTALLTOD++)) + done + die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D}/${D}" + unset INSTALLTOD + fi + + # dumps perms to stdout. if error, no perms dumped. + function stat_perms() { + local f + # only define do_stat if it hasn't been already + if ! type -p do_stat &> /dev/null; then + if ! type -p stat &>/dev/null; then + do_stat() { + # Generic version -- Octal result + python -c "import os,stat; print '%o' % os.stat('$1')[stat.ST_MODE]" + } + else + if [ "${USERLAND}" == "BSD" ] || [ "${USERLAND}" == "Darwin" ]; then + do_stat() { + # BSD version -- Octal result + $(type -p stat) -f '%p' "$1" + } + else + do_stat() { + # Linux version -- Hex result converted to Octal + f=$($(type -p stat) -c '%f' "$1") || return $? + printf '%o' "0x$f" + } + fi + fi + fi + + f=$(do_stat "$@") || return + f="${f:2:4}" + echo $f + } + + local file s + local count=0 + find "${D}/" -user portage | while read file; do + count=$(( $count + 1 )) + if [ -L "${file}" ]; then + lchown ${PORTAGE_INST_UID} "${file}" + else + s=$(stat_perms "$file") + if [ -z "${s}" ]; then + ewarn "failed stat_perm'ing $file. User intervention during install isn't wise..." + continue + fi + chown ${PORTAGE_INST_UID} "$file" + chmod "$s" "$file" + fi + done + if (( $count > 0 )); then + ewarn "$count files were installed with user portage!" + fi + + count=0 + find "${D}/" -group portage | while read file; do + count=$(( $count + 1 )) + if [ -L "${file}" ]; then + lchgrp ${PORTAGE_INST_GID} "${file}" + else + s=$(stat_perms "$file") + if [ -z "${s}" ]; then + echo "failed stat_perm'ing '$file' . User intervention during install isn't wise..." + continue + fi + chgrp ${PORTAGE_INST_GID} "$file" + chmod "$s" "$file" + fi + done + if (( $count > 0 )); then + ewarn "$count files were installed with group portage!" + fi + + unset -f stat_perms + + # Portage regenerates this on the installed system. + if [ -f "${D}/usr/share/info/dir.gz" ]; then + rm -f "${D}/usr/share/info/dir.gz" + fi + + if hasq multilib-strict ${FEATURES} && [ -x /usr/bin/file -a -x /usr/bin/find -a \ + -n "${MULTILIB_STRICT_DIRS}" -a -n "${MULTILIB_STRICT_DENY}" ]; then + MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT:-"(perl5|gcc|gcc-lib|debug|portage)"} | sed -e 's:\([(|)]\):\\\1:g') + for dir in ${MULTILIB_STRICT_DIRS}; do + [ -d "${D}/${dir}" ] || continue + for file in $(find ${D}/${dir} -type f | grep -v "^${D}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do + file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" && die "File ${file} matches a file type that is not allowed in ${dir}" + done + done + fi + +} + + +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 +} + +dyn_package() { + cd "${PORTAGE_BUILDDIR}/image" + install_mask "${PORTAGE_BUILDDIR}/image" ${PKG_INSTALL_MASK} + tar cpvf - ./ | bzip2 -f > ../bin.tar.bz2 || die "Failed to create tarball" + cd .. + xpak build-info inf.xpak + tbz2tool join bin.tar.bz2 inf.xpak "${PF}.tbz2" + addwrite "${PKGDIR}" + mv "${PF}.tbz2" "${PKGDIR}/All" || die "Failed to move tbz2 to ${PKGDIR}/All" + rm -f inf.xpak bin.tar.bz2 + if [ ! -d "${PKGDIR}/${CATEGORY}" ]; then + install -d "${PKGDIR}/${CATEGORY}" + fi + ln -sf "../All/${PF}.tbz2" "${PKGDIR}/${CATEGORY}/${PF}.tbz2" || die "Failed to create symlink in ${PKGDIR}/${CATEGORY}" + echo ">>> Done." + cd "${PORTAGE_BUILDDIR}" + touch .packaged || die "Failed to 'touch .packaged' in ${PORTAGE_BUILDDIR}" +} + +dyn_spec() { + tar czf "/usr/src/redhat/SOURCES/${PF}.tar.gz" "${O}/${PF}.ebuild" "${O}/files" || die "Failed to create base rpm tarball." + + cat <<__END1__ > ${PF}.spec +Summary: ${DESCRIPTION} +Name: ${PN} +Version: ${PV} +Release: ${PR} +Copyright: GPL +Group: portage/${CATEGORY} +Source: ${PF}.tar.gz +Buildroot: ${D} +%description +${DESCRIPTION} + +${HOMEPAGE} + +%prep +%setup -c + +%build + +%install + +%clean + +%files +/ +__END1__ + +} + +dyn_rpm() { + addwrite /usr/src/redhat/ + addwrite ${RPMDIR} + dyn_spec + rpmbuild -bb "${PF}.spec" || die "Failed to integrate rpm spec file" + install -D "/usr/src/redhat/RPMS/i386/${PN}-${PV}-${PR}.i386.rpm" "${RPMDIR}/${CATEGORY}/${PN}-${PV}-${PR}.rpm" || die "Failed to move rpm" +} + +if [ -n "${MISC_FUNCTIONS_ARGS}" ]; then + [ "$PORTAGE_DEBUG" == "1" ] && set -x + for x in ${MISC_FUNCTIONS_ARGS}; do + ${x} + done +fi + +true diff --git a/bin/quickpkg b/bin/quickpkg index 3ff5702af..09f48d21c 100755 --- a/bin/quickpkg +++ b/bin/quickpkg @@ -46,11 +46,11 @@ source @PORTAGE_BASE@/sbin/functions.sh # $1 = package-name w/version # $2 = category do_pkg() { - mkdir -p "${PORTAGE_TMPDIR}/portage-pkg" || exit 1 - chmod 0750 "${PORTAGE_TMPDIR}/portage-pkg" - MYDIR="${PORTAGE_TMPDIR}/portage-pkg/$1" + mkdir -p "${PORTAGE_TMPDIR}/binpkgs" || exit 1 + chmod 0750 "${PORTAGE_TMPDIR}/binpkgs" + MYDIR="${PORTAGE_TMPDIR}/binpkgs/$1" SRCDIR="${PORTAGE_DB}/$2/$1" - LOG="${PORTAGE_TMPDIR}/portage-pkg/$1-quickpkglog" + LOG="${PORTAGE_TMPDIR}/binpkgs/$1-quickpkglog" ebegin "Building package for $1" ( diff --git a/bin/regenworld b/bin/regenworld index 3d57d0f12..f75efe16d 100755 --- a/bin/regenworld +++ b/bin/regenworld @@ -5,7 +5,7 @@ import sys sys.path.insert(0, "@PORTAGE_BASE@/pym") - +import os import portage, string, re __candidatematcher__ = re.compile("^[0-9]+: \\*\\*\\* emerge ") @@ -44,7 +44,7 @@ if len(sys.argv) >= 2 and sys.argv[1] in ["-h", "--help"]: print "your existing world file (%s) before using this tool." % portage.WORLD_FILE sys.exit(0) -worldlist = portage.grabfile(portage.WORLD_FILE) +worldlist = portage.grabfile(os.path.join("/", portage.WORLD_FILE)) syslist = portage.settings.packages syslist = filter(issyspkg, syslist) @@ -88,4 +88,4 @@ for mykey in biglist: print "add to world:",myfavkey worldlist.append(myfavkey) -portage.write_atomic(portage.WORLD_FILE,"\n".join(worldlist)) +portage.write_atomic(os.path.join("/", portage.WORLD_FILE), "\n".join(worldlist)) diff --git a/bin/repoman b/bin/repoman index e7aae73e7..9ca26e69f 100755 --- a/bin/repoman +++ b/bin/repoman @@ -536,7 +536,7 @@ if isCvs or isSvn: err("Couldn't recognize repository type. Supported repositories:\n"+repr(REPOROOTS)) if isSvn: reposplit=string.split(os.path.normpath(myrepoinfo[1].split("svn.gentoo.org")[1].rstrip().replace("/var/svnroot",'')).replace(x,'')[2:],"/") - reposplit.insert(0,myrepo) + reposplit.insert(0,myreporoot) else: reposplit=string.split(myreporoot,"/") repolevel=len(reposplit) diff --git a/cnf/make.conf b/cnf/make.conf index 67af62b10..863fb957e 100644 --- a/cnf/make.conf +++ b/cnf/make.conf @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf,v 1.84.2.5 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.alpha b/cnf/make.conf.alpha index 9f1d9f162..613c2abb4 100644 --- a/cnf/make.conf.alpha +++ b/cnf/make.conf.alpha @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.alpha,v 1.40.2.5 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.amd64 b/cnf/make.conf.amd64 index 0d084cc54..ef4ef3212 100644 --- a/cnf/make.conf.amd64 +++ b/cnf/make.conf.amd64 @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.amd64,v 1.5.2.4 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.arm b/cnf/make.conf.arm index b725b8d25..ccb4e47b5 100644 --- a/cnf/make.conf.arm +++ b/cnf/make.conf.arm @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.arm,v 1.31.2.5 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.hppa b/cnf/make.conf.hppa index 3dc0a2c09..892fa51c4 100644 --- a/cnf/make.conf.hppa +++ b/cnf/make.conf.hppa @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.hppa,v 1.37.2.5 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.ia64 b/cnf/make.conf.ia64 index 9aa4e5a82..95df49395 100644 --- a/cnf/make.conf.ia64 +++ b/cnf/make.conf.ia64 @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.ia64,v 1.1.2.4 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.mac b/cnf/make.conf.mac index 3137fb97f..292d9a510 100644 --- a/cnf/make.conf.mac +++ b/cnf/make.conf.mac @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.mac,v 1.2 2004/09/30 06:34:27 vapier Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.mips b/cnf/make.conf.mips index b96e3c8d7..8602b00e2 100644 --- a/cnf/make.conf.mips +++ b/cnf/make.conf.mips @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.mips,v 1.38.2.4 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.ppc b/cnf/make.conf.ppc index 345088146..1b6ebcc77 100644 --- a/cnf/make.conf.ppc +++ b/cnf/make.conf.ppc @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.ppc,v 1.57.2.4 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.ppc64 b/cnf/make.conf.ppc64 index 64f4f7631..80c4e1fba 100644 --- a/cnf/make.conf.ppc64 +++ b/cnf/make.conf.ppc64 @@ -1,4 +1,4 @@ -# Copyright 1999-2005 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.ppc64,v 1.1.2.5 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.s390 b/cnf/make.conf.s390 index cb570c799..f1f612711 100644 --- a/cnf/make.conf.s390 +++ b/cnf/make.conf.s390 @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.s390,v 1.3.2.4 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.sparc b/cnf/make.conf.sparc index 0784f8091..637bc174e 100644 --- a/cnf/make.conf.sparc +++ b/cnf/make.conf.sparc @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.sparc,v 1.42.2.5 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.x86 b/cnf/make.conf.x86 index 37813afae..f1272ccd3 100644 --- a/cnf/make.conf.x86 +++ b/cnf/make.conf.x86 @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.x86,v 1.5.2.5 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.conf.x86-fbsd b/cnf/make.conf.x86-fbsd index 64be779a2..8e4ba3541 100644 --- a/cnf/make.conf.x86-fbsd +++ b/cnf/make.conf.x86-fbsd @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.conf.x86-fbsd,v 1.1.2.2 2005/04/13 15:28:38 jstubbs Exp $ # Contains local system settings for Portage system diff --git a/cnf/make.globals b/cnf/make.globals index b38eab384..d530a8dc2 100644 --- a/cnf/make.globals +++ b/cnf/make.globals @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/cnf/make.globals,v 1.56.2.5 2005/05/05 03:59:59 jstubbs Exp $ # System-wide defaults for the Portage system @@ -60,6 +60,10 @@ CONFIG_PROTECT="@DOMAIN_PREFIX@/etc" # Disable auto-use USE_ORDER="env:pkg:conf:defaults" +# Default ownership of installed files. +PORTAGE_INST_UID="0" +PORTAGE_INST_GID="0" + # ***************************** # ** DO NOT EDIT THIS FILE ** # *************************************************** diff --git a/man/ebuild.5 b/man/ebuild.5 index ff27939b2..fb57fbebc 100644 --- a/man/ebuild.5 +++ b/man/ebuild.5 @@ -1,4 +1,4 @@ -.TH "EBUILD" "5" "Dec 2005" "Portage 2.1" "portage" +.TH "EBUILD" "5" "Mar 2006" "Portage 2.1" "portage" .SH "NAME" ebuild \- the internal format, variables, and functions in an ebuild script .SH "DESCRIPTION" @@ -8,13 +8,14 @@ program accepts a single ebuild script as an argument. This script contains variables and commands that specify how to download, unpack, patch, compile, install and merge a particular software package from its original sources. In addition to all of this, the ebuild script -can also contain pre/post install/remove commands, as required. +can also contain pre/post install/remove commands, as required. All +ebuild scripts are written in bash. .SH "EXAMPLES" Here's a simple example ebuild: .DS .nf -# Copyright 1999\-2005 Gentoo Foundation +# Copyright 1999\-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ @@ -51,10 +52,11 @@ src_install() { .SH "VARIABLES" .TP .B MISC USAGE NOTES -- PORTAGE* and PORTDIR* variables may be found in \fBmake.conf\fR(5). +- All variables defined in \fBmake.conf\fR(5) are available for use in +ebuilds (such as the PORTAGE* and PORTDIR* variables) .br -- When assigning values to variables in ebuilds, you \fBcannot have a space\fR -between the variable name and the equal sign. +- When assigning values to variables in ebuilds, you \fBcannot have a +space\fR between the variable name and the equal sign. .TP .B P This variable contains the package name without the ebuild revision. @@ -92,7 +94,7 @@ Contains the package category name. .TP .B A Contains all source files required for the package. This variable must -not be defined. It is autogenerated from the \fISRC_URI\fR variables. +not be defined. It is autogenerated from the \fISRC_URI\fR variable. .TP \fBWORKDIR\fR = \fI"${PORTAGE_TMPDIR}/portage/${PF}/work"\fR Contains the path to the package build root. Do not modify this variable. @@ -121,8 +123,8 @@ Should contain a short description of the package. .TP \fBSRC_URI\fR = \fI"http://happy.com/little/${P}.tar.gz"\fR Contains a list of URI's for the required source files. It can contain -multiple URI's for a single source file. The fastest location is chosen -if the file was not found at \fIGENTOO_MIRROR\fB\fR. +multiple URI's for a single source file. The list is processed in order +if the file was not found on any of the \fIGENTOO_MIRROR\fRs. .TP \fBHOMEPAGE\fR = \fI"http://happy.com/"\fR Should contain a list of URL's for the sources main sites and other further @@ -137,17 +139,18 @@ being submitted for inclusion, it must have ~arch set for architectures where it has been PROVEN TO WORK. (Packages KEYWORDed this way may be unmasked for testing by setting ACCEPT_KEYWORDS="~arch" on the command line, or in \fBmake.conf\fR(5)) For an authoritative list please review -/usr/portage/profiles/arch.list. +/usr/portage/profiles/arch.list. Please keep this list in alphabetical order. .TP \fBSLOT\fR -This sets the SLOT for packages that may need to co\-exist. By default -you should set \fBSLOT\fR="0" unless you know what you are doing and need -to do otherwise. This value should \fINEVER\fR be left undefined. +This sets the SLOT for packages that may need to have multiple versions +co\-exist. By default you should set \fBSLOT\fR="0". If you are unsure, then +do not fiddle with this until you seek some guidance from some guru. This +value should \fINEVER\fR be left undefined. .TP \fBLICENSE\fR This should be a space delimited list of licenses that the package falls under. This \fB_must_\fR be set to a matching license in -/usr/portage/licenses/. If the license does not exist in portage yet you +/usr/portage/licenses/. If the license does not exist in portage yet, you must add it first. .TP \fBIUSE\fR @@ -342,13 +345,14 @@ or sun specifically. .SH "PORTAGE DECLARATIONS" .TP .B inherit -Inherit is portage's maintainance of extra classes of functions that -are external to ebuilds and provided as inheritable capabilities and -data. They define functions and set data types as drop-in replacements, -expanded, and simplified routines for extremely common tasks to streamline -the build process. Inherit may only be called once in an ebuild and it may -\fBnever be wrapped within any conditionals\fR of any kind. Specification of -the eclasses contains only their name and not the \fI.eclass\fR extention. +Inherit is portage's maintainance of extra classes of functions that are +external to ebuilds and provided as inheritable capabilities and data. They +define functions and set data types as drop-in replacements, expanded, and +simplified routines for extremely common tasks to streamline the build +process. Inherit may only be called once in an ebuild and it may \fBnever be +wrapped within any conditionals\fR of any kind. Specification of the eclasses +contains only their name and not the \fI.eclass\fR extention. Also note that +the inherit statement must come before other variable declarations. .SH "FUNCTIONS" .TP .B pkg_nofetch @@ -507,6 +511,16 @@ Same as \fBeinfo\fR, but should be used when showing a warning to the user. .TP \fBeerror\fR \fI"error message"\fR Same as \fBeinfo\fR, but should be used when showing an error to the user. +.TP +\fBebegin\fR \fI"helpful message"\fR +Like \fBeinfo\fR, we output a \fIhelpful message\fR and then hint that the +following operation may take some time to complete. Once the task is +finished, you need to call \fBeend\fR. +.TP +\fBeend\fR \fI\fR \fI["error message"]\fR +Followup the \fBebegin\fR message with an appropriate "OK" or "!!" (for +errors) marker. If \fIstatus\fR is non-zero, then the additional \fIerror +message\fR is displayed. .SH "HELPER FUNCTIONS: UNPACK" .TP \fBunpack\fR \fI\fR \fI[list of more sources]\fR @@ -540,7 +554,9 @@ This is used as a replacement for make. Performs 'make ${MAKEOPTS} .br if you are going to use \fBemake\fR, make sure your build is happy with parallel makes (make \-j2). It should be tested thoroughly as parallel -makes are notorious for failing _sometimes_ but not always. +makes are notorious for failing _sometimes_ but not always. If you determine +that your package fails to build in parallel, and you are unable to resolve +the issue, then you should run '\fBemake\fR -j1' instead of 'make'. .SH "HELPER FUNCTIONS: INSTALL" .TP \fBeinstall\fR \fI[make options]\fR diff --git a/man/env-update.1 b/man/env-update.1 index af299f35d..12f8fc878 100644 --- a/man/env-update.1 +++ b/man/env-update.1 @@ -1,10 +1,10 @@ -.TH "ENV-UPDATE" "1" "Dec 2005" "Portage 2.1" "Portage" +.TH "ENV-UPDATE" "1" "Mar 2006" "Portage 2.1" "Portage" .SH NAME -env-update \- updates environment settings automatically +env\-update \- updates environment settings automatically .SH SYNOPSIS -.B env-update +\fBenv\-update\fR \fI[options]\fR .SH DESCRIPTION -.B env-update +.B env\-update reads the files in \fI/etc/env.d\fR and automatically generates \fI/etc/profile.env\fR and \fI/etc/ld.so.conf\fR. Then \fBldconfig\fR(8) is run to update \fI/etc/ld.so.cache\fR. \fBenv-update\fR is run by @@ -16,7 +16,9 @@ active shell, you will probably have to run \fIsource /etc/profile\fR first. .SH OPTIONS .TP -None. +.B \-\-no\-ldconfig +Do not run ldconfig (and thus skip rebuilding the ldso cache, updating the +links in library paths, etc...). .SH "REPORTING BUGS" Please report bugs via http://bugs.gentoo.org/ .SH AUTHORS diff --git a/man/make.conf.5 b/man/make.conf.5 index 16ca627bd..ae0a67bf5 100644 --- a/man/make.conf.5 +++ b/man/make.conf.5 @@ -43,7 +43,7 @@ unless you know what you are doing. Defines the location of the ccache working directory. See the \fBccache\fR(1) man page for more information. .br -Defaults to ${PORTAGE_TMPDIR}/ccache +Defaults to /var/tmp/ccache .TP \fBCCACHE_SIZE\fR = \fI"size"\fR This controls the space use limitations for ccache. The default is 2 gigabytes diff --git a/pym/emergehelp.py b/pym/emergehelp.py index 28a78a126..2936dd628 100644 --- a/pym/emergehelp.py +++ b/pym/emergehelp.py @@ -1,4 +1,4 @@ -# Copyright 1999-2004 Gentoo Foundation +# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/pym/emergehelp.py,v 1.8.2.2 2005/01/16 02:35:33 carpaski Exp $ diff --git a/pym/portage.py b/pym/portage.py index 7e6c3d2e0..1a0e306de 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -86,7 +86,7 @@ try: 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 @@ -106,7 +106,7 @@ try: from portage_checksum import perform_md5,perform_checksum,prelink_capable import eclass_cache from portage_localization import _ - from portage_update import fixdbentries, update_dbentries + from portage_update import fixdbentries, update_dbentries, grab_updates # Need these functions directly in portage namespace to not break every external tool in existence from portage_versions import ververify,vercmp,catsplit,catpkgsplit,pkgsplit,pkgcmp @@ -1637,7 +1637,7 @@ class config: # XXX This would be to replace getstatusoutput completely. # XXX Issue: cannot block execution. Deadlock condition. -def spawn(mystring,mysettings,debug=0,free=0,droppriv=0,fd_pipes=None,**keywords): +def spawn(mystring,mysettings,debug=0,free=0,droppriv=0,sesandbox=0,fd_pipes=None,**keywords): """spawn a subprocess with optional sandbox protection, depending on whether sandbox is enabled. The "free" argument, when set to 1, will disable sandboxing. This allows us to @@ -1666,14 +1666,20 @@ def spawn(mystring,mysettings,debug=0,free=0,droppriv=0,fd_pipes=None,**keywords free=((droppriv and "usersandbox" not in features) or \ (not droppriv and "sandbox" not in features and "usersandbox" not in features)) + if sesandbox: + con = selinux.getcontext() + con = string.replace(con, mysettings["PORTAGE_T"], mysettings["PORTAGE_SANDBOX_T"]) + selinux.setexec(con) + if not free: keywords["opt_name"] += " sandbox" return portage_exec.spawn_sandbox(mystring,env=env,**keywords) else: keywords["opt_name"] += " bash" return portage_exec.spawn_bash(mystring,env=env,**keywords) - - + + if sesandbox: + selinux.setexec(None) def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",use_locks=1, try_mirrors=1): "fetch files. Will use digest file if available." @@ -1956,14 +1962,9 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", myfetch=string.replace(locfetch,"${URI}",loc) myfetch=string.replace(myfetch,"${FILE}",myfile) try: - if selinux_enabled: - con=selinux.getcontext() - con=string.replace(con,mysettings["PORTAGE_T"],mysettings["PORTAGE_FETCH_T"]) - selinux.setexec(con) - myret=spawn(myfetch,mysettings,free=1, droppriv=("userfetch" in mysettings.features)) - selinux.setexec(None) - else: - myret=spawn(myfetch,mysettings,free=1, droppriv=("userfetch" in mysettings.features)) + myret = spawn(myfetch, mysettings, free=1, + droppriv=("userfetch" in mysettings.features), + sesandbox=selinux_enabled) finally: #if root, -always- set the perms. if os.path.exists(mysettings["DISTDIR"]+"/"+myfile) and (fetched != 1 or os.getuid() == 0) \ @@ -2374,21 +2375,23 @@ def spawnebuild(mydo,actionmap,mysettings,debug,alwaysdep=0,logfile=None): retval=spawnebuild(actionmap[mydo]["dep"],actionmap,mysettings,debug,alwaysdep=alwaysdep,logfile=logfile) if retval: return retval - # spawn ebuild.sh - mycommand = EBUILD_SH_BINARY + " " - if selinux_enabled and ("sesandbox" in features) and (mydo in ["unpack","compile","test","install"]): - con=selinux.getcontext() - con=string.replace(con,mysettings["PORTAGE_T"],mysettings["PORTAGE_SANDBOX_T"]) - selinux.setexec(con) - retval=spawn(mycommand + mydo,mysettings,debug=debug, - free=actionmap[mydo]["args"][0], - droppriv=actionmap[mydo]["args"][1],logfile=logfile) - selinux.setexec(None) + # spawn ebuild.sh or misc-functions.sh as appropriate + if mydo in ["package","rpm"]: + mycommand = MISC_SH_BINARY + " dyn_" + mydo else: - retval=spawn(mycommand + mydo,mysettings, debug=debug, - free=actionmap[mydo]["args"][0], - droppriv=actionmap[mydo]["args"][1],logfile=logfile) - return retval + mycommand = EBUILD_SH_BINARY + " " + mydo + phase_retval = spawn(mycommand, mysettings, debug=debug, + droppriv=actionmap[mydo]["args"][0], + free=actionmap[mydo]["args"][1], + sesandbox=actionmap[mydo]["args"][2], logfile=logfile) + if phase_retval == os.EX_OK: + if mydo == "install": + mycommand = " ".join([MISC_SH_BINARY, "install_qa_check"]) + return spawn(mycommand, mysettings, debug=debug, + droppriv=actionmap[mydo]["args"][0], + free=actionmap[mydo]["args"][1], + sesandbox=actionmap[mydo]["args"][2], logfile=logfile) + return phase_retval # chunked out deps for each phase, so that ebuild binary can use it # to collapse targets down. @@ -2513,7 +2516,7 @@ def doebuild(myebuild,mydo,myroot,mysettings,debug=0,listonly=0,fetchonly=0,clea mysettings["BUILD_PREFIX"] = mysettings["PORTAGE_TMPDIR"]+"/portage" mysettings["HOME"] = mysettings["BUILD_PREFIX"]+"/homedir" - mysettings["PKG_TMPDIR"] = mysettings["PORTAGE_TMPDIR"]+"/portage-pkg" + mysettings["PKG_TMPDIR"] = mysettings["PORTAGE_TMPDIR"]+"/binpkgs" mysettings["PORTAGE_BUILDDIR"] = mysettings["BUILD_PREFIX"]+"/"+mysettings["PF"] mysettings["PORTAGE_BASHRC"] = EBUILD_SH_ENV_FILE @@ -2754,7 +2757,21 @@ def doebuild(myebuild,mydo,myroot,mysettings,debug=0,listonly=0,fetchonly=0,clea 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": + mysettings.load_infodir(pkg_dir) + 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) @@ -2873,15 +2890,19 @@ def doebuild(myebuild,mydo,myroot,mysettings,debug=0,listonly=0,fetchonly=0,clea "nouserpriv" in mysettings["RESTRICT"]): nosandbox = ("sandbox" not in features and "usersandbox" not in features) + sesandbox = selinux_enabled and "sesandbox" in features + + # args are for the to spawn function + # (droppriv, free, sesandbox) actionmap = { - "depend": {"args":(0,1)}, # sandbox / portage - "setup": {"args":(1,0)}, # without / root - "unpack": {"args":(0,1)}, # sandbox / portage - "compile":{"args":(nosandbox,1)}, # optional / portage - "test": {"args":(nosandbox,1)}, # optional / portage - "install":{"args":(0,0)}, # sandbox / root - "rpm": {"args":(0,0)}, # sandbox / root - "package":{"args":(0,0)}, # sandbox / root + "depend": {"args":(1, 0, 0)}, + "setup": {"args":(0, 1, 0)}, + "unpack": {"args":(1, 0, sesandbox)}, + "compile":{"args":(1, nosandbox, sesandbox)}, + "test": {"args":(1, nosandbox, sesandbox)}, + "install":{"args":(0, 0, sesandbox)}, + "rpm": {"args":(0, 0, 0)}, + "package":{"args":(0, 0, 0)}, } # merge the deps in so we have again a 'full' actionmap @@ -5806,7 +5827,7 @@ class dblink: # New code to remove stuff from the world and virtuals files when unmerged. if trimworld: - worldlist=grabfile(self.myroot+WORLD_FILE) + worldlist = grabfile(os.path.join(self.myroot, WORLD_FILE)) mykey=cpv_getkey(self.mycpv) newworldlist=[] for x in worldlist: @@ -5829,13 +5850,14 @@ class dblink: # (spanky noticed bug) # XXX: dumb question, but abstracting the root uid might be wise/useful for # 2nd pkg manager installation setups. - if not os.path.exists(os.path.dirname(self.myroot+WORLD_FILE)): - pdir = os.path.dirname(self.myroot + WORLD_FILE) - os.makedirs(pdir, mode=0755) - os.chown(pdir, 0, portage_gid) - os.chmod(pdir, 02770) + my_private_path = os.path.join(self.myroot, PRIVATE_PATH) + if not os.path.exists(my_private_path): + os.makedirs(my_private_path, mode=0755) + os.chown(my_private_path, 0, portage_gid) + os.chmod(my_private_path, 02770) - write_atomic(os.path.join(self.myroot,WORLD_FILE),"\n".join(newworldlist)) + write_atomic(os.path.join(self.myroot, WORLD_FILE), + "\n".join(newworldlist)) #do original postrm if myebuildpath and os.path.exists(myebuildpath): @@ -5846,7 +5868,8 @@ class dblink: if a != 0: writemsg("!!! FAILED postrm: "+str(a)+"\n") sys.exit(123) - + if "noclean" not in features: + doebuild(myebuildpath, "clean", self.myroot, self.settings, cleanup=cleanup, tree=self.treetype) self.unlockdb() def isowner(self,filename,destroot): @@ -5961,12 +5984,9 @@ class dblink: writemsg_stdout(">>> Merging %s %s %s\n" % (self.mycpv,"to",destroot)) # run preinst script - if myebuild: - # if we are merging a new ebuild, use *its* pre/postinst rather than using the one in /var/db/pkg - # (if any). - a=doebuild(myebuild,"preinst",root,self.settings,cleanup=cleanup,use_cache=0,tree=self.treetype) - else: - a=doebuild(inforoot+"/"+self.pkg+".ebuild","preinst",root,self.settings,cleanup=cleanup,use_cache=0,tree=self.treetype) + if myebuild is None: + myebuild = os.path.join(inforoot, self.pkg + ".ebuild") + a = doebuild(myebuild, "preinst", root, self.settings, cleanup=cleanup, use_cache=0, tree=self.treetype) # XXX: Decide how to handle failures here. if a != 0: @@ -5992,10 +6012,7 @@ class dblink: self.updateprotect() #if we have a file containing previously-merged config file md5sums, grab it. - if os.path.exists(destroot+CONFIG_MEMORY_FILE): - cfgfiledict=grabdict(destroot+CONFIG_MEMORY_FILE) - else: - cfgfiledict={} + cfgfiledict = grabdict(os.path.join(destroot, CONFIG_MEMORY_FILE)) if self.settings.has_key("NOCONFMEM"): cfgfiledict["IGNORE"]=1 else: @@ -6057,32 +6074,18 @@ class dblink: if cfgfiledict.has_key("IGNORE"): del cfgfiledict["IGNORE"] - # XXXX: HACK! PathSpec is very necessary here. - if not os.path.exists(destroot+PRIVATE_PATH): - os.makedirs(destroot+PRIVATE_PATH) - os.chown(destroot+PRIVATE_PATH,os.getuid(),portage_gid) - os.chmod(destroot+PRIVATE_PATH,02770) - dirlist = prefix_array(listdir(destroot+PRIVATE_PATH),destroot+PRIVATE_PATH+"/") - while dirlist: - dirlist.sort() - dirlist.reverse() # Gets them in file-before basedir order - x = dirlist[0] - if os.path.isdir(x): - dirlist += prefix_array(listdir(x),x+"/") - continue - os.unlink(destroot+PRIVATE_PATH+"/"+x) + my_private_path = os.path.join(destroot, PRIVATE_PATH) + if not os.path.exists(my_private_path): + os.makedirs(my_private_path) + os.chown(my_private_path, os.getuid(), portage_gid) + os.chmod(my_private_path, 02770) - mylock = portage_locks.lockfile(destroot+CONFIG_MEMORY_FILE) - writedict(cfgfiledict,destroot+CONFIG_MEMORY_FILE) + mylock = portage_locks.lockfile(os.path.join(destroot, CONFIG_MEMORY_FILE)) + writedict(cfgfiledict, os.path.join(destroot, CONFIG_MEMORY_FILE)) portage_locks.unlockfile(mylock) #do postinst script - if myebuild: - # if we are merging a new ebuild, use *its* pre/postinst rather than using the one in /var/db/pkg - # (if any). - a=doebuild(myebuild,"postinst",root,self.settings,use_cache=0,tree=self.treetype) - else: - a=doebuild(inforoot+"/"+self.pkg+".ebuild","postinst",root,self.settings,use_cache=0,tree=self.treetype) + a = doebuild(myebuild, "postinst", root, self.settings, use_cache=0, tree=self.treetype) # XXX: Decide how to handle failures here. if a != 0: @@ -6104,7 +6107,8 @@ class dblink: # Process ebuild logfiles elog_process(self.mycpv, self.settings) - + if "noclean" not in features: + doebuild(myebuild, "clean", root, self.settings, cleanup=cleanup, tree=self.treetype) return 0 def mergeme(self,srcroot,destroot,outfile,secondhand,stufftomerge,cfgfiledict,thismtime): @@ -6457,7 +6461,7 @@ class dblink: return os.path.exists(self.dbdir+"/CATEGORY") def cleanup_pkgmerge(mypkg,origdir): - shutil.rmtree(settings["PORTAGE_TMPDIR"]+"/portage-pkg/"+mypkg) + shutil.rmtree(settings["PORTAGE_TMPDIR"]+"/binpkgs/"+mypkg) if os.path.exists(settings["PORTAGE_TMPDIR"]+"/portage/"+mypkg+"/temp/environment"): os.unlink(settings["PORTAGE_TMPDIR"]+"/portage/"+mypkg+"/temp/environment") os.chdir(origdir) @@ -6478,7 +6482,7 @@ def pkgmerge(mytbz2,myroot,mysettings): return None mycat=mycat.strip() mycatpkg=mycat+"/"+mypkg - tmploc=mysettings["PORTAGE_TMPDIR"]+"/portage-pkg/" + tmploc=mysettings["PORTAGE_TMPDIR"]+"/binpkgs/" pkgloc=tmploc+"/"+mypkg+"/bin/" infloc=tmploc+"/"+mypkg+"/inf/" myebuild=tmploc+"/"+mypkg+"/inf/"+os.path.basename(mytbz2)[:-4]+"ebuild" @@ -6494,7 +6498,9 @@ def pkgmerge(mytbz2,myroot,mysettings): os.chdir(pkgloc) mysettings.configdict["pkg"]["CATEGORY"] = mycat; - a=doebuild(myebuild,"setup",myroot,mysettings,tree="bintree") + # Eventually we'd like to pass in the saved ebuild env here. + # Do cleanup=1 to ensure that there is no cruft prior to the setup phase. + a = doebuild(myebuild, "setup", myroot, mysettings, tree="bintree", cleanup=1) writemsg_stdout(">>> Extracting %s\n" % mypkg) notok=spawn("bzip2 -dqc -- '"+mytbz2+"' | tar xpf -",mysettings,free=1) if notok: @@ -6739,7 +6745,8 @@ mtimedb={} mtimedbkeys=[ "updates", "info", "version", "starttime", -"resume", "ldpath" +"resume", "resume_backup", +"ldpath" ] mtimedbfile=root+portage_const.CACHE_PATH+"/mtimedb" try: @@ -6765,50 +6772,39 @@ for x in mtimedb.keys(): #,"porttree":portagetree(root,virts),"bintree":binarytree(root,virts)} features=settings["FEATURES"].split() -def do_upgrade(mykey): +def parse_updates(mycontent): """Valid updates are returned as a list of split update commands.""" - writemsg("\n\n") - writemsg(green("Performing Global Updates: ")+bold(mykey)+"\n") - writemsg("(Could take a couple of minutes if you have a lot of binary packages.)\n") - writemsg(" "+bold(".")+"='update pass' "+bold("*")+"='binary update' "+bold("@")+"='/var/db move'\n"+" "+bold("s")+"='/var/db SLOT move' "+bold("S")+"='binary SLOT move' "+bold("p")+"='update /etc/portage/package.*'\n") - processed=1 myupd = [] - mylines = grabfile(mykey) + errors = [] + mylines = mycontent.splitlines() for myline in mylines: mysplit = myline.split() if len(mysplit) == 0: continue if mysplit[0] not in ("move", "slotmove"): - writemsg("portage: Update type \""+mysplit[0]+"\" not recognized.\n") - processed=0 + errors.append("ERROR: Update type not recognized '%s'" % myline) continue if mysplit[0]=="move": if len(mysplit)!=3: - writemsg("portage: Update command \""+myline+"\" invalid; skipping.\n") - processed=0 + errors.append("ERROR: Update command invalid '%s'" % myline) continue orig_value, new_value = mysplit[1], mysplit[2] for cp in (orig_value, new_value): if not (isvalidatom(cp) and isjustname(cp)): - writemsg("\nERROR: Malformed update entry '%s'\n" % myline) - processed=0 + errors.append("ERROR: Malformed update entry '%s'" % myline) continue if mysplit[0]=="slotmove": if len(mysplit)!=4: - writemsg("portage: Update command \""+myline+"\" invalid; skipping.\n") - processed=0 + errors.append("ERROR: Update command invalid '%s'" % myline) continue pkg, origslot, newslot = mysplit[1], mysplit[2], mysplit[3] if not isvalidatom(pkg): - writemsg("\nERROR: Malformed update entry '%s'\n" % myline) - processed=0 + errors.append("ERROR: Malformed update entry '%s'" % myline) continue # The list of valid updates is filtered by continue statements above. myupd.append(mysplit) - sys.stdout.write(".") - sys.stdout.flush() - return myupd, processed == 1 + return myupd, errors def commit_mtimedb(): if mtimedb: @@ -6864,7 +6860,7 @@ def update_config_files(update_iter): if file_contents.has_key(x): del file_contents[x] continue - worldlist = grabfile(WORLD_FILE) + worldlist = grabfile(os.path.join("/", WORLD_FILE)) for update_cmd in update_iter: if update_cmd[0] == "move": @@ -6887,7 +6883,7 @@ def update_config_files(update_iter): sys.stdout.write("p") sys.stdout.flush() - write_atomic(WORLD_FILE,"\n".join(worldlist)) + write_atomic(os.path.join("/", WORLD_FILE), "\n".join(worldlist)) for x in update_files: mydblink = dblink('','','/',settings) @@ -6901,37 +6897,35 @@ def update_config_files(update_iter): def global_updates(): updpath = os.path.join(settings["PORTDIR"], "profiles", "updates") - mylist = listdir(updpath, EmptyOnError=1) - # validate the file name (filter out CVS directory, etc...) - mylist = [myfile for myfile in mylist if len(myfile) == 7 and myfile[1:3] == "Q-"] - if len(mylist) > 0: - # resort the list - mylist = [myfile[3:]+"-"+myfile[:2] for myfile in mylist] - mylist.sort() - mylist = [myfile[5:]+"-"+myfile[:4] for myfile in mylist] - - if not mtimedb.has_key("updates"): - mtimedb["updates"] = {} - - didupdate = 0 + if not mtimedb.has_key("updates"): + mtimedb["updates"] = {} + try: + if settings["PORTAGE_CALLER"] == "fixpackages": + update_data = grab_updates(updpath) + else: + update_data = grab_updates(updpath, mtimedb["updates"]) + except portage_exception.DirectoryNotFound: + writemsg("--- 'profiles/updates' is empty or not available. Empty portage tree?\n") + return + if len(update_data) > 0: do_upgrade_packagesmessage = 0 myupd = [] timestamps = {} - for myfile in mylist: - mykey = os.path.join(updpath, myfile) - mystat = os.stat(mykey) - if not stat.S_ISREG(mystat.st_mode): - continue - if mykey not in mtimedb["updates"] or \ - mtimedb["updates"][mykey] != mystat.st_mtime or \ - settings["PORTAGE_CALLER"] == "fixpackages": - didupdate = 1 - valid_updates, no_errors = do_upgrade(mykey) - myupd.extend(valid_updates) - if no_errors: - # Update our internal mtime since we - # processed all of our directives. - timestamps[mykey] = mystat.st_mtime + for mykey, mystat, mycontent in update_data: + writemsg("\n\n") + writemsg(green("Performing Global Updates: ")+bold(mykey)+"\n") + writemsg("(Could take a couple of minutes if you have a lot of binary packages.)\n") + writemsg(" "+bold(".")+"='update pass' "+bold("*")+"='binary update' "+bold("@")+"='/var/db move'\n"+" "+bold("s")+"='/var/db SLOT move' "+bold("S")+"='binary SLOT move' "+bold("p")+"='update /etc/portage/package.*'\n") + valid_updates, errors = parse_updates(mycontent) + myupd.extend(valid_updates) + print len(valid_updates) * "." + if len(errors) == 0: + # Update our internal mtime since we + # processed all of our directives. + timestamps[mykey] = mystat.st_mtime + else: + for msg in errors: + writemsg("%s\n" % msg) update_config_files(myupd) db["/"]["bintree"] = binarytree("/", settings["PKGDIR"], virts) @@ -6943,8 +6937,6 @@ def global_updates(): db["/"]["vartree"].dbapi.move_slot_ent(update_cmd) db["/"]["bintree"].move_slot_ent(update_cmd) - print - # The above global updates proceed quickly, so they # are considered a single mtimedb transaction. if len(timestamps) > 0: @@ -6963,14 +6955,19 @@ def global_updates(): else: do_upgrade_packagesmessage = 1 - if didupdate: - #make sure our internal databases are consistent; recreate our virts and vartree - do_vartree(settings) - if do_upgrade_packagesmessage and \ - listdir(os.path.join(settings["PKGDIR"], "All"), EmptyOnError=1): - writemsg("\n\n\n ** Skipping packages. Run 'fixpackages' or set it in FEATURES to fix the") - writemsg("\n tbz2's in the packages directory. "+bold("Note: This can take a very long time.")) - writemsg("\n") + # Update progress above is indicated by characters written to stdout so + # we print a couple new lines here to separate the progress output from + # what follows. + print + print + + #make sure our internal databases are consistent; recreate our virts and vartree + do_vartree(settings) + if do_upgrade_packagesmessage and \ + listdir(os.path.join(settings["PKGDIR"], "All"), EmptyOnError=1): + writemsg(" ** Skipping packages. Run 'fixpackages' or set it in FEATURES to fix the") + writemsg("\n tbz2's in the packages directory. "+bold("Note: This can take a very long time.")) + writemsg("\n") if (secpass==2) and (not os.environ.has_key("SANDBOX_ACTIVE")): if settings["PORTAGE_CALLER"] in ["emerge","fixpackages"]: diff --git a/pym/portage_checksum.py b/pym/portage_checksum.py index 2dd447df2..8196628ca 100644 --- a/pym/portage_checksum.py +++ b/pym/portage_checksum.py @@ -120,7 +120,7 @@ def pyhash(filename, hashobject): def perform_checksum(filename, hash_function=md5hash, calc_prelink=0): myfilename = filename[:] - prelink_tmpfile = PRIVATE_PATH+"/prelink-checksum.tmp."+str(os.getpid()) + prelink_tmpfile = os.path.join("/", PRIVATE_PATH, "prelink-checksum.tmp." + str(os.getpid())) mylock = None if calc_prelink and prelink_capable: diff --git a/pym/portage_const.py b/pym/portage_const.py index 0af2d2d9b..b89d6cffc 100644 --- a/pym/portage_const.py +++ b/pym/portage_const.py @@ -30,12 +30,13 @@ PROFILE_PATH = PREFIX+"/etc/make.profile" 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 = "sandbox" BASH_BINARY = "bash" MOVE_BINARY = "mv" PRELINK_BINARY = "prelink" -WORLD_FILE = PRIVATE_PATH+"/world" +WORLD_FILE = PRIVATE_PATH + "/world" MAKE_CONF_FILE = PREFIX+"/etc/make.conf" MAKE_DEFAULTS_FILE = PROFILE_PATH + "/make.defaults" DEPRECATED_PROFILE_FILE = PROFILE_PATH+"/deprecated" diff --git a/pym/portage_update.py b/pym/portage_update.py index 0aadae1b3..f2d0675d1 100644 --- a/pym/portage_update.py +++ b/pym/portage_update.py @@ -1,7 +1,8 @@ -import os, re +import errno, os, re from portage_util import write_atomic +from portage_exception import DirectoryNotFound ignored_dbentries = ("CONTENTS", "environment.bz2") @@ -44,3 +45,38 @@ def fixdbentries(update_iter, dbdir): file_path = os.path.join(dbdir, myfile) write_atomic(file_path, mycontent) return len(updated_items) > 0 + +def grab_updates(updpath, prev_mtimes=None): + """Returns all the updates from the given directory as a sorted list of + tuples, each containing (file_path, statobj, content). If prev_mtimes is + given then only updates with differing mtimes are considered.""" + try: + mylist = os.listdir(updpath) + except OSError, oe: + if oe.errno == errno.ENOENT: + raise DirectoryNotFound(oe) + else: + raise oe + if prev_mtimes is None: + prev_mtimes = {} + # validate the file name (filter out CVS directory, etc...) + mylist = [myfile for myfile in mylist if len(myfile) == 7 and myfile[1:3] == "Q-"] + if len(mylist) == 0: + return [] + + # update names are mangled to make them sort properly + mylist = [myfile[3:]+"-"+myfile[:2] for myfile in mylist] + mylist.sort() + mylist = [myfile[5:]+"-"+myfile[:4] for myfile in mylist] + + update_data = [] + for myfile in mylist: + file_path = os.path.join(updpath, myfile) + mystat = os.stat(file_path) + if file_path not in prev_mtimes or \ + prev_mtimes[file_path] != mystat.st_mtime: + f = open(file_path) + content = f.read() + f.close() + update_data.append((file_path, mystat, content)) + return update_data