#!/bin/bash

. "/etc/sysconfig/powersave/sleep"

# the statefiles are used to record the system state before the sleep state
# and restore it after resume. Stopped services, unloaded modules etc. are
# recorded in these files.
STATE1=/var/lib/suspend2disk-state   # statefile for suspend-to-disk
STATE2=/var/lib/suspend2ram-state    # statefile for suspend-to-ram
STATE3=/var/lib/standby-state        # statefile for standby

# the logfiles log information (such as the output of rc-scripts) in addition
# to the statefiles to aid users in debugging suspend failures.
LSMOD_LOG1=/var/log/suspend2disk.log # logfile for suspend-to-disk
LSMOD_LOG2=/var/log/suspend2ram.log  # logfile for suspend-to-ram
LSMOD_LOG3=/var/log/standby.log      # logfile for standby

POWERSAVE="/usr/bin/powersave"
PCCARDCTL="/sbin/pccardctl" # if you still have cardmgr, use "/sbin/cardctl"
GRUBONCE="/usr/sbin/grubonce"

# are we APM or ACPI?
# $POWERSAVE -S &> /dev/null
# APM_ACPI=$?        # ACPI: 1, APM: 2, don't know: -1
###### not needed now ########

# this recursively unloads the given modules and all that depend on it
# first parameter is the module to be unloaded
# second parameter is the state file, where all unloaded modules are
#        recorded for reloading after resume.
# third parameter is the log file for the user.
unload_module(){
    local LOGFILE STATEFILE
    local MOD D C USED MODS I
    local UNL=$1 RET=1
    # we need the statefile to be set
    [ -z "$2" ] && DEBUG "no STATEFILE set in unload_module" ERROR && return 255
    [ -n "$3" ] && LOGFILE="$3" || LOGFILE=/dev/null
    STATEFILE="$2"
    # RET is the return code. If at least one module was unloaded, return 0.
    #     if no module was unloaded successfully, return 1
    #     if there was no module to unload, SUCCESS!, return 0
    while read MOD D C USED D; do
        [ "$MOD" != "$UNL" ] && continue
        if [ "$USED" == "-" ]; then
            if [ $C -eq 0 ]; then
                progress "${_M08} $UNL"
                echo "# trying to unload: $UNL" >> $STATEFILE
                echo "# trying to unload: $UNL" >> $LOGFILE
                if rmmod $UNL; then
                    echo "unloaded: $UNL" >> $STATEFILE
                    echo "unloaded: $UNL" >> $LOGFILE
                    RET=0
                else
                    DEBUG "could not unload module '$UNL'" WARN
                    echo "could not unload module '$UNL', usage count was 0." >> $LOGFILE
                fi
            else
                echo "could not unload module '$UNL', usage count: $C" >> $LOGFILE
            fi
        else
            USED=${USED//,/ }
            MODS=($USED)
            # it is slightly more likely to rmmod in one pass, if we try backwards.
            # is this really true? I don't know, but it doesn't hurt either.
            for I in `seq $[${#MODS[@]}-1] -1 0`; do
                MOD=${MODS[$I]}
                unload_module $MOD $STATEFILE $LOGFILE && RET=0
            done
            # if we unloaded at least one module, then let's try again!
            [ $RET -eq 0 ] && unload_module $UNL $STATEFILE $LOGFILE
            RET=$?
        fi
        return $RET
    done < /proc/modules
    # if we came this far, there was nothing to do, the module is no longer loaded.
    return 0
}

#######################################################
# unmount_fatfs function
# unmounts all (v)fat/ntfs partitions if possible.
#
unmount_fatfs(){
    local I J K # counters
    local D E   # dummies
    local RET  DEV MNT OPT TYPE MESSAGE MTAB
    declare -a DEV MNT OPT TYPE # arrays for the mtab entries

    progress "${_M04}"
    echo "== Unmounting FAT/NTFS filesystems: ==" >> $LSMOD_LOG
    MESSAGE=""; K=0
    MTAB=/etc/mtab # or /proc/mounts? which one is better?
    exec 2>&1   # why?
    # ugh, this is ugly. But remember, we could be having a mountpoint named
    # "/mnt/mount point name with whitespace in it"
    # yes, ugly quoting hell.
    eval `awk '
    BEGIN {X=0}
    { if (($3=="ntfs")||($3=="vfat")||($3==fat)) {
        Y=$2; gsub("\\\\\\\\", "\\\\\\\\\\\\", Y);
        print "DEV["X"]="$1;
        print "MNT["X"]=$(echo -e "Y")";
        print "TYP["X"]="$3;
        print "OPT["X"]="$4;
        X++}
    }' $MTAB`
    echo "Checking for mounted fat/ntfs filesystems:"
    # now do something with the list of devices / mountpoints...
    for (( I=0; ${#DEV[$I]}; I++ )); do
        echo "  device ${DEV[$I]} mounted on '${MNT[$I]}'" >> $LSMOD_LOG
        # stderr is additional information from fuser which we have to drop.
        # We need only the PIDs. They are on stdout.
        for J in $(fuser -m "${MNT[$I]}" 2>/dev/null);do
            while read D E; do
                case $D in
                    Name:)
                        if [ "$E" != "prepare_suspend" ]; then
                            MESSAGE=$MESSAGE" $E($J)"
                            echo "    is accessed by $E($J)" >> $LSMOD_LOG
                            let K++
                        fi
                        break ;;
                    *)  ;;
                esac
            done < /proc/$J/status
        done
    done
    [ $I -eq 0 ] && echo "  none found in $MTAB" >> $LSMOD_LOG
    exec 3>&2   # why?
    if [ $K -ne 0 ];then # one or more filesystems in use
        echo "  filesystems in use, asking user..." >> $LSMOD_LOG
        case $K in
            1)  MESSAGE="Process $MESSAGE is" ;;
            *)  MESSAGE="Processes $MESSAGE are" ;;
        esac
        MESSAGE=$MESSAGE" accessing an ntfs/fat mountpoint. \
Please make sure fat/ntfs mountpoints are unmountable before proceeding."
        question "$MESSAGE" "1"
        RET=$?
        if [ $RET -ne 0 ]; then
            echo "  user does not want to continue. aborting suspend" >> $LSMOD_LOG
            progress_finish
            $SCRIPT_RETURN $EV_ID 1 "prepare_sleep failed ($1): $MESSAGE"
            restore_after_sleep "$1"
            EXIT 1;
        fi
        echo "  user wants to continue anyway. Good luck." >> $LSMOD_LOG
    fi
    # no filesystem in use. Or user answered "proceed anyway".
    # umount ntfs/fat mount points ...
    for (( I=0; ${#DEV[$I]}; I++ )); do
        echo "# trying to umount device: ${DEV[$I]}" >> $STATE
        echo "trying to umount device: '${DEV[$I]}' '${MNT[$I]}' -t '${TYP[$I]}' -o '${OPT[$I]}'" >> $LSMOD_LOG
        umount ${MNT[$I]}; RET=$?
        if [ $RET -eq 0 ]; then
            # very verbose, but we have the whole mount command line ready for remount.
            # every variable in one line, makes it easier to re-parse (remember:
            # whitespace danger!)
            echo "unmounted: ${DEV[$I]}"              >> $STATE
            echo "# mountpoint unmounted: ${MNT[$I]}" >> $STATE
            echo "# fstype unmounted: -t ${TYP[$I]}"  >> $STATE
            echo "# options unmounted: -o ${OPT[$I]}" >> $STATE
            echo "  success." >> $LSMOD_LOG
        else
            echo "umount failed. Asking user what to do." >> $LSMOD_LOG
            MESSAGE="Unable to unmount device ${DEV[$I]}."
            DEBUG "$MESSAGE Asking the user" ERROR
            question "$MESSAGE Proceed anyway?" "1"
            RET=$?
            if [ $RET -ne 0 ]; then
                echo "user does not want to continue (good). Aborting suspend." >> $LSMOD_LOG
                progress_finish
                $SCRIPT_RETURN $EV_ID 1 "prepare_sleep failed ($1): $MESSAGE"
                restore_after_sleep "$1"
                EXIT 1;
            fi
            echo "user wants to continue anyway. Good luck." >> $LSMOD_LOG
        fi
    done
    echo "== FAT/NTFS filesystems unmounted ==" >> $LSMOD_LOG
}   ##### unmount_fatfs()

########################################################
# remount_fatfs function
# remounts the filesystems that were unmounted by
# unmount_fatfs()
remount_fatfs(){

    local D I   # dummy, counter
    local      DEV MNT TYP OPT
    declare -a DEV MNT TYP OPT
    
    echo >> $LSMOD_LOG
    echo "Remounting filesystems:" >> $LSMOD_LOG
    I=0
    while read DEV[$I]; do
        read MNT[$I]
        read TYP[$I]
        read OPT[$I]
        let I++
    done < <(awk -F 'unmounted: ' '/^unmounted:/ {
                print $2; getline;
                print $2; getline;
                print $2; getline;
                print $2 }' ${STATE}.resume )

    [ $I -eq 0 ] && echo "  not necessary." >> $LSMOD_LOG

    let I-- # incremented once too many times
    # we remount in reverse order...
    for (( ; I>=0 ; I-- )) ; do
        mount ${DEV[$I]} ${MNT[$I]} ${OPT[$I]} ; D=$?
        if [ $D -eq 0 ];then
            DEBUG "remounted ${DEV[$I]}" DIAG
            echo "  mounted '${DEV[$I]}' to '${MNT[$I]}', options '${OPT[$I]}'" >> $LSMOD_LOG
        else
            DEBUG "unable to remount ${DEV[$I]}" WARN
            echo "  could not mount '${DEV[$I]}' to '${MNT[$I]}', options '${OPT[$I]}', error $D" >> $LSMOD_LOG
        fi
    done
    
}   # remount_fatfs


#######################################################
# set_variables func
#
# function to set the variables according to what
# we are going to do.
# internally, use only in sleep_helper_functions
DEFAULT_S2D_UNLOAD="usb_storage sbp2 ohci_hcd uhci_hcd stir4200 ohci1394 ipw2200 rt2500 prism54 lt_modem Intel536 Intel537"
DEFAULT_S2R_UNLOAD="usb_storage sbp2 ohci_hcd uhci_hcd stir4200 ohci1394 ipw2200 rt2500 prism54 lt_modem Intel536 Intel537"
DEFAULT_STB_UNLOAD="usb_storage sbp2 ohci_hcd uhci_hcd stir4200 ohci1394 ipw2200 rt2500 prism54 lt_modem Intel536 Intel537"
DEFAULT_S2D_RESTART="slmodemd irda"
DEFAULT_S2R_RESTART="slmodemd irda"
DEFAULT_STB_RESTART="slmodemd irda"

set_variables(){
    case "$1" in
        suspend2disk)
            STATE=$STATE1
            LSMOD_LOG=$LSMOD_LOG1
            EJECT_PCMCIA=$SUSPEND2DISK_EJECT_PCMCIA
            MODULES_TO_UNLOAD="${UNLOAD_MODULES_BEFORE_SUSPEND2DISK:-$DEFAULT_S2D_UNLOAD}"
            SERVICES_TO_RESTART="${SUSPEND2DISK_RESTART_SERVICES:-$DEFAULT_S2D_RESTART}"
            RESTORE_CLOCK="$SUSPEND2DISK_RESTORE_CLOCK"
            UNMOUNT_FATFS="${SUSPEND2DISK_UNMOUNT_FATFS:-yes}"
            SWITCH_VT="$SUSPEND2DISK_SWITCH_VT"
            ;;
        suspend2ram)
            STATE=$STATE2
            LSMOD_LOG=$LSMOD_LOG2
            EJECT_PCMCIA=$SUSPEND2RAM_EJECT_PCMCIA
            MODULES_TO_UNLOAD="${UNLOAD_MODULES_BEFORE_SUSPEND2RAM:-$DEFAULT_S2R_UNLOAD}"
            SERVICES_TO_RESTART="${SUSPEND2RAM_RESTART_SERVICES:-$DEFAULT_S2R_RESTART}"
            RESTORE_CLOCK="$SUSPEND2RAM_RESTORE_CLOCK"
            UNMOUNT_FATFS="${SUSPEND2RAM_UNMOUNT_FATFS:-no}"
            SWITCH_VT="$SUSPEND2RAM_SWITCH_VT"
            ;;
        standby)
            STATE=$STATE3
            LSMOD_LOG=$LSMOD_LOG3
            EJECT_PCMCIA=$STANDBY_EJECT_PCMCIA
            MODULES_TO_UNLOAD="${UNLOAD_MODULES_BEFORE_STANDBY:-$DEFAULT_STB_UNLOAD}"
            SERVICES_TO_RESTART="${STANDBY_RESTART_SERVICES:-$DEFAULT_STB_RESTART}"
            RESTORE_CLOCK="$STANDBY_RESTORE_CLOCK"
            UNMOUNT_FATFS="${STANDBY_UNMOUNT_FATFS:-no}"
            SWITCH_VT="$STANDBY_SWITCH_VT"
            ;;
        *)
            echo "Wrong parameter '$1' in set_variables function in sleep_helper_functions script"
            ;;
    esac
}

