#!/bin/sh
#
# kboot - Kboot initialization and command-line interface
#
# Written 2005, 2006 by Werner Almesberger
#

if [ "x$0" = x/init ]; then
    __sysinit=true
else
    __sysinit=false
fi

###############################################################################
#
# Get us a controlling tty
#

if [ "x$1" = "x--dry-run" ]; then
    __dry_run=true
    shift
else
    __dry_run=false

    # Loop, so a simple "exit" won't make us panic

    while $__sysinit && [ -z "$__HAVE_CTTY" ]; do
	__HAVE_CTTY=true /sbin/getctty /dev/tty1 /init "$@"
    done
fi


###############################################################################
#
# System setup and internal initialization
#

if $__sysinit; then
    mount -t proc none /proc
    mount -t sysfs none /sys
    /sbin/udevstart
fi

__verbose=false
restricted=false
mount_rw=false
__mount_ro="-o ro"

__RESERVED="authorized_keys default delay initrd message mount_rw restricted"
__RESERVED="$__RESERVED root timeout"
__COMMON_ALL=/sbin/common-all

__FEATURES=/etc/kboot-features
__CONFIG=/etc/kboot.conf
__MESSAGE=/etc/message
__FSTAB=/etc/fstab
__HOSTS=/etc/hosts
__HISTORY=/tmp/.history
__KEYMAP=/etc/default.bkeymap

__MNT_TMP=/mnt/tmp
__MNT_ROOT=/mnt/root

#
# If all or some of the booted file system is mounted, we look for commands
# also there.
#

PATH=/sbin:/bin:/usr/sbin:/usr/bin
PATH=$PATH:$__MNT_ROOT/sbin:$__MNT_ROOT/bin
PATH=$PATH:$__MNT_ROOT/usr/sbin:$__MNT_ROOT/usr/bin
PATH=$PATH:$__MNT_ROOT/usr/local/sbin:$__MNT_ROOT/usr/local/bin

PS1='\w# '	# if user invokes a shell

export PATH PS1

trap 'echo "*** Emergency shell ***"; /bin/sh' 2

. $__COMMON_ALL


###############################################################################
#
# Read the initial configuration
#

__kboot=",$kboot,"	# boot parameters
unset kboot

. $__FEATURES


###############################################################################
#
# Network setup
#

if $__sysinit && ! $__dry_run && $__inetworking; then
    ifconfig lo 127.0.0.1 up
    ifconfig >/dev/urandom
    if $__use_dhcp; then
	udhcpc -n -s /sbin/udhcpc.script && __static_ip=false
    fi
    if $__static_ip; then
	ifconfig eth0 $__ipv4_addr netmask $__ipv4_netmask up
	[ ! -z "$__ipv4_default" ] && route add default gw $__ipv4_default
	>/etc/resolv.conf
	[ ! -z "$__ipv4_nameserver" ] && \
	  echo "nameserver $__ipv4_nameserver" >>/etc/resolv.conf
	[ ! -z "$__dns_domain" ] && \
	  echo "domain $__dns_domain" >>/etc/resolv.conf
    fi
else
    if $__dry_run && $__use_dhcp; then
	echo "Dry-running udhcpc" 1>&2
	udhcpc -n
    fi
fi


###############################################################################
#
# Read fstab from stdin
#

__partition_by_name()
{
    local name l

    name="$1"

    while read l; do
	set -f
	set -- $l
	set +f

	[ -b "/dev/$4" ] && fsbyname "$name" "/dev/$4" 2>/dev/null && return
    done

    return 1
}


