#!/bin/bash

# File:		/sbin/yast2
# Module:	yast2
# Summary:	Main YaST2 start script
# Authors:	Mathias Kettner <kettner@suse.de>
#		Klaus Kaempf <kkaempf@suse.de>
#		Ludwig Nussel <lnussel@suse.de>
#
# This script is called when the user just types 'yast2'. It starts
# the qt user interface in case the DISPLAY variable is set and other-
# wise ncurses. It starts then the module 'menu' which implements
# the configuration and administration menu.

export PATH=/sbin:/usr/sbin:$PATH

# load common script functions
. /usr/lib/YaST2/bin/yast2-funcs


# #211392, #265263
# if we are in X and do not have _input_ from terminal,
# save the output and display it via xmessage in case of error.
# TODO: also use bug-buddy or the kde thing... (#265263#c48)
redirect()
{
    if [ -n "$DISPLAY" -a ! -t 0 ]; then
	ERRLOG=`mktemp -t yast2-err-XXXXXX`
	trap exit_trap EXIT
	exec &> $ERRLOG
    fi
}

exit_trap()
{
    # handily, exit_code is set to $? of y2base.
    # If there was an error and there is anything to display, pop up.
    if [ $exit_code != 0 -a -s $ERRLOG ]; then
	xmessage -buttons OK:0 -default OK -center -file $ERRLOG
    fi
    rm -f $ERRLOG
}
# redirect the output if necessary
redirect

# Accumulated arguments for both the Qt UI and y2cc; currently supported:
# --fullscreen
# --noborder
Y2QT_ARGS=""
GNOME_SHELL="$ybindir/y2controlcenter-gnome"
KDE_SHELL="$ybindir/y2controlcenter"

printhelp()
{
	echo "Usage: $0 [OPTIONS] [MODULE] [module specific parameters]"
	echo
	echo "OPTIONS:"
	echo "	-h, --help	this message"
	echo "	-l, --list	list all available modules"
	echo "	-g, --geometry	default window size (qt only)"
	echo "	--noborder      no window manager border for main window"
	echo "	--fullscreen    use full screen"
	echo
	echo "exceptional case for installing packages:"
	echo "$0 OPTION <package> [<package> [...]]"
	echo
	echo "OPTION:"
	echo "	-i, --install	install rpm package"
	echo "	    --update 	update rpm package"
	echo "	    --remove	remove rpm package"
	echo
	echo "<package> can be a single short package name (e.g. gvim)"
	echo "which will be installed with dependency checking, or the full"
	echo "path to an rpm package (e.g /tmp/gvim.rpm) which will be"
	echo "installed without dependency checking"
	echo
}

listmodules()
{
    list=`/bin/ls -1 /usr/share/applications/YaST2/*.desktop 2>/dev/null`

    if [ -z "$list" ] ; then
	echo "No modules installed"
    else
	echo "Available modules:"
	echo
	grep -h "Exec=/sbin/yast2 " $list | \
	    sed 's|Exec=/sbin/yast2 \([^ ]\+\)\( .*\)\?|\1|' | \
	    sort -u
    fi
}

# Probes for default desktop GUI
probe_desktop_gui()
{
    if [ "$DESKTOP_SESSION" = "gnome" ]; then
	DESKTOP_GUI="gtk"
    elif echo $WINDOWMANAGER | grep -qi "gnome"; then
	DESKTOP_GUI="gtk"
    else
	DESKTOP_GUI="qt"
    fi
    if [ "$DESKTOP_GUI" = "qt" -a ! -x "$KDE_SHELL" ]; then
	DESKTOP_GUI="gtk"
    fi
    if [ "$DESKTOP_GUI" = "gtk" -a ! -x "$GNOME_SHELL" ]; then
	DESKTOP_GUI="qt"
    fi
}

# Select which control center shell we want to use
select_control_center()
{
    # 'auto' detects desktop
    if [ "$WANTED_SHELL" = "auto" ]; then
	probe_desktop_gui
	WANTED_SHELL=$DESKTOP_GUI
    fi

    # select binary
    y2ccbin=""
    case "$WANTED_SHELL" in
	gtk)
	    y2ccbin="$GNOME_SHELL"
	    ;;
	*)
	    y2ccbin="$KDE_SHELL"
	    ;;
    esac
}

