merge with trunk rev 2896:2915
authorKito <kito@gentoo.org>
Fri, 17 Mar 2006 17:28:10 +0000 (17:28 -0000)
committerKito <kito@gentoo.org>
Fri, 17 Mar 2006 17:28:10 +0000 (17:28 -0000)
svn path=/main/branches/prefix/; revision=2916

bin/ebuild.sh
bin/emerge
bin/misc-functions.sh
cnf/make.globals
pym/portage.py
pym/portage_util.py

index c1bb3d64e2579c3e8ba2e2cd9f3036c35a18e687..d0a6f75b40e766179d9dea5bcc4888fa8f185bb2 100755 (executable)
@@ -104,10 +104,7 @@ esyslog() {
 
 
 use() {
-       if useq ${1}; then
-               return 0
-       fi
-       return 1
+       useq ${1}
 }
 
 usev() {
@@ -119,64 +116,41 @@ usev() {
 }
 
 useq() {
-       local u="${1}"
-       local neg=0
-       if [ "${u:0:1}" == "!" ]; then
-               u="${u:1}"
-               neg=1
+       local u=$1
+       local found=0
+
+       # if we got something like '!flag', then invert the return value
+       if [[ ${u:0:1} == "!" ]] ; then
+               u=${u:1}
+               found=1
        fi
-       local x
 
        # Make sure we have this USE flag in IUSE
        if ! hasq "${u}" ${IUSE} ${E_IUSE} && ! hasq "${u}" ${PORTAGE_ARCHLIST} selinux; then
                echo "QA Notice: USE Flag '${u}' not in IUSE for ${CATEGORY}/${PF}" >&2
        fi
 
-       for x in ${USE}; do
-               if [ "${x}" == "${u}" ]; then
-                       if [ ${neg} -eq 1 ]; then
-                               return 1
-                       else
-                               return 0
-                       fi
-               fi
-       done
-       if [ ${neg} -eq 1 ]; then
-               return 0
+       if [[ " ${USE} " == *" ${u} "* ]] ; then
+               return ${found}
        else
-               return 1
+               return $((!found))
        fi
 }
 
 has() {
-       if hasq "$@"; then
-               return 0
-       fi
-       return 1
+       hasq "$@"
 }
 
 hasv() {
-       if hasq "$@"; then
-               echo "${1}"
+       if hasq "$@" ; then
+               echo "$1"
                return 0
        fi
        return 1
 }
 
 hasq() {
-       local x
-
-       local me=$1
-       shift
-
-       # All the TTY checks really only help out depend. Which is nice.
-       # Logging kills all this anyway. Everything becomes a pipe. --NJ
-       for x in "$@"; do
-               if [ "${x}" == "${me}" ]; then
-                       return 0
-               fi
-       done
-       return 1
+       [[ " ${*:2} " == *" $1 "* ]]
 }
 
 has_version() {
@@ -412,6 +386,7 @@ diefunc() {
        echo "!!! If you need support, post the topmost build error, and the call stack if relevant." >&2
        echo >&2
        if [ "${EBUILD_PHASE/depend}" == "${EBUILD_PHASE}" ]; then
+               local x
                for x in $EBUILD_DEATH_HOOKS; do
                        ${x} "$@" >&2 1>&2
                done
@@ -528,7 +503,7 @@ unpack() {
                        tgz)
                                tar xzf "${srcdir}${x}" ${tarvars} || die "$myfail"
                                ;;
-                       tbz2)
+                       tbz|tbz2)
                                bzip2 -dc "${srcdir}${x}" | tar xf - ${tarvars}
                                assert "$myfail"
                                ;;
@@ -556,6 +531,9 @@ unpack() {
                        LHa|LHA|lha|lzh)
                                lha xqf "${srcdir}/${x}" || die "$myfail"
                                ;;
+                       a|deb)
+                               ar x "${srcdir}/${x}" || die "$myfail"
+                               ;;
                        *)
                                echo "unpack ${x}: file format not recognized. Ignoring."
                                ;;
