diff options
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/vyatta-poweroff.pl | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/scripts/vyatta-poweroff.pl b/scripts/vyatta-poweroff.pl new file mode 100755 index 0000000..9103900 --- /dev/null +++ b/scripts/vyatta-poweroff.pl @@ -0,0 +1,189 @@ +#!/usr/bin/perl +# +# Module: vyatta-poweroff.pl +# +# **** License **** +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Based on the original vyatta-reboot script by Stig Thormodsrud +# +# Author: Alex Harpin +# Date: Jan 2015 +# Description: Script to shutdown or schedule a shutdown +# +# **** End License **** +# + +use lib "/opt/vyatta/share/perl5/"; +use Getopt::Long; +use POSIX; +use IO::Prompt; +use Sys::Syslog qw(:standard :macros); + +use strict; +use warnings; + +my $poweroff_job_file = '/var/run/poweroff.job'; + +sub parse_at_output { + my @lines = @_; + + foreach my $line (@lines) { + if ($line =~ /error/) { + return (1, '', ''); + } elsif ($line =~ /job (\d+) (.*)$/) { + return (0, $1, $2); + } + } + return (1, '', ''); +} + +sub is_poweroff_pending { + if ( ! -f $poweroff_job_file) { + return (0, ''); + } + my $job = `cat $poweroff_job_file`; + chomp $job; + my $line = `atq $job`; + if ($line =~ /\d+\s+(.*)\sa root$/) { + return (1, $1); + } else { + return (0, ''); + } +} + +sub do_poweroff { + my $login = shift; + + syslog("warning", "Poweroff now requested by $login"); + if (!system("sudo /sbin/shutdown -h now")) { + exec("sudo /usr/bin/killall sshd"); + } +} + +sub cancel_poweroff { + my ($login, $time) = @_; + + my $job = `cat $poweroff_job_file`; + chomp $job; + system("atrm $job"); + system("rm $poweroff_job_file"); + syslog("warning", "Poweroff scheduled for [$time] - CANCELED by $login"); +} + +my ($action, $at_time, $now); +GetOptions("action=s" => \$action, + "at_time=s" => \$at_time, + "now!" => \$now, +); + +if (! defined $action) { + die "no action specified"; +} + +openlog($0, "", LOG_USER); +my $login = getlogin() || getpwuid($<) || "unknown"; + +if ($action eq "poweroff") { + + my ($rc, $time) = is_poweroff_pending(); + if ($rc) { + if (defined $now) { + cancel_poweroff($login, $time); + do_poweroff($login); + } else { + print "Poweroff already scheduled for [$time]\n"; + exit 1; + } + } + + if (defined $now) { + do_poweroff($login); + } else { + if (prompt("Proceed with poweroff? (Yes/No) [No] ", -ynd=>"n")) { + do_poweroff($login); + } else { + print "Poweroff canceled\n"; + exit 1; + } + } +} + +if ($action eq "poweroff_at") { + if (! -f '/usr/bin/at') { + die "Package [at] not installed"; + } + + if (! defined $at_time) { + die "no at_time specified"; + } + + my ($rc, $rtime) = is_poweroff_pending(); + if ($rc) { + print "Poweroff already scheduled for [$rtime]\n"; + exit 1; + } + + my @lines = `echo true | at $at_time 2>&1`; + my ($err, $job, $time) = parse_at_output(@lines); + if ($err) { + print "Invalid time format [$at_time]\n"; + exit 1; + } + system("atrm $job"); + + print "\nPoweroff scheduled for $time\n\n"; + if (!prompt("Proceed with poweroff schedule? [confirm] ", -y1d=>"y")) { + print "Poweroff canceled\n"; + exit 1; + } + + @lines = `echo "sudo /sbin/shutdown -h now && sudo /usr/bin/killall sshd" | at $at_time 2>&1`; + ($err, $job, $time) = parse_at_output(@lines); + if ($err) { + print "Error: unable to schedule poweroff\n"; + exit 1; + } + system("echo $job > $poweroff_job_file"); + print "\nPoweroff scheduled for $time\n"; + syslog("warning", "Poweroff scheduled for [$time] by $login"); + + exit 0; +} + +if ($action eq "poweroff_cancel") { + + my ($rc, $time) = is_poweroff_pending(); + if (! $rc) { + print "No poweroff currently scheduled\n"; + exit 1; + } + cancel_poweroff($login, $time); + print "Poweroff canceled\n"; + exit 0; +} + +if ($action eq "show_poweroff") { + + my ($rc, $time) = is_poweroff_pending(); + if ($rc) { + print "Poweroff scheduled for [$time]\n"; + exit 0; + } else { + print "No poweroff currently scheduled\n"; + } + exit 1; +} + +exit 1; |