#!/bin/sh
# Copyright (C) 2004, 2005, 2006, 2007 Etersoft, Vitaly Lipatov <lav@etersoft.ru>
# Redistribution of this file is permitted under the terms of the
# GNU Public License (GPL)

# Now: Allow world to read our dir...
UMASK=0002
umask $UMASK

BINDIR=`dirname $0`

# FIXME: we do not need override it in right way
[ -z "$WINELOADER" ] && export WINELOADER=$BINDIR/wine-glibc
[ -z "$WINESERVER" ] && export WINESERVER=$BINDIR/wineserver
# missed on FreeBSD
[ -z "$UID" ] && export UID=`id -u`

ETCDIR=$BINDIR/../etc/wine
[ -d $ETCDIR ] || ETCDIR=/etc/wine
DATADIR=$BINDIR/../share/wine
LIBDIR=$BINDIR/../lib
STATEDIR=/var/lib/wine

WINEDIAG=$BINDIR/winediag

run_wine()
{
	# run wineserver for more delay
	# $WINESERVER -p 7
	if tty -s ; then
		exec $WINELOADER "$@"
	else
		echo "$0: Running without console, disable input"
		exec $WINELOADER "$@" </dev/null
		# TODO use log, but check winelog too
		# >$WINEPREFIX/output.log 2>&1
	fi
}

map_drive()
{
	test -d "${DEV}" || { echo "Dosdevices dir '${DEV}' does not exists"; return 1; }
	test -e "$1" || { echo "!!! Warning: Target '$1' does not exists. Skip '$2' device creating." ; return 1; }
	test -e ${DEV}/$2 && { echo "    SKIP: Device '$2' already mapped as '$(readlink ${DEV}/$2)'"; return 0; }
	ln -s "$1" ${DEV}/$2 && echo "Device '$2' created as link for '$1' target." || echo "Skipped $2"
	return 0
}

# Detect LinuxXP
[ -e /usr/bin/viewboots ] && export LINUXXP=1

if [ "$UID" = "0" ] && [ -z "$LINUXXP" ] ; then
	echo "It is not recommended to run WINE as root"
	exit 1
fi

# Use ~/.wine by default.
[ -z "$WINEPREFIX" ] && export WINEPREFIX=${HOME}/.wine

# If all environment is already created
if [ -e ${WINEPREFIX}/user.reg ] && [ "$1" != "--update" ]; then
	if [ -f ${WINEPREFIX}/config ] ; then
		echo "Warning: You have UNUSED old config file in $WINEPREFIX." >&2
		echo "It is recommended to rename (remove) old $WINEPREFIX and set new WINE environment." >&2
		echo
		exit 1
	fi
	# Only if libwine-etersoft present
	if [ -e $WINEDIAG ] && [ ! -f ${WINEPREFIX}/.etersoft-release ] ; then
		echo "Warning: Your WINE dir ($WINEPREFIX) is obsoleted. It can cause some problems." >&2
		echo "It is recommended to rename (remove) old $WINEPREFIX and set new WINE environment." >&2
		echo "Also you can update you WINE tree with wine --update command." >&2
		echo
		[ -e $WINEDIAG ] && exit 1
	else
		# check for version consistency
		true
	fi
	SYSREGSIZE=`cat ${WINEPREFIX}/system.reg | wc -c`
	if [ "$SYSREGSIZE" -le 100000 ] ; then
		echo "ERROR: You have broken system.reg (it has $SYSREGSIZE bytes, fewer than 100000 bytes)" >&2
		echo "Check your WINE installation or ask your support company" >&2
		exit 1
	fi
	if [ -e $WINEDIAG ] ; then
		$WINEDIAG >/dev/null 2>&1 || echo "Warning: you have some errors in winediag output. Run winediag command and check it." >&2
	fi

	if [ -z "$1" ] || [ "$1" = "--help" ] ; then
		$WINELOADER 
		echo "       wine --update                 Update WINE tree (registry and so on)"
		echo "       wine --attach dir             Attach user wine to shared dir"
		echo "       wine --admin dir              Create admin setup in shared dir (only for wineadmin group)"
		exit 0
	fi
	[ "$1" = "--admin" ] || [ "$1" = "--attach" ] && { echo "WINE $WINEPREFIX directory is already exists. Move it before attach to shared mode." ; exit 1; }
	run_wine "$@"
fi

