#!/usr/bin/perl -w
# $Id: pingchecker 8 2014-09-19 13:51:01Z abalama $
use strict;

=head1 NAME

pingchecker - App::MonM checker PING (TCP/UDP/ICMP)

=head1 VERSION

Version 1.01

=head1 SYNOPSIS

    pingchecker [-p tcp|udp|icmp|stream|syn|external] [-P PORTNUMBER]
        [-t SECS] [-b BYTES] HOST

    Type pingchecker -h or pingchecker -? for more information

=head1 DEPENDENCES

L<Net::Ping>

=head1 AUTHOR

Serz Minus (Lepenkov Sergey) L<http://www.serzik.com> E<lt>minus@mail333.comE<gt>.

=head1 COPYRIGHT

Copyright (C) 1998-2014 D&D Corporation. All Rights Reserved

=head1 LICENSE

This program is distributed under the GNU GPL v3.

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 3 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.

See C<LICENSE> file

=cut

use Net::Ping;
use Try::Tiny;
use Getopt::Long;
use Pod::Usage;

use constant {
        TIMEOUT     => 5,
        PROTOCOLS   => [qw/tcp udp icmp stream syn external/],
    };

use vars qw/$VERSION/;
$VERSION = '1.01';

$SIG{INT} = sub { die "ABORTED\n"; };

$| = 1;  # autoflush

BEGIN {
    sub say { return unless -t; print STDOUT @_ ? @_ : '',"\n" }
    sub err { print STDERR @_ ? @_ : '',"\n" }
    sub tms { sprintf "[%s GMT]", scalar(gmtime(time())) }
    sub exception { say "FAILED"; err tms, " ", @_ }
}

Getopt::Long::Configure("bundling");
my %OPT;
GetOptions(\%OPT,
    "help|usage|h",
    "longhelp|man|m|?",
    "protocol|proto|prot|p=s",  # Protocol
    "timeout|time|t=i",         # Timeout
    "port|P=i",                 # Port
    "bytes|byte|b=i",           # Bytes
) || pod2usage(-exitval => 1, -verbose => 0);
pod2usage(-exitval => 0, -verbose => 1) if $OPT{help};
pod2usage(-exitval => 0, -verbose => 2) if $OPT{longhelp};

my @args = @ARGV ? @ARGV : (); # Arguments
my $host    = shift(@args) || 'localhost';
my $proto   = $OPT{protocol} || 'tcp';
   $proto   = 'tcp' unless grep {$_ eq $proto} @{(PROTOCOLS)};
my $to      = $OPT{timeout} || TIMEOUT;
my $port    = $OPT{port} || 0;
my $bts     = $OPT{bytes} || 0;

my $err = '';

say "App::MonM pingchecker/$VERSION";
say;
START: say "START ", tms;
try {
    my $p;
    if ($bts) {
      $p = Net::Ping->new($proto, $to, $bts)
    } else {
      $p = Net::Ping->new($proto, $to)
    }
    if ($port) {
        $p->port_number($port);
        $err = "Host \"$host\" ($proto) not reachable on port \"$port\"" unless $p->ping($host,$to);
    } else {
        $err = "Host \"$host\" ($proto) not reachable" unless $p->ping($host,$to);
    }
    $p->close();
    undef($p);
}
catch {
    $err = $_;
};
FINISH: say "FINISH ", tms;
say;

if ($err) { 
    exception($err);
    print STDOUT "FAILED" unless -t;
} else { 
    say "OK";
    print STDOUT "OK" unless -t;
}

exit 0;
__END__
