1: #!/usr/bin/perl -w
   2: # pinger for AGate200 link
   3: 
   4: use strict;
   5: use POSIX;
   6: use Net::Ping;
   7: use Net::Telnet;
   8: 
   9: my $host = '192.168.1.1';                       # other end of the link
  10: my $agate = '192.168.1.2';                      # AGate to (try to) reset
  11: my $admin = 'admin@domain.org';                 # someone who cares
  12: my $maxfail = 3;                                # his patience
  13: my $pause = 60;                                 # secs to sleep between pings
  14: my $fail = 0;                                   # consider it pingable apriori
  15: my $log = '/var/log/pinger.log';                # log file
  16: 
  17: my $pid = fork;
  18: exit if $pid;
  19: die "Couldn't fork: $!" unless defined($pid);
  20: POSIX::setsid() or die "Can't start a new session: $!";
  21: my $time_to_die = 0;
  22: $SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signal_handler;
  23: 
  24: open (LOG, "> $log") or die "Can't open logfile: $!\n";
  25: select(LOG);
  26: $|++;
  27: print scalar localtime, " Started succesfully\n";
  28: 
  29: my $ping = Net::Ping->new("icmp") or die "Can't create new ping: $!\n";
  30: 
  31: until ($time_to_die) {
  32:         if ($ping->ping($host)) {
  33: #               print scalar localtime, " Ping $host: success\n";
  34:                 $fail = 0;
  35:         } else {
  36:                 print scalar localtime, " Ping $host: fail\n";
  37:                 $fail++;
  38:         }
  39:         if ($fail == $maxfail) {
  40:                 my $result = fix();
  41:                 $result ||= 'success';
  42:                 print scalar localtime, " Reset: $result\n";
  43:                 notify($result);
  44:         }
  45:         if ($fail > $maxfail) {
  46:                 fix();
  47:         }
  48:         sleep($pause);
  49: }
  50: 
  51: sub signal_handler {
  52:         $ping->close();
  53:         print scalar localtime, " Exiting\n";
  54:         close LOG;
  55:         $time_to_die = 1;
  56: }
  57: 
  58: sub notify {
  59:         my $result = shift;
  60:         my $minutes = ($maxfail*$pause)/60;
  61: 
  62:         open(MAIL, "| mail -s 'Wake up!' $admin") or die "Couldn't fork: $!\n";
  63:         print MAIL <<MESSAGE;
  64: 
  65: $host is unpingable more than $minutes minutes!
  66: Result of the reset: $result.
  67: Examine the situation ASAP!
  68: 
  69: Love, Pinger
  70: MESSAGE
  71: 
  72:         close(MAIL) or die "Couldn't close: $!\n";
  73:         print scalar localtime, " Notification sent: $admin\n";
  74: }
  75: 
  76: sub fix {
  77:         print scalar localtime, " Trying to reset: $agate\n";
  78:         my $t = Net::Telnet->new(Errmode => "return");
  79:         $t->open($agate);
  80:         $t->waitfor('/A Choice :/');
  81:         $t->print('9');
  82:         $t->waitfor('/reenter.*$/');
  83:         $t->print('');
  84:         $t->waitfor('/Password :/');
  85:         $t->print('figatebe');
  86:         $t->waitfor('/\(y\/n\):/');
  87:         $t->print('y');
  88:         $t->close($agate); 
  89:         return $t->errmsg;
  90: }