#!/bin/bash
# Copyright (C) 2006,2007 Lauri Leukkunen <lle@rahina.org>
# Licensed under GPL version 2

function version()
{
	cat $SBOX_DIR/share/scratchbox2/version
	exit 0
}

function usage()
{
	cat <<EOF
sb2 - crosscompiling environment
Usage:
    sb2 [OPTION]... [COMMAND] [PARAMETERS]

If no COMMAND is given, a bash shell in scratchbox2 environment is started.

Options:
    -v           display version
    -L level     enable logging (levels=one of error,warning,notice,info,debug,noise,noise2)
    -d           debug mode: log all redirections (logging level=debug)
    -h           print this help
    -t TARGET    target to use, use sb2-config -d TARGET to set a default
    -e           emulation mode
    -m MODE      use mapping mode MODE
    -M file      read mapping rules from "file"
    -s DIRECTORY load mapping scripts from alternative location
    -Q BUGLIST   emulate bugs of the old scratchbox 1 (BUGLIST consists of
                 letters: 'x' enables exec permission checking bug emulation)
    -R           use simulated root permissions (currently activates
                 "fakeroot" for this functionality)
    -p           Preserve session directories (including the directory
                 which is used for /tmp by most mapping modes)
    -S file      Write session information to "file" (see option -J)
    -J file      Don't create a new session; join an existing one (see -S) 
    -D file      delete an old session (see -S). Warning: this does not
                 check if the session is still in use!

Examples:
    sb2 ./configure
    sb2 make
    sb2 -e make install
    sb2 -m emulate make install
EOF
	exit 2
}

function exit_error()
{
		echo "$@"
		exit 1
}

function sanity_check()
{
	if [ `id -u` = 0 ] ; then
		exit_error "Do not use sbox2 as root!"
	fi
	# check that most important host and target files exist
}

# Collect & write all mapping- and policy rules to $SBOX_SESSION_DIR/rules.lua
#
# Parameters:
#  - list of rule files (if specified by the -M option)
#  - uses rules from $SBOX_LUA_SCRIPTS/pathmaps/$SBOX_MAPMODE if -M was not used
function write_rules_to_session_dir()
{
	input_files="$@"

	cat >$SBOX_SESSION_DIR/rules.lua <<END
-- Rules for session $SBOX_SESSION_DIR
-- Automatically generated file, do not edit.
--
END

	if [ -z "$input_files" ]
	then
		if [ -z "$SBOX_LUA_SCRIPTS" ]
		then
			SBOX_LUA_SCRIPTS="$SBOX_DIR/share/scratchbox2/lua_scripts"
		fi
		input_files=`ls $SBOX_LUA_SCRIPTS/pathmaps/$SBOX_MAPMODE/*.lua`
	fi
	
	for f in $input_files
	do
		if [ -r $f ]
		then
			echo "-- [ $f ]" >>$SBOX_SESSION_DIR/rules.lua
			cat $f >>$SBOX_SESSION_DIR/rules.lua
		else
			echo "-- [ Failed to read $f ]" >>$SBOX_SESSION_DIR/rules.lua
		fi
	done
}

