#! /bin/sh
#----------------------------------------------------------------------------
# /var/install/bin/show-menu - show menu
#
# Creation:     2001-11-04  fm
# Last Update:  $Id$
#
# Copyright (c) 2001-@@YEAR@@ the eisfair team, team(at)eisfair(dot)org
#
# 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; either version 2 of the License, or
# (at your option) any later version.
#----------------------------------------------------------------------------

# include eislib
. /var/install/include/eislib

default_run_path='/var/install/bin'
default_menu_path='/var/install/menu'
default_config_path='/etc/config.d'
default_doc_path='/usr/share/doc'
default_init_path='/etc/init.d'
xmlsplit='/usr/local/bin/xmlsplit'

menu_file="$1"
menu_package="$2"
url=''

if [ -n "$menu_package" ]
then
    PACKAGE="$menu_package"
    export PACKAGE
fi

#
# get command
#
#   Example:
#    $1         /var/install/bin/show-doc.cui -f /var/log/messages
#    returns    /var/install/bin/show-doc.cui
#
get_cmd()
{
    set - ${1}
    echo ${1}
}

### read_menu_file
#############################################################################
read_menu_file()
{
    MENU_TITLE=''
    MENU_SUBTITLE=''
    MENU_QUESTION='Select'
    MENU_COLS='60*'
    MENU_ROWS=0
    MENU_FLAGS='--spread --indent 12 --showexit'

    while read line
    do
        case "$line" in
        ''|'#'*|'<!--'*)
            : ## comment only - ignore
            ;;
        '<url/>')
            MENU_SUBTITLE="URL:"
            ;;
        '<version/>')
            MENU_SUBTITLE="base:"
            ;;
        '<package>'*)
            temp=`${xmlsplit} "$line" PACKAGE`
            if [ $? -eq 0 ]
            then
                eval "declare $temp"
                PACKAGE="$XMLSPLIT_TAG"
                export PACKAGE
            fi
            ;;
        '<title>'*)
            temp=`${xmlsplit} "$line" TITLE`
            if [ $? -eq 0 ]
            then
                eval "declare $temp"
                MENU_TITLE="$XMLSPLIT_TAG"
            fi
            ;;
        '<menu'*)
            temp=`${xmlsplit} "$line" MENU PACKAGE FILE PRE POST UI`
            if [ $? -eq 0 ]
            then
                let MENU_ROWS+=1

                eval "declare $temp"
                eval _ui='"${XMLSPLIT_ATTR_UI}"'

                # check for classic style entry
                if [ -z "${_ui}" -o "${_ui}" = "classic" ]
                then
                    [ -z "$XMLSPLIT_ATTR_PACKAGE" ] &&
                        XMLSPLIT_ATTR_PACKAGE="$PACKAGE"
                    eval MENU_${MENU_ROWS}_1='\"$XMLSPLIT_TAG\"'
                    export MENU_${MENU_ROWS}_1

                    eval MENU_${MENU_ROWS}_MY_PRE='"$XMLSPLIT_ATTR_PRE"'
                    eval MENU_${MENU_ROWS}_MY_POST='"$XMLSPLIT_ATTR_POST"'
                    eval MENU_${MENU_ROWS}_MY_PACKAGE='"$XMLSPLIT_ATTR_PACKAGE"'
                    eval MENU_${MENU_ROWS}_MY_ENTRY='menu'

                    file="$XMLSPLIT_ATTR_FILE"
                    [ -n "$file" ] &&
                    [ "`basename $file`" = "$file" ] &&
                        file="$default_menu_path/$file"
                    eval MENU_${MENU_ROWS}_MY_FILE='"$file"'
                    eval MENU_${MENU_ROWS}_MY_TASK=''
                    eval MENU_${MENU_ROWS}_MY_COMMAND='"$default_run_path/show-menu $default_menu_path/$XMLSPLIT_ATTR_FILE $XMLSPLIT_ATTR_PACKAGE"'

                    # check for read permission is granted
                    temp=`echo "${file}" | cut -d' ' -f1`
                    if [ -f "${temp}" -a ! -r "${temp}" ]
                    then
                        # error - ignore this entry
                        let MENU_ROWS-=1
                    fi
                else
                    let MENU_ROWS-=1
                fi
            fi
            ;;
        '<edit'*)
            temp=`${xmlsplit} "$line" EDIT PACKAGE STOPSTART PRE POST`
            if [ $? -eq 0 ]
            then
                let MENU_ROWS+=1

                eval "declare $temp"
                [ -z "$XMLSPLIT_ATTR_PACKAGE" ] &&
                    XMLSPLIT_ATTR_PACKAGE="$PACKAGE"
                eval MENU_${MENU_ROWS}_1='\"$XMLSPLIT_TAG\"'
                export MENU_${MENU_ROWS}_1

                eval MENU_${MENU_ROWS}_MY_PRE='"$XMLSPLIT_ATTR_PRE"'
                eval MENU_${MENU_ROWS}_MY_POST='"$XMLSPLIT_ATTR_POST"'
                eval MENU_${MENU_ROWS}_MY_PACKAGE='"$XMLSPLIT_ATTR_PACKAGE"'
                eval MENU_${MENU_ROWS}_MY_ENTRY='edit'

                package="$XMLSPLIT_ATTR_PACKAGE"
                eval MENU_${MENU_ROWS}_MY_FILE='"$default_config_path/$package"'

                if [ "$XMLSPLIT_ATTR_STOPSTART" = "true" ]
                then
                    eval MENU_${MENU_ROWS}_MY_COMMAND='"$default_run_path/edit -apply-stopstart \"$XMLSPLIT_ATTR_PACKAGE\" \"$XMLSPLIT_TAG\""'
                    eval MENU_${MENU_ROWS}_MY_TASK='apply-stopstart'
                else
                    eval MENU_${MENU_ROWS}_MY_COMMAND='"$default_run_path/edit -apply \"$XMLSPLIT_ATTR_PACKAGE\" \"$XMLSPLIT_TAG\""'
                    eval MENU_${MENU_ROWS}_MY_TASK='apply'
                fi
            fi
            ;;
        '<doc'*)
            temp=`${xmlsplit} "$line" DOC FILE PRE POST UI TAIL ENCODING`
            if [ $? -eq 0 ]
            then
                let MENU_ROWS+=1

                eval "declare $temp"
                eval _ui='"${XMLSPLIT_ATTR_UI}"'

                # check for classic style entry
                if [ -z "${_ui}" -o "${_ui}" = "classic" ]
                then
                    [ -z "$XMLSPLIT_ATTR_PACKAGE" ] &&
                        XMLSPLIT_ATTR_PACKAGE="$PACKAGE"
                    eval MENU_${MENU_ROWS}_1='\"$XMLSPLIT_TAG\"'
                    export MENU_${MENU_ROWS}_1

                    eval _tail='"${XMLSPLIT_ATTR_TAIL:-no}"'

                    if [ "${_tail}" = "yes" ]
                    then
                        follow='--follow'
                    fi

                    eval _encoding='"${XMLSPLIT_ATTR_ENCODING}"'

                    if [ -n "${_encoding}" ]
                    then
                        encoding="-e '${_encoding}'"
                    fi
                  
                    eval MENU_${MENU_ROWS}_MY_PRE='"$XMLSPLIT_ATTR_PRE"'
                    eval MENU_${MENU_ROWS}_MY_POST='"$XMLSPLIT_ATTR_POST"'
                    eval MENU_${MENU_ROWS}_MY_PACKAGE='"$XMLSPLIT_ATTR_PACKAGE"'
                    eval MENU_${MENU_ROWS}_MY_ENTRY='doc'

                    package="$XMLSPLIT_ATTR_PACKAGE"
                    file="$XMLSPLIT_ATTR_FILE"
                    [ -n "$file" ] &&
                    [ "`basename $file`" = "$file" ] &&
                        file="$default_doc_path/$package/$file"

                    # if only <doc> tag given and no file attr exists
                    [ -z "${file}" ] &&
                        file="${default_doc_path}/${package}/${package}.txt"

                    eval MENU_${MENU_ROWS}_MY_FILE='"$file"'
                    eval MENU_${MENU_ROWS}_MY_TASK=''
                    eval MENU_${MENU_ROWS}_MY_COMMAND='"$default_run_path/show-doc.cui --noframe --nocolor ${encoding} ${follow} --title \"$XMLSPLIT_TAG\" \"${file}\""'
                else
                    let MENU_ROWS-=1
                fi
            fi
            ;;
        '<script'*)
            temp=`${xmlsplit} "$line" SCRIPT FILE PRE POST UI`
            if [ $? -eq 0 ]
            then
                let MENU_ROWS+=1

                eval "declare $temp"
                eval _ui='"${XMLSPLIT_ATTR_UI}"'

                # check for classic style entry
                if [ -z "${_ui}" -o "${_ui}" = "classic" ]
                then
                    [ -z "$XMLSPLIT_ATTR_PACKAGE" ] &&
                        XMLSPLIT_ATTR_PACKAGE="$PACKAGE"
                    eval MENU_${MENU_ROWS}_1='\"$XMLSPLIT_TAG\"'
                    export MENU_${MENU_ROWS}_1

                    eval MENU_${MENU_ROWS}_MY_PRE='"$XMLSPLIT_ATTR_PRE"'
                    eval MENU_${MENU_ROWS}_MY_POST='"$XMLSPLIT_ATTR_POST"'
                    eval MENU_${MENU_ROWS}_MY_PACKAGE='"$XMLSPLIT_ATTR_PACKAGE"'
                    eval MENU_${MENU_ROWS}_MY_ENTRY='script'

                    file="$XMLSPLIT_ATTR_FILE"

                    # extract command from parameter(s)
                    cmd=`get_cmd "$file"`
                    # append $default_run_path if required
                    [ -n "${file}" ] &&
                    [ "`basename ${cmd}`" = "${cmd}" ] &&
                        file="${default_run_path}/${file}"

                    eval MENU_${MENU_ROWS}_MY_FILE='"$file"'
                    eval MENU_${MENU_ROWS}_MY_TASK=''

                    case "$XMLSPLIT_ATTR_FILE" in
                    /*)
                        eval command='"$XMLSPLIT_ATTR_FILE"'
                        ;;
                    ?*)
                        eval command='"$default_run_path/$XMLSPLIT_ATTR_FILE"'
                        ;;
                    *)  command='';;
                    esac

                    # check for execute permission is granted
                    temp=`echo "$command" | cut -d' ' -f1`
                    if [ -x "$temp" ]
                    then
                        eval MENU_${MENU_ROWS}_MY_COMMAND='"$command"'
                    else
                        # error - ignore this entry
                        let MENU_ROWS-=1
                    fi
                else
                    let MENU_ROWS-=1
                fi
            fi
            ;;
        '<init'*)
            temp=`${xmlsplit} "$line" INIT PACKAGE TASK PRE POST UI`
            if [ $? -eq 0 ]
            then
                let MENU_ROWS+=1

                eval "declare $temp"
                eval _ui='"${XMLSPLIT_ATTR_UI}"'

                # check for classic style entry
                if [ -z "${_ui}" -o "${_ui}" = "classic" ]
                then
                    [ -z "$XMLSPLIT_ATTR_PACKAGE" ] &&
                        XMLSPLIT_ATTR_PACKAGE="$PACKAGE"
                    eval MENU_${MENU_ROWS}_1='\"$XMLSPLIT_TAG\"'
                    export MENU_${MENU_ROWS}_1

                    eval MENU_${MENU_ROWS}_MY_PRE='"$XMLSPLIT_ATTR_PRE"'
                    eval MENU_${MENU_ROWS}_MY_POST='"$XMLSPLIT_ATTR_POST"'
                    eval MENU_${MENU_ROWS}_MY_PACKAGE='"$XMLSPLIT_ATTR_PACKAGE"'
                    eval MENU_${MENU_ROWS}_MY_ENTRY='init'

                    package="$XMLSPLIT_ATTR_PACKAGE"
                    files=''
                    for ac_file in $package
                    do
                        [ -z "$files" ] &&
                            files="$default_init_path/$ac_file" ||
                            files="$files $default_init_path/$ac_file"
                    done
                    eval MENU_${MENU_ROWS}_MY_FILE='"$files"'
                    eval MENU_${MENU_ROWS}_MY_TASK='"$XMLSPLIT_ATTR_TASK"'
                    if [ -n "$XMLSPLIT_ATTR_PACKAGE" \
                         -a -n "$XMLSPLIT_ATTR_TASK" ]
                    then
                        eval MENU_${MENU_ROWS}_MY_COMMAND='"$default_run_path/init \"$XMLSPLIT_ATTR_PACKAGE\" \"$XMLSPLIT_ATTR_TASK\" \"$XMLSPLIT_TAG\""'
                    else
                        # error - ignore this entry
                        let MENU_ROWS-=1
                    fi
                else
                    let MENU_ROWS-=1
                fi
            fi
            ;;
        '<'*)
            :  # ignore unknown tags
            ;;
        *)  # old behavior for compatibility
            if [ -z "$MENU_TITLE" ]
            then
                MENU_TITLE="$line"
            else
                case "$line" in
                '$URL')     MENU_SUBTITLE="URL:"      ;;
                '$VERSION') MENU_SUBTITLE="base:"     ;;
                *)          let MENU_ROWS+=1
                            set -- $line
                            eval MENU_${MENU_ROWS}_MY_COMMAND='"$1"'
                            shift
                            eval MENU_${MENU_ROWS}_1='\"$*\"'
                            export MENU_${MENU_ROWS}_1
                    ;;
                esac
            fi
            ;;
        esac
    done < $menu_file

    export MENU_TITLE
    export MENU_SUBTITLE
    export MENU_QUESTION
    export MENU_COLS
    export MENU_ROWS
    export MENU_FLAGS
}

run_script()
{
#TEST set -x
    run_file=$1
    [ -z "$run_file" ] && return
    shift
    type=$1
    eval run_package=$2
    # TEST
    if [ "$run_package" = 'testprepost' ]
    then
        mecho "Ready to execute $run_file with ($#) $*"
    fi
    if [ -f "$run_file" ]
    then
        sh -c "$run_file $*"
        rc=$?
    else
        if [ -f "$default_run_path/$run_file" ]
        then
            sh -c "$default_run_path/$run_file $*"
            rc=$?
        else
            mecho --error "unable to execute $type script $run_file"
            anykey
        fi
    fi
    # TEST
    if [ "$run_package" = 'testprepost' ]
    then
        mecho --warn "testing package testprepost (rc=$rc)"
        anykey
    fi
#TEST set +x
    case "${rc}" in
    0) : ;;
    2) return 127   ;;
    *)
        mecho --error "error in $run_file ($rc)"
        anykey
        return $rc
        ;;
    esac
}

#############################################################################
### main
#############################################################################

while [ 1 ]
do
    clrhome
    # check menu file
    if [ ! -f $menu_file ]
    then
        mecho --error "Menufile $menu_file does not exist"
        anykey
        break
    fi

    read_menu_file
    # check for items
    if [ $MENU_ROWS -le 0 ]
    then
        mecho --error "Menu contains no items"
        anykey
        break
    fi

    # prepare loop
    a='1'
    while [ 1 ]
    do
        # always show most current values
        case "$MENU_SUBTITLE" in
        URL:*)
            MENU_SUBTITLE="URL: `cat /var/install/url`"
            ;;
        base:*)
            version=`cat /etc/version`
            eiskernel=`grep "<version>" /var/install/packages/eiskernel 2>/dev/null | sed 's#</*version>##g'`
            kernel=`uname -r`
            MENU_SUBTITLE="base: $version   eiskernel: $eiskernel ($kernel)"
            ;;
        *)
            MENU_SUBTITLE=" "
            ;;
        esac

        $default_run_path/choose 'MENU' $a >/tmp/choose.$$
        rc=$?

        a=`cat /tmp/choose.$$`
        rm -f /tmp/choose.$$

        [ $rc = 255 ] && exit 1

        [ "$a" = "0" ] && exit 127
        [ -z "$a" ]  && break 2

        eval command='$MENU_'$a'_MY_COMMAND'
        eval pre='$MENU_'$a'_MY_PRE'
        eval post='$MENU_'$a'_MY_POST'
        eval file='$MENU_'$a'_MY_FILE'
        eval package='$MENU_'$a'_MY_PACKAGE'
        eval entry='$MENU_'$a'_MY_ENTRY'
        eval task='$MENU_'$a'_MY_TASK'

        if [ -z "$command" ]
        then
            mecho --error "show-menu internal error (a=$a)"
            anykey
        else
            rc=0
            if [ -n "$pre" ]
            then
                mecho --info 'Please wait ...'
                run_script "$pre" pre \'"$package"\' "$entry" \'"$file"\' \'"$task"\'
                rc=$?
                # set sh_rc to 2 to force a call of anykey
                sh_rc=2
            fi
            if [ "$rc" = '0' ]
            then
                sh -c "$command"
                sh_rc=$?
                if [ -n "$post" ]
                then
                    mecho --info 'Please wait ...'
                    run_script "$post" post \'"$package"\' "$entry" \'"$file"\' \'"$task"\'
                fi
            fi
        fi

        case $sh_rc in
        127)    exit 127    ;;
        0)                  ;;
        *)      anykey      ;;
        esac
    done
done

echo

exit 0