#######################################################
#
# PREPARE_SLEEP FUNC
#
# Function to unload modules and stop services for 
# a soon triggered/coming sleep mode
#
# give first param:
#
# suspend2disk
# suspend2ram
# standby
#
# second param is the id

prepare_sleep(){
    local D E X # dummies,counters
    local RET TYPE ide
    
    [ -z $1 ] && echo "Do not invoke this script from console, it is automatically invoked by the powersave daemon" && EXIT 1

#    set_variables "$1" prepare_sleep
    
    rm -f $STATE
    rm -f $LSMOD_LOG

    DEBUG "Stop services: $SERVICES_TO_RESTART" DEBUG
    DEBUG "Modules to unload: $MODULES_TO_UNLOAD" DEBUG
    # there should be at least one line in $STATE or we will get an
    # harmless but ugly error in restore_after_sleep.
    echo "# this file records the system state at entering $1." > $STATE
    echo "$1 initiated: `date +'%F %X'`" > $LSMOD_LOG
    echo "Loaded modules:" >> $LSMOD_LOG
    lsmod >> $LSMOD_LOG
    echo >> $LSMOD_LOG
    echo "Memory info:" >> $LSMOD_LOG
    free >> $LSMOD_LOG
    echo >> $LSMOD_LOG
    echo "------------------------------------------------------------------------------" >> $LSMOD_LOG
    echo "========we are going to sleep, preparing.========" >> $LSMOD_LOG

    ####### Check for devices which need to be remounted after suspend #######
    let PERCENT+=$STEP
    [ "$UNMOUNT_FATFS" == "yes" ] && unmount_fatfs "$1" "$EV_ID"

    ####### S t o p   S e r v i c e s   ##########
    let PERCENT+=$STEP
    progress "${_M05}"

    D="$SERVICES_TO_RESTART"
    E=${D:+\'}${D:-none}${D:+\'}
    echo "Stopping services: ($E configured)" >> $LSMOD_LOG
    D=true
    if [ "$SERVICES_TO_RESTART" != "NONE" ]; then
        D=false
        for X in $SERVICES_TO_RESTART; do
            /etc/init.d/$X status >/dev/null 2>&1 ; RET=$? # redirect needed to workaround initscript bug.
            if [ $RET -eq 0 ]; then
                echo "stopping $X:" >> $LSMOD_LOG
                progress "${_M06} $X"
                /etc/init.d/$X stop 2>&1 | awk '{print "##  "$0}' >> $LSMOD_LOG
                echo "stopped: $X" >> $STATE
                DEBUG "Service $X stopped" DIAG
		D=true
            else
                DEBUG "Service $X stop requested but was not running. Return code: '$RET'" INFO
            fi
        done
    fi
    $D || echo "none running." >> $LSMOD_LOG
    ####### S t o p   S e r v i c e s   ##########

    ####### Eject PCMCIA cards          ##########
    let PERCENT+=$STEP
    if [ "$EJECT_PCMCIA" == "yes" ]; then
        progress "${_M03}"
        echo "ejecting PCMCIA cards..." >> $LSMOD_LOG
        $PCCARDCTL eject
    fi

    ####### U n l o a d   M o d u l e s ##########
    let PERCENT+=$STEP
    progress "${_M07}"

    echo >> $LSMOD_LOG
    D="$MODULES_TO_UNLOAD"
    E=${D:+\'}${D:-none}${D:+\'}
    echo "------------------------------------------------------------------------------" >> $LSMOD_LOG
    echo "Unloading modules: ($E configured)" >> $LSMOD_LOG
    if [ "$MODULES_TO_UNLOAD" ]; then
        for module in $MODULES_TO_UNLOAD; do
            [ "$module" == "NONE" ] && continue
            echo "checking $module" >> $LSMOD_LOG
            # unload_module handles not-loaded modules gracefully.
            if ! unload_module $module $STATE $LSMOD_LOG; then
		MESSAGE="$1 failed on unloading '$module'."
		if [ "$UNL" != "$module" -a -n "$UNL" ]; then
			MESSAGE="$MESSAGE The module that refused to unload was '$UNL'."
		fi
		MESSAGE="$MESSAGE Trying to recover..."
                DEBUG "$MESSAGE" ERROR
                notify "$MESSAGE" ERROR CONTINUE $EV_ID
                progress_finish
                $SCRIPT_RETURN $EV_ID 1 "$MESSAGE"
                restore_after_sleep "$1"
                EXIT 1
            fi
        done
        DEBUG "Modules unloaded" DIAG
    fi
    ####### U n l o a d   M o d u l e s ##########

    let PERCENT+=$STEP
    progress ""

    # sync #we sync later, so comment this out.
    ### TODO: implement nicer, what about non-IDE disks?
    ### is this really still needed? ...better safe than sorry.
########################################################################
# seife: i am commenting this out for now.
# we do lots of stuff afterwards, so this is probably not worth anything
# but may slow down things considerably.
# i will talk to the kernel guys if it is needed or not.
########################################################################
#    for ide in /proc/ide/ide?/hd?; do
#        TYPE=""
#        read TYPE < $ide/media
#        case "$TYPE" in
#        disk)
#            DEBUG "We have a disk: /dev/${ide##*/}, Execute: blockdev --flushbufs /dev/${ide##*/}" INFO
#            /sbin/blockdev --flushbufs /dev/${ide##*/} &>/dev/null
#            [ $? != 0 ] && DEBUG "blockdev returned an error" WARN
#            ;;
#        *) 
#            DEBUG "We have no disk: /dev/${ide##*/}" DEBUG
#            ;;
#        esac
#    done


    echo "------------------------------------------------------------------------------" >> $LSMOD_LOG
    echo "prepare_sleep finished for $1" >> $LSMOD_LOG
    echo "------------------------------------------------------------------------------" >> $LSMOD_LOG

}

########################################################
# restore_after_sleep FUNC
#
# Function to load previously unloaded modules and start
# the stopped services for after resuming from a sleep
# sleep mode. Modules are loaded in reverse unloading
# order, services are started in reverse stopping order.
# Only hotplug is an exception: it is always started
# first to handle hotplug events generated by module loading.
#
# give first param:
# suspend2disk
# suspend2ram
# standby
restore_after_sleep() {

    local D X

    [ -z $1 ] && echo "Do not invoke this script from console, it is automatically invoked by the powersave daemon" && EXIT 1

    echo >> $LSMOD_LOG
    echo "== restore_after_sleep: restart and reload everything ==" >> $LSMOD_LOG
    
    # first: set the clock...
    [ "$RESTORE_CLOCK" = "yes" ] && restore_clock

    # sanity check. We had this once...
    if [ ! -e $STATE ]; then
        echo "WARNING: Statefile '$STATE' disappeared during suspend!" >> $LSMOD_LOG
        DEBUG "Statefile '$STATE' disappeared during suspend." ERROR
    fi

    # clean up after ourselves..
    touch $STATE                        # if it is not there for any reason, create it.
    mv -f $STATE ${STATE}.resume        # now move it out of the way.

    echo >> $LSMOD_LOG
    echo "Resuming:" >> $LSMOD_LOG
    echo "---------" >> $LSMOD_LOG

    switch_to_X

    # special case: hotplug should be started before inserting modules
    if D=`awk 'BEGIN {X=1} /^stopped: (boot\.|)hotplug/ {print $2; X=0} END {exit X}' ${STATE}.resume`; then
        echo "first starting $D:" >> $LSMOD_LOG
        /etc/init.d/$D start 2>&1 | awk '{print "##  "$0}' >> $LSMOD_LOG
        DEBUG "Service $D started again" DIAG
    fi

#    echo $STATE
    echo >> $LSMOD_LOG
    echo "Reloading modules:" >> $LSMOD_LOG
    ####### L o a d   M o d u l e s       ##########
    if [ "$MODULES_TO_UNLOAD" -a -s "${STATE}.resume" ]; then
        for module in `tac ${STATE}.resume| awk '/^unloaded:/ { print $2 }'`; do
            echo "  $module" >> $LSMOD_LOG
            modprobe $module
        done
        DEBUG "Modules loaded" DIAG
    fi
    # rm ${STATE}.resume # disabled for debugging
    ####### L o a d   M o d u l e s       ##########

    ####### reinsert PCMCIA cards         ##########
    if [ "$EJECT_PCMCIA" == "yes" ]; then
        echo "inserting PCMCIA cards..." >> $LSMOD_LOG
        $PCCARDCTL insert
    fi

    echo >> $LSMOD_LOG
    echo "Restarting services:" >> $LSMOD_LOG
    ####### S t a r t   S e r v i c e s  (but not hotplug or boot.hotplug)  ##########
    if [ "$SERVICES_TO_RESTART" -a -s "${STATE}.resume" ]; then
        for X in `tac ${STATE}.resume | awk '/^stopped:/ { if (($2!="hotplug")&&($2!="boot.hotplug")) print $2 }'`; do
            echo "starting $X:" >> $LSMOD_LOG
            /etc/init.d/$X start 2>&1 | awk '{print "##  "$0}' >> $LSMOD_LOG
            DEBUG "Service $X started again" DIAG
        done
    fi
    ####### S t a r t   S e r v i c e s   ##########
    #
    # powersave workaround requires an initial socket request after suspend
    #$POWERSAVE -c >/dev/null

    ####### remount previously unmounted devices #######
    remount_fatfs

    $SCRIPT_RETURN $EV_ID 0 "restore_after_$1 finished"

    return 0
}

########################################################
# restore_clock function
# restores the system clock from the hardware clock.
# variables are already set, so no magic needed here.
#
restore_clock(){
    echo -n "Restoring system clock. From: $(date +%D_%T), " >> $LSMOD_LOG
    /sbin/hwclock --hctosys
    echo "To: $(date +%D_%T)" >> $LSMOD_LOG
    return 0
}

#####################################################################
# get_kernels
# gets a list of available kernels from /boot/grub/menu.lst
# kernels are in the array $KERNELS, output to stdout to be eval-ed.
get_kernels(){
    DEBUG "Running get_kernels()" INFO
    local MENU_LST="/boot/grub/menu.lst"
    local I DUMMY
    declare -i I=0 J=-1

    # build an array KERNELS with all the kernels in /boot/grub/menu.lst
    # the array MENU_ENTRIES contains the corresponding menu entry numbers
    # DEFAULT_BOOT contains the default entry.
    while read LINE; do
        case $LINE in
        title*)
            let J++ # increase for every menu entry, even for non-linux
            DEBUG "Found grub menu entry #${J}: '${LINE}'" INFO
            ;;
        default*)
            DUMMY=($LINE)                   # "default 0 #maybe a comment"
            echo "DEFAULT_BOOT=${DUMMY[1]}" #  ^^[0]^^ 1 ^^[2]^ 3 ^^[4]^^
            DEBUG "Default boot entry is '${DUMMY[1]}'" INFO
            ;;
        kernel*)
            DUMMY=($LINE) # kernel (hd0,1)/boot/vmlinuz-ABC root=/dev/hda2
            echo "KERNELS[$I]='${DUMMY[1]##*/}'" # vmlinuz-ABC
            echo "MENU_ENTRIES[$I]=$J"
            DEBUG "Found kernel entry #${I}: '${DUMMY[1]##*/}'" INFO
            let I++
            ;;
        *)  ;;
        esac
    done < $MENU_LST
}