function sboxify_environment()
{
	if [ -r ~/.scratchbox2/config ]; then
		. ~/.scratchbox2/config
	fi

	if [ -z "$SBOX_TARGET" ]; then
		SBOX_TARGET=$DEFAULT_TARGET
	fi

	if [ -z "$SBOX_TARGET" ]; then
		echo "No target specified and none set as default, aborting."
		exit 2
	fi

	if [ ! -e ~/.scratchbox2/$SBOX_TARGET/sb2.config ]; then
		echo "Invalid target specified, aborting."
		exit 2
	fi

	LD_LIBRARY_PATH=$SBOX_DIR/lib/libsb2:$SBOX_DIR/lib64/libsb2:$SBOX_DIR/lib32/libsb2:/emul/lib64/libsb2:/emul/lib32/libsb2
	SBOX_LIBSB2="libsb2.so.1"
	
	. ~/.scratchbox2/$SBOX_TARGET/sb2.config

	# SBOX_MAPMODE has been set, read mode-specific settings
	if [ -f $SBOX_DIR/share/scratchbox2/modeconf/sb2rc.$SBOX_MAPMODE ]
	then
		. $SBOX_DIR/share/scratchbox2/modeconf/sb2rc.$SBOX_MAPMODE starting
	fi

	if [ "$SBOX_CONFIG_VERSION" != "8" ]; then
		echo "Please run sb2-init for your target:"
		echo "name: $SBOX_TARGET"
		echo "dir:  $SBOX_TARGET_ROOT"
		echo "gcc:  $SBOX_CROSS_GCC_DIR/${SBOX_CROSS_GCC_SUBST_PREFIX}gcc"
		echo "to update its sb2.config to work with current version of sb2"
		echo "for example: "
		echo sb2-init $SBOX_TARGET $SBOX_CROSS_GCC_DIR/${SBOX_CROSS_GCC_SUBST_PREFIX}gcc""
		exit 1
	fi

	if [ -n "$SBOX_DIR" ]; then
		if [ -z "$SBOX_LUA_SCRIPTS" ]; then
			SBOX_LUA_SCRIPTS="$SBOX_DIR/share/scratchbox2/lua_scripts"
		fi
	else
		exit_error "Incorrect target config in ~/.scratchbox2/$SBOX_TARGET/sb2.config"
	fi

	SBOX_TARGET_TOOLCHAIN_DIR=$(dirname "$SBOX_CROSS_GCC_DIR")

	if [ -z "$SBOX_MODE_PATH" ]
	then
		# /sb2/wrappers and /sb2/scripts contain utilities for
		# development support, and are available in the
		# software development modes ("simple" and "devel")
		export PATH=/sb2/wrappers:/sb2/scripts:$HOME/.scratchbox2/$SBOX_TARGET/bin:$SBOX_DIR/bin:$PATH:/sbin:/usr/sbin:$SBOX_TARGET_ROOT/bin:$SBOX_TARGET_ROOT/usr/bin:$SBOX_TARGET_ROOT/usr/local/bin
	else
		export PATH=$SBOX_MODE_PATH
	fi

	# LD_PRELOAD will be set to SBOX_LIBSB2 by sb2-monitor.

	export PS1="[SB2 $SBOX_MAPMODE $SBOX_TARGET] \u@\h \W \$ "
}


function initialize_sb_logging()
{
	cmd_param=$1
	args_param=$2
	if [ "$SBOX_MAPPING_LOGLEVEL" != "" ]; then
		tstamp=`SBOX_DISABLE_MAPPING=1 /bin/date +%Y%m%d-%H%M`
		if [ ! -d $HOME/sb2_logs ]
		then
			SBOX_DISABLE_MAPPING=1 mkdir $HOME/sb2_logs 
			echo "Created directory $HOME/sb2_logs for log files"
		fi
		MAPPING_LOGFILE=$HOME/sb2_logs/$cmd_param.$tstamp.$$.log
		export SBOX_MAPPING_LOGFILE=$MAPPING_LOGFILE

		if [ "$SBOX_MAPPING_DEBUG" == "1" ]; then
			# log command:
			echo "##Log from $cmd_param $args_param" >$MAPPING_LOGFILE

			# log initial environment if logging is enabled
			env | sed -e 's/^/#/' >>$MAPPING_LOGFILE
			echo "#SBOX_TARGET_ROOT=$SBOX_TARGET_ROOT" >>$MAPPING_LOGFILE
			echo "#SBOX_TOOLS_ROOT=$SBOX_TOOLS_ROOT" >>$MAPPING_LOGFILE
			echo "#SBOX_MAPMODE=$SBOX_MAPMODE" >>$MAPPING_LOGFILE

			echo "Running scratchbox with these settings:"
			echo "SBOX_LIBSB2 = $SBOX_LIBSB2"
			echo "SBOX_LUA_SCRIPTS = $SBOX_LUA_SCRIPTS"
			echo "SBOX_TOOLS_ROOT = $SBOX_TOOLS_ROOT"
			echo "SBOX_TARGET_ROOT = $SBOX_TARGET_ROOT"
			echo "SBOX_MAPPING_LOGFILE = $SBOX_MAPPING_LOGFILE"
			echo "SBOX_MAPPING_LOGLEVEL = $SBOX_MAPPING_LOGLEVEL"
			echo
		fi
	fi
}