# update or first run
####### WINE dir preparing ########
export DEVDIR=${WINEPREFIX}/dosdevices
mkdir -p ${WINEPREFIX} ${DEVDIR}
export SYSDRIVE="c:"
PROFILES=windows/profiles
WINTEMP=windows/temp
export CROOT=${DEVDIR}/$SYSDRIVE

$WINELOADER --version || { echo "$WINELOADER is broken on this system. Check for use appropriate 32-bit OS" ; exit 1; }
[ "$1"  = "--update" ] && echo -n "Updating... " || echo -n "First running... "
echo "Using WINEPREFIX=$WINEPREFIX"
# Kill all wine processes for any conflicts
$WINESERVER -k 2>/dev/null

# Tune admin setup
if [ "$1" = "--admin" ]; then
	shift
	WINEADMIN=$1 ; [ -z "$WINEADMIN" ] && WINEADMIN=default || shift
	[ `basename $WINEADMIN` = "$WINEADMIN" ] && WINEADMIN=$STATEDIR/$WINEADMIN
	[ -z "$WINEADMIN" ] && { echo "Use --admin with path to shared C:" ; exit 1; }
	mkdir -p $WINEADMIN 
	chgrp wineadmin $WINEADMIN 2>/dev/null && chmod 2775 $WINEADMIN || { echo "Shared dir $WINEADMIN cannot be accessed. Check you are in wineadmin group."; exit 1; }
	#UMASK=0002
fi

# Attach user to the directory
if [ "$1" = "--attach" ]; then
	shift
	WINEADMIN=$1 ; [ -z "$WINEADMIN" ] && WINEADMIN=default || shift
	[ -d $STATEDIR/$WINEADMIN ] && WINEADMIN=$STATEDIR/$WINEADMIN
	[ ! -d /$WINEADMIN ] && { echo "Prepared dir $WINEADMIN is not found"; exit 1; }
	[ ! -f $WINEADMIN/windows/inf/system.reg ] && { echo "Dir $WINEADMIN is not prepared dir"; exit 1; }

	ln -s dosdevices/$SYSDRIVE/windows/inf/system.reg ${WINEPREFIX}/system.reg
fi

# Attach shared dir
if [ -n "$WINEADMIN" ] ; then
	echo "Using shared WINE tree in $WINEADMIN"
	# load map_drive function
	#. $ETCDIR/map_devices.sh ""
	export DEV=${DEVDIR}
	map_drive $WINEADMIN $SYSDRIVE
fi

#mkdir -p $CROOT


# Follow code is copied from wineprefixcreate
echo "Creating default file tree..."
for i in \
    "$CROOT/windows" \
    "$CROOT/windows/command" \
    "$CROOT/windows/fonts" \
    "$CROOT/windows/inf" \
    "$CROOT/windows/system32" \
    "$CROOT/windows/system32/color" \
    "$CROOT/windows/system32/drivers" \
    "$CROOT/windows/system32/spool" \
    "$CROOT/windows/system32/spool/drivers" \
    "$CROOT/windows/temp"
do
    mkdir -p "$i"
done

# Make link for compatibility
[ -e "$CROOT/windows/system" ] || ln -s system32 $CROOT/windows/system

# Fix profile permission
mkdir -p ${CROOT}/$PROFILES/$USER && chmod o-rwx ${CROOT}/$PROFILES/$USER

if [ ! -w $CROOT/$WINTEMP/ ] ; then
	echo "Broken environment. We need writable $CROOT/$WINTEMP/"
	exit 1
fi

