#!/usr/bin/perl -w
#
# RMRTG - Remote MRTG Monitoring Client
#
use strict;
use IO::Socket;
use Getopt::Std;
use constant DEFAULT_SERVER_PORT => 5660;
use vars qw/$CRLF $opt_h $opt_t $host $command $socket $headers $body/;

# send strictly, accept leniently...
$CRLF = "\x0D\x0A";
$/ = "\x0A";

getopts('th');

usage() if $opt_h;
$host = shift || usage();
$command = shift || usage();
$socket = send_message( $host, $command, @ARGV );

# read in header block
while (<$socket>) {
	chomp;
	s/\x0D//g;
	last if m/^$/;
	$headers .= $_ . "\n";
	TRACE( "Header: >$_<" );
}
TRACE( "Header length: " . length($headers) . ' bytes' );

# get the body content
while (<$socket>) {
	chomp;
	s/\x0D//g;
	$body .= $_ . "\n";
	TRACE( "Body: >$_<" );
	if ( length($body) > 50000 ) {
		TRACE("WARNING! Long body content detected!");
		last;
	}
}
TRACE( "Content length: " . length($body) . ' bytes' );
print $body;

exit(0);

###### SUBROUTINES ###################################

sub send_message {
	my $remote_host = shift;
	my $remote_port = DEFAULT_SERVER_PORT;
	TRACE("Sending to $remote_host:$remote_port - " . @_ . ' args');
	
	# connect 
	my $socket = IO::Socket::INET->new(
		PeerAddr => $remote_host,
		PeerPort => $remote_port,
		Proto => 'tcp',
		Timeout => 3,
	) or die("Can't make socket: $@");

	# send data
	binmode( $socket );
	select $socket;
	$| = 1;
	select STDOUT;

	print( $socket "TRACE 1$CRLF" ) if $opt_t;
	print( $socket 'COMMAND ', join(' ', @_), "$CRLF$CRLF" );
	
	return $socket;
}

sub usage {
	print qq{$0 [-h] [-t] remote_host command [ args... ]

remote_host - the name or IP of the remote host you want to connect to
command - the filename of the command you want to run. e.g. foo.pl
    will be mapped to /home/mrtg/bin/foo.pl at the remote end.
args - a list of whatever options you want to pass to the command
-h - Display this help
-t - Turn on tracing messages (only use in testing)
};
	exit;
}

sub TRACE {
	return unless $opt_t;
	my $msg = shift;
	print STDERR 'rmrtgc> ', $msg, "\n";
}

=pod

=head1 NAME

rmrtgc - Remote MRTG information client. Connects to an rmrtg server.

=head1 DESCRIPTION

Connects to rmrtg daemon and asks for some data. See the readme for 
a bit more on the protocol, such that it is.

=head1 SYNOPSIS

	rmrtgc [ OPTIONS ] HOSTNAME COMMAND [ ARGUMENTS ]

The client simply passes the COMMAND and any ARGUMENTS to the rmrtg server
on HOSTNAME, and returns the response from the server.

You may specify options that modify how rmrtgc behaves...

=head1 OPTIONS

=over4

=item -t

Activates tracing messages. Use this when testing your rmrtg setup to get detailed
help on what is really happening, printed to STDERR. You should NOT use this switch 
in the mrtg.cfg file as the output will never be seen.

=item -h

Display the usage message and exit

=back

=head1 COPYRIGHT

Copyright (c) P Kent 2001. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

A copy of the GPL is supplied in the file 'GPL'

	                            NO WARRANTY

	BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
	FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
	OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
	PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
	OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
	MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
	TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
	PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
	REPAIR OR CORRECTION.

=head1 CVS

$Id: rmrtgc,v 1.3 2002/01/30 04:54:53 piers Exp $

=cut