# Select which toolkit we want to use (F#301083)
select_gui_frontend()
{
    if [ "$WANTED_GUI" = "auto" ]; then
	probe_desktop_gui
	WANTED_GUI=$DESKTOP_GUI
    fi
    
    if [ "$WANTED_GUI" = "gtk" ]; then
	if check_gtk; then
	    SELECTED_GUI=gtk
	else
#	    echo >&2 "GTK GUI wanted but not found, falling back to Qt."
	    WANTED_GUI=qt
	fi
    fi

    if [ "$WANTED_GUI" = "qt" ]; then
	if check_qt; then
	    SELECTED_GUI=qt
	else
	    echo >&2 "Qt GUI wanted but not found, falling back to ncurses."
	fi
    elif [ "$SELECTED_GUI" != "gtk" -a "$WANTED_GUI" != "ncurses" ]; then
	echo >&2 "Unknown GUI '$WANTED_GUI', falling back to ncurses."
    fi
}

TEMP=`/usr/bin/getopt -o hlg:s:Si --long help,list,kcontrol,geometry:,style:,strings,install,update,remove,fullscreen,noborder \
     -n 'yast2' -- "$@"`

if [ $? != 0 ] ; then echo "Exit." >&2 ; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
	case "$1" in
		-h|--help) printhelp; exit 0 ;;
		-l|--list) listmodules; exit 0 ;;
		-g|--geometry) Y2_GEOMETRY="-geometry $2"; shift 2; ;;
		-i|--install) Y2_INSTALL_PACKAGES=true; shift ;;
		--update) Y2_INSTALL_PACKAGES=true; Y2_INSTALL_ACTION=--update; shift ;;
		--remove) Y2_INSTALL_PACKAGES=true; Y2_INSTALL_ACTION=--remove; shift ;;
                --fullscreen) Y2QT_ARGS="$Y2QT_ARGS --fullscreen"; shift ;;
		--noborder)   Y2QT_ARGS="$Y2QT_ARGS --noborder"  ; shift ;;
		--kcontrol)   Y2QT_ARGS="$Y2QT_ARGS --kcontrol_id YaST" ; shift ;;
		--) shift ; break ;;
		*) echo "Unrecognized option $1" ; exit 1 ;;

	        # IMPORTANT: Remember to change that "getopt" call above, too
	        # if you change anything here!
	esac
done

if [ "$Y2_INSTALL_PACKAGES" = "true" ]; then
	export module=sw_single
	# #222757
	# prepend an additional argument if necessary
	set -- $Y2_INSTALL_ACTION "$@"
else
	# allow module as argument, defaults to "menu"
	export module="${1-menu}"
	shift
fi

case "`/usr/bin/basename $0`" in
	YaST|yast|yast1|zast)
		unset DISPLAY
	;;
esac

if [ "$UID" = 0 ]; then
    echo $$ > /var/run/yast.pid
fi

# set lang from sysconfig
set_lang_from_sysconfig

# default defaults
WANTED_GUI="auto"
WANTED_SHELL="auto"
DESKTOP_GUI="qt"

# read system settings
if [ -f /etc/sysconfig/yast2 ]; then
    source /etc/sysconfig/yast2
fi
# read user settings
if [ -f "$HOME/.yast2/yast2" ]; then
    source "$HOME/.yast2/yast2"
fi

# Fallback GUI
SELECTED_GUI=ncurses
# if we have a DISPLAY, select a preferred GUI
if [ -n "$DISPLAY" ]; then
    select_gui_frontend
fi

