#!/bin/sh set -eu # make sure we're root if [ "$(id -u)" != 0 ]; then sucmd="su -c" if command -v doas >/dev/null; then sucmd="doas" elif command -v sudo >/dev/null; then sucmd="sudo" fi exec $sucmd env HOME="$HOME" USERNAME="$(id -u -n)" "$0" "$@" fi # and make sure we're in a separate mount namespace if [ "$(readlink /proc/$$/ns/mnt | cut -d: -f2)" = "$(readlink /proc/1/ns/mnt | cut -d: -f2)" ]; then exec unshare -m "$0" "$@" fi bindpoints="/etc/resolv.conf" command="" user="$USERNAME" while getopts "be:u:c:" opt; do case $opt in 'b') bindpoints=" $bindpoints /var/cache/distfiles $HOME/aports $HOME/packages $HOME/.abuild " ;; 'e') bindpoints="$bindpoints $OPTARG" ;; 'u') user="$OPTARG" ;; 'c') command="$OPTARG" ;; *) echo "unknown $opt" ;; esac done shift $(( $OPTIND - 1 )) dest="$1" shift if [ ! -d "$dest" ]; then echo "no such directory: $dest" exit 1 fi if [ ! -x "$dest"/bin/sh ]; then echo "$dest does not contain executable /bin/sh" exit 1 fi mount -t proc proc "$dest"/proc mount -t sysfs sysfs "$dest"/sys mount -t tmpfs tmpfs "$dest"/tmp # some mini kernels don't have devtmpfs if grep -q devtmpfs /proc/filesystems; then mount -t devtmpfs devtmpfs "$dest"/dev else mount -t tmpfs tmpfs "$dest"/dev if [ -x "$dest"/sbin/mdev ]; then echo "devtmpfs not supported - running 'mdev -s' instead" chroot "$dest" /sbin/mdev -s else echo "devtmpfs not supported - devices need to be created manually" fi fi mount -t devpts devpts "$dest"/dev/pts mount -t tmpfs tmpfs "$dest"/dev/shm for bindpoint in $bindpoints; do if [ -f "$bindpoint" ]; then touch "$dest"/"$bindpoint" else mkdir -p "$dest"/"$bindpoint" fi mount --bind "$bindpoint" "$dest"/"$bindpoint" done # if running on chromeos, fixup symlink exec # https://goo.gl/8xICW6 # https://github.com/dnschneid/crouton/commit/5cb7ad05 if [ -e "/run/chrome" ]; then if mount -n -t securityfs -o nodev,noexec,nosuid securityfs /sys/kernel/security; then policies=/sys/kernel/security/chromiumos/inode_security_policies if [ -d "$policies" ]; then for policy in "$policies/allow_"*; do printf "$(realpath "$dest")" > "$policy" done fi umount /sys/kernel/security fi fi if [ "$command" ]; then exec chroot "$dest" su $user -c "$command" elif [ "$#" -gt 0 ]; then exec chroot "$dest" su $user -c "$*" else exec chroot "$dest" login -f $user fi