@@ -572,6 +550,7 @@ strip_duplicate_slashes () {
 }
 
 econf() {
+       local x
        local LOCAL_EXTRA_ECONF="${EXTRA_ECONF}"
 
        if [ -z "${ECONF_SOURCE}" ]; then
@@ -579,7 +558,6 @@ econf() {
        fi
        if [ -x "${ECONF_SOURCE}/configure" ]; then
                if [ -e ${PREFIX}/usr/share/gnuconfig/ ]; then
-                       local x
                        for x in $(find "${WORKDIR}" -type f '(' -name config.guess -o -name config.sub ')') ; do
                                echo " * econf: updating ${x/${WORKDIR}\/} with ${PREFIX}/usr/share/gnuconfig/${x##*/}"
                                cp -f ${PREFIX}/usr/share/gnuconfig/${x##*/} ${x}
@@ -619,7 +597,7 @@ econf() {
                        [ "${CONF_LIBDIR:0:1}" != "/" ] && CONF_LIBDIR="/${CONF_LIBDIR}"
 
                        CONF_LIBDIR_RESULT="${CONF_PREFIX}${CONF_LIBDIR}"
-                       for X in 1 2 3; do
+                       for x in 1 2 3; do
                                # The escaping is weird. It will break if you escape the last one.
                                CONF_LIBDIR_RESULT="${CONF_LIBDIR_RESULT//\/\///}"
                        done
@@ -732,15 +710,14 @@ pkg_nofetch() {
        [ -z "${SRC_URI}" ] && return
 
        echo "!!! The following are listed in SRC_URI for ${PN}:"
-       for MYFILE in `echo ${SRC_URI}`; do
-               echo "!!!   $MYFILE"
+       local x
+       for x in `echo ${SRC_URI}`; do
+               echo "!!!   ${x}"
        done
 }
 
 src_unpack() {
-       if [ "${A}" != "" ]; then
-               unpack ${A}
-       fi
+       [[ -n ${A} ]] && unpack ${A}
 }
 
 src_compile() {
@@ -798,13 +775,11 @@ pkg_config() {
 
 # Used to generate the /lib/cpp and /usr/bin/cc wrappers
 gen_wrapper() {
-       cat > $1 << END
-#!/bin/sh
-
-$2 "\$@"
-END
-
-       chmod 0755 $1
+       cat > "$1" <<-EOF
+       #!/bin/sh
+       exec $2 "\$@"
+       EOF
+       chmod 0755 "$1"
 }
 
 dyn_setup() {
@@ -847,8 +822,10 @@ dyn_unpack() {
                fi
        fi
 
-       install -m 0700 -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'"
-       [ -d "$WORKDIR" ] && cd "${WORKDIR}"
+       if [ ! -d "${WORKDIR}" ]; then
+               install -m ${PORTAGE_WORKDIR_MODE-0700} -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'"
+       fi
+       cd "${WORKDIR}" || die "Directory change failed: \`cd '${WORKDIR}'\`"
        echo ">>> Unpacking source..."
        src_unpack
        touch "${PORTAGE_BUILDDIR}/.unpacked" || die "IO Failure -- Failed 'touch .unpacked' in ${PORTAGE_BUILDDIR}"
@@ -953,50 +930,28 @@ docinto() {
 }
 
 insopts() {
-       INSOPTIONS=""
-       for x in $*; do
-               #if we have a debug build, let's not strip anything
-               if hasq nostrip $FEATURES $RESTRICT && [ "$x" == "-s" ]; then
-                       continue
-               else
-                       INSOPTIONS="$INSOPTIONS $x"
-               fi
-       done
-       export INSOPTIONS
+       export INSOPTIONS="$@"
+
+       # `install` should never be called with '-s' ...
+       [[ " ${INSOPTIONS} " == *" -s "* ]] && die "Never call insopts() with -s"
 }
 
 diropts() {
-       DIROPTIONS=""
-       for x in $*; do
-               DIROPTIONS="${DIROPTIONS} $x"
-       done
-       export DIROPTIONS
+       export DIROPTIONS="$@"
 }
 
 exeopts() {
-       EXEOPTIONS=""
-       for x in $*; do
-               #if we have a debug build, let's not strip anything
-               if hasq nostrip $FEATURES $RESTRICT && [ "$x" == "-s" ]; then
-                       continue
-               else
-                       EXEOPTIONS="$EXEOPTIONS $x"
-               fi
-       done
-       export EXEOPTIONS
+       export EXEOPTIONS="$@"
+
+       # `install` should never be called with '-s' ...
+       [[ " ${EXEOPTIONS} " == *" -s "* ]] && die "Never call exeopts() with -s"
 }
 
 libopts() {
-       LIBOPTIONS=""
-       for x in $*; do
-               #if we have a debug build, let's not strip anything
-               if hasq nostrip $FEATURES $RESTRICT && [ "$x" == "-s" ]; then
-                       continue
-               else
-                       LIBOPTIONS="$LIBOPTIONS $x"
-               fi
-       done
-       export LIBOPTIONS
+       export LIBOPTIONS="$@"
+
+       # `install` should never be called with '-s' ...
+       [[ " ${LIBOPTIONS} " == *" -s "* ]] && die "Never call libopts() with -s"
 }
 
 abort_handler() {
@@ -1064,6 +1019,7 @@ dyn_compile() {
                echo "!!! that you know what you are doing... You have 5 seconds to abort..."
                echo
 
+               local x
                for x in 1 2 3 4 5 6 7 8; do
                        echo -ne "\a"
                        LC_ALL=C sleep 0.25
@@ -1118,7 +1074,10 @@ dyn_compile() {
        bzip2 -9 environment
 
        cp "${EBUILD}" "${PF}.ebuild"
-       if hasq nostrip $FEATURES $RESTRICT; then
+       if [[ " ${FEATURES} " == *" nostrip "* ]] || \
+          [[ " ${RESTRICT} " == *" nostrip "* ]] || \
+          [[ " ${RESTRICT} " == *" strip "* ]]
+       then
                touch DEBUGBUILD
        fi
 
@@ -1181,8 +1140,8 @@ dyn_install() {
 
 dyn_preinst() {
        if [ -z "$IMAGE" ]; then
-                       eerror "${FUNCNAME}: IMAGE is unset"
-                       return 1
+               eerror "${FUNCNAME}: IMAGE is unset"
+               return 1
        fi
 
        [ "$(type -t pre_pkg_preinst)" == "function" ] && pre_pkg_preinst
@@ -1237,7 +1196,10 @@ dyn_help() {
        echo "  c++ flags   : ${CXXFLAGS}"
        echo "  make flags  : ${MAKEOPTS}"
        echo -n "  build mode  : "
-       if hasq nostrip $FEATURES $RESTRICT; then
+       if [[ " ${FEATURES} " == *" nostrip "* ]] || \
+          [[ " ${RESTRICT} " == *" nostrip "* ]] || \
+          [[ " ${RESTRICT} " == *" strip "* ]]
+       then
                echo "debug (large)"
        else
                echo "production (stripped)"
@@ -1389,7 +1351,7 @@ inherit() {
 
                shift
        done
-       ECLASS_DEPTH=$(($ECLASS_DEPTH - 1))
+       ((--ECLASS_DEPTH))
 }
 
 # Exports stub functions that call the eclass's functions, thereby making them default.
@@ -1609,10 +1571,15 @@ fi
 # We need to turn off pathname expansion for -* in KEYWORDS and
 # we need to escape ~ to avoid tilde expansion
 set -f
-KEYWORDS="`eval echo ${KEYWORDS//~/\\~}`"
+KEYWORDS=$(eval echo ${KEYWORDS//~/\\~})
 set +f
 
-hasq nostrip ${RESTRICT} && export DEBUGBUILD=1
+if [[ " ${FEATURES} " == *" nostrip "* ]] || \
+   [[ " ${RESTRICT} " == *" nostrip "* ]] || \
+   [[ " ${RESTRICT} " == *" strip "* ]]
+then
+       export DEBUGBUILD=1
+fi
 
 #a reasonable default for $S
 if [ "$S" = "" ]; then
index 736b3ab964b3dfcf882ecdeb53394081af26a257..7604dc93dbf76ada3228b10121848e2e180f53a4 100755 (executable)
@@ -1072,17 +1072,10 @@ class depgraph:
                                elif not "--oneshot" in myopts:
                                        myfavorites.append(mykey)
                        else:
-                               testkey = portage.dep_getkey(x)
-                               if testkey.startswith("null/"):
-                                       testatom = x.replace(testkey[5:], "cat/"+testkey[5:])
-                               elif "/" not in x:
-                                       testatom = "cat/"+x
-                               else:
-                                       testatom = x
-                               if not portage.isvalidatom(testatom):
-                                       print ("\n\n!!! '%s' is not a valid package atom." % x)
-                                       print "!!! Please check ebuild(5) for full details."
-                                       print "!!! (Did you specify a version but forget to prefix with '='?)"
+                               if not is_valid_package_atom(x):
+                                       portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x)
+                                       portage.writemsg("!!! Please check ebuild(5) for full details.\n")
+                                       portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
                                        return (0,[])
                                try:
                                        mykey=portage.dep_expand(x,mydb=portage.portdb)
@@ -2470,6 +2463,16 @@ def chk_updated_cfg_files():
                        print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
                print
 
+def is_valid_package_atom(x):
+       testkey = portage.dep_getkey(x)
+       if testkey.startswith("null/"):
+               testatom = x.replace(testkey[5:], "cat/"+testkey[5:])
+       elif "/" not in x:
+               testatom = "cat/"+x
+       else:
+               testatom = x
+       return portage.isvalidatom(testatom)
+
 # general options that should be taken into account before any action
 if "--debug" in myopts:
        edebug=1
@@ -2889,7 +2892,11 @@ elif "config"==myaction:
        if len(myfiles) != 1 or "system" in myfiles or "world" in myfiles:
                print red("!!! config can only take a single package atom at this time\n")
                sys.exit(1)
-
+       if not is_valid_package_atom(myfiles[0]):
+               portage.writemsg("!!! '%s' is not a valid package atom.\n" % myfiles[0])
+               portage.writemsg("!!! Please check ebuild(5) for full details.\n")
+               portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
+               sys.exit(1)
        print
        pkgs = portage.db[portage.root]["vartree"].dbapi.match(myfiles[0])
        if len(pkgs) == 0:
index d3a6e048b0612c7f912f3487008922748716b8ad..88d81dbc5599650873f30ee4a0eb5b5d8b7eaa45 100644 (file)
@@ -413,7 +413,7 @@ dyn_package() {
        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"
+       mv -f "${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}"
index c8c49eb82618c974810a453c09aa56eeedec103f..f5deb0dd5c0e03c44f5014bc6540fcbceeac8c0d 100644 (file)
@@ -66,6 +66,11 @@ PORTAGE_INST_GID="@wheelgid@"
 
 # Default PATH for ebuild env
 DEFAULT_PATH="@DOMAIN_PREFIX@/sbin:@DOMAIN_PREFIX@/usr/sbin:@DOMAIN_PREFIX@/bin:@DOMAIN_PREFIX@/usr/bin:@PORTAGE_BASE@/bin"
+
+# Mode bits for ${WORKDIR} (see ebuild.5).
+PORTAGE_WORKDIR_MODE="0700"
+
+
 #            *****************************
 #            **  DO NOT EDIT THIS FILE  **
 # ***************************************************
index cc9ddf248f7a8f7311fa9aa57b0c262f61db8610..a8e9f40f584192d426b12ac836bcd0d01e4883d9 100644 (file)
@@ -1579,6 +1579,10 @@ class config:
                                return 1
                return 0
 
+       def __contains__(self, mykey):
+               """Called to implement membership test operators (in and not in)."""
+               return bool(self.has_key(mykey))
+
        def keys(self):
                mykeys=[]
                for x in self.lookuplist:
@@ -1931,9 +1935,14 @@ 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:
-                                               myret = spawn(myfetch, mysettings, free=1,
-                                                       droppriv=("userfetch" in mysettings.features),
-                                                       sesandbox=selinux_enabled)
+                                               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))
                                        finally:
                                                #if root, -always- set the perms.
                                                if os.path.exists(mysettings["DISTDIR"]+"/"+myfile) and (fetched != 1 or os.getuid() == 0) \
@@ -2457,6 +2466,11 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, t
        else:
                mysettings["PORTAGE_BUILDDIR"] = os.path.join(mysettings["BUILD_PREFIX"], mysettings["PF"])
 
+       mysettings["WORKDIR"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "work")
+       mysettings["DEST"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "image") + os.sep
+       mysettings["D"] = os.path.normpath(mysettings["DEST"]+portage_const.PREFIX)
+       mysettings["T"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "temp")
+
        mysettings["PORTAGE_BASHRC"] = EBUILD_SH_ENV_FILE
 
        #set up KV variable -- DEP SPEEDUP :: Don't waste time. Keep var persistent.
@@ -2479,9 +2493,8 @@ def prepare_build_dirs(myroot, mysettings, cleanup):
        apply_secpass_permissions(mysettings["BUILD_PREFIX"],
        uid=portage_uid, gid=portage_gid, mode=00775)
 
-       # Should be ok again to set $T, as sandbox does not depend on it
-       # XXX Bug.  no way in hell this is valid for clean handling.
-       mysettings["T"]=mysettings["PORTAGE_BUILDDIR"]+"/temp"
+       # We enable cleanup when we want to make sure old cruft (such as the old
+       # environment) doesn't interfere with the current phase.
        if cleanup:
                if os.path.exists(mysettings["T"]):
                        shutil.rmtree(mysettings["T"])
@@ -2565,94 +2578,136 @@ def prepare_build_dirs(myroot, mysettings, cleanup):
                print "!!! Perhaps: rm -Rf",mysettings["BUILD_PREFIX"]
                print "!!!",str(e)
                return 1
-       try:
-               if "confcache" in features:
-                       if not mysettings.has_key("CONFCACHE_DIR"):
-                               mysettings["CONFCACHE_DIR"] = os.path.join(mysettings["PORTAGE_TMPDIR"], "confcache")
-                       if not os.path.exists(mysettings["CONFCACHE_DIR"]):
-                               if not os.getuid() == 0:
-                                       # we're boned.
-                                       features.remove("confcache")
-                                       mysettings["FEATURES"] = " ".join(features)
-                               else:
-                                       os.makedirs(mysettings["CONFCACHE_DIR"], mode=0775)
-                                       apply_secpass_permissions(mysettings["CONFCACHE_DIR"],
-                                       gid=portage_gid, mode=0775)
-                       else:
-                               apply_secpass_permissions(mysettings["CONFCACHE_DIR"],
-                               gid=portage_gid, mode=0775)
 
-               # check again, since it may have been disabled.
-               if "confcache" in features:
+       if "confcache" in features:
+               confcache_enabled = True
+               if "CONFCACHE_DIR" not in mysettings:
+                       mysettings["CONFCACHE_DIR"] = os.path.join(mysettings["PORTAGE_TMPDIR"], "confcache")
+               confcache_dir_mode = 0775
+
+               try:
+                       os.makedirs(mysettings["CONFCACHE_DIR"], mode=confcache_dir_mode)
+               except OSError, oe:
+                       if oe.errno == errno.EEXIST:
+                               pass
+                       elif errno == errno.EPERM:
+                               writemsg("Operation Not Permitted: makedirs(%s, mode=%s)\n" % (mysettings["CONFCACHE_DIR"], oct(confcache_dir_mode)))
+                               confcache_enabled = False
+
+               if confcache_enabled:
+                       try:
+                               confcache_enabled = apply_secpass_permissions(
+                                       mysettings["CONFCACHE_DIR"],
+                                       gid=portage_gid, mode=confcache_dir_mode)
+                       except portage_exception.OperationNotPermitted, e:
+                               writemsg("Operation Not Permitted: %s\n" % str(e))
+                               confcache_enabled = False
+
+               del confcache_dir_mode
+
+               if confcache_enabled:
                        for x in listdir(mysettings["CONFCACHE_DIR"]):
-                               p = os.path.join(mysettings["CONFCACHE_DIR"], x)
-                               apply_secpass_permissions(p, gid=portage_gid, mode=0660, mask=07000)
-       except OSError, e:
-               print "!!! Failed resetting perms on confcachedir %s" % mysettings["CONFCACHE_DIR"]
-               return 1                                                
-       #try:
-       #       mystat=os.stat(mysettings["CCACHE_DIR"])
-       #       if (mystat[stat.ST_GID]!=portage_gid) or ((mystat[stat.ST_MODE]&02070)!=02070):
-       #               print "*** Adjusting ccache permissions for portage user..."
-       #               os.chown(mysettings["CCACHE_DIR"],portage_uid,portage_gid)
-       #               os.chmod(mysettings["CCACHE_DIR"],02770)
-       #               spawn("chown -R "+str(portage_uid)+":"+str(portage_gid)+" "+mysettings["CCACHE_DIR"],mysettings, free=1)
-       #               spawn("chmod -R g+rw "+mysettings["CCACHE_DIR"],mysettings, free=1)
-       #except SystemExit, e:
-       #       raise
-       #except:
-       #       pass
+                               cache_file = os.path.join(mysettings["CONFCACHE_DIR"], x)
+                               try:
+                                       confcache_enabled = apply_secpass_permissions(cache_file, gid=portage_gid, mode=0660, mask=07000)
+                               except portage_exception.OperationNotPermitted, e:
+                                       writemsg("Operation Not Permitted: %s\n" % str(e))
+                                       confcache_enabled = False
+                               except portage_exception.FileNotFound, e:
+                                       writemsg("File Not Found: %s\n" % str(e))
+
+               if not confcache_enabled:
+                       writemsg("!!! Failed resetting perms on confcachedir %s\n" % mysettings["CONFCACHE_DIR"])
+                       features.remove("confcache")
+                       mysettings["FEATURES"] = " ".join(features)
 
        if "distcc" in features:
-               try:
-                       if (not mysettings.has_key("DISTCC_DIR")) or (mysettings["DISTCC_DIR"]==""):
-                               mysettings["DISTCC_DIR"]=mysettings["PORTAGE_TMPDIR"]+"/portage/.distcc"
-                       if not os.path.exists(mysettings["DISTCC_DIR"]):
-                               os.makedirs(mysettings["DISTCC_DIR"])
-                               apply_secpass_permissions(mysettings["DISTCC_DIR"],
+               
+               distcc_enabled = True
+
+               if "DISTCC_DIR" not in mysettings or "" == mysettings["DISTCC_DIR"]:
+                       mysettings["DISTCC_DIR"] = os.path.join(mysettings["BUILD_PREFIX"], ".distcc")
+               for x in ("", "lock", "state"):
+                       mydir = os.path.join(mysettings["DISTCC_DIR"], x)
+                       try:
+                               os.makedirs(mydir)
+                       except OSError, oe:
+                               if errno.EEXIST == oe.errno:
+                                       pass
+                               elif errno.EPERM == oe.errno:
+                                       distcc_enabled = False
+                                       break
+                               else:
+                                       raise
+                       try:
+                               distcc_enabled = apply_secpass_permissions(mydir,
                                uid=portage_uid, gid=portage_gid, mode=02775)
-                       for x in ("/lock", "/state"):
-                               if not os.path.exists(mysettings["DISTCC_DIR"]+x):
-                                       os.mkdir(mysettings["DISTCC_DIR"]+x)
-                                       apply_secpass_permissions(mysettings["DISTCC_DIR"]+x,
-                                       uid=portage_uid, gid=portage_gid, mode=02775)
-               except OSError, e:
+                       except portage_exception.OperationNotPermitted, e:
+                               writemsg("Operation Not Permitted: %s\n" % str(e))
+                               distcc_enabled = False
+                               break
+
+               if not distcc_enabled:
                        writemsg("\n!!! File system problem when setting DISTCC_DIR directory permissions.\n")
                        writemsg(  "!!! DISTCC_DIR="+str(mysettings["DISTCC_DIR"]+"\n"))
-                       writemsg(  "!!! "+str(e)+"\n\n")
                        time.sleep(5)
                        features.remove("distcc")
+                       mysettings["FEATURES"] = " ".join(features)
                        mysettings["DISTCC_DIR"]=""
 
-       mysettings["WORKDIR"]=mysettings["PORTAGE_BUILDDIR"]+"/work"
-       mysettings["DEST"]=mysettings["PORTAGE_BUILDDIR"]+"/image/"
-       mysettings["D"]=os.path.join(mysettings["DEST"],portage_const.PREFIX)
+       workdir_mode = 0700
+       try:
+               workdir_mode = int(eval(mysettings["PORTAGE_WORKDIR_MODE"]))
+               if workdir_mode & 07777 != workdir_mode:
+                       raise ValueError("Invalid file mode: %s" % mysettings["PORTAGE_WORKDIR_MODE"])
+       except KeyError, e:
+               writemsg("!!! PORTAGE_WORKDIR_MODE is unset, using %s." % oct(workdir_mode))
+       except ValueError, e:
+               writemsg("%s\n" % e)
+               writemsg("!!! Unable to parse PORTAGE_WORKDIR_MODE='%s', using %s.\n" % \
+               (mysettings["PORTAGE_WORKDIR_MODE"], oct(workdir_mode)))
+       try:
+               apply_secpass_permissions(mysettings["WORKDIR"],
+               uid=portage_uid, gid=portage_gid, mode=workdir_mode)
+       except portage_exception.FileNotFound:
+               pass # ebuild.sh will create it
+
+       if "PORT_LOGDIR" in mysettings:
+               logging_enabled = True
 
-       if mysettings.has_key("PORT_LOGDIR"):
-               if not os.access(mysettings["PORT_LOGDIR"],os.F_OK):
-                       try:
-                               os.mkdir(mysettings["PORT_LOGDIR"])
-                       except OSError, e:
-                               print "!!! Unable to create PORT_LOGDIR"
-                               print "!!!",e
-               if os.access(mysettings["PORT_LOGDIR"]+"/",os.W_OK):
+               try:
+                       os.makedirs(mysettings["PORT_LOGDIR"])
+               except OSError, oe:
+                       if errno.EEXIST == oe.errno:
+                               pass
+                       elif errno.EPERM == oe.errno:
+                               writemsg("!!! Unable to create PORT_LOGDIR\n")
+                               writemsg("!!! %s\n" % str(oe))
+                               logging_enabled = False
+                       else:
+                               raise
+
+               if logging_enabled:
                        try:
-                               apply_secpass_permissions(mysettings["PORT_LOGDIR"],
-                               uid=portage_uid, gid=portage_gid, mode=02770)
-                               if not mysettings.has_key("LOG_PF") or (mysettings["LOG_PF"] != mysettings["PF"]):
-                                       mysettings["LOG_PF"]=mysettings["PF"]
-                                       mysettings["LOG_COUNTER"]=str(db[myroot]["vartree"].dbapi.get_counter_tick_core("/"))
-                               logfile="%s/%s-%s.log" % (mysettings["PORT_LOGDIR"],mysettings["LOG_COUNTER"],mysettings["LOG_PF"])
-                       except OSError, e:
-                               mysettings["PORT_LOGDIR"]=""
-                               print "!!! Unable to chown/chmod PORT_LOGDIR. Disabling logging."
-                               print "!!!",e
-               else:
-                       print "!!! Cannot create log... No write access / Does not exist"
-                       print "!!! PORT_LOGDIR:",mysettings["PORT_LOGDIR"]
+                               logging_enabled = \
+                                       apply_secpass_permissions(mysettings["PORT_LOGDIR"],
+                                       uid=portage_uid, gid=portage_gid, mode=02770)
+                       except portage_exception.OperationNotPermitted, e:
+                               writemsg("!!! Operation Not Permitted: %s\n" % str(e))
+                               logging_enabled = False
+
+               if logging_enabled:
+                       if "LOG_PF" not in mysettings or \
+                       mysettings["LOG_PF"] != mysettings["PF"]:
+                               mysettings["LOG_PF"] = mysettings["PF"]
+                               mysettings["LOG_COUNTER"] = \
+                                       str(db[myroot]["vartree"].dbapi.get_counter_tick_core("/"))
+
+               if not logging_enabled:
+                       writemsg("!!! Permission issues with PORT_LOGDIR='%s'\n" % mysettings["PORT_LOGDIR"])
+                       writemsg("!!! Disabling logging.\n")
                        mysettings["PORT_LOGDIR"]=""
 
-
 def doebuild(myebuild,mydo,myroot,mysettings,debug=0,listonly=0,fetchonly=0,cleanup=0,dbkey=None,use_cache=1,fetchall=0,tree=None):
        global db, actionmap_deps
 
@@ -2705,8 +2760,14 @@ def doebuild(myebuild,mydo,myroot,mysettings,debug=0,listonly=0,fetchonly=0,clea
                mystatus = prepare_build_dirs(myroot, mysettings, cleanup)
                if mystatus:
                        return mystatus
+
+               if "PORT_LOGDIR" in mysettings:
+                       logfile = os.path.join(mysettings["PORT_LOGDIR"], "%s-%s.log" % \
+                               (mysettings["LOG_COUNTER"], mysettings["LOG_PF"]))
+
                if mydo=="unmerge":
-                       return unmerge(mysettings["CATEGORY"],mysettings["PF"],myroot,mysettings)
+                       return unmerge(mysettings["CATEGORY"],
+                               mysettings["PF"], myroot, mysettings)
 
        # if any of these are being called, handle them -- running them out of the sandbox -- and stop now.
        if mydo in ["clean","cleanrm"]:
@@ -6482,7 +6543,7 @@ def pkgmerge(mytbz2,myroot,mysettings):
        cleanup_pkgmerge(mypkg,origdir)
        return returnme
 
-
+# XXX Fix this
 if os.environ.has_key("ROOT"):
        root=os.environ["ROOT"]
        if not len(root):
index 69748869789d58a368700dcf171373db3e2a9d1a..61730c5fefa1141cb81762e8e77a498445f73311 100644 (file)
@@ -463,36 +463,56 @@ def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1,
        to be a superset of the mode argument (via logical OR).  When mask>0, the
        mode bits that the target file is allowed to have are restricted via
        logical XOR."""
-       try:
-               if stat_cached is None:
+
+       if stat_cached is None:
+               try:
                        stat_cached = os.stat(filename)
+               except OSError, oe:
+                       if oe.errno == errno.EPERM:
+                               raise OperationNotPermitted("stat('%s')" % filename)
+                       elif oe.errno == errno.ENOENT:
+                               raise FileNotFound(filename)
+                       else:
+                               raise
 
-               if      (uid != -1 and uid != stat_cached.st_uid) or \
-                       (gid != -1 and gid != stat_cached.st_gid):
+       if      (uid != -1 and uid != stat_cached.st_uid) or \
+               (gid != -1 and gid != stat_cached.st_gid):
+               try:
                        os.chown(filename, uid, gid)
-
-               st_mode = stat_cached.st_mode & 07777 # protect from unwanted bits
-               if mask >= 0:
-                       if mode == -1:
-                               mode = 0 # Don't add any mode bits when mode is unspecified.
+               except OSError, oe:
+                       if oe.errno == errno.EPERM:
+                               raise OperationNotPermitted("chown('%s', %i, %i)" % (filename, uid, gid))
+                       elif oe.errno == errno.ENOENT:
+                               raise FileNotFound(filename)
                        else:
-                               mode = mode & 07777
-                       if      (mode & st_mode != mode) or \
-                               (mask ^ st_mode != st_mode):
-                               new_mode = mode | st_mode
-                               new_mode = mask ^ new_mode
-                               os.chmod(filename, new_mode)
-               elif mode != -1:
-                       mode = mode & 07777 # protect from unwanted bits
-                       if mode != st_mode:
-                               os.chmod(filename, mode)
-       except OSError, oe:
-               if oe.errno == errno.EPERM:
-                       raise OperationNotPermitted(oe)
-               elif oe.errno == errno.ENOENT:
-                       raise FileNotFound(oe)
+                               raise
+
+       new_mode = -1
+       st_mode = stat_cached.st_mode & 07777 # protect from unwanted bits
+       if mask >= 0:
+               if mode == -1:
+                       mode = 0 # Don't add any mode bits when mode is unspecified.
                else:
-                       raise oe
+                       mode = mode & 07777
+               if      (mode & st_mode != mode) or \
+                       (mask ^ st_mode != st_mode):
+                       new_mode = mode | st_mode
+                       new_mode = mask ^ new_mode
+       elif mode != -1:
+               mode = mode & 07777 # protect from unwanted bits
+               if mode != st_mode:
+                       new_mode = mode
+
+       if new_mode != -1:
+               try:
+                       os.chmod(filename, new_mode)
+               except OSError, oe:
+                       if oe.errno == errno.EPERM:
+                               raise OperationNotPermitted("chmod('%s', %s)" % (filename, oct(new_mode)))
+                       elif oe.errno == errno.ENOENT:
+                               raise FileNotFound(filename)
+                       else:
+                               raise
 
 def apply_stat_permissions(filename, newstat, **kwargs):
        """A wrapper around apply_secpass_permissions that gets
@@ -515,11 +535,11 @@ def apply_secpass_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1,
                        stat_cached = os.stat(filename)
                except OSError, oe:
                        if oe.errno == errno.EPERM:
-                               raise OperationNotPermitted(oe)
+                               raise OperationNotPermitted("stat('%s')" % filename)
                        elif oe.errno == errno.ENOENT:
-                               raise FileNotFound(oe)
+                               raise FileNotFound(filename)
                        else:
-                               raise oe
+                               raise
 
        all_applied = True