#!/usr/local/bin/perl

use strict;
use Getopt::Std;

$| = 1;

my $USAGE = <<_EOU;
usage: execute_all.pl [-r username] filename { ip-file | ip-addr ... }
  -r  Skript als dieser Benutzer remote auf den Rechnern ausführen
_EOU

my $FPING = "/usr/sbin/fping";

main: {
   # Optionen
   my %opt;
   my $opt_ok = getopts ('r:', \%opt);

   # Parameter
   my $command_file = shift @ARGV;
   my @ip_addrs     = @ARGV;

   print ($USAGE), exit 1
       if not $opt_ok or not $command_file or not @ip_addrs;

   # per fping die Liste der IPs reduzieren auf die,
   # die tatsächlich online sind
   my $command;
   if ( -f $ip_addrs[0] ) {
       $command = "$FPING -A -q -a -r 3 \$(cat $ip_addrs[0]) ".
              "2>/dev/null | sort";
   } else {
       my $ip_addrs = join (" ", @ip_addrs);
       $command = "$FPING -A -q -a -r 3 $ip_addrs ".
              "2>/dev/null | sort";
   }

   # fping-Kommando ausführen
   my @fping_ip_addrs = split (/\s+/, qx[$command]);
   print ("Keine IP erreichbar.\n"), exit 1 if not @fping_ip_addrs;

   # einige IPs nicht erreichbar?
   if ( @fping_ip_addrs != @ip_addrs ) {
       print "Warnung: Folgende IP-Adressen sind nicht erreichbar:\n";
       my %fping_ip_addrs;
       @fping_ip_addrs{@fping_ip_addrs} = @fping_ip_addrs x (1);
       print join (" ", grep {!$fping_ip_addrs{$_}} @ip_addrs),"\n";
       print "Weiter [Return], Abbrechen [Strg+C] ";
       <STDIN>;
   }

   if ( $opt{r} ) {
       # Skript-Datei remote auf den Rechnern ausführen
       open (FH, $command_file)
           or die "can't read $command_file: $!";
       $command = join ('', <FH>);
       close FH;
       foreach my $ip (@fping_ip_addrs) {
           print "Führe Skript remote aus auf '$ip'...\n";
           system ("ssh", "$opt{r}\@$ip", $command);
       }
   } else {
       # Skript-Datei lokal mit IP als Parameter ausführen
       print ("Skript ist nicht ausführbar.\n"), exit 1
           if not -x $command_file;
       foreach my $ip (@fping_ip_addrs) {
           print "Führe Skript lokal aus mit '$ip'...\n";
           system ($command_file, $ip);
       }
   }
}