#!/usr/bin/perl # Copyright (C) 2008-2015 Petter Reinholdtsen # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # 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. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA use strict; use warnings; use Sys::Syslog qw(openlog syslog closelog LOG_NOTICE); my $delay = 5; my $wakeupblock = "/etc/shutdown-at-night/shutdown-at-night-nowakeup-others"; my $wakeuplist = "/etc/shutdown-at-night/clients"; my $wakeupgenerator = "/etc/shutdown-at-night/clients-generator"; my %hwaddrs; sub load_clients { my $fh = shift; while (<$fh>) { chomp; my ($ip, $hwaddr) = split(/\s+/); $hwaddrs{$ip} = $hwaddr; } } if ( -f $wakeupblock) { logmsg("not waking other clients, blocked by $wakeupblock"); exit 0; } # Locate hosts to wake up, from file if ( -f $wakeuplist ) { if (open(CLIENTS, "<", $wakeuplist)) { load_clients(*CLIENTS); close(CLIENTS); } } # Or using a dynamic script if ( -x $wakeupgenerator ) { if (open(CLIENTS, "$wakeupgenerator |")) { load_clients(*CLIENTS); close(CLIENTS); } } my %alive; map { $alive{$_} = 1; } get_alive_list(keys %hwaddrs); # Calculate when to start, assuming 20-30 seconds between each host #my $duration = $delay * scalar keys %hwaddrs; #my $allup = time(); # Start sending wakeup calls for my $ip (sort keys %hwaddrs) { if (! defined $alive{$ip}) { logmsg("sending wake-on-lan to $ip [$hwaddrs{$ip}]"); wakeup($ip, $hwaddrs{$ip}); sleep $delay; } else { logmsg("not sending wake-on-lan to already awake $ip [$hwaddrs{$ip}]"); } } # exit exit 0; sub wakeup { my ($ip, $hwaddr) = @_; `wakeonlan $hwaddr`; } sub get_alive_list { my @addresses = @_; if ($#addresses > 0) { return split(/\s+/, `fping -a @addresses 2>/dev/null`); } else { return []; } } sub logmsg { my $msg = shift; openlog("wakeupclients", undef, 'user'); syslog(LOG_NOTICE, "%s", $msg); closelog; }