From d09cc1546b4ef3d9e29e23520f08a2d3abd9ce9d Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 15 Jan 2020 12:11:39 +0100 Subject: Use original deadline if user logged out We add 300 seconds to the deadline if a user is currently logged in. Even if the user logs out immediately, we still wait those extra 5 minutes. Add ugly code to immediately trigger the shutdown (or whatever) in that case. --- src/main.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index c3d2cd0..35d983e 100644 --- a/src/main.c +++ b/src/main.c @@ -35,6 +35,7 @@ static const char *shutdownActions[SHUTDOWN_ENUM_END] = { #define TABMAX (20) static struct { time_t deadline; // MONOTONIC; 0 = none, or last one was disarmed and time elapsed past deadline + time_t noUserDeadline; // In case no user is logged in, consider this deadline too enum Shutdown action; bool disarmed; bool force; @@ -219,13 +220,17 @@ int main( int argc, char **argv ) } // End loop over users const time_t monoNOW = now(); // See if any reboot or poweroff is due (if none is currently pending or still 5min+ away) - if ( ! nextAction.force && config.shutdowns > 0 && ( nextAction.deadline == 0 || nextAction.deadline - monoNOW > 300 ) ) { + if ( ! nextAction.force && config.shutdowns > 0 // Next action is not forced, and have shutdown schedule + // and no current action pending, or next action more than 5 mins away + && ( nextAction.deadline == 0 || nextAction.deadline - monoNOW > 300 ) ) { + // next action is more than 5 mins away, reset for now if ( nextAction.deadline != 0 && nextAction.deadline - monoNOW > 300 ) { nextAction.deadline = 0; } const time_t NOW = time( NULL ); time_t deadline; int delta; + // Loop through all scheduled actions and find the next one for ( idx = 0; idx < config.shutdowns; ++idx ) { deadline = combineTime( NOW, &config.shutdown[idx] ); if ( deadline == 0 ) @@ -234,6 +239,7 @@ int main( int argc, char **argv ) if ( delta >= -6 && ( nextAction.deadline == 0 || ( nextAction.deadline - monoNOW - 3 ) > delta ) ) { // Engage nextAction.deadline = monoNOW + ( delta < 0 ? 0 : delta ); + nextAction.noUserDeadline = nextAction.deadline; nextAction.disarmed = false; nextAction.action = config.shutdown[idx].action; if ( delta < 300 ) { @@ -264,12 +270,22 @@ int main( int argc, char **argv ) } if ( nextAction.deadline != 0 && ( count == 0 || ( monoNOW - lastActivity ) >= config.minIdle || nextAction.force ) ) { // Some action seems pending - const int remaining = nextAction.deadline - monoNOW; + int remaining; + // No user logged in, no user deadline is max. 300 seconds in the past -> use that value + if ( userCount == 0 && nextAction.noUserDeadline + 300 > monoNOW && nextAction.noUserDeadline < nextAction.deadline ) { + remaining = nextAction.noUserDeadline - monoNOW; + if ( remaining < 0 ) { + remaining = 0; + } + } else { + remaining = nextAction.deadline - monoNOW; + } if ( remaining < -60 ) { if ( ! nextAction.disarmed ) { - fprintf( stderr, "Missed planned action!? Late by %d seconds. Ignored.\n", remaining ); + fprintf( stderr, "Missed planned action!? Late by %d seconds. Ignored.\n", -remaining ); } nextAction.deadline = 0; + nextAction.noUserDeadline = 0; } else if ( ! nextAction.disarmed ) { if ( remaining <= 1 ) { // Execute! @@ -551,6 +567,7 @@ void main_queueAction( enum Shutdown action, int delta ) if ( delta < 0 || action < 0 || action >= SHUTDOWN_ENUM_END ) return; time_t monoNOW = now(); + int realDelta = delta; if ( userCount != 0 ) { int idleTime = monoNOW - lastActivity; if ( idleTime < 3600 ) { @@ -566,6 +583,7 @@ void main_queueAction( enum Shutdown action, int delta ) if ( nextAction.deadline == 0 || ( nextAction.deadline - monoNOW - 3 ) > delta ) { // Engage nextAction.deadline = monoNOW + delta; + nextAction.noUserDeadline = monoNOW + realDelta; nextAction.disarmed = false; nextAction.force = true; nextAction.action = action; -- cgit v1.2.3-55-g7522