#!/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);
        }
    }
}
