summaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c102
1 files changed, 60 insertions, 42 deletions
diff --git a/src/main.c b/src/main.c
index f9960f5..032aa27 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,13 +25,6 @@ static time_t lastActivity;
static struct user *users;
// List of reboot and shutdown times
-enum Shutdown {
- REBOOT = 0,
- POWEROFF,
- KEXEC,
- SUSPEND,
- SHUTDOWN_ENUM_END,
-};
static const char *shutdownActions[SHUTDOWN_ENUM_END] = {
[REBOOT] = "reboot",
[POWEROFF] = "poweroff",
@@ -39,11 +32,6 @@ static const char *shutdownActions[SHUTDOWN_ENUM_END] = {
[SUSPEND] = "suspend",
};
#define TABMAX (20)
-struct time {
- int hour;
- int minute;
- enum Shutdown action;
-};
static struct {
time_t deadline; // MONOTONIC; 0 = none, or last one was disarmed and time elapsed past deadline
enum Shutdown action;
@@ -63,6 +51,8 @@ static struct {
int gracePeriod;
} config;
+static time_t combineTime( const time_t now, const struct time * time );
+
static void getXAuthority( struct user *user );
static bool parseCmdline( int argc, char **argv );
@@ -216,37 +206,22 @@ int main( int argc, char **argv )
nextAction.deadline = 0;
}
const time_t NOW = time( NULL );
- struct tm tmNOW;
- if ( localtime_r( &NOW, &tmNOW ) != NULL ) {
- struct tm dtime;
- time_t deadline;
- int delta;
- for ( idx = 0; idx < config.shutdowns; ++idx ) {
- dtime = tmNOW;
- dtime.tm_hour = config.shutdown[idx].hour;
- dtime.tm_min = config.shutdown[idx].minute;
- dtime.tm_sec = 0;
- deadline = mktime( &dtime );
- if ( deadline + 6 < NOW ) {
- // Try again tomorrow
- dtime.tm_mday++;
- deadline = mktime( &dtime );
- }
- if ( deadline == -1 ) {
- perror( "Cannot convert shutdown entry to time_t via mktime" );
- continue;
- }
- delta = deadline - NOW;
- if ( delta >= -6 && ( nextAction.deadline == 0 || ( nextAction.deadline - monoNOW - 3 ) > delta ) ) {
- // Engage
- nextAction.deadline = monoNOW + ( delta < 0 ? 0 : delta );
- nextAction.disarmed = false;
- nextAction.action = config.shutdown[idx].action;
- if ( delta < 300 ) {
- printf( "Scheduling reboot/poweroff in %d seconds\n", delta );
- }
- CAP_SLEEP( delta );
+ time_t deadline;
+ int delta;
+ for ( idx = 0; idx < config.shutdowns; ++idx ) {
+ deadline = combineTime( NOW, &config.shutdown[idx] );
+ if ( deadline == 0 )
+ continue;
+ delta = deadline - NOW;
+ if ( delta >= -6 && ( nextAction.deadline == 0 || ( nextAction.deadline - monoNOW - 3 ) > delta ) ) {
+ // Engage
+ nextAction.deadline = monoNOW + ( delta < 0 ? 0 : delta );
+ nextAction.disarmed = false;
+ nextAction.action = config.shutdown[idx].action;
+ if ( delta < 300 ) {
+ printf( "Scheduling reboot/poweroff in %d seconds\n", delta );
}
+ CAP_SLEEP( delta );
}
}
}
@@ -324,6 +299,32 @@ int main( int argc, char **argv )
return 0;
}
+static time_t combineTime( const time_t now, const struct time * time )
+{
+ struct tm dtime;
+ if ( localtime_r( &now, &dtime ) == NULL )
+ return 0;
+ time_t result;
+ dtime.tm_hour = time->hour;
+ dtime.tm_min = time->minute;
+ dtime.tm_sec = 0;
+ result = mktime( &dtime );
+ if ( result + 6 < now ) {
+ // Try again tomorrow
+ dtime.tm_mday++;
+ result = mktime( &dtime );
+ }
+ if ( result == -1 ) {
+ perror( "Cannot convert struct tm to time_t via mktime" );
+ return 0;
+ }
+ if ( result < now ) {
+ fprintf( stderr, "combineTime: Even +1 day seems in the past!?\n" );
+ return 0;
+ }
+ return result;
+}
+
/**
* This doesn't really use any clever logic but rather assumes that
* it will be $HOME/.Xauthority
@@ -359,6 +360,7 @@ static struct option long_options[] = {
{ "dpms-timeout", required_argument, NULL, 'dpms' },
{ "grace-period", required_argument, NULL, 'gp' },
{ "cmd", required_argument, NULL, 'cmd' },
+ { "send", required_argument, NULL, 'send' },
{ "test", no_argument, NULL, 't' },
{ NULL, 0, NULL, 0 }
};
@@ -435,6 +437,8 @@ static bool parseCmdline( int argc, char **argv )
case 'cmd':
config.shutdownCommand = strdup( optarg );
break;
+ case 'send':
+ exit( !rpc_send( optarg ) );
default:
fprintf( stderr, "Unhandled command line option %d, aborting\n", ch );
return false;
@@ -496,3 +500,17 @@ struct user* main_getUser( const char *terminal )
return NULL;
}
+void main_queueAction( enum Shutdown action, int delta )
+{
+ if ( delta < 0 || action < 0 || action >= SHUTDOWN_ENUM_END )
+ return;
+ time_t monoNOW = now();
+ if ( nextAction.deadline == 0 || ( nextAction.deadline - monoNOW - 3 ) > delta ) {
+ // Engage
+ nextAction.deadline = monoNOW + delta;
+ nextAction.disarmed = false;
+ nextAction.action = action;
+ printf( "RPC: Scheduling reboot/poweroff in %d seconds\n", delta );
+ }
+}
+