#!/bin/sh
#
# VDR shutdown hook for ACPI - Tobias Grimm <vdr@e-tobi.net>
# --------------------------
#
# This shutdown hook sets the wakeup time for the next timer using
# ACPI.
#

# read arguments for acpi-wakeup from conf-file
. /etc/vdr/vdr-addon-acpiwakeup.conf

# take care of UTC setting
if [ -f /etc/default/rcS ]; then
    UTC=$(egrep "^[^#]*UTC=" /etc/default/rcS | tail -n1 | cut -d= -f2)
fi

nop()
{
    # No Operation
    echo -n ""
}

if [ "$UTC" = "yes" ]; then
    TIME_FUNCTION="gmtime"
else
    TIME_FUNCTION="localtime"
fi

# Defaults:
[ -z "$ACPI_ENABLED" ]       && export ACPI_ENABLED="yes"
[ -z "$ACPI_REGULAR_DAYS" ]  && export ACPI_REGULAR_DAYS="0"
[ -z "$ACPI_REGULAR_TIME" ]  && export ACPI_REGULAR_TIME="00:00"
[ -z "$ACPI_START_AHEAD" ]   && export ACPI_START_AHEAD="5"

[ -z "$WAKEALARM" ]          && export WAKEALARM="/sys/class/rtc/rtc0/wakealarm"

TIMER=$1

TimeToString()
{
    echo $(perl -e "(\$s,\$mi,\$h,\$d,\$mo,\$y,\$t,\$t,\$t)=\
    $TIME_FUNCTION($1); printf(\"%04d-%02d-%02d %02d:%02d:%02d\",\
    \$y+1900,\$mo+1,\$d,\$h,\$mi,\$s);")
}

AcpiError()
{
    LOG="No writeable $WAKEALARM found. ACPI needed!!!"
    echo "LOG_MESSAGE=\"$LOG\""
    echo "ABORT_MESSAGE=\"ACPI not installed, shutdown aborted!\""
    exit 1
}

ResetWakeupTimeKernelGte2_6_23()
{
    if [ -w $WAKEALARM ]; then
        LOG="Writing to $WAKEALARM"
        echo "LOG_MESSAGE=\"$LOG\""
        echo 0 >$WAKEALARM
        return $?
    else
        return 1
    fi
}

SetWakeupTimeKernelGte2_6_23()
{
    if [ -w $WAKEALARM ]; then
        if ResetWakeupTimeKernelGte2_6_23 ; then
            LOG="Writing to $WAKEALARM"
            echo "LOG_MESSAGE=\"$LOG\""
            echo "$1" >$WAKEALARM
            return $?
        fi
    fi
    return 1
}


ResetWakeupTime()
{
    LOG="Resetting ACPI alarm time"
    echo "LOG_MESSAGE=\"$LOG\""
    ResetWakeupTimeKernelGte2_6_23 || AcpiError
}

SetWakeupTime()
{
    LOG="Setting ACPI alarm time to: `TimeToString $1`"
    echo "LOG_MESSAGE=\"$LOG\""
    SetWakeupTimeKernelGte2_6_23 "$1" || AcpiError
}

IsRegularDayOfWeek()
{
    local day
    for day in $ACPI_REGULAR_DAYS ; do
        if [ "$day" = "`date -d \"@$1\" +%u`" ] ; then
            return 0
        fi
    done
    return 1
}

if [ $ACPI_ENABLED = "yes" ]; then
    # check if we should wake up before the next timer:
    if [ "$ACPI_REGULAR_DAYS" != "0" ]; then
        REGULAR_TIMER=$(date -d "$ACPI_REGULAR_TIME" +%s)
        if [ $REGULAR_TIMER -lt $(date +%s) ] ; then
            REGULAR_TIMER=$(($REGULAR_TIMER + 24 * 60 * 60))
        fi
        while ! IsRegularDayOfWeek $REGULAR_TIMER ; do
            REGULAR_TIMER=$(($REGULAR_TIMER + 24 * 60 * 60))
        done

        if [ $TIMER -eq 0 ] || [ $TIMER -gt 0 -a $REGULAR_TIMER -lt $TIMER ] ; then
            TIMER=$REGULAR_TIMER
        fi
    fi
    if [ $TIMER -gt 0 ]; then
        MIN_START_AHEAD=$((`date +%s` + 60 * $ACPI_START_AHEAD))
        if [ $MIN_START_AHEAD -gt $TIMER ]; then
            LOG="Can not set wakeup time less than $ACPI_START_AHEAD minutes ahead."
            echo "LOG_MESSAGE=\"$LOG\""
            echo "ABORT_MESSAGE=\"Wakeup in less than $ACPI_START_AHEAD minutes, aborting!\""
            exit 1
        fi

        # adjust wakeup time by ACPI_START_AHEAD
        TIMER=$(($TIMER - 60 * $ACPI_START_AHEAD))
    fi

    if [ $TIMER -eq 0 ]; then
        ResetWakeupTime
    else
        SetWakeupTime "$TIMER"
    fi

else
    LOG="ACPIWakeup functionality is disabled"
    echo "LOG_MESSAGE=\"$LOG\""
fi