#############################################################
# grub-once()
# does the same as the grubonce script from the grub package:
# selects which menu entry to boot next.
grub-once() {
    if [ -x "$GRUBONCE" ]; then
        DEBUG "running '$GRUBONCE $1'" DIAG
        $GRUBONCE $1
    else
        DEBUG "$GRUBONCE not found, not preparing bootloader" DIAG
    fi
}

#############################################################
# progress
# pops up and updates a progress bar.
# needs global variables:
#  PERCENT
#  EV_ID
# takes one argument: the message.
progress() {
    if [ -z "$PERCENT" -o -z "$EV_ID" -o -z "$SCRIPT_RETURN" ]; then
        DEBUG "progress called without variables set." ERROR
        return 1
    fi
    $SCRIPT_RETURN $EV_ID 4 "${PERCENT}${1:+|$1}"
}

#############################################################
# progress_finish
# closes the progress bar
progress_finish() {
    PERCENT=101
    progress ""
}

#############################################################
# switch_to_vt
# switches to text console 1
switch_to_vt() {
    if [ "$SWITCH_VT" = "yes" ]; then
        echo "console no: `fgconsole`" >> $STATE
        chvt 1
    fi
}

#############################################################
# switch_to_X
# switches back to the console we were before suspend
switch_to_X() {
    if [ "$SWITCH_VT" = "yes" ]; then
        local CONS
        CONS=$(awk -F : '/^console no:/ {print $2}' ${STATE}.resume)
        [ -n "$CONS" ] && chvt $CONS
        echo "switched back to console: '$CONS'" >> $LSMOD_LOG
    fi
}