__read_fstab()
{
    local l dev name opts dir

    while read l; do
	l="${l%%#*}"
	set -f
	set -- $l
	set +f

	if [ "${2#/}" != "$2" ]; then
	    dev="$1"
	    name=
	    if [ "x${dev#LABEL=}" != "x$dev" ]; then
		name="-l${dev#LABEL=}"
	    fi
	    if [ "x${dev#UUID=}" != "x$dev" ]; then
		name="-u${dev#UUID=}"
	    fi
	    if [ ! -z "$name" ]; then
		if ! dev="`__partition_by_name "$name" </proc/partitions`"
		  then
		    continue
		fi
	    fi
	    if [ -z "$4" -o "$4" = defaults ]; then
		opts=
	    else
		opts="-o $4"
	    fi
	    if [ "x$2" = x/ ]; then
		dir="$__MNT_ROOT"
	    else
		dir="$__MNT_ROOT$2"
	    fi
	    __var_set_key __fstab_type "$dir" "$3"
	    __var_set_key __fstab_opts "$dir" "$opts"
	    __var_set_key __fstab_dev "$dir" "$dev"
	fi
    done
}


###############################################################################
#
# Try to mount all directories in a given path
#

__mount_path()
{
    local orig tail pos next

    orig="$1"
    if [ "${2#/}" = "$2" ]; then
	tail="$PWD/$2"
    else
	tail="$2"
    fi
    pos=
    while true; do
	#
	# Skip directories we already know about
	#
	if [ -z "`__var_get_key __known "$pos"`" ]; then
	    #
	    # Try to mount the current directory
	    #
	    if [ "x${root#/dev/}" != "x$root" -a "x$pos" = "x$__MNT_ROOT" ]; \
	      then
		if $__verbose; then
		    echo "Mounting -t auto $root $pos" 1>&2
		else
		    echo -ne 'Mounting ...\r' 1>&2
		fi
		if ! mount $__mount_ro -t auto "$root" "$pos"; then
		    return 1
		fi
		echo -ne '            \r' 1>&2
		__var_set_key __known "$pos" x
	    else
		local type

		type="`__var_get_key __fstab_type "$pos"`"
		if [ ! -z "$type" ]; then
		    local action

		    action="-t $type `__var_get_key __fstab_opts "$pos"`"
		    action="$action `__var_get_key __fstab_dev "$pos"`"
		    if [ "$type" = nfs ]; then
			action="-o nolock $action"
		    fi
		    if $__verbose; then
			echo "Mounting $action $pos" 1>&2
		    else
			echo -ne 'Mounting ...\r' 1>&2
		    fi
		    if ! mount $__mount_ro $action "$pos"; then
			return 1
		    fi
		    echo -ne '            \r' 1>&2
		    __var_set_key __known "$pos" x
		fi
	    fi
	fi

	[ -z "$tail" ] && break

	next="${tail%%/*}"
	if [ "x${tail#*/*}" = "x$tail" ]; then
	    tail=
	else
	    tail="${tail#*/}"
	fi
	if [ -z "$next" ]; then
	    continue
	fi

	#
	# Next path name component exists and is a directory -> proceed
	#
	if [ -d "$pos/$next" ]; then
	    pos="$pos/$next"
	    continue
	fi

	#
	# Next path name component doesn't exist or isn't a directory
	#
	if [ -e "$pos/$next" ]; then
	    echo "$orig: invalid path" 1>&2
	else
	    echo "$orig: not found" 1>&2
        fi
	return 1
    done
}


###############################################################################
#
# Validity checking of configuration variables
#

__check_boolean()
{
    local value

    value="`__var_get $1`"
    if [ "x$value" != xtrue -a "x$value" != xfalse ]; then
	echo "invalid setting \"$1=$value\", defaulting to \"$2\"" 1>&2
	__var_set $1 $2
    fi
}


__check_numeric()
{
    local value tmp

    value="`__var_get $1`"
    [ -z "$value" ] && return

    tmp="$value"
    while [ "x${tmp#[0-9]}" != "x$tmp" ]; do
	tmp="${tmp#[0-9]}"
    done
    if [ ! -z "$tmp" ]; then
	echo "invalid setting \"$1=$value\", defaulting to \"$2\"" 1>&2
	__var_set $1 "$2"
    fi
}


###############################################################################
#
# Read configuration files
#

if [ "x${__kboot##*,local,*}" = x ]; then
    __booted_config=false
fi

