changeset 0:bcd2e358d57f

Start by copying the existing control image building infrastructure from Aboriginal Linux, and shuffling the layout around a bit.
author Rob Landley <rob@landley.net>
date Sun, 03 Jul 2011 17:23:26 -0500
parents
children e6cf96654ab1
files common/README common/bootstrap/build-one-package.sh common/bootstrap/functions.sh common/bootstrap/init common/bootstrap/run-build-stages.sh common/builder.sh common/download_functions.sh common/utility_functions.sh images/busybox-test/build.sh images/gentoo-bootstrap/README images/gentoo-bootstrap/download.sh images/gentoo-bootstrap/mnt/build/bash.sh images/gentoo-bootstrap/mnt/build/file.sh images/gentoo-bootstrap/mnt/build/ncurses.sh images/gentoo-bootstrap/mnt/build/patch.sh images/gentoo-bootstrap/mnt/build/portage.sh images/gentoo-bootstrap/mnt/build/python.sh images/gentoo-bootstrap/mnt/build/rsync.sh images/gentoo-bootstrap/mnt/build/zlib.sh images/gentoo-bootstrap/mnt/files/emerge_wrapper.sh images/gentoo-bootstrap/mnt/files/etc/portage/profile/package.provided images/gentoo-bootstrap/mnt/package-list images/gentoo-bootstrap/patches/portage-2.1.8.3.patch images/hello-world/build.sh images/lfs-bootstrap/download.sh images/lfs-bootstrap/mnt/README images/lfs-bootstrap/mnt/build/autoconf.sh images/lfs-bootstrap/mnt/build/automake.sh images/lfs-bootstrap/mnt/build/bash.sh images/lfs-bootstrap/mnt/build/bison.sh images/lfs-bootstrap/mnt/build/bzip2.sh images/lfs-bootstrap/mnt/build/coreutils.sh images/lfs-bootstrap/mnt/build/diffutils.sh images/lfs-bootstrap/mnt/build/e2fsprogs.sh images/lfs-bootstrap/mnt/build/file.sh images/lfs-bootstrap/mnt/build/findutils.sh images/lfs-bootstrap/mnt/build/flex.sh images/lfs-bootstrap/mnt/build/gawk.sh images/lfs-bootstrap/mnt/build/gdbm.sh images/lfs-bootstrap/mnt/build/generic-check.sh images/lfs-bootstrap/mnt/build/gettext-stub.sh images/lfs-bootstrap/mnt/build/gettext.sh images/lfs-bootstrap/mnt/build/gmp.sh images/lfs-bootstrap/mnt/build/grep.sh images/lfs-bootstrap/mnt/build/groff.sh images/lfs-bootstrap/mnt/build/gzip.sh images/lfs-bootstrap/mnt/build/iana-etc.sh images/lfs-bootstrap/mnt/build/inetutils.sh images/lfs-bootstrap/mnt/build/iproute2.sh images/lfs-bootstrap/mnt/build/kbd.sh images/lfs-bootstrap/mnt/build/less.sh images/lfs-bootstrap/mnt/build/libtool.sh images/lfs-bootstrap/mnt/build/m4.sh images/lfs-bootstrap/mnt/build/make.sh images/lfs-bootstrap/mnt/build/man-db.sh images/lfs-bootstrap/mnt/build/module-init-tools.sh images/lfs-bootstrap/mnt/build/mpc.sh images/lfs-bootstrap/mnt/build/mpfr.sh images/lfs-bootstrap/mnt/build/ncurses.sh images/lfs-bootstrap/mnt/build/patch.sh images/lfs-bootstrap/mnt/build/perl.sh images/lfs-bootstrap/mnt/build/pkg-config.sh images/lfs-bootstrap/mnt/build/procps.sh images/lfs-bootstrap/mnt/build/psmisc.sh images/lfs-bootstrap/mnt/build/readline.sh images/lfs-bootstrap/mnt/build/sed.sh images/lfs-bootstrap/mnt/build/setup.nosrc images/lfs-bootstrap/mnt/build/shadow.sh images/lfs-bootstrap/mnt/build/sysklogd.sh images/lfs-bootstrap/mnt/build/sysvinit.sh images/lfs-bootstrap/mnt/build/tar.sh images/lfs-bootstrap/mnt/build/texinfo.sh images/lfs-bootstrap/mnt/build/udev.sh images/lfs-bootstrap/mnt/build/util-linux-ng.sh images/lfs-bootstrap/mnt/build/vim.nolink images/lfs-bootstrap/mnt/build/zlib.sh images/lfs-bootstrap/mnt/package-list images/static-tools/build.sh images/static-tools/patches/dropbear-fixstatic.patch images/static-tools/patches/strace-arm-eabi.patch images/static-tools/patches/strace-fixnet.patch
diffstat 81 files changed, 3145 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/README	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,68 @@
+Common infrastructure for natively building packages on target.
+
+This contains a top level file run on the host to create a control image:
+
+  control-image-wrapper.sh - script run on host to create a control image.
+
+And several files in the "mnt" subdirectory which are copied to the target:
+
+  init - First script run in a control image.  Copies root filesystem into
+         /home/chroot to get a writeable filesystem build can install more
+         packages into, and --bind mounts other directories in as appropriate
+         so the result actually works.  Chroots into the new filesystem
+         and runs /mnt/run-build-stages.sh.  When chroot exits, cleans up
+         bind mounts, tars up the result, and uploads it to the host via ftp.
+
+  functions.sh - reusable functions like set_titlebar and dotprogress.
+
+  run-build-stages.sh - Loop through /mnt/package-list calling
+         /mnt/build-one-package.sh on each entry, in order.  Stop at the first
+         failed package.
+
+         This script also maintains a manifest file listing installed packages,
+         skipping already installed packages when re-run unless $FORCE is set.
+
+         If $FILTER is set, skips listed packages (name|name|name).  Packages
+         can be annotated with categories (in #comments at the end of each
+         line) which $FILTER can also skip.
+
+  build-one-package.sh - Build a single package listed on the command line.
+
+         If /mnt/build/$NAME.nosrc exists, this runs it.  Otherwise, copy a
+         symlink tree from /mnt/packages/$NAME to /home/$NAME (via "cp -s",
+         first deleting any old /home/$NAME if it exists), then cd to
+         the new directory and run /mnt/build/$NAME.sh.  On success, delete
+         /home/$NAME on the way out.
+
+To use this infrastructure, create a new project subdirectory with
+"make-control-image.sh", "download.sh", "mnt/package-list", and
+"mnt/build/*", I.E.:
+
+1) Create a new sources/control-images/MYPROJECT subdirectory.
+
+2) Symlink the control image wrapper to make-control-image.sh in your new
+   directory, ala:
+
+     ln -s ../bootstrap-skeleton/control-image-wrapper.sh make-control-image.sh
+
+3) Create a download.sh script to fetch/extract/prepare your package source.
+
+   The control image wrapper script calls this download.sh configured so that
+   using the "download" function to grab packages from $URL (with $SHA1, using
+   the normal cacheing infrastructure) will automatically extract each
+   package into the "packages" subdirectory of the new control image.  The
+   tarball will wind up in a subdirectory under the top level "packages"
+   directory on the host.
+
+   This script gets run at control image creation time, it is not copied to
+   the target.  Remember to mark it executable.
+
+4) Create a "mnt" subdirectory under your new proect subdirectory, containing
+   additional files to be copied verbaim into the control image.  You will need
+   at least:
+
+   A) package-list - file listing packages to install, in order, one per line.
+
+   B) build - directory containing $PACKAGE.sh and $PACKAGE.nosrc build scripts.
+
+See the gentoo-boostrap and lfs-bootstrap directories for examples.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/bootstrap/build-one-package.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,64 @@
+#!/bin/ash
+
+# Yes, ash.  Because neither bash 2 nor hush support -o pipefail
+
+set -o pipefail
+
+source /mnt/functions.sh || exit 1
+
+# build $1
+
+set_titlebar "$1"
+
+# Three types of /mnt/build scripts:
+#
+# $1.nosrc - no source code in /mnt/build, perform no setup/cleanup.
+# $1.sh - source is symlink tree to "/mnt/build/$1".  This is faster and uses
+#         less disk space but confuses some packages.
+# $1.nolink - source is conventional copy of /mnt/build/$1
+
+if [ ! -e "/mnt/build/$1.nosrc" ]
+then
+  [ -e "/mnt/build/$1.nolink" ] && LINKTYPE=dp || LINKTYPE=s
+
+  # Snapshot source from /mnt/build/$1 to /home/$1
+
+  cd /home &&
+  rm -rf "/home/$1" &&
+  cp -${LINKTYPE}fR "/mnt/packages/$1" "$1" &&
+  cd "$1" || exit 1
+
+  # Lobotomize config.guess so it won't complain about unknown target types.
+  # 99% of packages do not care, but autoconf throws a temper tantrum if
+  # the version of autoconf that created this back when the package shipped
+  # didn't know what a microblaze or hexagon was.  Repeat after me:
+  #   "Autoconf is useless"
+
+  for guess in $(find . -name config.guess)
+  do
+    rm "$guess" &&
+    echo -e "#!/bin/sh\ngcc -dumpmachine" > "$guess" || exit 1
+  done
+  EXT=sh
+else
+  EXT=nosrc
+fi
+
+# Call package build script
+
+mkdir -p /home/log
+time "/mnt/build/$1".* 2>&1 | tee "/home/log/$1.log"
+if [ $? -ne 0 ]
+then
+  echo "$1" died >&2
+  exit 1
+fi
+
+# Delete copy of source if build succeeded
+
+if [ ! -z "$LINKTYPE" ]
+then
+  cd /home &&
+  rm -rf "$1" &&
+  sync || exit 1
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/bootstrap/functions.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,17 @@
+#!/bin/echo This file is sourced not run
+
+upload_result()
+{
+  ftpput $FTP_SERVER -P $FTP_PORT "$1-$HOST" "$1"
+}
+
+set_titlebar()
+{
+  echo -en "\033]2;($HOST) $1\007"
+  echo === "$1"
+}
+
+dotprogress()
+{
+  while read i; do echo -n .; done; echo
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/bootstrap/init	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# Start running here, and hand off to run-build-stages.sh in chroot.
+
+. /mnt/functions.sh
+
+[ -z "$NATIVE_BUILD" ] && NATIVE_BUILD=chroot
+
+# Is the root filesystem already writeable?
+
+if touch /.amiwrite 2>/dev/null && rm /.amiwrite 2>/dev/null
+then
+  # build and install stuff on the writable filesystem
+
+  /mnt/run-build-stages.sh
+else
+  # Create a new writeable chroot, build and install stuff in there
+
+  setup-chroot /home/"$NATIVE_BUILD" /mnt/run-build-stages.sh
+
+  # Upload a tarball of the result to the host
+
+  if [ $? -eq 0 ]
+  then
+    set_titlebar "upload tarball"
+    tar czvf "$NATIVE_BUILD".tar.gz "$NATIVE_BUILD" | dotprogress &&
+    upload_result "$NATIVE_BUILD".tar.gz
+  fi
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/bootstrap/run-build-stages.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Run each of the individual package build files, in order.
+
+[ -z "$MANIFEST" ] && MANIFEST=/usr/src/packages
+touch "$MANIFEST"
+  
+[ -z "$FILTER" ] || FILTER="/$FILTER/d"
+for i in $(sed -r -e "$FILTER" -e "s@#.*@@" /mnt/package-list)
+do
+  if [ -z "$FORCE" ] && grep -q "$i" "$MANIFEST"
+  then
+    echo "$i already installed"
+    continue
+  fi
+  /mnt/build-one-package.sh "$i" || exit 1
+  
+  sed -i -e "/$i/d" "$MANIFEST" &&
+  echo "$i" >> "$MANIFEST" || exit 1
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/builder.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# Control image generator infrastructure.
+
+source sources/include.sh || exit 1
+
+# Find path to our working directory.
+
+MYDIR="$(readlink -f "$(dirname "$(which "$0")")")"
+IMAGENAME="${MYDIR/*\//}"
+
+# Use our own directories for downloaded source tarballs and patches.
+# (We may have the same packages as the aboriginal build, but use different
+# versions, and we don't want our cleanup_oldfiles to overlap.)
+
+PATCHDIR="$MYDIR/patches"
+SRCDIR="$SRCDIR/control-images/$IMAGENAME" && mkdir -p "$SRCDIR" || dienow
+
+# Include package cache in the control image, so the target system image can
+# build from this source.
+
+WORK="$BUILD/control-images/$IMAGENAME" &&
+blank_tempdir "$WORK" &&
+SRCTREE="$WORK/packages" &&
+mkdir "$SRCTREE" &&
+
+# Copy common infrastructure to target
+
+cp "$MYDIR"/../bootstrap-skeleton/mnt/* "$WORK" || exit 1
+if [ -e "$MYDIR/mnt" ]
+then
+  cp -a "$MYDIR/mnt/." "$WORK" || exit 1
+fi
+
+# Populate packages directory
+
+echo "=== $IMAGENAME: Download/extract source code"
+
+EXTRACT_ALL=1
+
+source "$MYDIR"/download.sh || exit 1
+
+cleanup_oldfiles
+
+# Create sqaushfs image
+
+mksquashfs "$WORK" "$WORK.hdc" -noappend -all-root || dienow
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/download_functions.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,265 @@
+#!/bin/echo "This file is sourced, not run"
+
+# Remove version information and extension tarball name "$1".
+# If "$2", add that version number back, keeping original extension.
+
+noversion()
+{
+  LOGRUS='s/-*\(\([0-9\.]\)*\([_-]rc\)*\(-pre\)*\([0-9][a-zA-Z]\)*\)*\(\.tar\(\..z2*\)*\)$'
+  [ -z "$2" ] && LOGRUS="$LOGRUS//" || LOGRUS="$LOGRUS/$2\\6/"
+
+  echo "$1" | sed -e "$LOGRUS"
+}
+
+# Apply any patches to this package
+patch_package()
+{
+  ls "$PATCHDIR/${PACKAGE}"-*.patch 2> /dev/null | sort | while read i
+  do
+    if [ -f "$i" ]
+    then
+      echo "Applying $i"
+      (cd "${SRCTREE}/${PACKAGE}" &&
+       patch -p1 -i "$i" &&
+       sha1file "$i" >> "$SHA1FILE") ||
+        ([ -z "$ALLOW_PATCH_FAILURE" ] && dienow)
+    fi
+  done
+}
+
+# Get the tarball for this package
+
+find_package_tarball()
+{
+  # If there are multiple similar files we want the newest timestamp, in case
+  # the URL just got upgraded but cleanup_oldfiles hasn't run yet.  Be able to
+  # distinguish "package-123.tar.bz2" from "package-tests-123.tar.bz2" and
+  # return the shorter one reliably.
+
+  ls -tc "$SRCDIR/$1-"*.tar* 2>/dev/null | while read i
+  do
+    if [ "$(noversion "${i/*\//}")" == "$1" ]
+    then
+      echo "$i"
+      break
+    fi
+  done
+}
+
+# Extract tarball named in $1 and apply all relevant patches into
+# "$BUILD/packages/$1".  Record sha1sum of tarball and patch files in
+# sha1-for-source.txt.  Re-extract if tarball or patches change.
+
+extract_package()
+{
+  mkdir -p "$SRCTREE" || dienow
+
+  # Figure out whether we're using an unstable package.
+
+  PACKAGE="$1"
+  is_in_list "$PACKAGE" $USE_UNSTABLE && PACKAGE=alt-"$PACKAGE"
+
+  # Announce to the world that we're cracking open a new package
+
+  announce "$PACKAGE"
+
+  # Find tarball, and determine type
+
+  FILENAME="$(find_package_tarball "$PACKAGE")"
+  DECOMPRESS=""
+  [ "$FILENAME" != "${FILENAME/%\.tar\.bz2/}" ] && DECOMPRESS="j"
+  [ "$FILENAME" != "${FILENAME/%\.tar\.gz/}" ] && DECOMPRESS="z"
+
+  # If the source tarball doesn't exist, but the extracted directory is there,
+  # assume everything's ok.
+
+  SHA1FILE="$SRCTREE/$PACKAGE/sha1-for-source.txt"
+  if [ -z "$FILENAME" ]
+  then
+    if [ ! -e "$SRCTREE/$PACKAGE" ]
+    then
+      echo "No tarball for $PACKAGE" >&2
+      dienow
+    fi
+
+    # If the sha1sum file isn't there, re-patch the package.
+    [ ! -e "$SHA1FILE" ] && patch_package
+    return 0
+  fi
+
+  # Check the sha1 list from the previous extract.  If the source is already
+  # up to date (including patches), keep it.
+
+  SHA1TAR="$(sha1file "$FILENAME")"
+  SHALIST=$(cat "$SHA1FILE" 2> /dev/null)
+  if [ ! -z "$SHALIST" ]
+  then
+    for i in "$SHA1TAR" $(sha1file "$PATCHDIR/$PACKAGE"-* 2>/dev/null)
+    do
+      # Is this sha1 in the file?
+      if [ -z "$(echo "$SHALIST" | sed -n "s/$i/$i/p" )" ]
+      then
+        SHALIST=missing
+        break
+      fi
+      # Remove it
+      SHALIST="$(echo "$SHALIST" | sed "s/$i//" )"
+    done
+    # If we matched all the sha1sums, nothing more to do.
+    [ -z "$SHALIST" ] && return 0
+  fi
+
+  # Re-extract the package, deleting the old one (if any)..
+
+  echo -n "Extracting '$PACKAGE'"
+  (
+    UNIQUE=$(readlink /proc/self)
+    trap 'rm -rf "$BUILD/temp-'$UNIQUE'"' EXIT
+    rm -rf "$SRCTREE/$PACKAGE" 2>/dev/null
+    mkdir -p "$BUILD/temp-$UNIQUE" "$SRCTREE" || dienow
+
+    { tar -xv${DECOMPRESS} -f "$FILENAME" -C "$BUILD/temp-$UNIQUE" || dienow
+    } | dotprogress
+
+    mv "$BUILD/temp-$UNIQUE/"* "$SRCTREE/$PACKAGE" &&
+    echo "$SHA1TAR" > "$SHA1FILE"
+  )
+
+  [ $? -ne 0 ] && dienow
+
+  patch_package
+}
+
+# Confirm that a file has the appropriate checksum (or exists but SHA1 is blank)
+# Delete invalid file.
+
+confirm_checksum()
+{
+  SUM="$(sha1file "$SRCDIR/$FILENAME" 2>/dev/null)"
+  if [ x"$SUM" == x"$SHA1" ] || [ -z "$SHA1" ] && [ -f "$SRCDIR/$FILENAME" ]
+  then
+    if [ -z "$SHA1" ]
+    then
+      echo "No SHA1 for $FILENAME ($SUM)"
+    else
+      echo "Confirmed $FILENAME"
+    fi
+
+    # Preemptively extract source packages?
+
+    [ -z "$EXTRACT_ALL" ] && return 0
+    extract_package "$BASENAME"
+    return $?
+  fi
+
+  # If there's a corrupted file, delete it.  In theory it would be nice
+  # to resume downloads, but wget creates "*.1" files instead.
+
+  rm "$SRCDIR/$FILENAME" 2> /dev/null
+
+  return 1
+}
+
+# Attempt to obtain file from a specific location
+
+download_from()
+{
+  # Return success if we already have a valid copy of the file
+
+  confirm_checksum && return 0
+
+  # If we have another source, try to download file from there.
+
+  [ -z "$1" ] && return 1
+  wget -t 2 -T 20 -O "$SRCDIR/$FILENAME" "$1" ||
+    (rm "$SRCDIR/$FILENAME"; return 2)
+  touch -c "$SRCDIR/$FILENAME"
+
+  confirm_checksum
+}
+
+# Confirm a file matches sha1sum, else try to download it from mirror list.
+
+download()
+{
+  FILENAME=`echo "$URL" | sed 's .*/  '`
+  [ -z "$RENAME" ] || FILENAME="$(echo "$FILENAME" | sed -r "$RENAME")"
+  ALTFILENAME=alt-"$(noversion "$FILENAME" -0)"
+
+  if [ -z "$(sha1sum < /dev/null)" ]
+  then
+    echo "Error: please install sha1sum" >&2
+    exit 1
+  fi
+
+  echo -ne "checking $FILENAME\r"
+
+  # Update timestamps on both stable and unstable tarballs (if any)
+  # so cleanup_oldfiles doesn't delete stable when we're building unstable
+  # or vice versa
+
+  touch -c "$SRCDIR"/{"$FILENAME","$ALTFILENAME"} 2>/dev/null
+
+  # Give package name, minus file's version number and archive extension.
+  BASENAME="$(noversion "$FILENAME")"
+
+  # If unstable version selected, try from listed location, and fall back
+  # to PREFERRED_MIRROR.  Do not try normal mirror locations for unstable.
+
+  if is_in_list "$BASENAME" $USE_UNSTABLE
+  then
+    # If extracted source directory exists, don't download alt-tarball.
+    [ -e "$SRCTREE/alt-$BASENAME" ] && return 0
+
+    # Download new one as alt-packagename.tar.ext
+    FILENAME="$ALTFILENAME"
+    SHA1=
+
+    ([ ! -z "$PREFERRED_MIRROR" ] &&
+      download_from "$PREFERRED_MIRROR/$ALTFILENAME") ||
+      download_from "$UNSTABLE"
+    return $?
+  fi
+
+  # If environment variable specifies a preferred mirror, try that first.
+
+  if [ ! -z "$PREFERRED_MIRROR" ]
+  then
+    download_from "$PREFERRED_MIRROR/$FILENAME" && return 0
+  fi
+
+  # Try original location, then mirrors.
+  # Note: the URLs in mirror list cannot contain whitespace.
+
+  download_from "$URL" && return 0
+  for i in $MIRROR_LIST
+  do
+    download_from "$i/$FILENAME" && return 0
+  done
+
+  # Return failure.
+
+  echo "Could not download $FILENAME"
+  echo -en "\e[0m"
+  return 1
+}
+
+# Clean obsolete files out of the source directory
+
+START_TIME=`date +%s`
+
+cleanup_oldfiles()
+{
+  # wait for asynchronous downloads to complete
+
+  wait
+
+  for i in "${SRCDIR}"/*
+  do
+    if [ -f "$i" ] && [ "$(date +%s -r "$i")" -lt "${START_TIME}" ]
+    then
+      echo Removing old file "$i"
+      rm -rf "$i"
+    fi
+  done
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/utility_functions.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,215 @@
+#!/bin/echo "This file is sourced, not run"
+
+# This file contains generic functions, presumably reusable in other contexts.
+
+# Unset all environment variables that we don't know about, in case some crazy
+# person already exported $CROSS_COMPILE, $ARCH, $CDPATH, or who knows what
+# else.  It's hard to know what might drive some package crazy, so use a
+# whitelist.
+
+sanitize_environment()
+{
+  # Which variables are set in config?
+
+  TEMP=$(echo $(sed -n 's/.*export[ \t]*\([^=]*\)=.*/\1/p' config) | sed 's/ /,/g')
+
+  # What other variables should we keep?
+
+  TEMP="$TEMP,LANG,PATH,SHELL,TERM,USER,USERNAME,LOGNAME,PWD,EDITOR,HOME,DISPLAY,_"
+  TEMP="$TEMP,TOPSHELL,START_TIME,STAGE_NAME,TOOLCHAIN_PREFIX,HOST_ARCH"
+  TEMP="$TEMP,http_proxy,ftp_proxy,https_proxy,no_proxy"
+
+  # Unset any variable we don't recognize.  It can screw up the build.
+
+  for i in $(env | sed -n 's/=.*//p')
+  do
+    is_in_list $i "$TEMP" && continue
+    [ "${i:0:7}" == "DISTCC_" ] && continue
+    [ "${i:0:7}" == "CCACHE_" ] && continue
+
+    unset $i 2>/dev/null
+  done
+}
+
+# Assign (export) a variable only if current value is blank
+
+export_if_blank()
+{
+  [ -z "$(eval "echo \"\${${1/=*/}}\"")" ] && export "$1"
+}
+
+# Create a blank directory at first argument, deleting existing contents if any
+
+blank_tempdir()
+{
+  # sanity test: never rm -rf something we don't own.
+  [ -z "$1" ] && dienow
+  touch -c "$1" || dienow
+
+  # Delete old directory, create new one.
+  [ -z "$NO_CLEANUP" ] && rm -rf "$1"
+  mkdir -p "$1" || dienow
+}
+
+# output the sha1sum of a file
+
+sha1file()
+{
+  sha1sum "$@" | awk '{print $1}'
+}
+
+# dienow() is an exit function that works properly even from a subshell.
+# (actually_dienow is run in the parent shell via signal handler.)
+
+actually_dienow()
+{
+  echo -e "\n\e[31mExiting due to errors ($ARCH_NAME $STAGE_NAME $PACKAGE)\e[0m" >&2
+  exit 1
+}
+
+trap actually_dienow SIGUSR1
+TOPSHELL=$$
+
+dienow()
+{
+  kill -USR1 $TOPSHELL
+  exit 1
+}
+
+# Turn a bunch of output lines into a much quieter series of periods,
+# roughly one per screenfull
+
+dotprogress()
+{
+  x=0
+  while read i
+  do
+    x=$[$x + 1]
+    if [[ "$x" -eq 25 ]]
+    then
+      x=0
+      echo -n .
+    fi
+  done
+  echo
+}
+
+# Announce an action to the world
+
+announce()
+{
+  # Write a line to the log file with easily greppable header
+  echo "=== $1 ($ARCH_NAME $STAGE_NAME)"
+
+  # Set the title bar of the current xterm
+  [ -z "$NO_TITLE_BAR" ] && echo -en "\033]2;$ARCH_NAME $STAGE_NAME $1\007"
+}
+
+# Filter out unnecessary noise, keeping just lines starting with "==="
+
+maybe_quiet()
+{
+  [ -z "$FORK" ] && cat || grep "^==="
+}
+
+# Run a command background if FORK is set, in foreground otherwise
+
+maybe_fork()
+{
+  [ -z "$BUILD_VERBOSE" ] || echo "$*"
+
+  if [ -z "$FORK" ]
+  then
+    eval "$*"
+  else
+    eval "$*" &
+  fi
+}
+
+# Kill a process and all its decendants
+
+killtree()
+{
+  local KIDS=""
+
+  while [ $# -ne 0 ]
+  do
+    KIDS="$KIDS $(pgrep -P$1)"
+    shift
+  done
+
+  KIDS="$(echo -n $KIDS)"
+  if [ ! -z "$KIDS" ]
+  then
+    # Depth first kill avoids reparent_to_init hiding stuff.
+    killtree $KIDS
+    kill $KIDS 2>/dev/null
+  fi
+}
+
+# Search a colon-separated path for files matching a pattern.
+
+# Arguments are 1) path to search, 2) pattern, 3) command to run on each file.
+# During command, $DIR/$FILE points to file found.
+
+path_search()
+{
+  # For each each $PATH element, loop through each file in that directory,
+  # and create a symlink to the wrapper with that name.  In the case of
+  # duplicates, keep the first one.
+
+  echo "$1" | sed 's/:/\n/g' | while read DIR
+  do
+    find "$DIR/" -maxdepth 1 -mindepth 1 -name "$2" | sed 's@.*/@@' | \
+    while read FILE
+    do
+      eval "$3"
+
+      # Output is verbose.  Pipe it to dotprogress.
+
+      echo $FILE
+    done
+  done
+}
+
+# Abort if we haven't got a prerequisite in the $PATH
+
+check_prerequisite()
+{
+  if [ -z "$(which "$1")" ]
+  then
+    [ -z "$FAIL_QUIET" ] && echo No "$1" in '$PATH'. >&2
+    dienow
+  fi
+}
+
+# Search through all the files under a directory and collapse together
+# identical files into hardlinks
+
+collapse_hardlinks()
+{
+  SHA1LIST=""
+  find "$1" -type f | while read FILE
+  do
+    echo "$FILE"
+    SHA1=$(sha1file "$FILE")
+    MATCH=$(echo "$SHA1LIST" | grep "^$SHA1")
+    if [ -z "$MATCH" ]
+    then
+      # Yes, the quote spanning two lines here is intentional
+      SHA1LIST="$SHA1LIST
+$SHA1 $FILE"
+    else
+      FILE2="$(echo "$MATCH" | sed 's/[^ ]* //')"
+      cmp -s "$FILE" "$FILE2" || continue
+      ln -f "$FILE" "$FILE2" || dienow
+    fi
+  done
+}
+
+# Check if $1 is in the comma separated list $2
+
+is_in_list()
+{
+  [ "$2" == all ] || [ ! -z "$(echo ,"$2", | grep ,"$1",)" ]
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/busybox-test/build.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Run the busybox test suite.
+
+source sources/include.sh || exit 1
+
+WORK="$BUILD/control-images/busybox-test" && blank_tempdir "$WORK"
+
+# Don't download busybox, it's got to already be there in standard sources.
+
+setupfor busybox
+cd "$TOP"
+
+cat > "$WORK"/init << 'EOF' || dienow
+#!/bin/bash
+
+echo === $HOST Run busybox test suite
+
+cp -sfR /mnt/busybox busybox && cd busybox &&
+make defconfig &&
+ln -s /bin/busybox busybox &&
+cd testsuite &&
+./runtest &&
+cd .. &&
+rm -rf busybox || exit 1
+
+sync
+
+EOF
+
+chmod +x "$WORK"/init || dienow
+
+mksquashfs "$WORK" "$WORK.hdc" -noappend -all-root
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/README	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,16 @@
+Extend minimal native build environment into a seed for Gentoo Catalyst.
+
+This doesn't quite create an official Gentoo Stage 1.  We use busybox instead
+of gnu tools, we're uClibc-based instead of glibc-based, and we use our
+existing toolchain (with distcc acceleration) instead of asking portage
+to build one.  That said, this should be enough to run Catalyst and produce
+official Stage 1, Stage 2, and Stage 3 images.
+
+GFS used:
+
+  setup-base-packages.sh
+    strace, Python, ncurses, bash, tar, patch, findutils, file, pax-utils,
+    shadow
+  setup-portage.sh
+    /etc/passwd (root and portage), /etc/group (root and portage)
+    portage
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/download.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,34 @@
+# Download all the source tarballs we haven't got up-to-date copies of.
+
+URL=http://zlib.net/zlib-1.2.5.tar.bz2 \
+SHA1=543fa9abff0442edca308772d6cef85557677e02 \
+maybe_fork "download || dienow"
+
+URL=http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.7.tar.gz \
+SHA1=8233ee56ed84ae05421e4e6d6db6c1fe72ee6797 \
+maybe_fork "download || dienow"
+
+URL=http://python.org/ftp/python/2.6.5/Python-2.6.5.tar.bz2 \
+SHA1=24c94f5428a8c94c9d0b316e3019fee721fdb5d1 \
+RENAME='s/P/p/' \
+maybe_fork "download || dienow"
+
+URL=http://ftp.gnu.org/gnu/bash/bash-3.2.tar.gz \
+SHA1=fe6466c7ee98061e044dae0347ca5d1a8eab4a0d \
+maybe_fork "download || dienow"
+
+URL=http://www.samba.org/ftp/rsync/src/rsync-3.0.7.tar.gz \
+SHA1=63426a1bc71991d93159cd522521fbacdafb7a61 \
+maybe_fork "download || dienow"
+
+URL=http://ftp.gnu.org/gnu/patch/patch-2.5.9.tar.gz \
+SHA1=9a69f7191576549255f046487da420989d2834a6 \
+maybe_fork "download || dienow"
+
+URL=ftp://ftp.astron.com/pub/file/file-5.03.tar.gz \
+SHA1=f659a4e1fa96fbdc99c924ea8e2dc07319f046c1 \
+maybe_fork "download || dienow"
+
+URL=http://dev.gentoo.org/~zmedico/portage/archives/portage-2.1.8.tar.bz2 \
+SHA1=390c97f3783af2d9e52482747ead3681655ea9c3 \
+maybe_fork "download || dienow"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/build/bash.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Portage uses bash ~= regex matches, which were introduced in bash 3.
+
+./configure --enable-cond-regexp --disable-nls --prefix=/usr &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/build/file.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./configure --prefix=/usr &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/build/ncurses.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./configure --without-cxx-binding --with-shared &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/build/patch.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Need a patch with --dry-run to make portage happy
+
+./configure --prefix=/usr &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/build/portage.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# Portage isn't really designed to be portable, so this script contains
+# the "make install" stage that portage really should have within itself.
+
+# Install portage user/group, and libraries.
+
+echo portage:x:250:250:portage:/var/tmp/portage:/bin/false >> /etc/passwd &&
+echo portage::250:portage >> /etc/group &&
+mkdir -p /usr/lib/portage &&
+cp -a bin pym /usr/lib/portage/ &&
+
+# Add portage python modules to the python search path.
+
+echo /usr/lib/portage/pym > /usr/lib/python2.6/site-packages/gentoo.pth ||
+  exit 1
+
+# Install portage binaries into bin and sbin
+
+for i in archive-conf dispatch-conf emaint emerge-webrsync env-update \
+         etc-update fixpackages quickpkg regenworld
+do
+  ln /usr/lib/portage/bin/$i /usr/sbin/$i || exit 1
+done
+
+for i in  ebuild egencache emerge portageq repoman
+do
+  ln /usr/lib/portage/bin/$i /usr/bin/$i || exit 1
+done
+
+# Install portage man pages
+
+cp cnf/make.globals /etc/ &&
+cp man/*.1 /usr/man/man1 &&
+cp man/*.5 /usr/man/man5 &&
+
+mkdir -p /var/log /etc/portage/profile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/build/python.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./configure --prefix=/usr &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/build/rsync.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+./configure --prefix=/usr &&
+# Break link and touch file, otherwise ./configure tries to recreate it
+# which requires perl.
+cat proto.h-tstamp > proto.h.new &&
+mv -f proto.h.new proto.h-tstamp &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/build/zlib.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# 1.2.5 accidentally shipped the Makefile, then configure tries to
+# modify it in place, which fails if the filesystem is read only.
+# The fix is to remove it before configuring.
+
+rm Makefile && 
+./configure --prefix=/usr &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/files/emerge_wrapper.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+if [ "$1" != "--sync" ]
+then
+  echo 'No portage tree, run "emerge --sync".' >&2
+  exit 1
+fi
+
+if [ "$(id -u)" -ne 0 ]
+then
+  echo "You are not root." >&2
+  exit 1
+fi
+
+echo "Downloading portage tree..."
+mkdir -p /var/log /usr/portage &&
+cd /usr &&
+#wget http://127.0.0.1/aboriginal/mirror/portage-latest.tar.bz2 -O - | \
+wget http://gentoo.osuosl.org/snapshots/portage-latest.tar.bz2 -O - | \
+  tar xjC /usr
+if [ ! -d portage ]
+then
+  echo "Failed to download portage-latest tarball." >&2
+  exit 1
+fi
+
+if ! emerge.real --sync
+then
+  echo "Sync failed"
+  exit 1
+fi
+
+cd $(dirname $(readlink -f $(which emerge.real)))
+mv emerge.real emerge
+
+echo "Portage tree initialized"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/files/etc/portage/profile/package.provided	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,43 @@
+# Base aboriginal system
+
+sys-devel/gcc-4.2.1
+sys-devel/binutils-2.17
+sys-devel/make-3.81
+sys-libs/uclibc-0.9.31
+sys-kernel/linux-headers-2.6.35
+sys-apps/busybox-1.17.2
+
+# Stuff busybox provides
+
+app-arch/gzip-1.0
+sys-apps/sed-1.0
+sys-apps/findutils-1.0
+sys-apps/diffutils-1.0
+app-editors/vim-1.0
+sys-apps/gawk-1.0
+app-arch/tar-1.0
+app-arch/bzip2-1.0
+app-arch/cpio-1.0
+sys-process/procps-1.0
+sys-apps/which-1.0
+sys-apps/net-tools-1.0
+sys-apps/sysvinit-1.0
+sys-apps/util-linux-1.0
+sys-apps/coreutils-1.0
+sys-apps/less-1.0
+sys-apps/grep-1.0      
+sys-apps/shadow-1.0    
+sys-apps/module-init-tools-1.0
+net-misc/wget-1.0
+app-arch/xz-utils-1.0
+
+# Upgrades for seed
+
+sys-apps/portage-2.1.8.3
+dev-lang/python-2.6.5
+sys-libs/zlib-1.2.5
+sys-libs/ncurses-5.7
+app-shells/bash-3.2
+net-misc/rsync-3.0.7
+sys-devel/patch-2.5.9
+sys-apps/file-5.03
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/mnt/package-list	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+zlib ncurses python bash rsync patch file portage
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/gentoo-bootstrap/patches/portage-2.1.8.3.patch	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1155 @@
+Index: ChangeLog
+===================================================================
+--- a/ChangeLog	(revision 15731)
++++ b/ChangeLog	(revision 15814)
+@@ -1,3 +1,178 @@
++2010-03-10 00:31  zmedico
++
++	* [r15814] pym/_emerge/depgraph.py: Only try to merge portage asap
++	  when the new version is different. (trunk r15813)
++
++2010-03-09 21:27  zmedico
++
++	* [r15812] pym/_emerge/Scheduler.py, pym/_emerge/depgraph.py: Only
++	  create implicit libc deps when the version changes. (trunk
++	  r15810)
++
++2010-03-09 21:25  zmedico
++
++	* [r15811] pym/_emerge/Scheduler.py, pym/_emerge/depgraph.py:
++	  Disable implicit libc deps for ROOT != "/" since it's probably
++	  not needed. (trunk r15809)
++
++2010-03-09 20:21  zmedico
++
++	* [r15808] pym/_emerge/depgraph.py: Merge libc asap for all roots
++	  instead of just ROOT="/". (trunk r15804)
++
++2010-03-09 20:21  zmedico
++
++	* [r15807] pym/_emerge/sync/old_tree_timestamp.py: Add periods.
++	  (trunk r15803)
++
++2010-03-09 20:20  zmedico
++
++	* [r15806] pym/_emerge/sync/old_tree_timestamp.py: Use ewarn output
++	  style to add some color. (trunk r15802)
++
++2010-03-09 20:20  zmedico
++
++	* [r15805] man/portage.5: * Remove outdated profiles.desc sentence
++	  about "1 profile allowed per stable/dev/KEYWORD". Thanks to
++	  Torsten Veller <tove@g.o> for reporting.
++	  
++	  * Add 'exp' to valid profiles.desc status values, and update the
++	  example. (trunk r15795)
++
++2010-03-09 08:11  zmedico
++
++	* [r15794] pym/portage/mail.py: Import 'email' and 'smtlib' locally
++	  since python ebuilds remove the 'email' module when built with
++	  USE=build. (trunk r15793)
++
++2010-03-09 05:04  zmedico
++
++	* [r15792] pym/_emerge/Scheduler.py: Add --debug output for the
++	  scheduler digraph. (trunk r15790)
++
++2010-03-09 05:04  zmedico
++
++	* [r15791] pym/_emerge/Scheduler.py: If _implicit_libc_deps() finds
++	  both a new-style virtual and an old-style PROVIDE virtual, use
++	  the new-style virtual. (trunk r15789)
++
++2010-03-09 04:31  zmedico
++
++	* [r15788] pym/_emerge/actions.py: Add support for displaying
++	  profile listed in make.profile/parent when make.profile is not a
++	  symlink. The first parent with a path inside $PORTDIR is
++	  displayed. (trunk r15787)
++
++2010-03-09 03:59  zmedico
++
++	* [r15786] pym/_emerge/Scheduler.py: Fix typo in parenthesis from
++	  previous commit. (trunk r15784)
++
++2010-03-09 03:58  zmedico
++
++	* [r15785] pym/_emerge/Scheduler.py: Bug #303567 - Create implicit
++	  dependencies on libc, in order to ensure that libc is installed
++	  as early as possible. (trunk r15783)
++
++2010-03-09 02:42  zmedico
++
++	* [r15782] pym/portage/dbapi/vartree.py,
++	  pym/portage/proxy/lazyimport.py: When portage upgrades or
++	  downgrades itself, preload lazily referenced portage submodules
++	  into memory so that imports won't fail later. (trunk r15778)
++
++2010-03-09 02:42  zmedico
++
++	* [r15781] man/emerge.1, pym/_emerge/help.py: Move --update from
++	  the actions to the options section. (trunk r15777)
++
++2010-03-09 02:42  zmedico
++
++	* [r15780] man/emerge.1, pym/_emerge/help.py: Clean up/sync docs
++	  for emerge --sync, and add a note about PORTAGE_SYNC_STALE.
++	  (trunk r15776)
++
++2010-03-09 02:42  zmedico
++
++	* [r15779] man/emerge.1: Escape hyphens. (trunk r15775)
++
++2010-03-08 09:40  zmedico
++
++	* [r15772] pym/_emerge/sync/__init__.py: Add copyright header.
++	  (trunk r15771)
++
++2010-03-08 09:10  zmedico
++
++	* [r15770] pym/_emerge/actions.py: Disable PORTAGE_SYNC_STALE
++	  warnings when --usepkgonly is enabled. (trunk r15769)
++
++2010-03-08 09:05  zmedico
++
++	* [r15768] pym/portage/package/ebuild/config.py: Exclude
++	  PORTAGE_SYNC_STALE from the ebuild environment. (trunk r15767)
++
++2010-03-08 08:57  zmedico
++
++	* [r15766] pym/_emerge/depgraph.py: Bug #307409 - Force --verbose
++	  mode when displaying circular deps. (trunk r15765)
++
++2010-03-08 08:47  zmedico
++
++	* [r15764] pym/portage/mail.py: Bug #291331 - Force ascii encoding
++	  in send_mail() in order to avoid UnicodeEncodeError from
++	  smtplib.sendmail with python3. (trunk r15759)
++
++2010-03-08 08:47  zmedico
++
++	* [r15763] pym/_emerge/sync/old_tree_timestamp.py: Show --sync in
++	  messages, to help avoid confusion. (trunk r15758)
++
++2010-03-08 08:47  zmedico
++
++	* [r15762] man/make.conf.5: Note that PORTAGE_SYNC_STALE=0 will
++	  disable warnings. (trunk r15757)
++
++2010-03-08 08:47  zmedico
++
++	* [r15761] cnf/make.globals, man/make.conf.5,
++	  pym/_emerge/actions.py, pym/_emerge/sync: Produce a warning
++	  message if the timestamp of the portage tree is more than 30 days
++	  old, and make it adjustable via the PORTAGE_SYNC_STALE variable.
++	  Thanks to Ned Ludd <solar@g.o> for the most of this code. (trunk
++	  r15756)
++
++2010-03-08 08:46  zmedico
++
++	* [r15760] pym/portage/package/ebuild/doebuild.py: Bug #308415 -
++	  Fix broken uri parameter passed to fetch () for some cases when
++	  using ebuild(1). (trunk r15755)
++
++2010-03-04 11:23  zmedico
++
++	* [r15749] pym/portage/package/ebuild/getmaskingstatus.py: Bug
++	  #307723 - Define basestring for python3. (trunk r15745)
++
++2010-03-04 11:23  zmedico
++
++	* [r15748] pym/portage/package/ebuild/doebuild.py,
++	  pym/portage/package/ebuild/fetch.py: Fix imports
++	  doebuild_environment and prepare_build_dirs imports to import
++	  from the real location instead of importing proxies. (trunk
++	  r15744)
++
++2010-03-04 11:22  zmedico
++
++	* [r15747] pym/portage/package/ebuild/fetch.py: Bug #307707 - Fix
++	  fetch() to use the correct spawn function when calling nofetch.
++	  (trunk r15743)
++
++2010-03-04 11:22  zmedico
++
++	* [r15746] man/color.map.5, pym/_emerge/depgraph.py,
++	  pym/portage/output.py: Add new colors for binary packages in the
++	  merge list. Thanks to Sebastian Luther (few) for this patch.
++	  (trunk r15739)
++
+ 2010-03-03 06:27  zmedico
+ 
+ 	* [r15731] NEWS: Add news about splitting the top-level
+Index: cnf/make.globals
+===================================================================
+--- a/cnf/make.globals	(revision 15731)
++++ b/cnf/make.globals	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 1999-2006 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: make.globals 15254 2010-01-29 18:49:10Z zmedico $
++# $Id: make.globals 15761 2010-03-08 08:47:02Z zmedico $
+ # System-wide defaults for the Portage system
+ 
+ #            *****************************
+@@ -80,6 +80,10 @@
+ 
+ PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages"
+ 
++# The number of days after the last `emerge --sync` that a warning
++# message should be produced.
++PORTAGE_SYNC_STALE="30"
++
+ # Minimal CONFIG_PROTECT
+ CONFIG_PROTECT="/etc"
+ CONFIG_PROTECT_MASK="/etc/env.d"
+Index: man/color.map.5
+===================================================================
+--- a/man/color.map.5	(revision 15731)
++++ b/man/color.map.5	(revision 15814)
+@@ -50,6 +50,15 @@
+ \fBPKG_MERGE_WORLD\fR = \fI"green"\fR
+ Defines color used for world packages planned to be merged.
+ .TP
++\fBPKG_BINARY_MERGE\fR = \fI"darkgreen"\fR
++Defines color used for packages planned to be merged using a binary package.
++.TP
++\fBPKG_BINARY_MERGE_SYSTEM\fR = \fI"darkgreen"\fR
++Defines color used for system packages planned to be merged using a binary package.
++.TP
++\fBPKG_BINARY_MERGE_WORLD\fR = \fI"green"\fR
++Defines color used for world packages planned to be merged using a binary package.
++.TP
+ \fBPKG_NOMERGE\fR = \fI"darkblue"\fR
+ Defines color used for packages not planned to be merged.
+ .TP
+Index: man/emerge.1
+===================================================================
+--- a/man/emerge.1	(revision 15731)
++++ b/man/emerge.1	(revision 15814)
+@@ -195,7 +195,7 @@
+ name starts with "kde"; \fBemerge \-\-search "%gcc$"\fR searches for any 
+ package that ends with "gcc"; \fBemerge \-\-search "office"\fR searches for 
+ any package that contains the word "office".  If you want to include the 
+-category into the search string, prepend an @: \fBemerge --search 
++category into the search string, prepend an @: \fBemerge \-\-search 
+ "%@^dev-java.*jdk"\fR. If you want to search the package descriptions as well, 
+ use the \fB\-\-searchdesc\fR action.
+ .TP
+@@ -205,11 +205,26 @@
+ matched as regular expressions.
+ .TP
+ .BR \-\-sync
+-Initiates a portage tree update with one of the rsync.gentoo.org
+-mirrors.  \fBNote that any changes you have made to the portage
+-tree will be erased\fR.  Except for special circumstances, 
+-this uses \fBrsync\fR to do the update.  See \fBmake.conf\fR(5)'s 
+-description of PORTDIR_OVERLAY for a method to avoid deletions.
++This updates the portage tree that is located in the
++directory that the PORTDIR variable refers to (default
++location is /usr/portage). The SYNC variable specifies
++the remote URI from which files will be synchronized.
++The \fBPORTAGE_SYNC_STALE\fR variable configures
++warnings that are shown when emerge \-\-sync has not
++been executed recently.
++
++\fBWARNING:\fR
++The emerge \-\-sync action will modify and/or delete
++files located inside the directory that the PORTDIR
++variable refers to (default location is /usr/portage).
++For more information, see the PORTDIR documentation in
++the make.conf(5) man page.
++
++\fBNOTE:\fR
++The \fBemerge\-webrsync\fR program will download the entire
++portage tree as a tarball, which is much faster than emerge
++\-\-sync for first time syncs.
++
+ .TP
+ .BR "\-\-unmerge " (\fB\-C\fR)
+ \fBWARNING: This action can remove important packages!\fR Removes
+@@ -219,13 +234,6 @@
+ \fIebuilds\fR. For a dependency aware version of \fB\-\-unmerge\fR,
+ use \fB\-\-depclean\fR or \fB\-\-prune\fR.
+ .TP
+-.BR "\-\-update " (\fB\-u\fR)
+-Updates packages to the best version available, which may not always be the 
+-highest version number due to masking for testing and development.
+-Package atoms
+-specified on the command line are greedy, meaning that unspecific atoms may
+-match multiple installed versions of slotted packages.
+-.TP
+ .BR "\-\-version " (\fB\-V\fR)
+ Displays the version number of \fBemerge\fR.
+ .SH "OPTIONS"
+@@ -536,6 +544,13 @@
+ constraint is removed, hopefully leading to a more
+ readable dependency tree.
+ .TP
++.BR "\-\-update " (\fB\-u\fR)
++Updates packages to the best version available, which may
++not always be the  highest version number due to masking
++for testing and development. Package atoms specified on
++the command line are greedy, meaning that unspecific
++atoms may match multiple versions of slotted packages.
++.TP
+ .BR "\-\-use\-ebuild\-visibility[=n]"
+ Use unbuilt ebuild metadata for visibility
+ checks on built packages.
+Index: man/make.conf.5
+===================================================================
+--- a/man/make.conf.5	(revision 15731)
++++ b/man/make.conf.5	(revision 15814)
+@@ -639,6 +639,12 @@
+ .br
+ Defaults to 3.
+ .TP
++\fBPORTAGE_SYNC_STALE\fR = \fI[NUMBER]\fR
++Defines the number of days after the last `emerge \-\-sync` that a warning
++message should be produced. A value of 0 will disable warnings.
++.br
++Defaults to 30.
++.TP
+ \fBPORTAGE_TMPDIR\fR = \fI[path]\fR
+ Defines the location of the temporary build directories.
+ .br
+Index: man/portage.5
+===================================================================
+--- a/man/portage.5	(revision 15731)
++++ b/man/portage.5	(revision 15814)
+@@ -751,23 +751,22 @@
+ .TP
+ .BR profiles.desc
+ List all the current stable and development profiles.  If a profile is listed 
+-here, then it will be checked by repoman.  At the moment, only 1 profile is 
+-allowed per stable/dev/KEYWORD; the last one found is the last one used.
+-
++here, then it will be checked by repoman.
+ .I Format:
+ .nf
+ \- comments begin with # (no inline comments)
+ \- one profile list per line in format: arch dir status
+ \- arch must be listed in arch.list
+ \- dir is relative to profiles.desc
+-\- status must be 'stable' or 'dev'
++\- status must be 'stable', 'dev', or 'exp'
+ .fi
+ 
+ .I Example:
+ .nf
+-alpha default-linux/alpha/2004.3 stable
+-m68k  default-linux/m68k         dev
+-x86   default-linux/x86/2004.3   stable
++alpha        default/linux/alpha/10.0    stable
++m68k         default/linux/m68k/10.0     dev
++x86          default/linux/x86/10.0      stable
++x86-linux    prefix/linux/x86            exp
+ .fi
+ .TP
+ .BR repo_name
+Index: pym/_emerge/actions.py
+===================================================================
+--- a/pym/_emerge/actions.py	(revision 15731)
++++ b/pym/_emerge/actions.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 1999-2009 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: actions.py 15687 2010-03-02 21:07:53Z zmedico $
++# $Id: actions.py 15788 2010-03-09 04:31:13Z zmedico $
+ 
+ from __future__ import print_function
+ 
+@@ -53,6 +53,7 @@
+ from _emerge.search import search
+ from _emerge.SetArg import SetArg
+ from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
++from _emerge.sync.old_tree_timestamp import old_tree_timestamp_warn
+ from _emerge.unmerge import unmerge
+ from _emerge.UnmergeDepPriority import UnmergeDepPriority
+ from _emerge.UseFlagDisplay import UseFlagDisplay
+@@ -64,6 +65,9 @@
+ def action_build(settings, trees, mtimedb,
+ 	myopts, myaction, myfiles, spinner):
+ 
++	if '--usepkgonly' not in myopts:
++		old_tree_timestamp_warn(settings['PORTDIR'], settings)
++
+ 	# validate the state of the resume data
+ 	# so that we can make assumptions later.
+ 	for k in ("resume", "resume_backup"):
+@@ -2249,19 +2253,38 @@
+ 	writemsg_level("".join("%s\n" % l for l in msg),
+ 		level=logging.ERROR, noiselevel=-1)
+ 
++def relative_profile_path(portdir, abs_profile):
++	realpath = os.path.realpath(abs_profile)
++	basepath   = os.path.realpath(os.path.join(portdir, "profiles"))
++	if realpath.startswith(basepath):
++		profilever = realpath[1 + len(basepath):]
++	else:
++		profilever = None
++	return profilever
++
+ def getportageversion(portdir, target_root, profile, chost, vardb):
+-	profilever = "unavailable"
++	profilever = None
+ 	if profile:
+-		realpath = os.path.realpath(profile)
+-		basepath   = os.path.realpath(os.path.join(portdir, "profiles"))
+-		if realpath.startswith(basepath):
+-			profilever = realpath[1 + len(basepath):]
+-		else:
++		profilever = relative_profile_path(portdir, profile)
++		if profilever is None:
+ 			try:
+-				profilever = "!" + os.readlink(profile)
+-			except (OSError):
++				for parent in portage.grabfile(
++					os.path.join(profile, 'parent')):
++					profilever = relative_profile_path(portdir,
++						os.path.join(profile, parent))
++					if profilever is not None:
++						break
++			except portage.exception.PortageException:
+ 				pass
+-		del realpath, basepath
++
++			if profilever is None:
++				try:
++					profilever = "!" + os.readlink(profile)
++				except (OSError):
++					pass
++
++	if profilever is None:
++		profilever = "unavailable"
+ 
+ 	libcver=[]
+ 	libclist  = vardb.match("virtual/libc")
+Index: pym/_emerge/depgraph.py
+===================================================================
+--- a/pym/_emerge/depgraph.py	(revision 15731)
++++ b/pym/_emerge/depgraph.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 1999-2009 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: depgraph.py 15711 2010-03-02 21:14:20Z zmedico $
++# $Id: depgraph.py 15814 2010-03-10 00:31:43Z zmedico $
+ 
+ from __future__ import print_function
+ 
+@@ -3341,7 +3341,9 @@
+ 		if replacement_portage == running_portage:
+ 			replacement_portage = None
+ 
+-		if replacement_portage is not None:
++		if replacement_portage is not None and \
++			(running_portage is None or \
++			(running_portage.cpv != replacement_portage.cpv)):
+ 			# update from running_portage to replacement_portage asap
+ 			asap_nodes.append(replacement_portage)
+ 
+@@ -3363,12 +3365,16 @@
+ 
+ 		# Merge libc asap, in order to account for implicit
+ 		# dependencies. See bug #303567.
+-		libc_pkg = self._dynamic_config.mydbapi[running_root].match_pkgs(
+-			portage.const.LIBC_PACKAGE_ATOM)
+-		if libc_pkg:
+-			libc_pkg = libc_pkg[0]
+-			if libc_pkg.operation == 'merge':
+-				asap_nodes.append(libc_pkg)
++		for root in (running_root,):
++			libc_pkg = self._dynamic_config.mydbapi[root].match_pkgs(
++				portage.const.LIBC_PACKAGE_ATOM)
++			if libc_pkg:
++				libc_pkg = libc_pkg[0]
++				if libc_pkg.operation == 'merge':
++					# Only add a dep when the version changes.
++					if not libc_pkg.root_config.trees[
++						'vartree'].dbapi.cpv_exists(libc_pkg.cpv):
++						asap_nodes.append(libc_pkg)
+ 
+ 		def gather_deps(ignore_priority, mergeable_nodes,
+ 			selected_nodes, node):
+@@ -3904,7 +3910,7 @@
+ 			tempgraph.remove(node)
+ 		display_order.reverse()
+ 		self._frozen_config.myopts.pop("--quiet", None)
+-		self._frozen_config.myopts.pop("--verbose", None)
++		self._frozen_config.myopts["--verbose"] = True
+ 		self._frozen_config.myopts["--tree"] = True
+ 		portage.writemsg("\n\n", noiselevel=-1)
+ 		self.display(display_order)
+@@ -4500,12 +4506,20 @@
+ 
+ 				def pkgprint(pkg_str):
+ 					if pkg_merge:
+-						if pkg_system:
+-							return colorize("PKG_MERGE_SYSTEM", pkg_str)
+-						elif pkg_world:
+-							return colorize("PKG_MERGE_WORLD", pkg_str)
++						if built:
++							if pkg_system:
++								return colorize("PKG_BINARY_MERGE_SYSTEM", pkg_str)
++							elif pkg_world:
++								return colorize("PKG_BINARY_MERGE_WORLD", pkg_str)
++							else:
++								return colorize("PKG_BINARY_MERGE", pkg_str)
+ 						else:
+-							return colorize("PKG_MERGE", pkg_str)
++							if pkg_system:
++								return colorize("PKG_MERGE_SYSTEM", pkg_str)
++							elif pkg_world:
++								return colorize("PKG_MERGE_WORLD", pkg_str)
++							else:
++								return colorize("PKG_MERGE", pkg_str)
+ 					elif pkg_status == "uninstall":
+ 						return colorize("PKG_UNINSTALL", pkg_str)
+ 					else:
+Index: pym/_emerge/help.py
+===================================================================
+--- a/pym/_emerge/help.py	(revision 15731)
++++ b/pym/_emerge/help.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 1999-2009 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: help.py 15687 2010-03-02 21:07:53Z zmedico $
++# $Id: help.py 15781 2010-03-09 02:42:23Z zmedico $
+ 
+ from __future__ import print_function
+ 
+@@ -195,18 +195,31 @@
+ 		print("                emerge -S 'perl.*module'")
+ 		print()
+ 		print("       "+green("--sync"))
+-		print("              Tells emerge to update the Portage tree as specified in")
+-		print("              The SYNC variable found in /etc/make.conf.  By default, SYNC instructs")
+-		print("              emerge to perform an rsync-style update with rsync.gentoo.org.")
++		desc = "This updates the portage tree that is located in the " + \
++			"directory that the PORTDIR variable refers to (default " + \
++			"location is /usr/portage). The SYNC variable specifies " + \
++			"the remote URI from which files will be synchronized. " + \
++			"The PORTAGE_SYNC_STALE variable configures " + \
++			"warnings that are shown when emerge --sync has not " + \
++			"been executed recently."
++		for line in wrap(desc, desc_width):
++			print(desc_indent + line)
+ 		print()
+-		print("              'emerge-webrsync' exists as a helper app to emerge --sync, providing a")
+-		print("              method to receive the entire portage tree as a tarball that can be")
+-		print("              extracted and used. First time syncs would benefit greatly from this.")
++		print(desc_indent + turquoise("WARNING:"))
++		desc = "The emerge --sync action will modify and/or delete " + \
++			"files located inside the directory that the PORTDIR " + \
++			"variable refers to (default location is /usr/portage). " + \
++			"For more information, see the PORTDIR documentation in " + \
++			"the make.conf(5) man page."
++		for line in wrap(desc, desc_width):
++			print(desc_indent + line)
+ 		print()
+-		print("              "+turquoise("WARNING:"))
+-		print("              If using our rsync server, emerge will clean out all files that do not")
+-		print("              exist on it, including ones that you may have created. The exceptions")
+-		print("              to this are the distfiles, local and packages directories.")
++		print(desc_indent + green("NOTE:"))
++		desc = "The emerge-webrsync program will download the entire " + \
++			"portage tree as a tarball, which is much faster than emerge " + \
++			"--sync for first time syncs."
++		for line in wrap(desc, desc_width):
++			print(desc_indent + line)
+ 		print()
+ 		print("       "+green("--unmerge")+" ("+green("-C")+" short option)")
+ 		print("              "+turquoise("WARNING: This action can remove important packages!"))
+@@ -216,13 +229,6 @@
+ 		print("              ebuilds. For a dependency aware version of --unmerge, use")
+ 		print("              --depclean or --prune.")
+ 		print()
+-		print("       "+green("--update")+" ("+green("-u")+" short option)")
+-		print("              Updates packages to the best version available, which may not")
+-		print("              always be the highest version number due to masking for testing")
+-		print("              and development. Package atoms specified on the command")
+-		print("              line are greedy, meaning that unspecific atoms may match multiple")
+-		print("              installed versions of slotted packages.")
+-		print()
+ 		print("       "+green("--version")+" ("+green("-V")+" short option)")
+ 		print("              Displays the currently installed version of portage along with")
+ 		print("              other information useful for quick reference on a system. See")
+@@ -591,6 +597,15 @@
+ 		for line in wrap(desc, desc_width):
+ 			print(desc_indent + line)
+ 		print()
++		print("       "+green("--update")+" ("+green("-u")+" short option)")
++		desc = "Updates packages to the best version available, which may " + \
++			"not always be the  highest version number due to masking " + \
++			"for testing and development. Package atoms specified on " + \
++			"the command line are greedy, meaning that unspecific " + \
++			"atoms may match multiple versions of slotted packages."
++		for line in wrap(desc, desc_width):
++			print(desc_indent + line)
++		print()
+ 		print("       " + green("--use-ebuild-visibility") + "[=%s]" % turquoise("n"))
+ 		desc = "Use unbuilt ebuild metadata for visibility " + \
+ 			"checks on built packages."
+Index: pym/_emerge/Scheduler.py
+===================================================================
+--- a/pym/_emerge/Scheduler.py	(revision 15731)
++++ b/pym/_emerge/Scheduler.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 1999-2009 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: Scheduler.py 15708 2010-03-02 21:13:39Z zmedico $
++# $Id: Scheduler.py 15812 2010-03-09 21:27:32Z zmedico $
+ 
+ from __future__ import print_function
+ 
+@@ -18,6 +18,7 @@
+ from portage import _unicode_decode
+ from portage import _unicode_encode
+ from portage.cache.mappings import slot_dict_class
++from portage.const import LIBC_PACKAGE_ATOM
+ from portage.elog.messages import eerror
+ from portage.output import colorize, create_color_func, darkgreen, red
+ bad = create_color_func("BAD")
+@@ -351,6 +352,11 @@
+ 		self._find_system_deps()
+ 		self._prune_digraph()
+ 		self._prevent_builddir_collisions()
++		self._implicit_libc_deps()
++		if '--debug' in self.myopts:
++			writemsg("\nscheduler digraph:\n\n", noiselevel=-1)
++			self._digraph.debug_print()
++			writemsg("\n", noiselevel=-1)
+ 
+ 	def _find_system_deps(self):
+ 		"""
+@@ -412,6 +418,69 @@
+ 					priority=DepPriority(buildtime=True))
+ 			cpv_map[pkg.cpv].append(pkg)
+ 
++	def _implicit_libc_deps(self):
++		"""
++		Create implicit dependencies on libc, in order to ensure that libc
++		is installed as early as possible (see bug #303567). If the merge
++		list contains both a new-style virtual and an old-style PROVIDE
++		virtual, the new-style virtual is used.
++		"""
++		implicit_libc_roots = set([self._running_root.root])
++		libc_set = InternalPackageSet([LIBC_PACKAGE_ATOM])
++		norm_libc_pkgs = {}
++		virt_libc_pkgs = {}
++		for pkg in self._mergelist:
++			if not isinstance(pkg, Package):
++				# a satisfied blocker
++				continue
++			if pkg.installed:
++				continue
++			if pkg.root in implicit_libc_roots and \
++				pkg.operation == 'merge':
++				if libc_set.findAtomForPackage(pkg):
++					if pkg.category == 'virtual':
++						d = virt_libc_pkgs
++					else:
++						d = norm_libc_pkgs
++					if pkg.root in d:
++						raise AssertionError(
++							"found 2 libc matches: %s and %s" % \
++							(d[pkg.root], pkg))
++					d[pkg.root] = pkg
++
++		# Prefer new-style virtuals over old-style PROVIDE virtuals.
++		libc_pkg_map = norm_libc_pkgs.copy()
++		libc_pkg_map.update(virt_libc_pkgs)
++
++		# Only add a dep when the version changes.
++		for libc_pkg in list(libc_pkg_map.values()):
++			if libc_pkg.root_config.trees['vartree'].dbapi.cpv_exists(
++				libc_pkg.cpv):
++				del libc_pkg_map[pkg.root]
++
++		if not libc_pkg_map:
++			return
++
++		libc_pkgs = set(libc_pkg_map.values())
++		earlier_libc_pkgs = set()
++
++		for pkg in self._mergelist:
++			if not isinstance(pkg, Package):
++				# a satisfied blocker
++				continue
++			if pkg.installed:
++				continue
++			if pkg.root in implicit_libc_roots and \
++				pkg.operation == 'merge':
++				if pkg in libc_pkgs:
++					earlier_libc_pkgs.add(pkg)
++				else:
++					my_libc = libc_pkg_map.get(pkg.root)
++					if my_libc is not None and \
++						my_libc in earlier_libc_pkgs:
++						self._digraph.add(my_libc, pkg,
++							priority=DepPriority(buildtime=True))
++
+ 	class _pkg_failure(portage.exception.PortageException):
+ 		"""
+ 		An instance of this class is raised by unmerge() when
+Index: pym/_emerge/sync/__init__.py
+===================================================================
+--- a/pym/_emerge/sync/__init__.py	(revision 15731)
++++ b/pym/_emerge/sync/__init__.py	(revision 15814)
+@@ -0,0 +1,3 @@
++# Copyright 2010 Gentoo Foundation
++# Distributed under the terms of the GNU General Public License v2
++# $Id: __init__.py 15772 2010-03-08 09:40:46Z zmedico $
+Index: pym/_emerge/sync/old_tree_timestamp.py
+===================================================================
+--- a/pym/_emerge/sync/old_tree_timestamp.py	(revision 15731)
++++ b/pym/_emerge/sync/old_tree_timestamp.py	(revision 15814)
+@@ -0,0 +1,99 @@
++# Copyright 2010 Gentoo Foundation
++# Distributed under the terms of the GNU General Public License v2
++# $Id: old_tree_timestamp.py 15807 2010-03-09 20:21:05Z zmedico $
++
++import locale
++import logging
++import time
++
++from portage import os
++from portage.exception import PortageException
++from portage.localization import _
++from portage.output import EOutput
++from portage.util import grabfile, writemsg_level
++
++def have_english_locale():
++	lang, enc = locale.getdefaultlocale()
++	if lang is not None:
++		lang = lang.lower()
++		lang = lang.split('_', 1)[0]
++	return lang is None or lang in ('c', 'en')
++
++def whenago(seconds):
++	sec = int(seconds)
++	mins = 0
++	days = 0
++	hrs = 0
++	years = 0
++	out = []
++
++	if sec > 60:
++		mins = sec / 60
++		sec = sec % 60
++	if mins > 60:
++		hrs = mins / 60
++		mins = mins % 60
++	if hrs > 24:
++		days = hrs / 24
++		hrs = hrs % 24
++	if days > 365:
++		years = days / 365
++		days = days % 365
++
++	if years:
++		out.append(str(years)+"y ")
++	if days:
++		out.append(str(days)+"d ")
++	if hrs:
++		out.append(str(hrs)+"h ")
++	if mins:
++		out.append(str(mins)+"m ")
++	if sec:
++		out.append(str(sec)+"s ")
++
++	return "".join(out).strip()
++
++def old_tree_timestamp_warn(portdir, settings):
++	unixtime = time.time()
++	default_warnsync = 30
++
++	timestamp_file = os.path.join(portdir, "metadata/timestamp.x")
++	try:
++		lastsync = grabfile(timestamp_file)
++	except PortageException:
++		return False
++
++	if not lastsync:
++		return False
++
++	lastsync = lastsync[0].split()
++	if not lastsync:
++		return False
++
++	try:
++		lastsync = int(lastsync[0])
++	except ValueError:
++		return False
++
++	var_name = 'PORTAGE_SYNC_STALE'
++	try:
++		warnsync = float(settings.get(var_name, default_warnsync))
++	except ValueError:
++		writemsg_level("!!! %s contains non-numeric value: %s\n" % \
++			(var_name, settings[var_name]),
++			level=logging.ERROR, noiselevel=-1)
++		return False
++
++	if warnsync <= 0:
++		return False
++
++	if (unixtime - 86400 * warnsync) > lastsync:
++		out = EOutput()
++		if have_english_locale():
++			out.ewarn("Last emerge --sync was %s ago." % \
++				whenago(unixtime - lastsync))
++		else:
++			out.ewarn(_("Last emerge --sync was %s.") % \
++				time.strftime('%c', time.localtime(lastsync)))
++		return True
++	return False
+Index: pym/portage/dbapi/vartree.py
+===================================================================
+--- a/pym/portage/dbapi/vartree.py	(revision 15731)
++++ b/pym/portage/dbapi/vartree.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 1998-2009 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: vartree.py 15727 2010-03-03 01:27:27Z zmedico $
++# $Id: vartree.py 15782 2010-03-09 02:42:40Z zmedico $
+ 
+ __all__ = [
+ 	"vardbapi", "vartree", "dblink"] + \
+@@ -3181,6 +3181,9 @@
+ 		if self.myroot == "/" and \
+ 			match_from_list(PORTAGE_PACKAGE_ATOM, [self.mycpv]) and \
+ 			not self.vartree.dbapi.cpv_exists(self.mycpv):
++			# Load lazily referenced portage submodules into memory,
++			# so imports won't fail during portage upgrade/downgrade.
++			portage.proxy.lazyimport._preload_portage_submodules()
+ 			settings = self.settings
+ 			base_path_orig = os.path.dirname(settings["PORTAGE_BIN_PATH"])
+ 			from tempfile import mkdtemp
+Index: pym/portage/mail.py
+===================================================================
+--- a/pym/portage/mail.py	(revision 15731)
++++ b/pym/portage/mail.py	(revision 15814)
+@@ -1,36 +1,43 @@
+ # portage.py -- core Portage functionality
+ # Copyright 1998-2004 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: mail.py 14860 2009-11-21 04:04:37Z zmedico $
++# $Id: mail.py 15794 2010-03-09 08:11:46Z zmedico $
++
++# Since python ebuilds remove the 'email' module when USE=build
++# is enabled, use a local import so that
++# portage.proxy.lazyimport._preload_portage_submodules()
++# can load this module even though the 'email' module is missing.
++# The elog mail modules won't work, but at least an ImportError
++# won't cause portage to crash during stage builds. Since the
++# 'smtlib' module imports the 'email' module, that's imported
++# locally as well.
+ 
+-from email.mime.text import MIMEText
+-from email.mime.multipart import MIMEMultipart as MultipartMessage
+-from email.mime.base import MIMEBase as BaseMessage
+-from email.header import Header
+-import smtplib
+ import socket
+ import sys
+ import time
+ 
+ from portage import os
+ from portage import _encodings
+-from portage import _unicode_encode
++from portage import _unicode_decode, _unicode_encode
+ from portage.localization import _
+ import portage
+ 
+ if sys.hexversion >= 0x3000000:
+ 	basestring = str
+ 
+-if sys.hexversion >= 0x3000000:
+-	def TextMessage(_text):
+-		mimetext = MIMEText(_text)
++def TextMessage(_text):
++	from email.mime.text import MIMEText
++	mimetext = MIMEText(_text)
++	if sys.hexversion >= 0x3000000:
+ 		mimetext.set_charset("UTF-8")
+-		return mimetext
+-else:
+-	TextMessage = MIMEText
++	return mimetext
+ 
+ def create_message(sender, recipient, subject, body, attachments=None):
+ 
++	from email.header import Header
++	from email.mime.base import MIMEBase as BaseMessage
++	from email.mime.multipart import MIMEMultipart as MultipartMessage
++
+ 	if sys.hexversion < 0x3000000:
+ 		sender = _unicode_encode(sender,
+ 			encoding=_encodings['content'], errors='strict')
+@@ -69,6 +76,9 @@
+ 	return mymessage
+ 
+ def send_mail(mysettings, message):
++
++	import smtplib
++
+ 	mymailhost = "localhost"
+ 	mymailport = 25
+ 	mymailuser = ""
+@@ -135,7 +145,17 @@
+ 				myconn = smtplib.SMTP(mymailhost, mymailport)
+ 			if mymailuser != "" and mymailpasswd != "":
+ 				myconn.login(mymailuser, mymailpasswd)
+-			myconn.sendmail(myfrom, myrecipient, message.as_string())
++
++			message_str = message.as_string()
++			if sys.hexversion >= 0x3000000:
++				# Force ascii encoding in order to avoid UnicodeEncodeError
++				# from smtplib.sendmail with python3 (bug #291331).
++				message_str = _unicode_encode(message_str,
++					encoding='ascii', errors='backslashreplace')
++				message_str = _unicode_decode(message_str,
++					encoding='ascii', errors='replace')
++
++			myconn.sendmail(myfrom, myrecipient, message_str)
+ 			myconn.quit()
+ 		except smtplib.SMTPException as e:
+ 			raise portage.exception.PortageException(_("!!! An error occured while trying to send logmail:\n")+str(e))
+Index: pym/portage/output.py
+===================================================================
+--- a/pym/portage/output.py	(revision 15731)
++++ b/pym/portage/output.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 1998-2009 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: output.py 15245 2010-01-29 18:47:30Z zmedico $
++# $Id: output.py 15746 2010-03-04 11:22:15Z zmedico $
+ 
+ __docformat__ = "epytext"
+ 
+@@ -139,6 +139,9 @@
+ _styles["PKG_MERGE"]               = ( "darkgreen", )
+ _styles["PKG_MERGE_SYSTEM"]        = ( "darkgreen", )
+ _styles["PKG_MERGE_WORLD"]         = ( "green", )
++_styles["PKG_BINARY_MERGE"]        = ( "darkgreen", )
++_styles["PKG_BINARY_MERGE_SYSTEM"] = ( "darkgreen", )
++_styles["PKG_BINARY_MERGE_WORLD"]  = ( "green", )
+ _styles["PKG_UNINSTALL"]           = ( "red", )
+ _styles["PKG_NOMERGE"]             = ( "darkblue", )
+ _styles["PKG_NOMERGE_SYSTEM"]      = ( "darkblue", )
+Index: pym/portage/package/ebuild/config.py
+===================================================================
+--- a/pym/portage/package/ebuild/config.py	(revision 15731)
++++ b/pym/portage/package/ebuild/config.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 2010 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: config.py 15705 2010-03-02 21:11:02Z zmedico $
++# $Id: config.py 15768 2010-03-08 09:05:13Z zmedico $
+ 
+ __all__ = [
+ 	'autouse', 'best_from_dict', 'check_config_instance', 'config',
+@@ -274,7 +274,8 @@
+ 		"PORTAGE_REPO_DUPLICATE_WARN",
+ 		"PORTAGE_RO_DISTDIRS",
+ 		"PORTAGE_RSYNC_EXTRA_OPTS", "PORTAGE_RSYNC_OPTS",
+-		"PORTAGE_RSYNC_RETRIES", "PORTAGE_USE", "PORT_LOGDIR",
++		"PORTAGE_RSYNC_RETRIES", "PORTAGE_SYNC_STALE",
++		"PORTAGE_USE", "PORT_LOGDIR",
+ 		"QUICKPKG_DEFAULT_OPTS",
+ 		"RESUMECOMMAND", "RESUMECOMMAND_HTTP", "RESUMECOMMAND_HTTP",
+ 		"RESUMECOMMAND_SFTP", "SYNC", "USE_EXPAND_HIDDEN", "USE_ORDER",
+Index: pym/portage/package/ebuild/doebuild.py
+===================================================================
+--- a/pym/portage/package/ebuild/doebuild.py	(revision 15731)
++++ b/pym/portage/package/ebuild/doebuild.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 2010 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: doebuild.py 15713 2010-03-02 21:14:43Z zmedico $
++# $Id: doebuild.py 15760 2010-03-08 08:46:53Z zmedico $
+ 
+ __all__ = ['doebuild', 'doebuild_environment', 'spawn', 'spawnebuild']
+ 
+@@ -25,6 +25,7 @@
+ 	'portage.package.ebuild.config:check_config_instance',
+ 	'portage.package.ebuild.digestcheck:digestcheck',
+ 	'portage.package.ebuild.digestgen:digestgen',
++	'portage.package.ebuild.fetch:fetch',
+ 	'portage.util.ExtractKernelVersion:ExtractKernelVersion'
+ )
+ 
+@@ -47,7 +48,6 @@
+ from portage.localization import _
+ from portage.manifest import Manifest
+ from portage.output import style_to_ansi_code
+-from portage.package.ebuild.fetch import fetch
+ from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs
+ from portage.util import apply_recursive_permissions, \
+ 	apply_secpass_permissions, noiselimit, normalize_path, \
+@@ -810,7 +810,8 @@
+ 			mydo not in ("digest", "manifest") and "noauto" not in features)
+ 		alist = mysettings.configdict["pkg"].get("A")
+ 		aalist = mysettings.configdict["pkg"].get("AA")
+-		if alist is None or aalist is None:
++		if alist is None or aalist is None or \
++			(not emerge_skip_distfiles and need_distfiles):
+ 			# Make sure we get the correct tree in case there are overlays.
+ 			mytree = os.path.realpath(
+ 				os.path.dirname(os.path.dirname(mysettings["O"])))
+@@ -827,25 +828,26 @@
+ 				return 1
+ 			mysettings.configdict["pkg"]["A"] = " ".join(alist)
+ 			mysettings.configdict["pkg"]["AA"] = " ".join(aalist)
++
++			if not emerge_skip_distfiles and need_distfiles:
++				if "mirror" in features or fetchall:
++					fetchme = aalist
++				else:
++					fetchme = alist
++				if not fetch(fetchme, mysettings, listonly=listonly,
++					fetchonly=fetchonly):
++					return 1
++
+ 		else:
+ 			alist = set(alist.split())
+ 			aalist = set(aalist.split())
+-		if ("mirror" in features) or fetchall:
+-			fetchme = aalist
+-			checkme = aalist
+-		else:
+-			fetchme = alist
+-			checkme = alist
+ 
+ 		if mydo == "fetch":
+ 			# Files are already checked inside fetch(),
+ 			# so do not check them again.
+ 			checkme = []
+-
+-		if not emerge_skip_distfiles and \
+-			need_distfiles and not fetch(
+-			fetchme, mysettings, listonly=listonly, fetchonly=fetchonly):
+-			return 1
++		else:
++			checkme = alist
+ 
+ 		if mydo == "fetch" and listonly:
+ 			return 0
+Index: pym/portage/package/ebuild/fetch.py
+===================================================================
+--- a/pym/portage/package/ebuild/fetch.py	(revision 15731)
++++ b/pym/portage/package/ebuild/fetch.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 2010 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: fetch.py 15718 2010-03-02 21:37:48Z zmedico $
++# $Id: fetch.py 15748 2010-03-04 11:23:00Z zmedico $
+ 
+ from __future__ import print_function
+ 
+@@ -20,18 +20,26 @@
+ import portage
+ portage.proxy.lazyimport.lazyimport(globals(),
+ 	'portage.package.ebuild.config:check_config_instance,config',
++	'portage.package.ebuild.doebuild:doebuild_environment,' + \
++		'spawn@doebuild_spawn',
++	'portage.package.ebuild.prepare_build_dirs:prepare_build_dirs',
+ )
+ 
+-from portage import doebuild_environment, OrderedDict, os, prepare_build_dirs, selinux, _encodings, _shell_quote, _unicode_encode
++from portage import OrderedDict, os, selinux, _encodings, \
++	_shell_quote, _unicode_encode
+ from portage.checksum import perform_md5, verify_all
+-from portage.const import BASH_BINARY, CUSTOM_MIRRORS_FILE, EBUILD_SH_BINARY, GLOBAL_CONFIG_PATH
++from portage.const import BASH_BINARY, CUSTOM_MIRRORS_FILE, \
++	EBUILD_SH_BINARY, GLOBAL_CONFIG_PATH
+ from portage.data import portage_gid, portage_uid, secpass, userpriv_groups
+-from portage.exception import FileNotFound, OperationNotPermitted, PermissionDenied, PortageException, TryAgain
++from portage.exception import FileNotFound, OperationNotPermitted, \
++	PermissionDenied, PortageException, TryAgain
+ from portage.localization import _
+ from portage.locks import lockfile, unlockfile
+ from portage.manifest import Manifest
+ from portage.output import colorize, EOutput
+-from portage.util import apply_recursive_permissions, apply_secpass_permissions, ensure_dirs, grabdict, shlex_split, varexpand, writemsg, writemsg_level, writemsg_stdout
++from portage.util import apply_recursive_permissions, \
++	apply_secpass_permissions, ensure_dirs, grabdict, shlex_split, \
++	varexpand, writemsg, writemsg_level, writemsg_stdout
+ from portage.process import spawn
+ 
+ _userpriv_spawn_kwargs = (
+@@ -1096,7 +1104,7 @@
+ 					ebuild_phase = mysettings.get("EBUILD_PHASE")
+ 					try:
+ 						mysettings["EBUILD_PHASE"] = "nofetch"
+-						spawn(_shell_quote(EBUILD_SH_BINARY) + \
++						doebuild_spawn(_shell_quote(EBUILD_SH_BINARY) + \
+ 							" nofetch", mysettings, fd_pipes=fd_pipes)
+ 					finally:
+ 						if ebuild_phase is None:
+Index: pym/portage/package/ebuild/getmaskingstatus.py
+===================================================================
+--- a/pym/portage/package/ebuild/getmaskingstatus.py	(revision 15731)
++++ b/pym/portage/package/ebuild/getmaskingstatus.py	(revision 15814)
+@@ -1,9 +1,11 @@
+ # Copyright 2010 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: getmaskingstatus.py 15672 2010-03-02 21:01:19Z zmedico $
++# $Id: getmaskingstatus.py 15749 2010-03-04 11:23:09Z zmedico $
+ 
+ __all__ = ['getmaskingstatus']
+ 
++import sys
++
+ import portage
+ from portage import eapi_is_supported, _eapi_is_deprecated
+ from portage.dep import match_from_list
+@@ -11,6 +13,9 @@
+ from portage.package.ebuild.config import config
+ from portage.versions import catpkgsplit, cpv_getkey
+ 
++if sys.hexversion >= 0x3000000:
++	basestring = str
++
+ def getmaskingstatus(mycpv, settings=None, portdb=None):
+ 	if settings is None:
+ 		settings = config(clone=portage.settings)
+Index: pym/portage/proxy/lazyimport.py
+===================================================================
+--- a/pym/portage/proxy/lazyimport.py	(revision 15731)
++++ b/pym/portage/proxy/lazyimport.py	(revision 15814)
+@@ -1,6 +1,6 @@
+ # Copyright 2009 Gentoo Foundation
+ # Distributed under the terms of the GNU General Public License v2
+-# $Id: lazyimport.py 14327 2009-09-21 16:07:07Z arfrever $
++# $Id: lazyimport.py 15782 2010-03-09 02:42:40Z zmedico $
+ 
+ __all__ = ['lazyimport']
+ 
+@@ -20,6 +20,24 @@
+ _module_proxies = {}
+ _module_proxies_lock = threading.RLock()
+ 
++def _preload_portage_submodules():
++	"""
++	Load lazily referenced portage submodules into memory,
++	so imports won't fail during portage upgrade/downgrade.
++	Note that this recursively loads only the modules that
++	are lazily referenced by currently imported modules,
++	so some portage submodules may still remain unimported
++	after this function is called.
++	"""
++	while True:
++		remaining = False
++		for name in list(_module_proxies):
++			if name.startswith('portage.'):
++				remaining = True
++				_unregister_module_proxy(name)
++		if not remaining:
++			break
++
+ def _register_module_proxy(name, proxy):
+ 	_module_proxies_lock.acquire()
+ 	try:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/hello-world/build.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# Download all the source tarballs we haven't got up-to-date copies of.
+
+# The tarballs are downloaded into the "packages" directory, which is
+# created as needed.
+
+source sources/include.sh || exit 1
+
+# Set up working directories
+
+WORK="$BUILD/control-images/hello-world"
+blank_tempdir "$WORK"
+
+cat > "$WORK"/init << 'EOF' || dienow
+#!/bin/bash
+
+echo Started second stage init
+
+cd /home &&
+gcc -lpthread /usr/src/thread-hello2.c -o hello &&
+./hello
+
+# Upload our hello world file to the output directory (named hello-$HOST).
+# No reason, just an example.
+
+ftpput $FTP_SERVER -P $FTP_PORT hello-$HOST hello
+
+sync
+
+EOF
+
+chmod +x "$WORK"/init || dienow
+
+cd "$TOP"
+
+mksquashfs "$WORK" "$WORK.hdc" -noappend -all-root
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/download.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,48 @@
+# Build Linux From Scratch 6.7 packages under target environment.
+
+# Note: this doesn't rebuild the toolchain packages (libc, binutils,
+# gcc, linux-headers), but reuses the toolchain we've got, because:
+
+# 1) Building a new toolchain is a target-dependent can of worms.
+# 2) Doing so would lose distcc acceleration.
+# 3) Building glibc under uClibc is buggy because glibc expects that a
+#    2.6 kernel will have TLS, and uClibc without NPTL doesn't.  (Yes,
+#    repeat after me, "autoconf is useless".)
+
+# Download upstream tarball
+
+URL=http://ftp.osuosl.org/pub/lfs/lfs-packages/lfs-packages-6.7.tar \
+SHA1=9bda969efdfd4d51bda8fafeff082f2397249876 \
+RENAME='s/-sources//' \
+download || dienow
+
+URL=ftp://penma.de/code/gettext-stub/gettext-stub-1.tar.gz \
+SHA1=ef706667010893c5492173c543d2c5b715abb8a7 \
+download || dienow
+
+cleanup_oldfiles
+
+# Extract the individual packages from the upstream tarball
+
+SRCDIR="$SRCTREE/lfs-packages"
+PATCHDIR="$SRCDIR"
+
+# Fixups for tarball names the Aboriginal extract scripts can't parse
+
+mv "$SRCDIR"/sysvinit-2.88{dsf,}.tar.bz2 &&
+mv "$SRCDIR"/tcl{8.5.8-src,-src-8.5.8}.tar.gz &&
+mv "$SRCDIR"/udev-{161-testfiles,testfiles-161}.tar.bz2 || exit 1
+
+# Remove damaged patches (whitespace damaged, don't apply without "fuzz").
+
+rm "$SRCDIR"/gcc-4.5.1-startfiles_fix-1.patch &&
+rm "$SRCDIR"/tar-1.23-overflow_fix-1.patch || exit 1
+
+# Break down upstream tarball
+
+for i in $(cd "$SRCDIR"; ls *.tar.*)
+do
+  extract_package $(noversion $i)
+done
+
+rm -rf "$SRCDIR"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/README	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,27 @@
+Automates the build of Linux From Scratch 6.7.
+
+This adds/replaces files in the existing filesystem.  At the end of the build
+BusyBox is still there but most of the symlinks to it have been replaced with
+the corresponding gnu tools.
+
+This does not attempt to replace the existing toolchain or C library, although
+there's no reason you can't run a separate script to do that before running
+this build.
+
+We're not building grub because bootloaders are both extremely target-specific
+(which CPU, which board, which boot media...  Booting an ARM from the network
+or booting MIPS from flash isn't really grub's thing).  You'll have to set up
+your own bootloader as appropriate for your hardware.  (QEMU has a built-in
+bootloader in the -kernel option.)
+
+Note that we skip the various "move stuff from /usr/bin to /bin" steps
+because /lib, /bin, and /sbin are all symlinks to the appropriate directory
+under /usr so we've already combined all that stuff already.  (That split
+happened when Ken and Dennis filled up their original root filesystem's RK05
+disk pack on the PDP-11 they developed Unix on in 1971, so they let their
+operating system files leak into the second disk, where all the user
+directories lived.  They eventually added a third disk on /home and moved the
+user directories to there, but kept the OS straddling two disks.  These days
+between initramfs and cheap multi-terrabyte drives that split is a useless
+historical artifact kept alive by people blindly following procedures they
+no longer understand.  Don't get me started on /opt.)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/autoconf.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/automake.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+./configure --prefix=/usr --docdir=/usr/share/doc/automake &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/bash.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+./configure --prefix=/usr --bindir=/bin --htmldir=/usr/share/doc/bash \
+  --without-bash-malloc --with-installed-readline &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  chown -R nobody . &&
+  su-tools nobody -s /bin/bash -c "make tests" || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/bison.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+./configure --prefix=/usr &&
+echo '#define YYENABLE_NLS 1' >> lib/config.h &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/bzip2.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# Use relative paths when installing symlinks, not absolute paths.
+sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' Makefile &&
+
+# The extra song and dance is to install the shared library, and
+# make the bzip2 binary use it.
+
+make -f Makefile-libbz2_so &&
+make clean &&
+make &&
+make PREFIX=/usr install &&
+cp bzip2-shared /bin/bzip2 &&
+cp -a libbz2.so* /lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/coreutils.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+./configure --prefix=/usr --enable-no-install-program=kill,uptime &&
+make -j "$CPUS" || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make NON_ROOT_USERNAME=nobody check-root &&
+  echo "dummy:x:1000:nobody" >> /etc/group &&
+  chown -R nobody . &&
+  su-tools nobody -s /bin/bash -c "make RUN_EXPENSIVE_TESTS=yes check" &&
+  sed -i '/^dummy:/d' /etc/group || exit 1
+fi
+
+make install &&  
+mv /usr/bin/chroot /usr/sbin || exit 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/diffutils.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/e2fsprogs.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+mkdir build &&
+cd build &&
+../configure --prefix=/usr --with-root-prefix="" \
+  --enable-elf-shlibs --disable-libblkid --disable-libuuid \
+  --disable-uuidd --disable-fsck --disable-tls &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install &&
+make install-libs &&
+chmod u+w /usr/lib/{libcom_err,libe2p,libext2fs,libss}.a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/file.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/findutils.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+./configure --prefix=/usr --libexecdir=/usr/lib/findutils \
+  --localstatedir=/var/lib/locate &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/flex.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+/mnt/build/generic-check.sh
+
+# Create lex wrapper
+
+cat > /usr/bin/lex << 'EOF' &&
+#!/bin/sh
+
+exiec /usr/bin/flex -l "$@"
+EOF
+chmod 755 /usr/bin/lex || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  mkdir /usr/share/doc/flex &&
+  cp doc/flex.pdf /usr/share/doc/flex
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/gawk.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+./configure --prefix=/usr --libexecdir=/usr/lib &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  mkdir /usr/share/doc/gawk &&
+  cp doc/awkforai.txt doc/*.eps doc/*.pdf doc/*.jpg /usr/share/doc/gawk
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/gdbm.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+./configure --prefix=/usr &&
+make -j $CPUS &&
+make install &&
+make install-compat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/generic-check.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# Standard install, plus "make check".
+
+./configure --prefix=/usr --bindir=/bin &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/gettext-stub.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Stub to compile packages that refuse to build without gettext.
+
+gcc -shared -fpic -o /usr/lib/libintl.so libintl-stub.c &&
+cp libintl-stub.h /usr/include/libintl.h &&
+cp msgfmt /usr/bin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/gettext.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Swap out incestuous knowledge of the internals of glibc for incestuous
+# knowledge of the internals of uClibc.  (The resulting code should never
+# trigger anyway, but it needs to be able to _compile_...)
+
+sed -i 's/thread_locale->__names\[category]/thread_locale->cur_locale/' \
+  gettext-runtime/intl/localename.c gettext-tools/gnulib-lib/localename.c &&
+sed -i 's%LIBS = @LIBS@%LIBS = @LIBS@ ../libgrep/libgrep.a%' \
+  gettext-tools/src/Makefile.in gettext-tools/tests/Makefile.in &&
+
+./configure --prefix=/usr --docdir=/usr/share/doc/gettext &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/gmp.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Doesn't work with uClibc++ yet.
+# [ ! -z "$(which c++)" ] && X="--enable-cxx"
+
+./configure --prefix=/usr $X --enable-mpbsd &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check 2>&1 | tee gmp-check-log
+  awk '/tests passed/{total+=$2} ; END{print total}' gmp-check-log
+fi
+
+make install || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  mkdir -p /usr/share/doc/gmp-5.0.1 &&
+  cp doc/isa_abi_headache doc/connfiguration doc/*.html \
+    /usr/share/doc/gmp-5.0.1
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/grep.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/groff.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+PAGE=letter ./configure --prefix=/usr &&
+make -j $CPUS &&
+make docdir=/usr/share/doc/groff install &&
+ln -s eqn /usr/bin/geqn &&
+ln -s tbl /usr/bin/gtbl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/gzip.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/iana-etc.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/inetutils.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+./configure --prefix=/usr --libexecdir=/usr/sbin --localstatedir=/var \
+  --disable-logger --disable-syslogd --disable-whois --disable-servers &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/iproute2.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# arpd needs berkeley DB, switch it off.
+sed -i '/^TARGETS/s@arpd@@g' misc/Makefile &&
+
+# bugfix, why this isn't a patch I have no idea.
+sed -i '1289i\\tfilter.cloned = 2;' ip/iproute.c &&
+
+# Don't be confused by symlinks
+sed -i 's/ find / find -L /g' Makefile &&
+
+make DESTDIR= -j $CPUS &&
+make DESTDIR= SBINDIR=/sbin MANDIR=/usr/share/man \
+  DOCDIR=/usr/share/doc/iproute2 install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/kbd.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+./configure --prefix=/usr --datadir=/lib/kbd --disable-nls &&
+make -j $CPUS &&
+make install || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  mkdir /usr/share/doc/kbd &&
+  cp -R doc/* /usr/share/doc/kbd
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/less.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./configure --prefix=/usr --sysconfdir=/etc &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/libtool.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/m4.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+sed -i -e '/"m4.h"/a#include <sys/stat.h>' src/path.c &&
+./configure --prefix=/usr &&
+make || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/make.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/man-db.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+./configure --prefix=/usr --libexecdir=/usr/lib \
+  --docdir=/usr/share/doc/man-db --sysconfdir=/etc --disable-setuid &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/module-init-tools.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# Read-only filesystem, can't modify in place.
+
+rm -f modprobe.d.5 &&
+echo '.so man5/modprobe.conf.5' > modprobe.d.5 || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  ./configure &&
+  make check &&
+  ./tests/runtests &&
+  make clean || exit 1
+fi
+
+./configure --prefix=/ --enable-zlib-dynamic --mandir=/usr/share/man &&
+make -j $CPUS &&
+make INSTALL=install install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/mpc.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/mpfr.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# TODO: The --enable-thread-safe here requires TLS
+
+./configure --prefix=/usr --docdir=/usr/share/doc/mpfr-3.0.0 &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  make html &&
+  make install-html
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/ncurses.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+[ ! -z "$(which c++)" ] && X="--without-cxx --without-cxx-binding"
+
+./configure --prefix=/usr --with-shared --without-debug --enable-widec $X &&
+make -j $CPUS &&
+make install || exit 1
+
+# Make sure various packages can find ncurses no matter what weird names
+# they look for.
+
+for lib in ncurses form panel menu
+do
+    ln -sf lib${lib}w.so /usr/lib/lib${lib}.so &&
+    ln -sf lib${lib}w.a /usr/lib/lib${lib}.a || exit 1
+done
+ln -sf libncursesw.so libcursesw.so &&
+ln -sf libncurses.so /usr/lib/libcurses.so &&
+ln -sf libncursesw.a /usr/lib/libcursesw.a &&
+ln -sf libncurses.a /usr/lib/libcurses.a || exit 1
+
+if [ ! -z "$(which c++)" ]
+then
+  ln -sf libncurses++w.a /usr/lib/libncurses++.a || exit 1
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/patch.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/perl.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+if [ ! -e /etc/hosts ]
+then
+  echo "127.0.0.1 localhost $(hostname)" > /etc/hosts || exit 1
+fi
+
+# Configure hardwires on the "stack protector", which doesn't work in this
+# context.  Rip out all mention of it.
+
+sed -i 's/-fstack-protector//' Configure &&
+
+# Make Perl use the system zlib instead of a built-in copy.
+
+sed -i -e "s|BUILD_ZLIB\s*= True|BUILD_ZLIB = False|"           \
+       -e "s|INCLUDE\s*= ./zlib-src|INCLUDE    = /usr/include|" \
+       -e "s|LIB\s*= ./zlib-src|LIB        = /usr/lib|"         \
+    cpan/Compress-Raw-Zlib/config.in &&
+./Configure -des -Dprefix=/usr -Dvendorprefix=/usr \
+  -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 \
+  -Dpager="/usr/bin/less -is" -Duseshrplib -Dusenm=n &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make test || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/pkg-config.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+sed -i -e 's/XT])dnl/XT])[]dnl/' \
+       -e 's/\.])dnl/\.])[]dnl/' pkg.m4 &&
+./configure --prefix=/usr &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/procps.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+sed -i -e 's@\*/module.mk@proc/module.mk ps/module.mk@' Makefile &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/psmisc.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Another bugfix that you'd think would be a patch, but no...
+
+sed -i 's@#include<sys\/usr.h>@#include <bits\/types.h>\&@' configure &&
+
+./configure --prefix=/usr --disable-nls &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/readline.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+sed -i '/MV.*old/d' Makefile.in &&
+sed -i '/{OLDSUFF}/c:' support/shlib-install &&
+./configure --prefix=/usr --libdir=/lib &&
+make -j $CPUS SHLIB_LIBS=-lncurses &&
+make install  || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  mkdir /usr/share/doc/readline &&
+  install -m644 doc/*.ps doc/*.pdf doc/*.html doc/*.dvi \
+    /usr/share/doc/readline || exit 1
+fi
+
+cat > /etc/inputrc << "EOF"
+# Allow the command prompt to wrap to the next line
+set horizontal-scroll-mode Off
+
+# Enable 8bit input
+set meta-flag On
+set input-meta On
+
+# Turns off 8th bit stripping
+set convert-meta Off
+
+# Keep the 8th bit for display
+set output-meta On
+
+# none, visible or audible
+set bell-style none
+
+# All of the following map the escape sequence of the value
+# contained in the 1st argument to the readline specific functions
+"\eOd": backward-word
+"\eOc": forward-word
+
+# for linux console
+"\e[1~": beginning-of-line
+"\e[4~": end-of-line
+"\e[5~": beginning-of-history
+"\e[6~": end-of-history
+"\e[3~": delete-char
+"\e[2~": quoted-insert
+
+# for xterm
+"\eOH": beginning-of-line
+"\eOF": end-of-line
+
+# for Konsole
+"\e[H": beginning-of-line
+"\e[F": end-of-line
+EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/sed.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+./configure --prefix=/usr --bindir=/bin --htmldir=/usr/share/doc/sed &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  make html &&
+  make -C doc install-html || exit 1
+fi
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/setup.nosrc	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+set +h
+
+# Basic setup.  Create directories not in the aboriginal base system.
+
+cd / &&
+
+# The first package (zlib) dies with hush.
+
+ln -sf bash /bin/sh &&
+
+mkdir -p boot etc/opt opt media/floppy media/cdrom srv var/tmp &&
+chmod 0750 root &&
+chmod 1777 tmp var/tmp &&
+rm -rf /usr/local &&
+ln -sf . usr/local &&
+cd usr/share &&
+mkdir -p doc info locale man misc terminfo zoneinfo &&
+cd ../.. &&
+ln -sf share/man share/doc share/info usr &&
+cd var &&
+mkdir -p lib lock log mail run spool opt cache local &&
+cd lib &&
+mkdir -p misc locate &&
+cd ../.. &&
+
+cat > etc/passwd << "EOF" &&
+root:x:0:0:root:/root:/bin/bash
+bin:x:1:1:bin:/dev/null:/bin/false
+nobody:x:99:99:Unprivileged User:/dev/null:/bin/false
+guest:x:500:500:guest:/home/guest:/bin/sh
+EOF
+
+cat > etc/group << "EOF" &&
+root:x:0:
+bin:x:1:
+sys:x:2:
+kmem:x:3:
+tty:x:4:
+tape:x:5:
+daemon:x:6:
+floppy:x:7:
+disk:x:8:
+lp:x:9:
+dialout:x:10:
+audio:x:11:
+video:x:12:
+utmp:x:13:
+usb:x:14:
+cdrom:x:15:
+mail:x:34:
+nogroup:x:99:
+guest:x:500:
+EOF
+
+touch /var/run/utmp /var/log/btmp /var/log/lastlog /var/log/wtmp &&
+chgrp -v utmp /var/run/utmp /var/log/lastlog &&
+chmod -v 664 /var/run/utmp /var/log/lastlog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/shadow.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Disable the groups program, coreutils provides a better one.
+
+sed -i 's/groups$(EXEEXT) //' src/Makefile.in &&
+find man -name Makefile.in -exec sed -i 's/groups\.1 / /' {} \; &&
+
+# Disable Chinese/Korean man pages Man-DB can't format properly.
+
+sed -i -e 's/ ko//' -e 's/ zh_CN zh_TW//' man/Makefile.in &&
+
+# Change default password encryption to something that _doesn't_ limit
+# password lengths to 8 characters, and change the user mbox location to
+# the "new" one everybody started using back in the 1990's.
+
+sed -i -e 's@#ENCRYPT_METHOD DES@ENCRYPT_METHOD MD5@' \
+       -e 's@/var/spool/mail@/var/mail@' etc/login.defs &&
+       
+./configure --sysconfdir=/etc --without-nscd &&
+make -j $CPUS &&
+make install &&
+pwconv &&
+grpconv
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/sysklogd.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+make -j $CPUS &&
+make BINDIR=/sbin install &&
+cat > /etc/syslog.conf << "EOF"
+auth,authpriv.* -/var/log/auth.log
+*.*;auth,authpriv.none -/var/log/sys.log
+daemon.* -/var/log/daemon.log
+kern.* -/var/log/kern.log
+mail.* -/var/log/mail.log
+user.* -/var/log/user.log
+*.emerg *
+EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/sysvinit.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# Use the util-linux-ng "wall" command
+
+sed -i -e 's/utmpdump wall/utmpdump/' \
+       -e 's/mountpoint.1 wall.1/mountpoint.1/' src/Makefile &&
+make -C src -j $CPUS &&
+make -C src install &&
+cat > /etc/inittab << "EOF"
+id:3:initdefault:
+
+si::sysinit:/etc/rc.d/init.d/rc sysinit
+
+l0:0:wait:/etc/rc.d/init.d/rc 0
+l1:S1:wait:/etc/rc.d/init.d/rc 1
+l2:2:wait:/etc/rc.d/init.d/rc 2
+l3:3:wait:/etc/rc.d/init.d/rc 3
+l4:4:wait:/etc/rc.d/init.d/rc 4
+l5:5:wait:/etc/rc.d/init.d/rc 5
+l6:6:wait:/etc/rc.d/init.d/rc 6
+
+ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
+
+su:S016:once:/sbin/sulogin
+
+1:2345:respawn:/sbin/agetty tty1 9600
+2:2345:respawn:/sbin/agetty tty2 9600
+3:2345:respawn:/sbin/agetty tty3 9600
+4:2345:respawn:/sbin/agetty tty4 9600
+5:2345:respawn:/sbin/agetty tty5 9600
+6:2345:respawn:/sbin/agetty tty6 9600
+EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/tar.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+sed -i /SIGPIPE/d src/tar.c &&
+./configure --prefix=/usr --bindir=/bin --libexecdir=/usr/sbin &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  sed -i '35 i AT_UNPRIVILEGED_PREREQ' tests/remfiles01.at &&
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/texinfo.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,1 @@
+generic-check.sh
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/udev.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+mkdir -p /lib/udev/devices || exit 1
+if [ ! -e /lib/udev/devices/null ]
+then
+  mknod -m0666 /lib/udev/devices/null c 1 3 || exit 1
+fi
+sed -i 's/ libudev-install-move-hook//' Makefile.in &&
+install -d /lib/firmware /lib/udev/devices/pts /lib/udev/devices/shm &&
+./configure --sysconfdir=/etc --sbindir=/sbin \
+  --with-rootlibdir=/lib --libexecdir=/lib/udev --disable-extras \
+  --disable-introspection &&
+make -j $CPUS || exit 1
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+make install &&
+rmdir /usr/share/doc/udev &&
+cd /mnt/packages/udev-config &&
+make -j $CPUS install || exit 1
+
+if [ ! -z "$DOCS" ]
+then
+  make install-doc
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/util-linux-ng.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+sed -e 's@etc/adjtime@var/lib/hwclock/adjtime@g' \
+  -i $(grep -rl '/etc/adjtime' .) &&
+mkdir -p /var/lib/hwclock &&
+./configure --enable-arch --enable-partx --enable-write --disable-nls &&
+make -j $CPUS &&
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/vim.nolink	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+sed -i '$a #define SYS_VIMRC_FILE "/etc/vimrc"' src/feature.h &&
+
+./configure --prefix=/usr --enable-multibyte &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make test || exit 1
+fi
+
+make install &&
+ln -sf vim /usr/bin/vi || exit 1
+for i in /usr/share/man/man1/vim.1 /usr/share/man/*/man1/vim.1
+do
+  ln -sf vim.1 $(dirname $i)/vi.1 || exit 1
+done
+
+cat > /etc/vimrc << "EOF"
+set nocompatible
+set backspace=2
+syntax on
+if (&term == "iterm") || (&term == "putty")
+  set background=dark
+endif
+EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/build/zlib.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# zlib 1.2.5 accidentally shipped a generated file, which it then tries to
+# overwrite in-place.  This doesn't work so well on a read only filesystem.
+
+rm -f Makefile &&
+
+# Fix another bug.
+
+sed -i 's/ifdef _LARGEFILE64_SOURCE/ifndef _LARGEFILE64_SOURCE/' zlib.h &&
+
+# Otherwise, standard build
+
+./configure --prefix=/usr &&
+make -j $CPUS || exit 1
+
+if [ ! -z "$CHECK" ]
+then
+  make check || exit 1
+fi
+
+make install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/lfs-bootstrap/mnt/package-list	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,49 @@
+setup
+zlib
+m4		#development
+gmp		#development
+mpfr		#development
+mpc		#development
+sed		#busybox
+pkg-config	#development
+ncurses
+#gettext		#development internationalization
+gettext-stub	#development internationalization
+util-linux-ng
+e2fsprogs	#busybox
+coreutils	#busybox
+gawk		#busybox
+iana-etc
+bison		#development
+procps		#busybox
+grep		#busybox
+readline	#development
+bash		#development
+libtool		#development pointless
+gdbm
+inetutils	#busybox?
+perl
+autoconf	#development
+automake	#development
+bzip2		#busybox
+diffutils	#busybox
+file
+findutils	#busybox
+flex		#development
+groff
+gzip		#busybox
+iproute2	#busybox?
+kbd		#busybox?
+less		#busybox
+make		#development
+man-db
+module-init-tools #busybox
+patch		#busybox
+psmisc		#busybox?
+shadow		#busybox
+sysklogd	#busybox
+sysvinit	#busybox
+tar		#busybox
+texinfo		#development pointless
+udev		#busybox
+vim
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/static-tools/build.sh	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,94 @@
+#!/bin/bash
+
+# Download all the source tarballs we haven't got up-to-date copies of.
+
+# The tarballs are downloaded into the "packages" directory, which is
+# created as needed.
+
+source sources/include.sh || exit 1
+
+PATCHDIR="$SOURCES/control-images/static-tools-patches"
+SRCDIR="$SRCDIR/static-tools" && mkdir -p "$SRCDIR" || dienow
+WORK="$BUILD/control-images/static-tools" && blank_tempdir "$WORK"
+SRCTREE="$WORK"
+
+EXTRACT_ALL=1
+
+echo "=== Download source code."
+
+# Note: set SHA1= blank to skip checksum validation.
+
+URL=http://downloads.sf.net/sourceforge/strace/strace-4.5.19.tar.bz2 \
+SHA1=5554c2fd8ffae5c1e2b289b2024aa85a0889c989 \
+maybe_fork download || dienow
+
+URL=http://zlib.net/zlib-1.2.5.tar.bz2 \
+SHA1=543fa9abff0442edca308772d6cef85557677e02 \
+maybe_fork "download || dienow"
+
+URL=http://matt.ucc.asn.au/dropbear/releases/dropbear-0.53.1.tar.bz2 \
+SHA1= \
+maybe_fork download || dienow
+
+URL=http://kernel.org/pub/software/utils/pciutils/pciutils-3.1.7.tar.bz2 \
+SHA1= \
+maybe_fork download || dienow
+
+echo === Got all source.
+
+cleanup_oldfiles
+
+cat > "$WORK"/init << 'EOF' || dienow
+#!/bin/bash
+
+upload_result()
+{
+  ftpput $FTP_SERVER -P $FTP_PORT "$1-$HOST" "$1"
+}
+
+echo Started second stage init
+
+echo === Native build static zlib
+
+cp -sfR /mnt/zlib zlib &&
+cd zlib &&
+# 
+rm -f Makefile &&
+./configure &&
+make -j $CPUS &&
+cd .. || exit 1
+
+echo === $HOST Native build static dropbear
+
+cp -sfR /mnt/dropbear dropbear &&
+cd dropbear &&
+CFLAGS="-I ../zlib -Os" LDFLAGS="--static -L ../zlib" ./configure &&
+sed -i 's@/usr/bin/dbclient@ssh@' options.h &&
+make -j $CPUS PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" MULTI=1 SCPPROGRESS=1 &&
+strip dropbearmulti &&
+upload_result dropbearmulti &&
+cd .. &&
+rm -rf dropbear || exit 1
+
+echo === $HOST native build static strace
+
+cp -sfR /mnt/strace strace &&
+cd strace &&
+CFLAGS="--static -Os" ./configure &&
+make -j $CPUS &&
+strip strace &&
+upload_result strace &&
+cd .. &&
+rm -rf strace || dienow
+
+echo === $HOST native build rsync
+
+sync
+
+EOF
+
+chmod +x "$WORK"/init || dienow
+
+cd "$TOP"
+
+mksquashfs "$WORK" "$WORK.hdc" -noappend -all-root
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/static-tools/patches/dropbear-fixstatic.patch	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,37 @@
+#
+# old_revision [c7f6c45c46a2f8e2394756c68ae825d6e4dc7489]
+#
+# patch "Makefile.in"
+#  from [ea21753734b01f01ea1062923f4cb5eac65eadec]
+#    to [3dcc9b69742a8a4f59ea9f22b6d80bad2c761117]
+#
+============================================================
+--- Makefile.in	ea21753734b01f01ea1062923f4cb5eac65eadec
++++ Makefile.in	3dcc9b69742a8a4f59ea9f22b6d80bad2c761117
+@@ -28,7 +28,7 @@ COMMONOBJS=dbutil.o buffer.o \
+ 		queue.o \
+ 		atomicio.o compat.o  fake-rfc2553.o 
+ 
+-SVROBJS=@CRYPTLIB@ svr-kex.o svr-algo.o svr-auth.o sshpty.o \
++SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \
+ 		svr-authpasswd.o svr-authpubkey.o svr-authpubkeyoptions.o svr-session.o svr-service.o \
+ 		svr-chansession.o svr-runopts.o svr-agentfwd.o svr-main.o svr-x11fwd.o\
+ 		svr-tcpfwd.o svr-authpam.o
+@@ -56,7 +56,7 @@ HEADERS=options.h dbutil.h session.h pac
+ 		loginrec.h atomicio.h x11fwd.h agentfwd.h tcpfwd.h compat.h \
+ 		listener.h fake-rfc2553.h
+ 
+-dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS) 
++dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS) @CRYPTLIB@ 
+ dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS)
+ dropbearkeyobjs=$(COMMONOBJS) $(KEYOBJS)
+ dropbearconvertobjs=$(COMMONOBJS) $(CONVERTOBJS)
+@@ -167,7 +167,7 @@ ifeq ($(MULTI),1)
+ # multi-binary compilation.
+ MULTIOBJS=
+ ifeq ($(MULTI),1)
+-	MULTIOBJS=dbmulti.o $(sort $(foreach prog, $(PROGRAMS), $($(prog)objs)))
++	MULTIOBJS=dbmulti.o $(sort $(foreach prog, $(PROGRAMS), $($(prog)objs))) @CRYPTLIB@ 
+ 	CFLAGS+=$(addprefix -DDBMULTI_, $(PROGRAMS)) -DDROPBEAR_MULTI
+ endif
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/static-tools/patches/strace-arm-eabi.patch	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,11 @@
+--- a/linux/arm/syscallent.h
++++ b/linux/arm/syscallent.h
+@@ -453,7 +453,7 @@
+ 	{ 5,	TN,	sys_recvmsg,		"recvmsg"	}, /* 417 */
+ 	{ 4,	TN,	sys_accept4,		"accept4"	}, /* 418 */
+ 
+-#if SYS_ipc_subcall != 419
++#if defined(SYS_ipc_subcall) && (SYS_ipc_subcall != 419)
+  #error fix me
+ #endif
+ 	{ 4,	0,	printargs,		"ipc_subcall"	}, /* 419 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/images/static-tools/patches/strace-fixnet.patch	Sun Jul 03 17:23:26 2011 -0500
@@ -0,0 +1,24 @@
+diff -ru strace/configure strace.new/configure
+--- strace/configure	2009-10-21 12:41:11.000000000 -0500
++++ strace.new/configure	2010-02-05 01:30:15.000000000 -0600
+@@ -5880,7 +5880,7 @@
+ do :
+   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include <stddef.h>
+-#include <linux/socket.h>
++#include <sys/socket.h>
+ "
+ eval as_val=\$$as_ac_Header
+    if test "x$as_val" = x""yes; then :
+diff -ru strace/configure.ac strace.new/configure.ac
+--- strace/configure.ac	2009-10-12 14:54:43.000000000 -0500
++++ strace.new/configure.ac	2010-02-05 01:30:35.000000000 -0600
+@@ -258,7 +258,7 @@
+ ], [], [])
+ AC_CHECK_HEADERS([linux/icmp.h linux/in6.h linux/netlink.h linux/if_packet.h],
+                  [], [], [#include <stddef.h>
+-#include <linux/socket.h>])
++#include <sys/socket.h>])
+ AC_CHECK_HEADERS([asm/sigcontext.h], [], [], [#include <signal.h>])
+ AC_CHECK_TYPES([struct sigcontext_struct,
+ 		struct sigcontext],,, [#include <signal.h>])