if [ "$SELECTED_GUI" = "ncurses" ]; then
    if check_ncurses ; then
	TTY=`/usr/bin/tty`
        # on console, start yast in UTF-8 locale (only on a 'local' console)
        if [ "$TERM" = "linux" -a \( "$TTY" = /dev/console -o "$TTY" != "${TTY#/dev/tty[0-9]}" \) ] ; then
	    case "$LANG" in
		# if it is known that a language doesn't yet work well with ncurses
		# on console use English instead:
		ja*|ko*|zh*)
		    export LANG=en_US.UTF-8
		    export LC_CTYPE=en_US.UTF-8
		;;
		*)
	            # get rid of encoding and/or modifier
		    # but not for POSIX and C locale 
		    # (POSIX.UTF-8 doesn't make sense)
		    if [ "$LANG" != "POSIX" ] && [ $LANG != "C" ]; then
		        export LANG=${LANG%%[.@]*}.UTF-8
		    fi
		    export LC_CTYPE=${LC_CTYPE%%[.@]*}.UTF-8
	        ;;
	    esac
	    if /bin/testutf8 ; [ $? -eq 1 ] ; then
		/usr/bin/test -x /bin/unicode_start && /bin/unicode_start
		uc_started=1
	    fi
        else
	    case "$TERM" in
		vt*|xterm*|linux|screen*)
		    # probe terminal and fix lang settings
		    UTF8TESTED=0
		    # binary /bin/testutf8 is missing at least on s390x, #158001
		    /usr/bin/test -x /bin/testutf8 && UTF8TESTED=1 && /bin/testutf8
		    # return code of the /bin/testutf8 (more info in bug #179989)
		    # 0=stdin does not support utf8, 1=not utf8, 2=utf8

		    UTF8STATUS=$?
		    
		    # the terminal supports utf8, but it's not currently set
		    # so strip .UTF-8 suffix from locale	
		    if [ "$UTF8TESTED" == "1" ] && [ $UTF8STATUS -eq 1 ] ; then
			/usr/bin/test -n "$LANG" && LANG=${LANG%.UTF-8}
			/usr/bin/test -n "$LC_CTYPE" && LC_CTYPE=${LC_CTYPE%.UTF-8}
		    # the terminal supports utf8 and it is currently set
		    # so strip any possible suffix from locale and append .UTF-8
		    elif [ "$UTF8TESTED" == "1" ] && [ $UTF8STATUS -eq 2 ]; then
			#do not append .UTF-8 suffix to POSIX and C locale (#285178)
			if [ "$LANG" != "POSIX" ] && [ $LANG != "C" ]; then
			    /usr/bin/test -n "$LANG" && LANG=${LANG%%[.@]*}.UTF-8
			fi
			/usr/bin/test -n "$LC_CTYPE" && LC_CTYPE=${LC_CTYPE%%[.@]*}.UTF-8
		    fi
		    #default: do nothing, keep locale untouched
		;;
	    esac
	fi

	# this fixes launching of interactive subprocesses, #150799
	NCTHREADS=--nothreads

	# set color theme, if defined
	if [ ! -z "$Y2NCURSES_COLOR_THEME" ]; then
	    export Y2NCURSES_COLOR_THEME="$Y2NCURSES_COLOR_THEME" 
	fi

	# use menu.ycp
	# TODO: this does not need to be a special case. refactor after release
	if [ $module == "menu" ] ; then
	    while true ; do
		$ybindir/y2base menu ncurses $NCTHREADS
		exit_code=$?
		if [ ! -e "/var/lib/YaST2/restart_menu" ] ; then
		    break
		fi
	    done
	else
	    # Transform every argument into a ycp string, that is surround all
	    # args by ("...").  args may contain spaces.
	    a=("$@")
	    b=("${a[@]/#/(\"}")
	    c=("${b[@]/%/\")}")
	    set -- "${c[@]}"

	  while true ; do
	    $ybindir/y2base "$module" "$@" ncurses $NCTHREADS
	    exit_code=$?
	    if [ ! $module == "online_update" -o ! -e "/var/lib/YaST2/selected_patches.ycp" ] ; then
		break
	    fi
	  done
	fi
	if [ "$uc_started" ] ; then
	    /usr/bin/test -x /bin/unicode_stop && /bin/unicode_stop
	fi
    else
	rpm -V yast2-core yast2-ncurses yast2-qt yast2-gtk >&2
	echo "Something is wrong with the YaST user interface." >&2
	exit_code=1
    fi
# quick hack: treat gtk like qt
elif [ "$SELECTED_GUI" = "qt" -o "$SELECTED_GUI" = "gtk" ]; then
    set_qt_home_dir

    # find which control center shell we want, if there is none we
    # fall back to the built-in ycp menu
    y2ccbin=""
    if [ $module == "menu" ]; then
	select_control_center
    fi
	
    if [ $module == "menu" -a -e "$y2ccbin" ] ; then
	$y2ccbin $Y2QT_ARGS "$@"
	exit_code=$?
    else
	
	# Special case: "sw_single" needs a lot of screen space -
	# always start it in full screen mode.
	#
	# This works well with KDE, but other WMs tend to be too broken for that,
	# so enable this only for KDE.
	#

	if  echo $WINDOWMANAGER | grep -qi "kde" ; then

  	    # ${WINDOWMANAGER##*/} deletes the longest shell wildcard pattern
	    # matching "*/", leaving only the last path name component.

	    if [ $module == "sw_single" ] ; then
	        case "$Y2QT_ARGS" in
	    	*fullscreen*) ;;
	    	*) Y2QT_ARGS="$Y2QT_ARGS --fullscreen" ;;
	        esac
	    fi
	fi

	# Transform every argument into a ycp string, that is surround all
	# args by ("...").  args may contain spaces.
	a=("$@")
	b=("${a[@]/#/(\"}")
	c=("${b[@]/%/\")}")
	set -- "${c[@]}"

      while true ; do
	$ybindir/y2base $module "$@" "$SELECTED_GUI" $Y2_GEOMETRY $Y2QT_ARGS
	exit_code=$?

	if [ ! $module == "online_update" -o ! -e "/var/lib/YaST2/selected_patches.ycp" ] ; then
	    break
	fi
      done
    fi
else
    echo >&2 "Internal error, unhandled '$SELECTED_GUI'"
fi

if [ "$UID" = 0 ]; then
    rm -f /var/run/yast.pid
fi

exit $exit_code