if $___sysinit && $__booted_config; then
    if [ -r $__FSTAB ]; then
	__read_fstab <$__FSTAB
    fi
    if __mount_path /etc $__MNT_ROOT/etc 2>/dev/null; then
	[ -r "$__MNT_ROOT/etc/kboot.conf" ] &&
	    cp "$__MNT_ROOT/etc/kboot.conf" $__CONFIG
	[ -r "$__MNT_ROOT/etc/fstab" ] &&
	    cp "$__MNT_ROOT/etc/fstab" $__FSTAB
	[ -r "$__MNT_ROOT/etc/hosts" ] &&
	    cp "$__MNT_ROOT/etc/hosts" $__HOSTS
    fi
fi

[ -r $__CONFIG ] && . $__CONFIG

if [ -r $__FSTAB ]; then
    # overwrite old entries
    __read_fstab <$__FSTAB
fi

__check_boolean restricted false
__check_boolean mount_rw false
__check_numeric delay ""
__check_numeric timeout ""

if $__sysinit && $mount_rw; then
    __mount_ro=
    #
    # the next step may fail, e.g. if we haven't mounted anything, in which
    # case we don't care about seeing some stray error message
    #
    mount -o remount,rw $__MNT_ROOT >/dev/null 2>&1
fi


###############################################################################
#
# Mount a file system by device; prints the mount point on stdout
#


__mount_dev()
{
    local id dir

    id="`echo "$1" | md5sum`"
    id=${id%% *}
    dir="$__MNT_TMP/$id"
    if [ ! -d "$dir" ]; then
	mkdir "$dir" || return
	echo -ne 'Mounting ...\r' 1>&2
	if ! mount -t auto $__mount_ro "$1" "$dir"; then
	    rmdir "$dir"
	    return 1
	fi
	echo -ne '            \r' 1>&2
    fi
    echo "$dir"
    __var_set_key __mnt_map $id "$1:"
}


###############################################################################
#
# Mount an NFS file system by path; prints the mount point on stdout
#


# @@@ merge with __mount_dev

__mount_nfs()
{
    local id dir

    id="`echo "$1" | md5sum`"
    id=${id%% *}
    dir="$__MNT_TMP/${id%% *}"
    if [ ! -d "$dir" ]; then
	mkdir "$dir" || return
	echo -ne 'Mounting ...\r' 1>&2
	if ! mount -t nfs $__mount_ro -o nolock "$1" "$dir"; then
	    rmdir "$dir"
	    return 1
	fi
	echo -ne '            \r' 1>&2
    fi
    echo "$dir"
    __var_set_key __mnt_map $id "$1"
}


###############################################################################
#
# Load a file via wget to /tmp, then print the name of the temporary file
# to stdout.
#

__wget()
{
    local name

    name="`echo "$1" | md5sum`"
    name="/tmp/${name%% *}"
    wget -O $name "$1" >/dev/null 2>&1 && echo $name
}


###############################################################################
#
# Load a file via tftp to /tmp, then print the name of the temporary file
# to stdout.
#

__tftp()
{
    local name path host port

    name="`echo "$1" | md5sum`"
    name="/tmp/${name%% *}"
    path="${1#tftp://}"
    host="${path%%/*}"
    port="${host##*:}"
    host="${host%:*}"
    path="/${path#*/}"
    tftp -g -l $name -r "$path" "$host" "$port" && echo $name
}


###############################################################################
#
# Translate a path and automount all components. Prints the translated path on
# standard output.
#