#
# Write variables to $SBOX_SESSION_DIR/sb2-session.conf
# NOTE: this file will be read by lua interpreter and the shell,
# so only simple string assignments are allowed! 
# (even comments are different in Lua and shell scripts..)
function create_common_sb2_conf_file_for_session()
{
	sbox_user_home_dir=$HOME
	if [ -z "$HOME" ]
	then
		sbox_user_home_dir="/home/unknown_user"
	fi

	cat <<END >>$SBOX_SESSION_DIR/sb2-session.conf
comment_1=" Common configuration file for Lua and Shell scripts."
comment_2=" Automatically generated file, do not edit."

sbox_target="$SBOX_TARGET"

sbox_dir="$SBOX_DIR"
sbox_workdir="$SBOX_WORKDIR"
sbox_user_home_dir="$sbox_user_home_dir"
sbox_target_toolchain_dir="$SBOX_TARGET_TOOLCHAIN_DIR"

sbox_mapmode="$SBOX_MAPMODE"
sbox_target_root="$SBOX_TARGET_ROOT"
sbox_tools_root="$SBOX_TOOLS_ROOT"

sbox_cpu="$SBOX_CPU"
sbox_cputransparency_method="$SBOX_CPUTRANSPARENCY_METHOD"
sbox_sbrsh_config="$SBRSH_CONFIG"

sbox_cross_gcc_prefix_list="$SBOX_CROSS_GCC_PREFIX_LIST"
sbox_cross_gcc_dir="$SBOX_CROSS_GCC_DIR"
sbox_extra_cross_compiler_args="$SBOX_EXTRA_CROSS_COMPILER_ARGS"
sbox_cross_gcc_subst_prefix="$SBOX_CROSS_GCC_SUBST_PREFIX"
sbox_cross_gcc_specs_file="$SBOX_CROSS_GCC_SPECS_FILE"
sbox_extra_cross_compiler_stdinc="$SBOX_EXTRA_CROSS_COMPILER_STDINC"
sbox_block_cross_compiler_args="$SBOX_BLOCK_CROSS_COMPILER_ARGS"

sbox_extra_cross_ld_args="$SBOX_EXTRA_CROSS_LD_ARGS"
sbox_block_cross_ld_args="$SBOX_BLOCK_CROSS_LD_ARGS"

sbox_host_gcc_prefix_list="$SBOX_HOST_GCC_PREFIX_LIST"
sbox_host_gcc_dir="$SBOX_HOST_GCC_DIR"
sbox_extra_host_compiler_args="$SBOX_EXTRA_HOST_COMPILER_ARGS"
sbox_host_gcc_subst_prefix="$SBOX_HOST_GCC_SUBST_PREFIX"
sbox_block_host_compiler_args="$SBOX_BLOCK_HOST_COMPILER_ARGS"

sbox_uname_machine="$SBOX_UNAME_MACHINE"
sbox_libsb2="$SBOX_LIBSB2"
END
}

function write_ld_library_path_replacement_to_exec_config()
{
	rootdir=$1
	varname=$2

	# Build replacement for LD_LIBRARY_PATH:

	# First, make sure that libsb2 is searched
	liblocations="$SBOX_DIR/lib/libsb2 /usr/lib/libsb2"

	# Include directories listed in ld.so.conf
	if [ -f $rootdir/etc/ld.so.conf ]
	then
		lloc2=`egrep '^/' $rootdir/etc/ld.so.conf`
		liblocations="$liblocations $lloc2"
	fi
	# Include directories listed in ld.so.conf.d/*
	if [ -d $rootdir/etc/ld.so.conf.d ]
	then
		lloc2=`cat $rootdir/etc/ld.so.conf.d/* 2>/dev/null | egrep '^/'`
		liblocations="$liblocations $lloc2"
	fi

	# Next, force libfakeroot to be searced:
	liblocations="$liblocations /usr/lib/libfakeroot \
		/usr/lib64/libfakeroot /usr/lib32/libfakeroot"

	# Find all directories that are used in the ld.so cache file:
	if [ -x $rootdir/sbin/ldconfig ]
	then
		# print contents of the cache, take destination
		# names (the part after "=>"), drop file names (leave
		# directory names, and remove duplicates:
		dirs_in_cache=`$rootdir/sbin/ldconfig -p \
			-C $rootdir/etc/ld.so.cache | 
			fgrep '=>' | 
			sed -e 's/^.*=> //' -e 's:/[^/]*$::' | 
			sort | uniq`
		ld_library_extras_from_cache=$dirs_in_cache
		liblocations="$liblocations $dirs_in_cache"
	fi

	# Last, the default locations:
	# (these may be already included by the previous step)
	liblocations="$liblocations /lib /usr/lib"

	# Create the variable.
	echo "$varname =" >>$SBOX_SESSION_DIR/exec_config.lua
	colon=""
	for l in $liblocations
	do
		if [ -d $rootdir$l ]
		then
			echo " \"$colon$rootdir$l\" .." >>$SBOX_SESSION_DIR/exec_config.lua
			colon=":"
		fi
	done
	# Finalize the library search path.
	echo " \"\"" >>$SBOX_SESSION_DIR/exec_config.lua
}

