--- portage-2.0.51_rc7/bin/ebuild.sh 2004-09-21 04:08:05.000000000 +0300 +++ portage-2.0.51_rc7.new/bin/ebuild.sh 2004-10-07 21:34:15.000000000 +0200 @@ -65,6 +65,15 @@ export SANDBOX_ON="0" # sandbox support functions; defined prior to profile.bashrc srcing, since the profile might need to add a default exception (/usr/lib64/conftest fex, bug #60147) +addlogread() +{ + if [ "$1" = "1" ]; then + export SANDBOX_LOGREAD="1" + else + unset SANDBOX_LOGREAD + fi +} + addread() { export SANDBOX_READ="$SANDBOX_READ:$1" @@ -389,7 +398,256 @@ done } +CONFCACHE_MD5SUM="$PORTAGE_TMPDIR/configure-$CBUILD-$CHOST-$THOST.md5sums" +CONFCACHE_SETTINGS="$PORTAGE_TMPDIR/configure-$CBUILD-$CHOST-$THOST.cache" + +# $1 - file to write the configure cache out to + +confcache_prepare () { + + echo ">>> Preparing configure cache" + + # step 1 - make sure that none of the files in our list of deps + # have changed since we last built something + + addwrite "$CONFCACHE_MD5SUM" + confcache_checksums + + case "$?" in + 2) + return + ;; + 1) + echo ">>> Configure deps have changed; using an empty cache" + rm "$CONFCACHE_MD5SUM" + return + ;; + esac + + # step 2 - now we copy the existing cache into the temporary file + + cat $CONFCACHE_SETTINGS > $1 +} + +confcache_checksums () { + + # if any of them have changed, we throw the whole cache away + # a future version, written in python, will be able to do + # per config-line deps + + if [ ! -f "$CONFCACHE_MD5SUM" ]; then + echo ">>> You have no md5sum cache file; assuming this is your first time" + return 2 + fi + + while read x ; do + sum="`echo $x | cut -d ' ' -f 1`" + file="`echo $x | cut -d ' ' -f 2-`" + + new_sum="`md5sum $file | awk '{ print $1 }'`" + if [ "$new_sum" != "$sum" ]; then + return 1 + fi + done < $CONFCACHE_MD5SUM + + return 0 +} + +# $1 - file containing the updated configure cache +# $SANDBOX_LOG - file containing the sandbox log + +confcache_update () { + + # special cases + + if [ ! -f "$1" ]; then + echo "confcache_update(): unable to find temporary cache $1" + return + fi + + echo ">>> Updating global configure cache from $1" + + addwrite "$CONFCACHE_SETTINGS" + addwrite "$CONFCACHE_MD5SUM" + + # step 1 - replace our global configure cache + + cp -f "$1" "$CONFCACHE_SETTINGS" + + # step 2 - make a list of files from the sandbox log + + if [ ! -f "$SANDBOX_LOG" ]; then + # nothing we can do - let's bail + echo "confcache_update: sandbox log not found" + return + fi + + echo ">>> Reading list of files used by configure" + if [ -n "$CCACHE_DIR" ]; then + local REMOVE_CCACHE_DIR="$CCACHE_DIR" + else + local REMOVE_CCACHE_DIR="/root/.ccache" + fi + files="`grep open_rd $SANDBOX_LOG | sed -e 's/^open_rd: \+//' | grep -v /tmp | grep -v /var/tmp | grep -v $REMOVE_CCACHE_DIR | grep -v /dev | sort | uniq`" + + # step 3 - add each file to the global md5 cache + # + # yes, this is a bit slow, but relying on egrep to search the file + # is risky. Sooner or later, some spanner package will rely on + # a file that contains spaces. + + # special case - do we *have* a CONFCACHE_MD5SUM file atm? + + if [ ! -f "$CONFCACHE_MD5SUM" ]; then + + echo ">>> No md5sum cache found; populating for first time" + + # create the file + touch $CONFCACHE_MD5SUM + + # populate it + + OLD_IFS="$IFS" + NEW_IFS="^M" + # IFS="$NEW_IFS" + + for x in $files ; do + IFS="$OLD_IFS" + + if [ ! -f "$x" ] ; then + continue + fi + + newsum="`md5sum \"$x\" | awk '{ print $1 }'`" + echo "$newsum $x" >> $CONFCACHE_MD5SUM + + # IFS="$NEW_IFS" + done + IFS="$OLD_IFS" + fi + + # if we don't + + OLD_IFS="$IFS" + NEW_IFS=" +" + + IFS="$NEW_IFS" + + echo ">>> Updating md5sum cache" + + for x in $files ; do + if [ ! -f "$x" ]; then + continue + fi + + infile=0 + while read y < $CONFCACHE_MD5SUM ; do + IFS="$OLD_IFS" + + sum="`echo $x | cut -d ' ' -f 1`" + file="`echo $x | cut -d ' ' -f 2-`" + + if [ "$file" = "$x" ]; then + infile=1 + break + fi + IFS="$NEW_IFS" + done + + IFS="$OLD_IFS" + + if [ "$infile" = "0" ]; then + newsum="`md5sum \"$x\" | awk '{ print $1 }'`" + echo "$newsum $x" >> $CONFCACHE_MD5SUM + fi + + IFS="$NEW_IFS" + done + + IFS="$OLD_IFS" +} + +confcache_start() { + # global configure cache - stuart@gentoo.org + # + # if FEATURES="sandbox confcache" are set, we maintain a global + # cache of results from previous configure statements + # + # this global cache should benefit all machines, but especially + # multi-processor boxes + + if [ "${FEATURES//*confcache*/true}" = "true" -a "${FEATURES//*sandbox*/true}" = "true" -a "${RESTRICT//*noconfcache*/true}" != "true" ]; then + CONF_CACHE="`/bin/tempfile`" + echo ">>> Temporary configure cache file is $CONF_CACHE" + addwrite "$CONF_CACHE" + confcache_prepare "$CONF_CACHE" + EXTRA_ECONF="--cache-file=$CONF_CACHE $EXTRA_ECONF" + addlogread 1 + + # mark these variables read-only, so that they can't be + # changed to, say, /etc/passwd + + # typeset -r CONF_CACHE + # typeset -r READLOG + else + echo "!!! Not using global configure cache" + fi +} + +confcache_stop() { + if [ "${FEATURES//*confcache*/true}" = "true" -a "${FEATURES//*sandbox*/true}" = "true" -a "${RESTRICT//*noconfcache*/true}" != "true" ]; then + addlogread 0 + confcache_update "$CONF_CACHE" + [ -f "$CONF_CACHE" ] && rm -f "$CONF_CACHE" + + # now we need to clean up the log file, otherwise portage + # will have a fit ;-) + # + # here, we remove all the entries that the SANDBOX_LOGREAD + # feature will have added + # + # any entries that we don't remove are sandbox violations + # by definitions + echo ">>> Fixing sandbox log" + if [ -f "$SANDBOX_LOG" ]; then + SANDBOX_DIRS="`echo $SANDBOX_WRITE | tr ':' ' '`" + + sed -i -e "s/^open_rd:.*//" \ + -e "s/^execve:.*//" \ + -e "s/^opendir:.*//" $SANDBOX_LOG + for x in $SANDBOX_DIRS ; do + sed -i -e "s/^open_wr: ${x//\//\\/}.*//" \ + -e "s/^unlink: ${x//\//\\/}.*//" \ + -e "s/^rename: ${x//\//\\/}.*//" \ + -e "s/^chmod: ${x//\//\\/}.*//" \ + -e "s/^chown: ${x//\//\\/}.*//" \ + -e "s/^symlink: ${x//\//\\/}.*//" \ + -e "s/^rmdir: ${x//\//\\/}.*//" \ + -e "s/^mkdir: ${x//\//\\/}.*//" $SANDBOX_LOG + done + + # now we remove the empty lines + + TMPFILE="`tempfile`" + egrep -v '^$' $SANDBOX_LOG > $TMPFILE + cat $TMPFILE > $SANDBOX_LOG + rm $TMPFILE + + # if the file is empty, we can now remove the file + # + # this test may break on arches that do not use GNU ls + + if [ "`ls -l $SANDBOX_LOG | awk '{ print $5 }'`" = "0" ]; then + rm -f $SANDBOX_LOG + fi + fi + fi +} + econf() { + confcache_start + if [ -x ./configure ]; then if hasq autoconfig $FEATURES && ! hasq autoconfig $RESTRICT; then if [ -e /usr/share/gnuconfig/ -a -x /bin/basename ]; then @@ -440,8 +698,12 @@ ${EXTRA_ECONF} \ "$@" || die "econf failed" else + [ -n "$CONF_CACHE" ] && rm -f "$CONF_CACHE" + [ -n "$READLOG" ] && rm -f "$READLOG" die "no configure script found" fi + + confcache_stop } einstall() { --- portage-2.0.51_rc7/src/sandbox-1.1/libsandbox.c 2004-08-02 21:49:31.000000000 +0300 +++ portage-2.0.51_rc7.new/src/sandbox-1.1/libsandbox.c 2004-10-07 15:27:53.000000000 +0200 @@ -1193,14 +1193,14 @@ debug_log_env = getenv("SANDBOX_DEBUG"); debug_log_path = getenv("SANDBOX_DEBUG_LOG"); - if (((NULL == log_path) || - (0 != strncmp(absolute_path, log_path, strlen(log_path)))) && + if (((NULL != log_path) || + (0 == strncmp(absolute_path, log_path, strlen(log_path)))) && ((NULL == debug_log_env) || (NULL == debug_log_path) || (0 != strncmp(absolute_path, debug_log_path, strlen(debug_log_path)))) - && (0 == check_access(sbcontext, func, absolute_path)) ) { - if (1 == sbcontext->show_access_violation) { + + if ((0 == check_access(sbcontext, func, absolute_path)) && (1 == sbcontext->show_access_violation)) { fprintf(stderr, "\e[31;01mACCESS DENIED\033[0m %s:%*s%s\n", func, (int) (10 - strlen(func)), "", absolute_path); @@ -1226,9 +1226,33 @@ } } } + + result = 0; } + else if (getenv("SANDBOX_LOGREAD") != NULL) + { + /* create the log message */ + + sprintf ( + buffer, + "%s:%*s%s\n", + func, + (int) (10 - strlen(func)), + "", + absolute_path + ); + + /* fprintf(stderr, buffer); */ + + /* log the event to the log file anyway */ + log_file = true_open(log_path, O_APPEND | O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (log_file >= 0) { + write(log_file, buffer, strlen(buffer)); + close(log_file); + } - result = 0; + result = 1; + } } else if (NULL != debug_log_env) { if (NULL != debug_log_path) { if (0 != strncmp(absolute_path, debug_log_path, strlen(debug_log_path))) {