__xlat_path()
{
    local path before after mount dir

    #
    # Make path absolute, rooted at kboot's /
    #

    path="$1"

    #
    # //path (absolute path in the kboot environment)
    #
    if [ "x${path#//}" != "x$path" ]; then
	: ; # do nothing
    #
    # /path (absolute path in the booted environment)
    #
    elif [ "x${path#/}" != "x$path" ]; then
	path="$__MNT_ROOT$path"
    #
    # path (relative path, wherever it may point)
    #
    else
	path="$PWD/${path#/}"
    fi

    #
    # Detect exact device or file name matches
    #

    #
    # absolute/relative path to device name or to file
    # 
    if [ -b "$path" -o -f "$path" ]; then
	echo "$path"
	return 0
    #
    # device name under /dev
    #
    elif [ -b "/dev/$1" ]; then
	echo "/dev/$1"
	return 0
    fi

    #
    # Handle device:, host:, and protocol:
    #

    if [ "x${1#?*:}" != "x$1" ]; then
	before="${1%%:*}"
	after="${1#*:}"

	#
	# /dev/path:path_on_device
	# /dev/path:/path_on_device
	#
	if [ -b "$before" ]; then
	    if $__verbose; then
		echo "Mounting $before (auto)" 1>&2
	    fi
	    if ! __mount_dev "$before" >/tmp/tmp; then
		return 1
	    fi
	    echo "`cat /tmp/tmp`/$after"
	    return 0
 	fi

	#
	# http:... or ftp:...
	#
	if [ "$before" = http -o "$before" = ftp ]; then
	    __wget "$1"
	    return
	#
	# tftp:...
	#
	elif [ "$before" = tftp ]; then
	    __tftp "$1"
	    return
        #
        # device_name:path_on_device
        # device_name:/path_on_device
        #
	elif [ -b "/dev/$before" ]; then
	    if $__verbose; then
		echo "Mounting /dev/$before (auto)" 1>&2
	    fi
	    if ! __mount_dev "/dev/$before" >/tmp/tmp; then
		return 1
	    fi
	    echo "`cat /tmp/tmp`/$after"
	    return 0
	#
	# host:/path
	#
	else
	    if [ -z "${1#*:}" ]; then
		echo "$1: invalid path" 1>&2
		return 1
	    fi
	    if ! $__nfs_client; then
		echo "NFS client support is not enabled" 1>&2
		return 1
	    fi
	    if $__verbose; then
		echo "Mounting ${1%/*} (NFS)" 1>&2
	    fi
	    if ! __mount_nfs "${1%/*}" >/tmp/tmp; then
		return 1
	    fi
	    echo "`cat /tmp/tmp`/${1##*/}"
	    return 0
	fi
    fi

    #
    # So it's either a plain and simple path name, or something beyond our
    # understanding
    #

    dir="${path%/*}"
    __mount_path "$1" "$dir" || return 1

    echo "$path"
}


###############################################################################
#
# Boot through kexec
#

__boot_kexec()
{
    local file args __initrd

    file="$1"
    shift
    args=
    __initrd="$initrd"
    while [ ! -z "$*" ]; do
	if [ "x${1#initrd=}" = "x$1" ]; then
	    args="$args $1"
	else
	    __initrd="${1#initrd=}"
	fi
	shift
    done
    if [ ! -z "$__initrd" ]; then
	if ! __xlat_path "$__initrd" >/tmp/tmp; then
	    echo "access to initrd $__initrd failed" 1>&2
	    return 1
	fi
	__initrd="--initrd=`cat /tmp/tmp`"
    fi
    if $__dry_run || $__verbose; then
	echo \
	  "kexec --command-line=\"root=$root$args\" $__initrd -f \"$file\"" \
	  1>&2
    fi
    if ! $__dry_run; then
	if [ -z "$__initrd" ]; then
	    kexec --command-line="root=$root$args" -f "$file"
	else
	    kexec --command-line="root=$root$args" "$__initrd" -f "$file"
	fi
    fi
}


###############################################################################
#
# Boot some other OS through the first-stage boot loader
#

__boot_other()
{
    echo "sorry, we don't support booting from $1 yet" 2>&1
}


###############################################################################
#
# Completion
#

#
# __completion contains the current completion
# __completions contains the completions, keyed with the name of the previous
#               completion
# __first_completion is the first completion
# __last_completion is the previous completion
#

__reset_completion()
{
    while [ ! -z "$__first_completion" ]; do
	local next

	next="`__var_get_key __completions "$__first_completion"`"
	__var_del_key __completions "$__first_completion"
	__first_completion="$next"
    done
    __first_completion=
    __last_completion=
    __completion=
}


#
# __add_completion new_completion
#