# Test if qemu has "-0 argv0" and "-E envvar=value" flags
function check_qemu_features()
{
	qemu_path=$1

	test_output=`$qemu_path -h | grep '^-0'`
	if [ -n "$test_output" ]
	then
		# -0 is suported
		conf_cputransparency_has_argv0_flag="true"
	else
		conf_cputransparency_has_argv0_flag="false"
	fi

	test_output=`$qemu_path -h | grep '^-E'`
	if [ -n "$test_output" ]
	then
		# -E is suported
		conf_cputransparency_qemu_has_env_control_flags="true"
	else
		conf_cputransparency_qemu_has_env_control_flags="false"
	fi
}

# Test if the "--argv0" flag is supported by the ld.so
function check_ld_so_argv0_feature()
{
	rootdir=$1
	ld_so_path=$2

	ld_so_argv_flag_works="false" # the default

	# Executing ld.so without any arguments should print 
	# usage information to stderr:
	test_output=`$ld_so_path 2>&1 | grep 'argv0 STRING'`
	if [ -n "$test_output" ]
	then
		# description about --argv0 exists!
		ld_so_argv_flag_works="true"
	fi
}

function write_libsb2_and_ld_so_state_to_exec_config()
{
	rootdir=$1
	sb2_installed_varname=$2
	sbox_dir_varname=$3
	ld_so_path_varname=$4
	ld_so_supports_argv0_varname=$5

	# Check if ld.so can be used from $rootdir by 
	# checking that libsb2 has been installed to tools

	if [ -d $rootdir/$SBOX_DIR/lib/libsb2 ]
	then
		sbox_dir_2=$rootdir/$SBOX_DIR
	elif [ -d $rootdir/usr/lib/libsb2 ]
	then
		sbox_dir_2=$rootdir/usr
	else
		sbox_dir_2=""
	fi

	if [ -f $sbox_dir_2/lib/libsb2/libsb2.so.1 ]
	then
		echo "$sb2_installed_varname = true" >>$SBOX_SESSION_DIR/exec_config.lua
		ld_so_found="yes"
	else
		echo "$sb2_installed_varname = false" >>$SBOX_SESSION_DIR/exec_config.lua
		ld_so_found="no"
	fi

	echo "$sbox_dir_varname = \"$sbox_dir_2\"" >>$SBOX_SESSION_DIR/exec_config.lua

	# check the dynamic linker:

	# First try if the default linker can be used
	ld_so_candidate=$rootdir/lib/ld-linux.so.2
	if [ -f $ld_so_candidate ]
	then
		check_ld_so_argv0_feature $rootdir $ld_so_candidate
		if [ "$ld_so_argv_flag_works" != "true" ]
		then
			# the default ld.so does not support --argv0.
			# Find out if a replacement has been installed for sb2:
			ld_so_with_version=`readlink $ld_so_candidate`
			ld_so_candidate2=$SBOX_DIR/lib/libsb2/$ld_so_with_version
			if [ -f "$ld_so_candidate2" ]
			then
				check_ld_so_argv0_feature $rootdir $ld_so_candidate2
				if [ "$ld_so_argv_flag_works" == "true" ]
				then
					ld_so_candidate=$ld_so_candidate2
				fi # else keep the default ld_so_candidate
			fi # no replacement, use the default ld.so. No --argv0
		fi
	else
		ld_so_candidate=""
		ld_so_argv_flag_works="false"
	fi
			
	if [ -n "$SBOX_OPT_Z_NO_LD_SO_EXEC" ]
	then
		ld_so_candidate=""
		ld_so_argv_flag_works="false"
	fi

	if [ -n "$ld_so_candidate" ]
	then
		echo "$ld_so_path_varname = \"$ld_so_candidate\"" >>$SBOX_SESSION_DIR/exec_config.lua
		echo "$ld_so_supports_argv0_varname = $ld_so_argv_flag_works" >>$SBOX_SESSION_DIR/exec_config.lua

	else
		echo "$ld_so_path_varname = nil" >>$SBOX_SESSION_DIR/exec_config.lua
		echo "$ld_so_supports_argv0_varname = false" >>$SBOX_SESSION_DIR/exec_config.lua
	fi
}

