#!/usr/bin/perl
#
# Xymon test to check tftp servwrs
#
# This server script is based on Roland Rosenfeld's conn6 test which
# itself is based on a shell script from the Debian hobbit-plugins
# package, but rewritten in Perl.
#
# Just add tftp to the services of a host and this script will try to
# download the file /pxelinux.0 via TFTP from the given host.
#
# Alternatively you can add colon separated a file or path which
# should be used to test the TFTP server.
#
# Currently only one file per server can be tested.
#
# Examples:
# 10.1.2.3 foo # ftp tftp
# 10.1.2.4 bar # smtp tftp:bootmgr.exe
# 10.1.2.5 baz # tftp:/sparc.img
#
# Copyright (c) 2011       Roland Rosenfeld <roland@spinnaker.de>
# Copyright (c) 2011-2012  Axel Beckert <abe@debian.org>
#
#    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 Data::Dumper;

use Hobbit;
use Net::TFTP;

my $default_path = '/pxelinux.0';
my %remote_path  = ();

open(HOSTGREP, '-|', "$ENV{XYMONHOME}/bin/xymongrep tftp tftp:\* dialup" )
  || croak("cannot run $ENV{XYMONHOME}/bin/xymongrep");
while (<HOSTGREP>) {
    if (/^(\d+\.\d+\.\d+\.\d+)\s+(\S+)\s+#\s+(.*)$/) {
        my ( $ipv4, $host, $services ) = ( $1, $2, $3 );

        # parse services:
        my $dialup = 0;
        my @destinations;
        foreach my $service ( split /\s+/, $services ) {
            if ( $service eq 'dialup' ) {
                $dialup = 1;
            }
            elsif ( $service eq 'tftp' ) {
                push @destinations, $host;
                $remote_path{$host} = $default_path;
            }
            elsif ( $service =~ /^tftp:(.*)$/ ) {
                push @destinations, $host;
                $remote_path{$host} = $1;
            }
        }
        next if $#destinations == -1;    # no tftp found, only dialup

        my $output = '';
        my $color  = 'green';
        foreach my $destination (@destinations) {
            my $tftp = Net::TFTP->new($destination);
            my $bb = new Hobbit( { test => 'tftp', hostname => $destination } );

            my $fh    = $tftp->get( $remote_path{$destination} );
            my $error = $tftp->error;

            my $remote_file_contents = undef;
            read( $fh, $remote_file_contents, 1 );

            if ($remote_file_contents) {
                if ($error) {
                    if ( $dialup == 1 ) {
                        $bb->add_color('clear');
                        $bb->print("&red Couldn't download $remote_path{$destination} from $destination via TFTP");
                    }
                    else {
                        $bb->color_line('red',"Couldn't download $remote_path{$destination} from $destination via TFTP");
                    }
                }
                else {
                    $bb->color_line('green',"Successfully downloaded $remote_path{$destination} from $destination via TFTP");
                }
            }
            else {
                if ( $dialup == 1 ) {
                    $bb->add_color('clear');
                    $bb->print("&red Couldn't download $remote_path{$destination} from $destination via TFTP");
                }
                else {
                    $bb->color_line('red',"Couldn't download $remote_path{$destination} from $destination via TFTP");
                }
            }
            $bb->send();
        }
    }
}