# Copy the .inf script and run it
if [ -w "$CROOT/windows/inf/" ] ; then
	install -m664 "$DATADIR/wine.inf" "$CROOT/windows/inf/wine.inf"
	# Apply additional reg files from /etc
	ls -1 ${ETCDIR}/*.reg | sort | xargs cat > "${CROOT}/windows/inf/vendor.reg"
	#echo "See T: drive" >${CROOT}/windows/temp/README.txt 2>/dev/null
fi

# move to C: before run wine programs
cd "$CROOT/$WINTEMP"
WINESAFE=yes "${WINELOADER}" rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 128 wine.inf
WINESAFE=yes "${WINELOADER}" regedit.exe "$CROOT/windows/inf/vendor.reg"

# check for locking if network version
WINELOCKTEST="$LIBDIR/wine/winelocktest-linux.exe.so"
WINECLT="$CROOT/windows/command/winelocktest.exe.so"
if [ -r $WINELOCKTEST ] && ln -sf $WINELOCKTEST "$WINECLT" 2>/dev/null && ! "$WINELOADER" "$WINECLT" >/dev/null ; then
	"$WINELOADER" "$WINECLT"
	echo "Error: You use /home via NFS probably, but do not run nfslock process on server."
	echo "Check you system and try again."
	exit 1
fi

$WINESERVER -w

# OLD: check for wineadmin : groups >/dev/null 2>&1 | grep wineadmin
if [ -n "$WINEADMIN" ] ; then
	# attach to registry if not yet
	SYSREG=windows/inf/system.reg
	if [ ! -f ${CROOT}/$SYSREG ] && [ ! -L ${WINEPREFIX}/system.reg ] ; then
		mv ${WINEPREFIX}/system.reg "$CROOT/$SYSREG" && chgrp wineadmin "$CROOT/$SYSREG" && ln -s dosdevices/c:/$SYSREG "$WINEPREFIX/system.reg"
	fi
	chmod a+rwxt $WINEADMIN/$PROFILES/ 2>/dev/null
	# Fix tmp permission
	chgrp wineadmin "$CROOT/$WINTEMP" 2>/dev/null && chmod a+rwxt "$CROOT/$WINTEMP"
fi

# Copying from datadir if we have some prepared tree there
if cd ${LIBDIR}/wine-default 2>/dev/null ; then
	echo "Copying prepared tree from '${LIBDIR}/wine-default' ..."
	XARGS="xargs -IQQQ"
	echo | $XARGS 2>/dev/null || XARGS="xargs -iQQQ"
	find ./ -type d | $XARGS install -d "${CROOT}/QQQ" 2>/dev/null
	# FIXME: use hard links if possible, preserve attributions (like cp -p)
	find ./ -type f | $XARGS install -m664 "QQQ" "${CROOT}/QQQ" 2>/dev/null
	#find ./ -type f | $XARGS ln "QQQ" "${CROOT}/QQQ" 2>/dev/null
	cd -
fi

# Create disks (only for first time)
echo "Building local device environment..."
if [ "$1" != "--update" ]; then
	#$ETCDIR/map_devices.sh ${DEVDIR}
	export DEV=${DEVDIR}
	for i in `ls -1 ${ETCDIR}/*.sh | sort` ; do
		[ -r $i ] && . $i ${DEVDIR}
	done
	# load map_drive function
	#. $ETCDIR/map_devices.sh ""
	#TP=../../tmp ; [ -d $TP ] || TP=$TMP
	#export DEV=${DEVDIR}
	#map_drive "$TP" t: || echo "Error t: disk creating. remove $WINEPREFIX first"
fi

# TODO: for better years
# Tune WINE apps autostart during X login
# mkdir -p ~/.xsession.d
# test -f ~/.xsession.d/wineboot || ln -sf $BINDIR/wineboot ~/.xsession.d

# for usability
if [ ! -d ${HOME}/wine_c ] && [ ! -f ${HOME}/wine_c ] ; then
	rm -f ${HOME}/wine_c
	ln -s ${CROOT} ${HOME}/wine_c || :
fi

DESKTOPMENU="$HOME/Desktop/WINE Applications"
if [ -d "$HOME/Desktop" ] && [ ! -d "$DESKTOPMENU" ] ; then
	mkdir -p ${CROOT}/$PROFILES/DESKTOPMENU && ln -s ${CROOT}/$PROFILES/DESKTOPMENU "${DESKTOPMENU}"
	#mkdir -p "${DESKTOPMENU}"
	cp -f $DATADIR/menu.directory "${DESKTOPMENU}/.directory"
fi

# Test for libwine-etersoft installed
[ -e $WINEDIAG ] && ( echo "Please do not change this file." ; $WINELOADER --version ) >${WINEPREFIX}/.etersoft-release

#Xdialog --msgbox "WINE has been configured for the first time.\nUse ${HOME}/wine_c as WINE C: disk\nCopy your program into and install it." 0 0
# some registry problem (CurrentVersion)?
$WINELOADER wineboot

cd -
[ "$1"  = "--update" ] && shift
[ -n "$1" ] && run_wine "$@"

echo "WINE@Etersoft has been configured for the first time."
echo "Use ${HOME}/wine_c as WINE C:\\ disk."
echo "Copy your program into and install it."
echo