function write_locale_paths_to_exec_config()
{
	local rootdir
	local locale_path_varname
	local message_catalog_prefix_varname
	locale locale_path

	rootdir=$1
	locale_path_varname=$2
	message_catalog_prefix_varname=$3
	locale_path=$HOME/.scratchbox2/$SBOX_TARGET/locales

	echo "$locale_path_varname=\"$locale_path\"" \
	    >> $SBOX_SESSION_DIR/exec_config.lua
	echo "$message_catalog_prefix_varname=\"$SBOX_TARGET_ROOT\"" \
	    >> $SBOX_SESSION_DIR/exec_config.lua
}

# Write configuration file $SBOX_SESSION_DIR/exec_config.lua
function create_exec_config_file()
{
	cat >$SBOX_SESSION_DIR/exec_config.lua <<END
-- exec settings. Automatically generated file, do not edit.
END

	# 1. Exec settings for tools
	if [ "$SBOX_TOOLS_ROOT" != "" ]; then
		write_ld_library_path_replacement_to_exec_config \
			$SBOX_TOOLS_ROOT conf_tools_ld_so_library_path 

		write_libsb2_and_ld_so_state_to_exec_config \
			$SBOX_TOOLS_ROOT \
			conf_tools_sb2_installed conf_tools_sbox_dir \
			conf_tools_ld_so conf_tools_ld_so_supports_argv0

		if [ ld_so_found != "yes" ]
		then
			# ld.so from tools can not be used. Add tools' shared
			# library locations to the normal LD_LIBRARY_PATH;	
			# this is risky but the best what we can do now
			# (these extra locations must be after other locations
			# in LD_LIBRARY_PATH => $ld_library_path_extras won't
			# be added to LD_LIBRARY_PATH here, but later)
			ld_library_path_extras=`echo $ld_library_extras_from_cache |
				sed -e s:^:$rootdir:g -e "s; ;:$rootdir;g"`
		fi
	else
		# SBOX_TOOLS_ROOT was empty, tools will be used from
		# host environment.
		cat <<END >>$SBOX_SESSION_DIR/exec_config.lua
conf_tools_ld_so_library_path = nil
conf_tools_sb2_installed = false
conf_tools_sbox_dir = ""
conf_tools_ld_so = nil
conf_tools_ld_so_supports_argv0 = false
END
	fi

	# 2. Exec settings for rootstrap
	conf_cputransparency_has_argv0_flag="false"
	conf_cputransparency_qemu_has_env_control_flags="false"

	if [ "$SBOX_CPUTRANSPARENCY_METHOD" == "" ]; then
		# CPU transparency method has not been set:
		# host CPU == target CPU

		write_ld_library_path_replacement_to_exec_config \
			$SBOX_TARGET_ROOT conf_target_ld_so_library_path 

		write_libsb2_and_ld_so_state_to_exec_config \
			$SBOX_TARGET_ROOT \
			conf_target_sb2_installed conf_target_sbox_dir \
			conf_target_ld_so conf_target_ld_so_supports_argv0

		write_locale_paths_to_exec_config \
			$SBOX_TARGET_ROOT \
			conf_target_locale_path \
			conf_target_message_catalog_prefix
	else
		# SBOX_TOOLS_ROOT was empty, tools will be used from
		# host environment.
		cat <<END >>$SBOX_SESSION_DIR/exec_config.lua
conf_target_ld_so_library_path = nil
conf_target_sb2_installed = false
conf_target_sbox_dir = ""
conf_target_ld_so = nil
conf_target_ld_so_supports_argv0 = false
conf_target_locale_path = nil
conf_target_message_catalog_prefix = nil
END

		case "$SBOX_CPUTRANSPARENCY_METHOD" in	
		*qemu*)	check_qemu_features $SBOX_CPUTRANSPARENCY_METHOD
			;;
		esac
	fi

	cat <<END >>$SBOX_SESSION_DIR/exec_config.lua
conf_cputransparency_has_argv0_flag=$conf_cputransparency_has_argv0_flag
conf_cputransparency_qemu_has_env_control_flags=$conf_cputransparency_qemu_has_env_control_flags
END
}

