--- /dev/null
+#! /bin/bash
+
+# Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+## Expected env:
+# $VSERVER_DIR ... path to vserver-cfg dir
+# $VSERVER_NAME ... name of vserver
+
+declare -a NICE_CMD=()
+declare -a CHBIND_OPTS=()
+declare -a CAP_OPTS=()
+declare -a CHCONTEXT_FLAG_OPTS=()
+declare -a CHCONTEXT_OPTS=()
+declare -a CAPCHROOT_OPTS=()
+declare -a INTERFACES=()
+declare -a START_CMD=()
+
+SILENT_OPT=
+
+function _generateInterfaceList
+{
+ local vdir="$1"
+ local iface
+ local ip
+
+ for iface in "$VSERVER_DIR/interfaces/"*; do
+ test -d "$iface" || continue
+ test ! -e "$iface"/disabled || continue
+
+ read ip <"$iface"/ip || continue
+ INTERFACES=( "${INTERFACES[@]}" "$ip" )
+ done 2>/dev/null
+}
+
+function _generateChbindOptions
+{
+ local vdir="$1"
+ local i
+ local bcast=
+
+ local f=$vdir/interfaces/bcast
+ test ! -e "$f" || read bcast <"$f"
+
+ CHBIND_OPTS=( $SILENT_OPT ${bcast:+--bcast "$bcast"} )
+
+ for i in "${INTERFACES[@]}"; do
+ CHBIND_OPTS=( "${CHBIND_OPTS[@]}" --ip "$i" )
+ done
+}
+
+function _generateNiceCommand
+{
+ local vdir=$1
+ local nice
+
+ test -e "$vdir/nice" || return 0;
+ read nice <"$vdir"/nice
+
+ NICE_CMD=( $_NICE -$nice )
+}
+
+function _generateCapabilityOptions
+{
+ local vdir=$1
+ local cap
+
+ test -e "$vdir"/capabilities || return 0
+
+ CAP_OPTS=()
+ CAPCHROOT_OPTS=()
+
+ while read cap; do
+ case x"$cap" in
+ x|x#) ;;
+ !CAP_SYSCHROOT)
+ CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" )
+ CAPCHROOT_OPTS=( "${CAPCHROOT_OPTS[@]}" --nochroot )
+ ;;
+ *)
+ CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" );;
+ esac
+ done <"$vdir"/capabilities
+}
+
+function _generateFlagOptions
+{
+ local vdir=$1
+ local init_default=3
+
+ CHCONTEXT_FLAG_OPTS=()
+
+ ## TODO: get_initdefault
+ START_CMD=( /etc/rc.d/rc $init_default )
+ test ! -x "$vdir/etc/init.d/rc" || {
+ START_CMD=( /etc/init.d/rc $init_default )
+ }
+
+ test -e "$vdir"/flags || return 0
+
+ while read flag; do
+ case x"$flag" in
+ x|x#) ;;
+ dummy) ;;
+ minit|fakeinit)
+ CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" \
+ --disconnect --flag --fakeinit )
+ case "$flag" in
+ minit) START_CMD=( /sbin/minit-start );;
+ *) START_CMD=( /sbin/init );;
+ esac
+ ;;
+ *)
+ CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}"
+ --flag "$flag" )
+ ;;
+ esac
+ done <"$vdir"/flags
+}
+
+function _generateChcontextOptions
+{
+ local vdir=$1
+ local ctx hostname domainname
+ local cap_opts
+ local flag
+
+ {
+ read ctx <"$vdir"/context
+ read hostname <"$vdir"/hostname
+ read domainname <"$vdir"/domainname
+ } 2>/dev/null
+
+ _generateCapabilityOptions "$vdir"
+ _generateFlagOptions "$vdir"
+
+ CHCONTEXT_OPTS=( $SILENT_OPT \
+ "${CHCONTEXT_FLAG_OPTS[@]}" \
+ "${CAP_OPTS[@]}" \
+ --secure
+ ${ctx:+--ctx "$ctx"} \
+ ${hostname:+--hostname "$hostname"} \
+ ${domainname:+--domainname "$domainname"} )
+}
+
+
+function enableSingleInterface
+{
+ local iface=$1
+
+ local dev
+ local ip
+ local mask
+ local bcast
+ local name
+ local scope
+
+ read dev <"$iface"/dev || dev=$dev_default
+ read ip <"$iface"/ip || { echo $"Can not read ip for '$iface'" >&3; return 1; }
+ read prefix <"$iface"/prefix || prefix=$prefix_default
+ read mask <"$iface"/mask || mask=$mask_default
+ read bcast <"$iface"/bcast || bcast=$bcast_default
+ read name <"$iface"/name
+ read scope <"$iface"/scope
+
+ test ! -e "$iface"/only_ip || unset dev
+
+ if test "$dev"; then
+ test "$prefix" || {
+ $_MASK2PREFIX "$mask" || prefix=$?
+ test "$prefix" != 255
+ }
+
+ case "$dev" in
+ *.*)
+ test -d /proc/net/vlan || {
+ echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers"
+ return 1
+ }
+ test -f /proc/net/vlan || {
+ $_VCONFIG add ${dev/./ }
+ $_IP addr add 127.0.0.1/8 broadcast 127.255.255.255 dev "$dev"
+ $_IP link set "$dev" up
+ }
+ ;;
+ esac
+
+ $_IP addr add "$ip${prefix:+/$prefix}" ${bcast:-broadcast +}${bcast:+broadcast "$bcast"} \
+ ${name:+label "$dev:$name"} dev "$dev"
+ $_IP route add "$ip""${prefix:+/$prefix}" dev "$dev"
+ $_IP link set "$dev" up
+ fi 2>&3
+}
+
+function setInterfaceDefaults
+{
+ read dev_default <"$1"/dev
+ read mask_default <"$1"/mask
+ read prefix_default <"$1"/prefix
+ read bcast_default <"$1"/bcast
+
+ test -z "mask_default" -o "$prefix_default" || {
+ $_MASK2PREFIX "$mask_default" || prefix_default=$?
+ test "$prefix_default" != 255
+ }
+}
+
+function enableInterfaces
+{
+ local VSERVER_DIR=$1
+ local VSERVER_NAME=$2
+
+ local iface
+
+ local dev_default
+ local mask_default
+ local bcast_default
+ local prefix_default
+
+ declare -a all_ips
+
+ setInterfaceDefaults 3>&2 2>/dev/null
+
+ for iface in "$VSERVER_DIR/interfaces/"*; do
+ test -d "$iface" || continue
+ test ! -e "$iface"/disabled || continue
+
+ enableSingleInterface "$iface" 3>&2 2>/dev/null
+ done
+}
+
+
+
+
+
+function generateOptions
+{
+ _generateInterfaceList "$1"
+ _generateChbindOptions "$1"
+ _generateNiceCommand "$1"
+ _generateChcontextOptions "$1"
+}
+
+function mountVserver
+{
+ local cfgdir=$1
+ local vdir=$1/vdir
+ local src dst type opts aux
+ local mountopts
+
+ declare -a mountopts
+
+ test -e "$cfgdir"/fstab || return 0
+
+ cat "$cfgdir"/fstab | while read src dst type opts aux; do
+ test "$src" -a "$dst" -a "$type" -a "$opts" || continue
+
+ if test "$type" = "bind"; then
+ mountopts=( --bind )
+ else
+ mountopts=( -type $type -o "$opts" )
+ fi
+
+ $_CHBIND "${CHBIND_OPTS[@]}" \
+ $_MOUNT "${mountopts}" "$src" "$vdir$dst"
+ done
+}
+
+function execScriptlets
+{
+ local vdir=$1
+ local name=$2
+ local flavor=$3
+ local i
+
+ for i in "$vdir/scripts/$flavor" "$vdir/scripts/$flavor.d"/*; do
+ test -f "$i" -a -x "$i" || continue
+ "$i" "$flavor" "$name"
+ done
+}
+
+############################################
+
+: ${VSERVER_NAME:=$(basename "$VSERVER_DIR")}
+
+if test -e "$VSERVER_DIR"/noisy; then
+ SILENT_OPT=
+else
+ SILENT_OPT='--silent'
+fi
+
+if isVserverRunning "$VSERVER_DIR"; then
+ echo $"vserver '$VSERVER_NAME' already running; aborting..."
+ exit 1
+fi
+
+execScriptlets "$VSERVER_DIR" "$VSERVER_NAME" pre-start
+generateOptions "$VSERVER_DIR"
+enableInterfaces "$VSERVER_DIR" "$VSERVER_NAME"
+
+# TODO: utmp
+
+mountVserver "$VSERVER_DIR"
+
+cd "$VSERVER_DIR"/vdir/
+
+"${NICE_CMD[@]}" \
+ "$_CHBIND" "${CHBIND_OPTS[@]}" \
+ "$_CHCONTEXT" "${CHCONTEXT_OPTS[@]}" \
+ "$_SAVE_CTXINFO" "$VSERVER_DIR" \
+ "$_CAPCHROOT" "${CAPCHROOT_OPTS[@]}" . "${START_CMD[@]}"
+
+execScriptlets "$VSERVER_DIR" "$VSERVER_NAME" post-start