I've been comparing my Mon setup with 1.0pre5, and turned up a few
fixes that I made years ago that never made it into the mainstream.

One of them was a whole bunch of fixes to nntp.monitor.  In particular,
error messages that formerly were only available with debug options
(like "no welcome message") are delivered to Mon as you would expect.
The debug option is still there, but now it dumps the transaction with
the news server so you can see what's going on.  I've also added file
support for the user/password for auth testing, so that you don't need
to let your Mon users see the login info in mon.cgi.  The option
for testing news feeding hosts without "mode reader" now actually works,
and it even passes perl -w / use strict checks.

The new monitor is attached.

        -- Ed
#!/usr/bin/perl -w
#
# Use try to connect to a nntp server, and
# wait for the right output.
#
# For use with "mon".
#
my $usage="Usage: nntp.monitor [-p port] [-t timeout] [-g group] [-f] [-A 
authfile] [-u user] [-a password] [-d] host [host...]\n";
#
#  -A authfile # authfile has two lines, first is username, then password
#              # script will use them with "authinfo"
# -u user -a pass # if you want to pass auth info on command line
#
#  -d for debugging
#
# This monitor connects to the NNTP server(s), checks for a greeting,
# then performs a "mode reader" and a "group (groupname)", and then disconnects.
# If the group is not specified by the -g option, then "control" is assumed.
#
# if "-f" is supplied, then it is assumed that a feeder is being tested,
# and the "mode reader" and "group (groupname)" commands are not executed.
#
# Adapted from "http.monitor" by
# Jim Trocki, [EMAIL PROTECTED]

# minor bugfixes by [EMAIL PROTECTED] on Thu Mar  1 18:26:43 EST 2001
# news authentication added by [EMAIL PROTECTED] on Wed Jun 27 20:02:08 EDT 2001
# Added auth syntax from Kai Schaetzl/conactive.com to mainstream this version

#
# http.monitor written by
#
# Jon Meek
# American Cyanamid Company
# Princeton, NJ
#
# $Id: nntp.monitor,v 1.2 2005/02/12 03:20:15 root Exp $
#
#    Copyright (C) 1998, Jim Trocki
#
#    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

use Getopt::Std;
use English;
use strict;

use vars qw($opt_g $opt_p $opt_t $opt_f $opt_d $opt_A $opt_u $opt_a);
getopts ("a:fg:p:t:u:dA:") || die $usage;

my $GROUP = $opt_g || 'control';
my $PORT = $opt_p || 119;
my $TIMEOUT = $opt_t || 30;
my $FEEDER = $opt_f;
my $DEBUG = $opt_d || "";
my $AUTHFILE = $opt_A || "";
my ($username, $password);

my @failures = ();
my @details=   ();


if ($AUTHFILE)
{
        open(AUTH, "<$AUTHFILE")|| die "nntp.monitor: (local error) cannot open 
authfile $AUTHFILE: $!\n";
        $username= <AUTH> || die "nntp.monitor: (local error) cannot read 
username from authfile $AUTHFILE: $!\n";
        $password= <AUTH> || die "nntp.monitor: (local error) cannot read 
password from authfile $AUTHFILE: $!\n";
        close AUTH;
}

# if user or pass specified on commandline, override auth file
$username= $opt_u if $opt_u;
$password= $opt_a if $opt_a;

foreach my $host (@ARGV) {

    if (! &nntpGET($host, $PORT)) {
        push (@failures, $host);
    }
}

if (@failures == 0) {
    exit 0;
}

print join (" ", sort @failures), "\n";
print sort @details if (scalar @details) > 0;

exit 1;


sub nntpGET {
    use Socket;
    use Sys::Hostname;

    my($Server, $Port) = @_;
    my($ServerOK, $TheContent);

    $ServerOK = 0;

    $TheContent = '';

###############################################################
    eval {

        local $SIG{ALRM} = sub { die "Timeout Alarm" };
        alarm $TIMEOUT;
        my $result = &OpenSocket($Server, $Port); # Open a connection to the 
server
        if (!$result) { # Failure to open the socket
            print "$Server: Unable to open socket\n" if $DEBUG;
            return '';
        }

        #
        # welcome message
        #
        transact("", '^2\d\d', "$Server: No welcome message\n") || return 0;

        if (!$FEEDER) {
            #
            # mode reader, wait for OK response
            #
        transact("mode reader", '^2\d\d', "$Server: Unable to perform 'mode 
reader'") || return 0;

                if ($AUTHFILE)
                {
                        transact("authinfo user $username", '^38\d', "$Server: 
unexpected response to 'authinfo user'") || return 0;
                        transact("authinfo pass $password", '^28\d', "$Server: 
authentication error") || return 0;
                }

            #
            # select $GROUP group, wait for OK response
            #

        transact("group $GROUP", '^2\d\d', "$Server: Unable to select group 
'$GROUP'") || return 0;
            
        }

        #
        # log out
        #
        transact("quit", '^2\d\d', "$Server: No response on 'quit' command") || 
return 0;


        $ServerOK = 1;

        close(S);
        alarm 0; # Cancel the alarm

    };

    if ($EVAL_ERROR and ($EVAL_ERROR =~ /^Timeout Alarm/)) {
        push(@details, "$Server: timeout($TIMEOUT)\n");
        return 0;
    }
    return $ServerOK;

}

sub OpenSocket {
#
# Make a Berkeley socket connection between this program and a TCP port
#  on another (or this) host. Port can be a number or a named service
#
    my($OtherHostname, $Port) = @_;
    my($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len,
          $ThisAddr, $that, $OtherHostAddr, $result);
    $OurHostname = &hostname;

    $proto = getprotobyname('tcp');
    $Port = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/;
    $ThisAddr = gethostbyname($OurHostname);
    $OtherHostAddr = gethostbyname($OtherHostname);
        if (!defined $OtherHostAddr)
        {
                push (@details, "$OtherHostname: cannot resolve hostname\n");
                return undef
        }

    $that = sockaddr_in ($Port, $OtherHostAddr);

    if (! ($result = socket(S, PF_INET, SOCK_STREAM, $proto)) ||
       (! ($result = connect(S, $that))) )
        {
         push (@details, "$OtherHostname: $!\n");  return undef;
        }

    select(S); $| = 1; select(STDOUT);      # set S to be un-buffered
    return 1;                               # success
}

sub transact # "string to send", "pattern to expect", "error message"
{
    my ($sendstr, $rxpattern, $errormsg) = @_;
    my ($rxstr);

        warn "DEBUG: sending data: $sendstr<CR LF>\n" if $DEBUG;
    print S $sendstr . "\r\n" unless $sendstr eq "";

    $rxstr = <S>;
        warn "DEBUG: received data: $rxstr\n" if $DEBUG;

    if ($rxstr !~ $rxpattern) {
        alarm 0;
        push(@details, $errormsg . "\n");
        return 0;
    }
    return 1;
}
_______________________________________________
mon mailing list
mon@linux.kernel.org
http://linux.kernel.org/mailman/listinfo/mon

Reply via email to