function get_SBOX_SESSION_DIR_from_file()
{
	file=$1

	SBOX_SESSION_DIR=""
	if [ ! -r "$file" ]
	then
		echo "Failed to read '$file'"
		return
	fi

	if grep -q "# SB2 SessionInfo:" "$file" 2>/dev/null
	then
		# $file seems to be valid
		SBOX_SESSION_DIR=`sed -n -e 's/^SBOX_SESSION_DIR=//p' < $file`
	else
		echo "'$file' is not a valid SB2 session information file"
		return
	fi

	if [ ! -d "$SBOX_SESSION_DIR" -o \
	     ! -f $SBOX_SESSION_DIR/.joinable-session ]
	then
		echo "Session '$SBOX_SESSION_DIR' does not exist"
		SBOX_SESSION_DIR=""
		return
	fi
	# else the session seems to be valid.
}


my_path=$_
if [ $(basename $my_path) != $(basename $0) ]; then
	my_path=$0
	if [ $(basename $my_path) = $my_path ]; then
		my_path=$(which $my_path)
	fi
fi

SBOX_DIR=$(readlink -f $(dirname $(readlink -f $my_path))/..)
SBOX_WORKDIR=$(readlink -f $PWD)
SBOX_FAKEROOT_PREFIX=""

while getopts vdht:em:s:L:Q:pM:ZRS:J:D: foo
do
	case $foo in
	(v) version ;;
	(d) export SBOX_MAPPING_DEBUG=1
	    export SBOX_MAPPING_LOGLEVEL=debug ;;
	(L) export SBOX_MAPPING_DEBUG=1
	    export SBOX_MAPPING_LOGLEVEL=$OPTARG ;;
	(Q) export SBOX_EMULATE_SB1_BUGS=$OPTARG ;;
	(h) usage ;;
	(t) SBOX_TARGET=$OPTARG ;;
	(e) SBOX_MAPMODE=emulate ;;
	(m) SBOX_MAPMODE=$OPTARG ;;
	(M) SBOX_RULEFILES="$SBOX_RULEFILES $OPTARG" ;;
	(s) SBOX_LUA_SCRIPTS=$OPTARG;;
	(p) SBOX_SESSION_NO_CLEANUP="y";;
	(Z) SBOX_OPT_Z_NO_LD_SO_EXEC="y";;
	(R) SBOX_FAKEROOT_PREFIX="fakeroot";;
	(S) SBOX_WRITE_SESSION_INFO_TO_FILE=$OPTARG ;;
	(J) SBOX_JOIN_SESSION_FILE=$OPTARG ;;
	(D) SBOX_DELETE_SESSION_FILE=$OPTARG ;;
	(*) usage ;;
	esac
done
shift $(($OPTIND - 1))

if [ -n "$SBOX_SESSION_DIR" -a -f "$SBOX_SESSION_DIR/rules.lua" ]
then
	# already inside an sb2 session; ignore all options and just exec the command.
	echo "WARNING: recursive calls to sb2 are not supported (session already exists)"
	echo "WARNING: going to execute '$*' in this session"
	exec $*
fi

if [ "$SBOX_MAPPING_DEBUG" == "1" ]; then
	# check that loglevel is valid
	case $SBOX_MAPPING_LOGLEVEL in
	(error|warning|notice|info|debug|noise|noise2)	;; # OK
	(*) usage ;;
	esac
else
	# default logging level
	export SBOX_MAPPING_LOGLEVEL=warning
fi

# read commands to execute from stdin - not yet implemented
if [ "$1" = "-" ] ; then
	STDIN=true
fi

if [ -n "$SBOX_DELETE_SESSION_FILE" ]
then
	# Delete a session
	get_SBOX_SESSION_DIR_from_file "$SBOX_DELETE_SESSION_FILE"
	if [ ! -z "$SBOX_SESSION_DIR" ]
	then
		# now we "know" that $SBOX_SESSION_DIR is a directory,
		# but double-checking doesn't hurt before rm -rf..
		if [ -d "$SBOX_SESSION_DIR" ]
		then
			rm -rf $SBOX_SESSION_DIR
		fi
	fi
	rm "$SBOX_DELETE_SESSION_FILE"
	exit 0
fi

if [ -n "$SBOX_JOIN_SESSION_FILE" ]
then
	# Join an existing session, don't create it..
	get_SBOX_SESSION_DIR_from_file "$SBOX_JOIN_SESSION_FILE"
	if [ -z "$SBOX_SESSION_DIR" ]
	then
		# failed to get SBOX_SESSION_DIR,
		# error message has been printed.
		exit 1
	fi