__add_completion()
{
    if [ -z "$__first_completion" ]; then
	__first_completion="$1"
	__completion="$1"
    else
	__var_set_key __completions "$__last_completion" "$1"
    fi
    __last_completion="$1"
}


__next_completion()
{
    __completion="`__var_get_key __completions "$__completion"`"
    if [ -z "$__completion" ]; then
	__completion="$__first_completion"
    fi
}


__have_completion()
{
    [ ! -z "$__first_completion" ]
}


#
# __complete_label prefix postfix
# (@@@ postfix is not yet implemented)
#


__complete_label()
{
    # use __ to avoid polluting label name space
    local __l __var __n

    if [ "x${1#*[^a-zA-Z0-9_]}" != "x$1" ]; then
	return
    fi
    set >/tmp/tmp
    while read __l; do
	__var="${__l%%=*}"
	if [ "x${__l#*=}" = "x$__l" -o \
	  "x${__var#[a-z]}" = "x$__var" ]; then
	    continue
	fi
	for __n in $__RESERVED; do
	    if [ "$__n" = "${__var%%=*}" ]; then
		continue 2
	    fi
	done
	if [ "x${__var##$1*}" != "x$__var" ]; then
	    __add_completion "$__var"
	fi
    done </tmp/tmp
    rm -f /tmp/tmp
}


#
# __complete_path prefix postfix
# (@@@ postfix is not yet implemented)
#


__complete_path()
{
    local dir old_pwd prefix n

    dir="${__path%/*}"
    __mount_path "$1" "$dir" || return
    old_pwd="$PWD"
    if [ ! -z "$dir" ] && ! cd "$dir" 2>/dev/null; then
	__add_completion "$1"
	return
    fi
    if [ "x${1%/*}" = "x$1" ]; then
	prefix=
    elif [ "x${1%:}" != "x$1" ]; then
	prefix="$1"
    else
	prefix="${1%/*}/"
    fi
    for n in "${__path##*/}"*; do
	if [ "x$n" != "x${__path##*/}"'*' ]; then
	    if [ -d "$n" ]; then
		__add_completion "$prefix$n"
	    else
		__add_completion "$prefix$n "
	    fi
	fi
    done
    cd "$old_pwd"
}


###############################################################################
#
# Update the SSH keys
#

if $__sysinit && $__ssh_server; then
    if $__booted_config; then
	[ -r "$__MNT_ROOT/etc/ssh/ssh_host_rsa_key" ] &&
	    dropbearconvert openssh dropbear \
	      "$__MNT_ROOT/etc/ssh/ssh_host_rsa_key" \
	      /etc/dropbear/dropbear_rsa_host_key
	[ -r "$__MNT_ROOT/etc/ssh/ssh_host_dsa_key" ] &&
	    dropbearconvert openssh dropbear \
	      "$__MNT_ROOT/etc/ssh/ssh_host_dsa_key" \
	      /etc/dropbear/dropbear_dss_host_key
	[ -r "$__MNT_ROOT/etc/dropbear/dropbear_rsa_host_key" ] &&
	    cp "$__MNT_ROOT/etc/dropbear/dropbear_rsa_host_key" /etc/dropbear/
	[ -r "$__MNT_ROOT/etc/dropbear/dropbear_dss_host_key" ] &&
	    cp "$__MNT_ROOT/etc/dropbear/dropbear_dss_host_key" /etc/dropbear/
    fi
    if [ ! -z "$authorized_keys" ]; then
	if __xlat_path "$authorized_keys" >/tmp/tmp; then
	    cp "`cat /tmp/tmp`" /.ssh/authorized_keys
	fi
    fi
fi

###############################################################################
#
# Start the dropbear sshd
#

if $__sysinit && $__ssh_server; then
    mount -t devpts none /dev/pts
    dropbear -j `$__dry_run && echo "" -p 2222`
fi

###############################################################################
#
# Keymap selection
#

if $__sysinit && [ -r $__KEYMAP ]; then
    loadkmap <$__KEYMAP
fi

###############################################################################
#
# Command input loop
#