else
	# Create a new session
	if [ -n "$SBOX_WRITE_SESSION_INFO_TO_FILE" -a \
	     -f "$SBOX_WRITE_SESSION_INFO_TO_FILE" ]
	then
		echo "File '$SBOX_WRITE_SESSION_INFO_TO_FILE' already exists."
		exit 1
	fi

	# Create session directories
	date_and_time_now=`date +%Y%m%d-%H%M%S`
	SBOX_SESSION_DIR=`mktemp -d /tmp/sb2-$USER-$date_and_time_now.XXXXXX`

	mkdir -p $SBOX_SESSION_DIR
	mkdir -p $SBOX_SESSION_DIR/tmp

	if [ -n "$SBOX_WRITE_SESSION_INFO_TO_FILE" ]
	then
		cat >$SBOX_WRITE_SESSION_INFO_TO_FILE <<END
# SB2 SessionInfo:
SBOX_SESSION_DIR=$SBOX_SESSION_DIR
END
		touch $SBOX_SESSION_DIR/.joinable-session
	fi

	if [ -n "$SBOX_SESSION_NO_CLEANUP" ]
	then
		touch $SBOX_SESSION_DIR/.preserve-session
	fi
fi

# SBOX_SESSION_DIR needs to be passed in environment variable, always.
export SBOX_SESSION_DIR

sboxify_environment

if [ -z "$SBOX_JOIN_SESSION_FILE" ]
then
	# creating a new session..
	ln -s $SBOX_LUA_SCRIPTS $SBOX_SESSION_DIR/lua_scripts
	write_rules_to_session_dir $SBOX_RULEFILES
	create_exec_config_file
	create_common_sb2_conf_file_for_session
fi

# set the initial binary name for the mapping engine
export __SB2_BINARYNAME="bash"

if [ -n "$SBOX_TOOLS_ROOT" ]; then
	SHELL=$SBOX_TOOLS_ROOT/bin/bash
else
	SHELL=/bin/bash
fi

# Final addition to LD_LIBRARY_PATH, if needed
if [ -n "$ld_library_path_extras" ]
then
	LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ld_library_path_extras
fi

# ------------ cleanup:
# Unset variables which used to be passed in environment,
# but have been moved to sb2-session.conf.
unset SBOX_MAPMODE
unset SBOX_TARGET_ROOT
unset SBOX_TOOLS_ROOT
# ------------
# Export variables that need to be available in environment;
# don't export anything unnecessary!
#
# FIXME: Currently this list contains many variables that should not 
# be in the environment. Cleanup continues...

export DEB_BUILD_ARCH
export DEB_BUILD_ARCH_CPU
export DEB_BUILD_ARCH_ABI
export DEB_BUILD_GNU_CPU
export DEB_BUILD_GNU_TYPE
export DEB_BUILD_GNU_SYSTEM

export DEB_HOST_ARCH
export DEB_HOST_ARCH_OS
export DEB_HOST_ARCH_CPU

export DEB_HOST_GNU_CPU
export DEB_HOST_GNU_TYPE
export DEB_HOST_GNU_SYSTEM

export LD_LIBRARY_PATH

# ------------
# Now everything is ready, programs can be executed in SB2'ed environment.
# Create reverse mapping rules before starting the actual command (or shell)
sb2-monitor -L $SBOX_LIBSB2 -- $SBOX_DIR/bin/sb2-show \
	execluafile $SBOX_SESSION_DIR/lua_scripts/create_reverse_rules.lua \
	>$SBOX_SESSION_DIR/rev_rules.lua

# ------------


if [ $# -gt 0 -o "$STDIN" = true ] ; then
	binary="$1"
	shift 1
	args="$@"
	initialize_sb_logging $(echo $binary | sed 's/\//_/g') "$args"
	exec $SBOX_FAKEROOT_PREFIX sb2-monitor -L $SBOX_LIBSB2 -x $SBOX_DIR/share/scratchbox2/scripts/sb2-exitreport \
		-- $SHELL -c "$binary $args"
else
	initialize_sb_logging sb2
	exec $SBOX_FAKEROOT_PREFIX sb2-monitor -L $SBOX_LIBSB2 -x $SBOX_DIR/share/scratchbox2/scripts/sb2-exitreport \
		-- $SHELL --noprofile --norc
fi