if [ ! -z "$message" ] && __xlat_path "$message" >/tmp/tmp; then
    cat "`cat /tmp/tmp`"
elif [ -r $__MESSAGE ]; then
    cat $__MESSAGE
fi

trap - 2

>$__HISTORY
__delay=
__timeout=
if [ -z "$default" ]; then
    if [ ! -z "$delay" -o ! -z "$timeout" ]; then
	echo "Warning: ignoring timeout, because \"default\" is not set" 1>&2
    fi
else
    if $__sysyinit && [ ! -z "$delay" ]; then
	__delay="-d $delay"
    fi
    if [ ! -z "$timeout" ]; then
	__timeout="-t $timeout"
    fi
fi

__completion=
while true; do
    if [ "$PWD" = "$__MNT_ROOT" ]; then
	__cwd=/
    elif [ "${PWD#$__MNT_ROOT/}" != "$PWD" ]; then
	__cwd="/${PWD#$__MNT_ROOT/}"
    elif [ "${PWD#$__MNT_TMP/}" != "$PWD" ]; then
	__id="${PWD#$__MNT_TMP/}"
	if [ "x${__id##*/*}" = x ]; then
	    __tail="${__id#*/}"
	else
	    __tail=
	fi
	__id="${__id%%/*}"
	__id="`__var_get_key __mnt_map "$__id"`"
	if [ -z "$__id" ]; then
	    __cwd="/$PWD"
	else
	    if [ "x${__id%/}" = "x$__id" ]; then
		__tail="/$__tail"
	    fi
	    __cwd="$__id$__tail"
	fi
    else
	__cwd="/$PWD"
    fi
    if [ "$__cwd" = // ]; then
	__prompt="kboot: "
    else
	__prompt="kboot $__cwd: "
    fi
    echo -n "$__prompt"
    if \
      __l="`readline -w -f $__HISTORY $__delay $__timeout -m "<  >" \
      -i "$__completion"`"; then
	__delay=
	__complete=false
	case "$__l" in
	    ENTER\ *)
		__reset_completion
		__l="${__l#ENTER }"
		[ -z "$__l" ] && __l="$default";;
	    TAB\ *)
		while [ ! -z "$__prompt" ]; do  # sloooowww...
		    echo -ne '\b'
		    __prompt="${__prompt#?}"
		done
		__l="${__l#TAB }"
		__l="${__l%<  >}"  # @@@
		if [ ! -z "$__completion" -a \
		  "x${__l% }" = "x${__completion% }" ]; then
		    __next_completion
		    continue
		fi
		__reset_completion
		if [ "x${__l# }" != "x$__l" ]; then
		    continue  2 # no general file name completion yet
		fi
		__complete=true;;
	    INTR\ *)
		__reset_completion
		continue;;
	   EOF\ *)
		__reset_completion
		$__dry_run && exit
		__l="$default";;
	    *)	# TIMEOUT or ENTER with an empty line
		__reset_completion
		__l="$default";;
	esac
    else
	# trouble ...
	if ! $restricted; then
	    echo '*** readline failed - entering emergency shell ***' 1>&2
	    /bin/sh
	fi
	continue
    fi

    #
    # The next step is a little hairy ...
    #
    set -f
    set -- $__l
    set +f
    [ -z "$1" ] && ! $__complete && continue
    __cmd="$1"
    [ -z "$1" ] || shift

    ###########################################################################
    #
    # Handle assignments
    #

    if ! $__complete && [ "x${__cmd#*=*}" != "x$__cmd" ]; then
	eval "$__cmd" "$@"
	continue
    fi

    ###########################################################################
    #
    # Try to expand "label"
    #

    if ! $__complete && [ "x${__cmd#[a-z]}" != "x$__cmd" -a \
      "x${__cmd#*[^a-zA-Z0-9_]*}" = "x$__cmd" ]; then
	__len="`eval echo '$'\"{#$__cmd}\" 2>/dev/null`"
	if [ ! -z "$__len" -a "$__len" != 0 ]; then
	    __expand="`eval echo '$'$__cmd`"
	    if $__verbose; then
		echo "Expanding $__cmd -> $__expand"
	    fi
	    set $__expand "$@"
	    __cmd="$1"
	    shift
	elif $restricted; then
	    echo "$__cmd: not defined" 1>&2
	    continue
	fi
    fi

    ###########################################################################
    #
    # Canonicalize the path name (if that's what it is)
    #

    if ! __xlat_path "$__cmd" >/tmp/tmp; then
	continue
    fi
    __path="`cat /tmp/tmp`"

    ###########################################################################
    #
    # Handle command name completion
    #

    if $__complete; then
	__complete_label "$__cmd"
	if ! $restricted && [ ! -z "$__cmd" -o "$PWD" != / ]; then
	    __complete_path "$__cmd"
	fi
	__have_completion || __add_completion "$__cmd"
	continue
    fi

    ###########################################################################
    #
    # Exact match takes priority over anything else
    #

    #
    # path to device name
    # 
    if [ -b "$__path" ]; then
	__boot_other "$__path" "$@"
	continue
    #
    # path to kernel image (but not executable - we handle them later)
    #
    elif [ -f "$__path" ]; then
	__boot_kexec "$__path" "$@"
	# on failure, fall through
    fi

    ###########################################################################
    #
    # Special case: "cd"
    #

    if [ "x$__cmd" = xcd ]; then
	#
	# cd -> kboot root
	#
	if [ -z "$1" ]; then
	    cd /
	else
	    __path="${1%/}/"
	    if ! __xlat_path "$__path" >/tmp/tmp; then
		continue
	    fi
	    __path="`cat /tmp/tmp`"
	    __mount_path "$1" "$__path"
	    __path="${__path%/}"
	    cd "$__path"
	fi
	continue
    fi

    ###########################################################################
    #
    # Special case: "pwd"
    #

    if [ "x$__cmd" = xpwd ]; then
	echo "$__cwd"
	continue
    fi

    ###########################################################################
    #
    # Okay, it's either a path name or a shell command now. We'll first try the
    # path name hypothesis.
    #

    __dir="${__path%/*}"
    __mount_path "$__cmd" "$__dir" || continue

    if [ -d "$__path" ]; then
	echo "$__cmd: not a file" 2>&1
	continue
    elif [ -f "$__path" ]; then
	# maybe it's a kernel ?
	__boot_kexec "$__path" "$@"
	# if it's some kind of absolute path, try it now
	if [ "x${__cmd#/}" != "x$__cmd" ]; then
	    "$__path" "$@"
	    continue
	fi
	# anything else goes to the shell
    fi

    ###########################################################################
    #
    # Shell, do thy thing
    #

    [ "x$__cmd" = "x!" ] && continue	# ash doesn't like this

    # search PATH first

    if [ "x${__cmd#*/*}" = "x$__cmd" ]; then
	# recycle __path
	__path="$PATH"
	while [ ! -z "$__path" ]; do
	    if [ "x${__path#*:*}" = "x$__path" ]; then
		__dir="$__path"
		__path=
	    else
		__dir="${__path%%:*}"
		__path="${__path#*:}"
	    fi
	    if [ -x "$__dir/$__cmd" ]; then
		__cmd="$__dir/$__cmd"
		break
	    fi
	done
    fi

    if [ "x${__cmd#$__MNT_ROOT}" != "x$__cmd" ]; then
	chroot $__MNT_ROOT /bin/sh -c \
	  "cd ${PWD#$__MNT_ROOT} && ${__cmd#$__MNT_ROOT} $*"
    else
	for __n in "$@"; do
	    # not everything wants translation, so we just try and see what
	    # works
	    if __xlat_path "$__n" >/tmp/tmp 2>/dev/null; then
		if [ -e "`cat /tmp/tmp`" ]; then
		    __cmd="$__cmd `cat /tmp/tmp`"
		else
		    __cmd="$__cmd $__n"
		fi
	    else
		__cmd="$__cmd $__n"
	    fi
	done
	eval "$__cmd"
    fi

done
