Blame bin/mrtg.lib64

Packit 3f632f
#! /usr/bin/perl -w
Packit 3f632f
# -*- mode: cperl -*-
Packit 3f632f
Packit 3f632f
###################################################################
Packit 3f632f
# MRTG 2.17.7  Multi Router Traffic Grapher
Packit 3f632f
###################################################################
Packit 3f632f
# Created by Tobias Oetiker <tobi@oetiker.ch>
Packit 3f632f
#            and Dave Rand <dlr@bungi.com>
Packit 3f632f
#
Packit 3f632f
# For individual Contributers check the CHANGES file
Packit 3f632f
#
Packit 3f632f
###################################################################
Packit 3f632f
#
Packit 3f632f
# Distributed under the GNU General Public License
Packit 3f632f
#
Packit 3f632f
###################################################################
Packit 3f632f
my @STARTARGS=($0,@ARGV);
Packit 3f632f
Packit 3f632f
@main::DEBUG=qw();
Packit 3f632f
# DEBUG TARGETS
Packit 3f632f
# cfg  - watch the config file reading
Packit 3f632f
# dir  - directory mangeling
Packit 3f632f
# base - basic program flow
Packit 3f632f
# tarp - target parser
Packit 3f632f
# snpo - snmp polling
Packit 3f632f
# snpo2 - more snmp debug
Packit 3f632f
# coca - confcache operations
Packit 3f632f
# repo - track confcache repopulation
Packit 3f632f
# fork - forking view
Packit 3f632f
# time - some timing info
Packit 3f632f
# log  - logging of data via rateup or rrdtool
Packit 3f632f
# eval - trace eval experssions
Packit 3f632f
# prof - add timeing info some interesting bits of code
Packit 3f632f
Packit 3f632f
$main::GRAPHFMT="png";
Packit 3f632f
# There older perls tend to behave peculiar with
Packit 3f632f
# large integers ...
Packit 3f632f
require 5.005;
Packit 3f632f
Packit 3f632f
use strict;
Packit 3f632f
# addon jpt
Packit 3f632f
BEGIN {
Packit 3f632f
    # Automatic OS detection ... do NOT touch
Packit 3f632f
    if ( $^O =~ /^(ms)?(dos|win(32|nt)?)/i ) {
Packit 3f632f
	$main::OS = 'NT';
Packit 3f632f
	$main::SL = '\\';
Packit 3f632f
	$main::PS = ';';        
Packit 3f632f
    } elsif ( $^O =~ /^NetWare$/i ) {
Packit 3f632f
	$main::OS = 'NW';
Packit 3f632f
	$main::SL = '/';
Packit 3f632f
	$main::PS = ';';
Packit 3f632f
    } elsif ( $^O =~ /^VMS$/i ) {
Packit 3f632f
	$main::OS = 'VMS';
Packit 3f632f
	$main::SL = '.';
Packit 3f632f
	$main::PS = ':';
Packit 3f632f
    } elsif ( $^O =~ /^os2$/i ) {
Packit 3f632f
	$main::OS = 'OS2';
Packit 3f632f
	$main::SL = '/';
Packit 3f632f
	$main::PS = ';';
Packit 3f632f
    } else {
Packit 3f632f
	$main::OS = 'UNIX';
Packit 3f632f
	$main::SL = '/';
Packit 3f632f
	$main::PS = ':';
Packit 3f632f
    }
Packit 3f632f
    if ( $ENV{LANG} and $ENV{LANG} =~ /UTF.*8/i ){        
Packit 3f632f
        my $args = join " ", map { /\s/ ? "\"$_\"" : $_ } @ARGV;
Packit 3f632f
        $args ||= "";
Packit 3f632f
        print <
Packit 3f632f
-----------------------------------------------------------------------
Packit 3f632f
ERROR: Mrtg will most likely not work properly when the environment
Packit 3f632f
       variable LANG is set to UTF-8. Please run mrtg in an environment
Packit 3f632f
       where this is not the case. Try the following command to start:
Packit 3f632f
Packit 3f632f
       env LANG=C ${0} $args 
Packit 3f632f
-----------------------------------------------------------------------
Packit 3f632f
ERR
Packit 3f632f
        exit 0;
Packit 3f632f
    }
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
Packit 3f632f
use FindBin;
Packit 3f632f
use lib "${FindBin::Bin}";
Packit 3f632f
use lib "${FindBin::Bin}${main::SL}..${main::SL}lib${main::SL}mrtg2";
Packit 3f632f
use Getopt::Long;
Packit 3f632f
use Math::BigFloat;
Packit 3f632f
Packit 3f632f
# search for binaries in the bin and bin/../lib  directory
Packit 3f632f
use MRTG_lib "2.100016";
Packit 3f632f
Packit 3f632f
my $NOW = timestamp;
Packit 3f632f
Packit 3f632f
my $graphiteObj;
Packit 3f632f
Packit 3f632f
# $SNMP_Session::suppress_warnings = 2;
Packit 3f632f
use locales_mrtg "0.07";
Packit 3f632f
Packit 3f632f
# Do not Flash Console Windows for the forked rateup process 
Packit 3f632f
BEGIN {
Packit 3f632f
    if ($^O eq 'MSWin32'){
Packit 3f632f
	eval {local $SIG{__DIE__};require Win32; Win32::SetChildShowWindow(0)};
Packit 3f632f
	warn "WARNING: $@\n" if $@;
Packit 3f632f
    }    
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
$main::STARTTIME = time;
Packit 3f632f
Packit 3f632f
%main::verified_rrd = ();
Packit 3f632f
    
Packit 3f632f
if ($MRTG_lib::OS eq 'OS2') {
Packit 3f632f
# in daemon mode we will pause 3 seconds to be sure that parent died
Packit 3f632f
  require OS2::Process;
Packit 3f632f
  if (OS2::Process::my_type() eq 'DETACH') {sleep(3);}
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
if ($MRTG_lib::OS eq 'UNIX') {
Packit 3f632f
   $SIG{INT} = $SIG{TERM} = 
Packit 3f632f
           sub {   unlink ${main::Cleanfile} 
Packit 3f632f
                       if defined $main::Cleanfile;
Packit 3f632f
                   unlink ${main::Cleanfile2}
Packit 3f632f
                       if defined $main::Cleanfile2;
Packit 3f632f
                   unlink ${main::Cleanfile3}
Packit 3f632f
                       if defined $main::Cleanfile3;
Packit 3f632f
                   warn "$NOW: ERROR: Bailout after SIG $_[0]\n";
Packit 3f632f
                   exit 1;
Packit 3f632f
                };
Packit 3f632f
  $SIG{HUP} = sub {
Packit 3f632f
                   unlink ${main::Cleanfile} 
Packit 3f632f
                       if defined $main::Cleanfile;
Packit 3f632f
                   unlink ${main::Cleanfile2}
Packit 3f632f
                       if defined $main::Cleanfile2;
Packit 3f632f
                   unlink ${main::Cleanfile3}
Packit 3f632f
                       if defined $main::Cleanfile3;
Packit 3f632f
                   die "$NOW: ERROR: Bailout after SIG $_[0]\n";
Packit 3f632f
                };
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
Packit 3f632f
END {
Packit 3f632f
    local($?, $!);
Packit 3f632f
    unlink ${main::Cleanfile} if defined $main::Cleanfile;
Packit 3f632f
    unlink ${main::Cleanfile2} if defined $main::Cleanfile2;
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
&mai;;
Packit 3f632f
Packit 3f632f
exit(0);
Packit 3f632f
Packit 3f632f
#### Functions ################################################
Packit 3f632f
Packit 3f632f
sub main {
Packit 3f632f
Packit 3f632f
    
Packit 3f632f
    # read in the config file
Packit 3f632f
    my @routers;
Packit 3f632f
    my %cfg;
Packit 3f632f
    my %rcfg;
Packit 3f632f
    my %opts; 
Packit 3f632f
    my $EXITCODE = 0;
Packit 3f632f
    
Packit 3f632f
    GetOptions(\%opts, 'user=s', 'group=s', 'lock-file=s','confcache-file=s','logging=s', 'check', 'fhs', 'daemon',  'pid-file=s','debug=s', 'log-only') or die "Please use valid Options\n";
Packit 3f632f
Packit 3f632f
    if (defined $opts{debug}){
Packit 3f632f
        @main::DEBUG = split /\s*,\s*/, $opts{debug};
Packit 3f632f
	if (defined $SNMP_util::Debug){
Packit 3f632f
	        $SNMP_util::Debug = 1 if grep /^snpo2$/, @main::DEBUG;
Packit 3f632f
	}
Packit 3f632f
    }
Packit 3f632f
    if (grep /^prof$/, @main::DEBUG){
Packit 3f632f
	require Time::HiRes;
Packit 3f632f
        eval "sub gettimeofday() {return Time::HiRes::time()}";
Packit 3f632f
	# note this will crash if the module is missing
Packit 3f632f
	# so only use the --debug=prof if you have Time::HiRes installed
Packit 3f632f
    } else {
Packit 3f632f
	eval "sub gettimeofday() {return time()}";
Packit 3f632f
    }
Packit 3f632f
    debug 'time', "prog start ".localtime(time);
Packit 3f632f
Packit 3f632f
    my $uid = $<;
Packit 3f632f
    my $gid = $(;
Packit 3f632f
Packit 3f632f
    if (defined $opts{group}) {
Packit 3f632f
        $gid = getgrnam($opts{group});
Packit 3f632f
        die "$NOW: ERROR: Unknown Group: $opts{group})\n" if not defined $gid;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    if (defined $opts{user}) {
Packit 3f632f
        $uid = getpwnam($opts{user});
Packit 3f632f
        die "$NOW: ERROR: Unknown User: $opts{user})\n" if not defined $uid;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # If we've specified using FHS (http://www.pathname.com/fhs/) on the command line,
Packit 3f632f
    # use the relevant path definitions (can be overridden later):
Packit 3f632f
Packit 3f632f
    my $confcachefile;
Packit 3f632f
    my $pidfile;
Packit 3f632f
    my $lockfile;
Packit 3f632f
    my $templock;
Packit 3f632f
    my $logfile;
Packit 3f632f
Packit 3f632f
    if (defined $opts{"fhs"}) {
Packit 3f632f
	$confcachefile = "/var/cache/mrtg/mrtg.ok";
Packit 3f632f
	$pidfile = "/var/run/mrtg.pid";
Packit 3f632f
	$lockfile = "/var/cache/mrtg/mrtg.lck";
Packit 3f632f
	$templock = "/var/cache/mrtg/mrtg.lck.$$";
Packit 3f632f
	$logfile = "/var/log/mrtg.log";
Packit 3f632f
    }	
Packit 3f632f
Packit 3f632f
    my $cfgfile = shift @ARGV;
Packit 3f632f
Packit 3f632f
    if ( !defined $cfgfile and -r "/etc/mrtg.cfg" ) { $cfgfile = "/etc/mrtg.cfg"; }
Packit 3f632f
Packit 3f632f
    printusage() unless defined $cfgfile;
Packit 3f632f
Packit 3f632f
    # PID file code, used later if daemonizing...
Packit 3f632f
    if ( !defined($pidfile) ) {
Packit 3f632f
        $pidfile =  $cfgfile;
Packit 3f632f
        $pidfile =~ s/\.[^.\/]+$//;
Packit 3f632f
        $pidfile .= '.pid';
Packit 3f632f
    }
Packit 3f632f
    $pidfile =  $opts{"pid-file"} || $pidfile;
Packit 3f632f
Packit 3f632f
    # Run as a daemon, specified on command line (required for FHS compliant daemon)
Packit 3f632f
    if (defined $opts{"daemon"}) {
Packit 3f632f
	# Create a pidfile, then chown it so we can use it once we change user
Packit 3f632f
	&create_pid($pidfile);
Packit 3f632f
	chown $uid, $gid, $pidfile;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    ($(,$)) = ($gid,$gid) ;
Packit 3f632f
    ($<,$>) = ($uid,$uid) ;
Packit 3f632f
    die "$NOW: ERROR failed to set UID to $uid\n" unless ($< == $uid and  $> == $uid);
Packit 3f632f
Packit 3f632f
    $logfile = $opts{logging} || $logfile;
Packit 3f632f
    if (defined $logfile){
Packit 3f632f
	setup_loghandlers $logfile;
Packit 3f632f
        warn "Started mrtg with config \'$cfgfile\'\n";
Packit 3f632f
    }	
Packit 3f632f
Packit 3f632f
    # lets make sure that there are not two mrtgs running in parallel.
Packit 3f632f
    # so we lock on the cfg file. Nothing fancy, just a lockfile
Packit 3f632f
Packit 3f632f
    $lockfile = $opts{"lock-file"} || $lockfile;
Packit 3f632f
Packit 3f632f
    if (! defined $lockfile) {
Packit 3f632f
        $lockfile = $cfgfile."_l";
Packit 3f632f
    }
Packit 3f632f
    if (! defined $templock) {
Packit 3f632f
        $templock = $lockfile."_" . $$ ;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    debug('base', "Creating Lockfiles $lockfile,$templock");
Packit 3f632f
    &lockit($lockfile,$templock);
Packit 3f632f
Packit 3f632f
    debug('base', "Reading Config File: $cfgfile");
Packit 3f632f
    my $cfgfile_age = -M $cfgfile;
Packit 3f632f
    readcfg($cfgfile,\@routers,\%cfg,\%rcfg);
Packit 3f632f
Packit 3f632f
    imggen($cfg{icondir} || $cfg{imagedir} || $cfg{workdir});
Packit 3f632f
    
Packit 3f632f
    # Enable or disable snmpv3
Packit 3f632f
    if(defined $cfg{enablesnmpv3}) {
Packit 3f632f
        $cfg{enablesnmpv3} = lc($cfg{enablesnmpv3});
Packit 3f632f
    } else {
Packit 3f632f
        $cfg{enablesnmpv3} = 'no';
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    if ($cfg{threshmailserver}) {
Packit 3f632f
        if  (eval {local $SIG{__DIE__};require Net::SMTP;})   {
Packit 3f632f
	    import Net::SMTP;
Packit 3f632f
            debug('base', "Loaded Net::SMTP module for ThreshMail.");
Packit 3f632f
        } else {
Packit 3f632f
            die "$NOW: WARNING: Can't load Net::SMTP module. This is required for ThreshMail.";
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
    # Check we have the necessary libraries for IPv6 support
Packit 3f632f
    if ($cfg{enablesnmpv3} eq 'yes') {
Packit 3f632f
        if  (eval {local $SIG{__DIE__};require Net_SNMP_util;})   {
Packit 3f632f
	    import Net_SNMP_util;
Packit 3f632f
            debug('base', "SNMP V3 libraries found, SNMP V3 enabled.");
Packit 3f632f
        } else {
Packit 3f632f
            warn "$NOW: WARNING: SNMP V3 libraries not found, SNMP V3 disabled.\n";
Packit 3f632f
            $cfg{enablesnmpv3} =  'no';
Packit 3f632f
	    require SNMP_util;
Packit 3f632f
	    import SNMP_util;
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
    else {	# load V1/V2 libraries 
Packit 3f632f
	require SNMP_util;
Packit 3f632f
	import SNMP_util;
Packit 3f632f
    }
Packit 3f632f
    
Packit 3f632f
Packit 3f632f
    # Enable or disable IPv6
Packit 3f632f
    if(defined $cfg{enableipv6}) {
Packit 3f632f
        $cfg{enableipv6} = lc($cfg{enableipv6});
Packit 3f632f
    } else {
Packit 3f632f
        $cfg{enableipv6} = 'no';
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # Check we have the necessary libraries for IPv6 support
Packit 3f632f
    if ($cfg{enableipv6} eq 'yes') {
Packit 3f632f
        if ( eval {local $SIG{__DIE__};require Socket; require Socket6; require IO::Socket::INET6;}) {
Packit 3f632f
            import Socket;
Packit 3f632f
            import Socket6;
Packit 3f632f
            debug('base', "IPv6 libraries found, IPv6 enabled.");
Packit 3f632f
        } else {
Packit 3f632f
            warn "$NOW: WARNING: IPv6 libraries not found, IPv6 disabled.\n";
Packit 3f632f
            $cfg{enableipv6} =  'no';
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # Module invocation for sending a copy of the time series data to graphite.
Packit 3f632f
    if(defined $cfg{sendtographite}) {
Packit 3f632f
      require Net::Graphite;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # from our last run we kept some info about
Packit 3f632f
    # the configuration of our devices around
Packit 3f632f
    debug('base', "Reading Interface Config cache");
Packit 3f632f
    $confcachefile =  $opts{"confcache-file"} || $confcachefile;
Packit 3f632f
    if ( !defined($confcachefile) ) {
Packit 3f632f
        $confcachefile = $cfgfile;
Packit 3f632f
        $confcachefile  =~ s/\.[^.\/]+$//;
Packit 3f632f
        $confcachefile .= ".ok";
Packit 3f632f
    }
Packit 3f632f
    my $confcache = readconfcache($confcachefile);
Packit 3f632f
Packit 3f632f
    # Check the config and create the target object
Packit 3f632f
    debug('base', "Checking Config File");
Packit 3f632f
    my @target;
Packit 3f632f
    cfgcheck(\@routers, \%cfg, \%rcfg, \@target, \%opts);
Packit 3f632f
Packit 3f632f
    # exit here if we only check the config file
Packit 3f632f
    # in case of an error, cfgcheck() already exited
Packit 3f632f
    if (defined $opts{check}) {
Packit 3f632f
        debug('base', "Remove Lock Files");
Packit 3f632f
        close LOCK; unlink ($templock, $lockfile);
Packit 3f632f
        debug('base', "Exit after successful config file check");
Packit 3f632f
        exit 0;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # postload rrdtool support
Packit 3f632f
    if ($cfg{logformat} eq 'rrdtool'){
Packit 3f632f
        debug('base', "Loading RRD support");
Packit 3f632f
	require 'RRDs.pm';
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # set the locale
Packit 3f632f
    my $LOC;
Packit 3f632f
    if ( $cfg{'language'} and defined($lang2tran::LOCALE{"\L$cfg{'language'}\E"})) {
Packit 3f632f
	debug('base', "Loading Locale for ".$cfg{'language'});
Packit 3f632f
	$LOC=$lang2tran::LOCALE{"\L$cfg{'language'}\E"};
Packit 3f632f
    } else {
Packit 3f632f
	debug('base', "Loading default Locale");
Packit 3f632f
	$LOC=$lang2tran::LOCALE{'default'};
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # Daemon Code
Packit 3f632f
    my $last_time=0;
Packit 3f632f
    my $curent_time;
Packit 3f632f
    my $sleep_time;
Packit 3f632f
    if (defined $opts{"daemon"}) { $cfg{'runasdaemon'} = "yes"; }
Packit 3f632f
    &demonize_me($pidfile,$cfgfile) if defined $cfg{'runasdaemon'}  and $cfg{'runasdaemon'} =~ /y/i  and $MRTG_lib::OS ne 'VMS'
Packit 3f632f
    	and not (defined $cfg{'nodetach'} and $cfg{'nodetach'} =~ /y/i);
Packit 3f632f
    # auto restart on die if running as demon
Packit 3f632f
Packit 3f632f
    $SIG{__DIE__} = sub {
Packit 3f632f
        warn $_[0];
Packit 3f632f
        warn "*** Restarting after 10 seconds in an attempt to recover from the error above\n";
Packit 3f632f
        sleep 10;
Packit 3f632f
        exec @STARTARGS;
Packit 3f632f
    } if $cfg{'runasdaemon'};
Packit 3f632f
Packit 3f632f
    debug('base', "Starting main Loop");
Packit 3f632f
    do {                        # Do this loop once for native mode and forever in daemon mode 
Packit 3f632f
        my $router;        
Packit 3f632f
        $NOW = timestamp;   # get the time
Packit 3f632f
        debug 'time', "loop start ".localtime(time);
Packit 3f632f
Packit 3f632f
        #if we run as daemon, we sleep in between collection cycles
Packit 3f632f
        $sleep_time=  (int($cfg{interval}*60))-(time-$last_time);
Packit 3f632f
        if ($sleep_time > 0 ) { #If greater than 0 the sleep that amount of time
Packit 3f632f
	    debug('time', "Sleep time $sleep_time seconds");
Packit 3f632f
            sleep ($sleep_time);
Packit 3f632f
        } elsif ($last_time > 0) {
Packit 3f632f
            warn "$NOW: WARNING: data collection did not complete within interval!\n";
Packit 3f632f
        }
Packit 3f632f
        $last_time=time;
Packit 3f632f
Packit 3f632f
        # set meta expires if there is an index file
Packit 3f632f
        # 2000/05/03 Bill McGonigle <bill@zettabyte.net>
Packit 3f632f
        if (defined $cfg{'writeexpires'}) {
Packit 3f632f
           my $exp = &expistr($cfg{'interval'});
Packit 3f632f
           my $fil;
Packit 3f632f
           $fil = "$cfg{'htmldir'}index.html"  if -e "$cfg{'htmldir'}index.html";
Packit 3f632f
           $fil = "$cfg{'htmldir'}index.htm"  if -e "$cfg{'htmldir'}index.htm";
Packit 3f632f
            if (defined $fil) {
Packit 3f632f
                   open(META, ">$fil.meta");
Packit 3f632f
                   print META "Expires: $exp\n";
Packit 3f632f
                   close(META);
Packit 3f632f
            }
Packit 3f632f
        }
Packit 3f632f
Packit 3f632f
Packit 3f632f
        # Use SNMP to populate the target object
Packit 3f632f
	debug('base', "Populate Target object by polling SNMP and".
Packit 3f632f
	      " external Datasources");
Packit 3f632f
        debug 'time', "snmp read start ".localtime(time);
Packit 3f632f
        readtargets($confcache,\@target, \%cfg);
Packit 3f632f
Packit 3f632f
        $NOW = timestamp;   # get the time
Packit 3f632f
        # collect data for each router or pseudo target (`executable`)
Packit 3f632f
        debug 'time', "target loop start ".localtime(time);
Packit 3f632f
        foreach $router (@routers) {
Packit 3f632f
	    debug('base', "Act on Router/Target $router");
Packit 3f632f
            if (defined $rcfg{'setenv'}{$router}) {
Packit 3f632f
                my $line = $rcfg{'setenv'}{$router};
Packit 3f632f
                while ( $line =~ s/([^=]+)=\"([^\"]*)\"\s*// ) # " - unconfuse the highliter
Packit 3f632f
 		{ 
Packit 3f632f
		    $ENV{$1}=$2;
Packit 3f632f
                }
Packit 3f632f
	    }
Packit 3f632f
	    my($savetz) = $ENV{'TZ'};
Packit 3f632f
	    if (defined $rcfg{'timezone'}{$router}) {
Packit 3f632f
                $ENV{'TZ'} = $rcfg{'timezone'}{$router};
Packit 3f632f
		if ( $main::OS eq 'UNIX' ){
Packit 3f632f
			require 'POSIX.pm';
Packit 3f632f
			POSIX::tzset();
Packit 3f632f
		}
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            my ($inlast, $outlast, $uptime, $name, $time) = 
Packit 3f632f
              getcurrent(\@target, $router, \%rcfg, \%cfg);
Packit 3f632f
Packit 3f632f
            if ( defined($inlast) and defined($outlast)) {
Packit 3f632f
              $EXITCODE = $EXITCODE | 1;
Packit 3f632f
            }
Packit 3f632f
            else {
Packit 3f632f
              $EXITCODE = $EXITCODE | 2;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
	    debug('base', "Get Current values: in:".( defined $inlast ? $inlast : "undef").", out:".
Packit 3f632f
                                                 ( defined $outlast? $outlast : "undef").", up:".
Packit 3f632f
                                                 ( defined $uptime ? $uptime : "undef").", name:".
Packit 3f632f
                                                 ( defined $name ? $name : "undef").", time:".
Packit 3f632f
                                                 ( defined $time ? $time : "undef"));
Packit 3f632f
Packit 3f632f
            #abort, if the router is not responding.
Packit 3f632f
            if ($cfg{'logformat'} ne 'rrdtool') {
Packit 3f632f
              # undefined values are ok for rrdtool !
Packit 3f632f
              #if ( not defined $inlast or not defined $outlast){
Packit 3f632f
              #  warn "$NOW: WARNING: Skipping Update of $router, inlast is not defined\n"
Packit 3f632f
              #          unless defined $inlast;
Packit 3f632f
              #  warn "$NOW: WARNING: Skipping Update of $router, outlast is not defined\n"
Packit 3f632f
              #          unless defined $outlast;
Packit 3f632f
              #  next;
Packit 3f632f
              #}
Packit 3f632f
Packit 3f632f
              if (defined $inlast and $inlast < 0) {
Packit 3f632f
                $inlast += 2**31;
Packit 3f632f
                # this is likely to be a broken snmp counter ... lets compensate
Packit 3f632f
              }  
Packit 3f632f
              if (defined $outlast and $outlast < 0) {
Packit 3f632f
                $outlast += 2**31;
Packit 3f632f
                # this is likely to be a broken snmp counter ... lets compensate
Packit 3f632f
              }  
Packit 3f632f
            }
Packit 3f632f
	    
Packit 3f632f
            my ($maxin, $maxout, $maxpercent, $avin, $avout, $avpercent,$avmxin, $avmxout,
Packit 3f632f
                $cuin, $cuout, $cupercent);
Packit 3f632f
	    debug('base', "Create Graphics");
Packit 3f632f
            if ($rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
                ($maxin, $maxout, $maxpercent, $avin, $avout, $avpercent,
Packit 3f632f
                 $cuin, $cuout, $cupercent, $avmxin, $avmxout) =
Packit 3f632f
                  writegraphics($router, \%cfg, \%rcfg, $inlast, $outlast, $time,$LOC, \%opts);
Packit 3f632f
            } else {
Packit 3f632f
                ($maxin, $maxout ,$avin, $avout, $cuin, $cuout, $avmxin, $avmxout) =
Packit 3f632f
                  writegraphics($router, \%cfg, \%rcfg, $inlast, $outlast, $time,$LOC, \%opts);
Packit 3f632f
            }
Packit 3f632f
            # skip this update if we did not get anything usefull out of
Packit 3f632f
            # writegraphics
Packit 3f632f
            next if not defined $maxin;
Packit 3f632f
Packit 3f632f
	    debug('base', "Check for Thresholds");
Packit 3f632f
            threshcheck(\%cfg,\%rcfg,$cfgfile,$router,$cuin,$cuout);
Packit 3f632f
Packit 3f632f
	    if (defined $opts{'log-only'}){
Packit 3f632f
		debug('base', "Disable Graph and HTML generation");
Packit 3f632f
	    }
Packit 3f632f
Packit 3f632f
	    if ($cfg{logformat} eq 'rateup' and not defined $opts{'log-only'} ){
Packit 3f632f
		debug('base', "Check for Write HTML Pages");
Packit 3f632f
		writehtml($router, \%cfg, \%rcfg,
Packit 3f632f
			  $maxin, $maxout, $maxpercent, $avin, $avout, $avmxin, $avmxout, $avpercent,
Packit 3f632f
			  $cuin, $cuout, $cupercent, $uptime, $name, $LOC)
Packit 3f632f
	    }
Packit 3f632f
Packit 3f632f
            #
Packit 3f632f
            clonedirectory($router,\%cfg, \%rcfg);
Packit 3f632f
            #
Packit 3f632f
Packit 3f632f
            #put TZ things back in shape ... 
Packit 3f632f
            if ($savetz) {
Packit 3f632f
                $ENV{'TZ'} =  $savetz;
Packit 3f632f
            } else {
Packit 3f632f
                delete $ENV{'TZ'};
Packit 3f632f
            }
Packit 3f632f
	    if ( $main::OS eq 'UNIX' ){
Packit 3f632f
		require 'POSIX.pm';
Packit 3f632f
		POSIX::tzset();
Packit 3f632f
	    };
Packit 3f632f
        }
Packit 3f632f
        # Has the cfg file been modified since we started? if so, reload it.
Packit 3f632f
        if ( -M $cfgfile < $cfgfile_age and 
Packit 3f632f
          $cfg{'runasdaemon'} and $cfg{'runasdaemon'} =~ /y/i ) {
Packit 3f632f
            # reload the configuration
Packit 3f632f
            $cfgfile_age = -M $cfgfile;
Packit 3f632f
            debug('base', "Re-reading Config File: $cfgfile");
Packit 3f632f
            @routers = (); %cfg = (); %rcfg = ();
Packit 3f632f
            readcfg($cfgfile,\@routers,\%cfg,\%rcfg);
Packit 3f632f
            cfgcheck(\@routers, \%cfg, \%rcfg, \@target, \%opts);
Packit 3f632f
        }
Packit 3f632f
        debug('base', "End of main Loop");
Packit 3f632f
    } while ($cfg{'runasdaemon'} and $cfg{'runasdaemon'} =~ /y/i ); #In daemon mode run forever
Packit 3f632f
    debug('base', "Exit main Loop");
Packit 3f632f
    # OK we are done, remove the lock files ... 
Packit 3f632f
Packit 3f632f
    debug('base', "Remove Lock Files");
Packit 3f632f
    close LOCK; unlink ($templock, $lockfile);
Packit 3f632f
Packit 3f632f
    debug('base', "Store Interface Config Cache");
Packit 3f632f
    delete $$confcache{___updated} if exists $$confcache{___updated}; # make sure everything gets written out not only the updated entries
Packit 3f632f
    writeconfcache($confcache,$confcachefile);
Packit 3f632f
Packit 3f632f
    if ( ! $cfg{'runasdaemon'} or $cfg{'runasdaemon'} !~ /y/i ) {
Packit 3f632f
      if ( ($EXITCODE & 1) and ($EXITCODE & 2) ) {
Packit 3f632f
        # At least one target was sucessful
Packit 3f632f
        exit 91;
Packit 3f632f
      }
Packit 3f632f
      elsif ( not ($EXITCODE & 1) and ($EXITCODE & 2) ) {
Packit 3f632f
        # All targets failed
Packit 3f632f
        exit 92;
Packit 3f632f
      }
Packit 3f632f
    }
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
# ( $inlast, $outlast, $uptime, $name, $time ) =
Packit 3f632f
#    &getcurrent( $target, $rou, $rcfg, $cfg )
Packit 3f632f
# Calculate monitored data for device $rou based on information in @$target
Packit 3f632f
# and referring to configuration data in %$rcfg and %$cfg. In the returned
Packit 3f632f
# list, $inlast and $outlast are the input and output monitored data values,
Packit 3f632f
# $uptime is the device uptime, $name is the device name, and $time is the
Packit 3f632f
# current time when the calculation was performed.
Packit 3f632f
sub getcurrent {
Packit 3f632f
	my( $target, $rou, $rcfg, $cfg ) = @_;
Packit 3f632f
	# Hash indexed by $mode for conveniently saving $inlast and $outlast
Packit 3f632f
	my %last;
Packit 3f632f
	# Initialize uptime, device name, and data collection time to empty strings
Packit 3f632f
	my $uptime = '';
Packit 3f632f
	my $name = '';
Packit 3f632f
	my $time = '';
Packit 3f632f
Packit 3f632f
	# Calculate input and output monitored data
Packit 3f632f
	foreach my $mode( qw( _IN_  _OUT_ ) ) {
Packit 3f632f
		# Initialize monitored data, warning message, and death message
Packit 3f632f
		# to empty strings
Packit 3f632f
		my $data;
Packit 3f632f
		my $warning;
Packit 3f632f
		my $death;
Packit 3f632f
		{
Packit 3f632f
			# Code block used to calculate monitoring data
Packit 3f632f
			# Localize warning and death exception handlers to capture
Packit 3f632f
			# error message less any leading and trailing white space
Packit 3f632f
			local $SIG{ __WARN__ } =
Packit 3f632f
				sub { $_[0] =~ /^\s*(.+?)\s*$/; $warning = $1; };
Packit 3f632f
			local $SIG{ __DIE__ } =
Packit 3f632f
				sub { $_[0] =~ /^\s*(.+?)\s*$/; $death = $1; };
Packit 3f632f
			# Calculate monitoring data. $rcfg->{ target }{ $rou } contains
Packit 3f632f
			# a Perl expression for the calculation.
Packit 3f632f
			$data = eval "$rcfg->{target}{$rou}";
Packit 3f632f
       		}
Packit 3f632f
		# Test for various exceptions occurring in the calculation
Packit 3f632f
		if( $warning ) {
Packit 3f632f
			warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' (warn): $warning\n";
Packit 3f632f
			$data = undef;
Packit 3f632f
		} elsif( $death ) {
Packit 3f632f
			warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' (kill): $death\n";
Packit 3f632f
			$data = undef;
Packit 3f632f
		} elsif( $@ ) {
Packit 3f632f
			warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' (eval): $@\n";
Packit 3f632f
			$data = undef;
Packit 3f632f
		} elsif( not defined $data ) {
Packit 3f632f
			warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' did not eval into defined data\n";
Packit 3f632f
			$data = undef;
Packit 3f632f
		} elsif( $data and $data !~ /^[-+]?\d+(\.\d*)?([eE][+-]?[0-9]+)?$/ ) {
Packit 3f632f
			warn "$NOW: ERROR: Target[$rou][$mode] '$$rcfg{target}{$rou}' evaluated to '$data' instead of a number\n";
Packit 3f632f
			$data = undef;
Packit 3f632f
		} elsif( length( $data ) > 190 ) {
Packit 3f632f
			warn "$NOW: ERROR: $mode value: '$data' is way to long ...\n";
Packit 3f632f
			$data = undef;
Packit 3f632f
		} else {
Packit 3f632f
			# At this point data is considered valid. Round to an integer
Packit 3f632f
			# unless RRDTool is in use and this is a gauge
Packit 3f632f
                        if (not ( $cfg->{ logformat } eq 'rrdtool'
Packit 3f632f
                                      and  defined $rcfg->{ options }{ gauge }{ $rou })){
Packit 3f632f
                            if (ref $data and ref $data eq 'Math::BigFloat') {
Packit 3f632f
                			$data->ffround( 0 )
Packit 3f632f
                            } else {
Packit 3f632f
                                        $data = sprintf "%.0f", $data;
Packit 3f632f
                            }
Packit 3f632f
                        }
Packit 3f632f
			# Remove any leading plus sign
Packit 3f632f
			$data =~ s/^\+//;
Packit 3f632f
		}
Packit 3f632f
		$last{ $mode } = $data;
Packit 3f632f
	}
Packit 3f632f
Packit 3f632f
	# Set $u to the unique index of the @$target array referred to in the
Packit 3f632f
	# monitored data calculation for the current device. $u will be set to
Packit 3f632f
	# -1 if that index is not unique.
Packit 3f632f
	my $u = $rcfg->{ uniqueTarget }{ $rou };
Packit 3f632f
Packit 3f632f
	# Get the uptime, device name, and data collection time from the @$target
Packit 3f632f
	# array if the monitored data calculation refers only to one target.
Packit 3f632f
	# Otherwise it doesn't make sense to do this.
Packit 3f632f
	if( $u >= 0 ) {
Packit 3f632f
		$uptime = $target->[ $u ]{ _UPTIME_ };
Packit 3f632f
		$name = $target->[ $u ]{ _NAME_ };
Packit 3f632f
		$time = $target->[ $u ]{ _TIME_ };
Packit 3f632f
Packit 3f632f
                if ($time =~ /^([-0-9.]+)$/) {
Packit 3f632f
                   $time = $1;
Packit 3f632f
                }
Packit 3f632f
Packit 3f632f
	}
Packit 3f632f
Packit 3f632f
	# Set the time to the current time if it was not set above
Packit 3f632f
	$time = time unless $time;
Packit 3f632f
Packit 3f632f
	# Cache uptime location for reading name
Packit 3f632f
	my( $uploc );
Packit 3f632f
Packit 3f632f
	# Get the uptime and device name from the alternate location (community@host or
Packit 3f632f
	# (OID:community@host or OID) that may have been specified with the RouterUptime
Packit 3f632f
	# target keyword
Packit 3f632f
	if( defined $rcfg->{ routeruptime }{ $rou } ) {
Packit 3f632f
		my( $noid, $nloc ) = split( /:/, $rcfg->{ routeruptime }{ $rou }, 2 );
Packit 3f632f
		# If only location (community@host) was specified then
Packit 3f632f
		# move the location details into the right place
Packit 3f632f
		if( $noid =~ /@/ ) {
Packit 3f632f
			$nloc = $noid;
Packit 3f632f
			$noid = undef;
Packit 3f632f
		}
Packit 3f632f
		# If no OID (community@host) was specified use the hardcoded default
Packit 3f632f
		if( not $noid ) {
Packit 3f632f
			$noid = 'sysUptime';
Packit 3f632f
		}
Packit 3f632f
		# If no location (community@host) was specified use values from the
Packit 3f632f
		# unique target referred to in the monitored data calculation
Packit 3f632f
		if( not $nloc ){
Packit 3f632f
                        if ($u >= 0) {
Packit 3f632f
          		    my $comm = $target->[ $u ]{ Community };
Packit 3f632f
			    my $host = $target->[ $u ]{ Host };
Packit 3f632f
			    my $opt = $target->[ $u ]{ SnmpOpt };
Packit 3f632f
			    $nloc = "$comm\@$host$opt";
Packit 3f632f
		        } else {
Packit 3f632f
                            die "$NOW: ERROR: You must specify the location part of the RouterUptime oid for non unique targets! ($rou)\n";
Packit 3f632f
                        }
Packit 3f632f
                }
Packit 3f632f
        
Packit 3f632f
		$uploc = $nloc;
Packit 3f632f
		# Get the device uptime if $noid(OID) and $nloc (community@host) have been specified
Packit 3f632f
		# one way or the other
Packit 3f632f
		debug('base', "Fetching sysUptime and sysName from: $noid:$nloc");
Packit 3f632f
		( $uptime, $name ) = snmpget( $uploc, $rcfg->{ snmpoptions }{ $rou }, $noid, 'sysName');
Packit 3f632f
	}
Packit 3f632f
Packit 3f632f
	# Get the device name from the alternate location (OID or
Packit 3f632f
	# OID:community@host) that may have been specified with the RouterName
Packit 3f632f
	# target keyword
Packit 3f632f
	if( defined $rcfg->{ routername }{ $rou } ) {
Packit 3f632f
		my( $noid, $nloc ) = split( /:/, $rcfg->{ routername }{ $rou }, 2 );
Packit 3f632f
		# If no location (community@host) was specified use values from the
Packit 3f632f
		# unique target referred to in the monitored data calculation
Packit 3f632f
		if( $u >= 0 and not $nloc ) {
Packit 3f632f
			my $comm = $target->[ $u ]{ Community };
Packit 3f632f
			my $host = $target->[ $u ]{ Host };
Packit 3f632f
			my $opt = $target->[ $u ]{ SnmpOpt };
Packit 3f632f
			$nloc = "$comm\@$host$opt";
Packit 3f632f
		}
Packit 3f632f
		# Get the location from the RouterUptime keyword if that is defined
Packit 3f632f
		# and $nloc has not otherwise been specified
Packit 3f632f
		$nloc = $uploc if $uploc and not $nloc;
Packit 3f632f
		# Get the device name if $nloc (community@host) has been specified
Packit 3f632f
		# one way or the other
Packit 3f632f
		debug('base', "Fetching sysName from: $noid:$nloc");
Packit 3f632f
		( $name ) = snmpget( $nloc, $$rcfg{snmpoptions}{ $rou }, $noid ) if $nloc;
Packit 3f632f
	}
Packit 3f632f
  
Packit 3f632f
	return ( $last{ _IN_ }, $last{ _OUT_ }, $uptime, $name, $time );
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
sub rateupcheck ($) {
Packit 3f632f
    my $router = shift;
Packit 3f632f
    if ($?) {
Packit 3f632f
        my $value = $?;
Packit 3f632f
        my $signal =  $? & 127; #ignore the most significant bit 
Packit 3f632f
                                #as it is always one when it is a returning
Packit 3f632f
                                #child says dave ...
Packit 3f632f
        if (($MRTG_lib::OS ne 'UNIX') || ($signal != 127)) {
Packit 3f632f
            my $exitval = $? >> 8;
Packit 3f632f
            warn "$NOW: WARNING: rateup died from Signal $signal\n".
Packit 3f632f
              " with Exit Value $exitval when doing router '$router'\n".
Packit 3f632f
                " Signal was $signal, Returncode was $exitval\n"
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
sub clonedirectory {
Packit 3f632f
    my($router,$cfg, $rcfg) = @_;
Packit 3f632f
    require File::Copy;
Packit 3f632f
    import File::Copy;
Packit 3f632f
Packit 3f632f
    return unless ( $$rcfg{'clonedirectory'}{$router} );
Packit 3f632f
Packit 3f632f
    my ($clonedstdir, $clonedsttarget ,$srcname, $dstname);
Packit 3f632f
Packit 3f632f
    ($clonedstdir, $clonedsttarget ) = split (/,|\s+/, $$rcfg{'clonedirectory'}{$router}) if ( $$rcfg{'clonedirectory'}{$router} =~ /,|\S\s+\S/ );
Packit 3f632f
Packit 3f632f
    if ( defined $clonedsttarget ) {
Packit 3f632f
		$clonedsttarget =~ s/\s+//;
Packit 3f632f
		$clonedsttarget = lc($clonedsttarget);
Packit 3f632f
    } else {
Packit 3f632f
        	$clonedstdir = $$rcfg{'clonedirectory'}{$router};
Packit 3f632f
    }
Packit 3f632f
    if ( $$rcfg{'directory'}{$router} ne $clonedstdir) {
Packit 3f632f
	$clonedstdir =~ s/\s+$//;
Packit 3f632f
        $clonedstdir .= "/" unless ($clonedstdir =~ /\/$/);
Packit 3f632f
        my $fullpathsrcdir = "$$cfg{'logdir'}$$rcfg{'directory'}{$router}";
Packit 3f632f
        my $fullpathdstdir = "$$cfg{'logdir'}$clonedstdir";
Packit 3f632f
Packit 3f632f
        die "$NOW: ERROR: Destination dir: $fullpathdstdir not found for cloning process\n" unless ( -e $fullpathdstdir );
Packit 3f632f
        die "$NOW: ERROR: Destination dir: $fullpathdstdir is not a directory destination for cloning process\n" unless ( -d $fullpathdstdir );
Packit 3f632f
        die "$NOW: ERROR: Destination dir: $fullpathdstdir is not writeable for cloning process\n" unless ( -w $fullpathdstdir );
Packit 3f632f
Packit 3f632f
        if ( defined $clonedsttarget ) {
Packit 3f632f
        	debug('base', "Clone directory $fullpathsrcdir to $fullpathdstdir " . 
Packit 3f632f
			       "renaming target $router to $clonedsttarget"); 
Packit 3f632f
	} else {
Packit 3f632f
        	debug('base', "Clone directory $fullpathsrcdir to $fullpathdstdir");
Packit 3f632f
	}
Packit 3f632f
Packit 3f632f
        foreach my $srcfile (<$fullpathsrcdir$router\[.-\]*>) {
Packit 3f632f
                debug('base', "copying $srcfile $fullpathdstdir");
Packit 3f632f
                copy("$srcfile","$fullpathdstdir") or warn "$NOW: WARNING: Cloning $srcfile to $fullpathdstdir unsuccessful; $!\n";
Packit 3f632f
                if ($srcfile =~ /\.html/i) {
Packit 3f632f
                        debug('base', "altering $fullpathdstdir/$router.$$rcfg{'extension'}{$router}");
Packit 3f632f
                        #
Packit 3f632f
                        my $dirrel = "../" x ($$rcfg{'clonedirectory'}{$router} =~ tr|/|/|);
Packit 3f632f
                        #
Packit 3f632f
                        debug('base', "dirrel $dirrel $clonedstdir");
Packit 3f632f
                        open(HTML,"$fullpathdstdir/$router.$$rcfg{'extension'}{$router}");
Packit 3f632f
                        my @CLONEHTML = <HTML>;
Packit 3f632f
                        close(HTML);
Packit 3f632f
                        foreach ( @CLONEHTML ) {
Packit 3f632f
	    			if ( defined $clonedsttarget and /$router/ ) {
Packit 3f632f
                                       	debug('base', "altering $router to $clonedsttarget in html file");
Packit 3f632f
					s/$router/$clonedsttarget/i;
Packit 3f632f
				}
Packit 3f632f
                                if ( /SRC=/i and /$$rcfg{'directory'}{$router}/ ) {
Packit 3f632f
                                        debug('base', "altering from $_");
Packit 3f632f
                                        s|(\.\./)+|$dirrel|;
Packit 3f632f
                                        s|$$rcfg{'directory'}{$router}|$clonedstdir|;
Packit 3f632f
                                        debug('base', "altering to $_");
Packit 3f632f
                                }
Packit 3f632f
                        }
Packit 3f632f
                        open(HTML,">$fullpathdstdir/$router.$$rcfg{'extension'}{$router}");
Packit 3f632f
                        print HTML $_ for ( @CLONEHTML );
Packit 3f632f
                        close(HTML);
Packit 3f632f
                }
Packit 3f632f
	    	if ( defined $clonedsttarget ) {
Packit 3f632f
			$srcfile =~ /.+\/(.+)?$/;
Packit 3f632f
			$srcname = $1;
Packit 3f632f
			$dstname = $srcname;
Packit 3f632f
			$dstname =~ s/$router/$clonedsttarget/;
Packit 3f632f
                        debug('base', "Clone renaming $srcname to $dstname at $fullpathdstdir");
Packit 3f632f
                	rename("$fullpathdstdir/$srcname","$fullpathdstdir/$dstname") or 
Packit 3f632f
				warn "$NOW: WARNING: Renaming $fullpathdstdir/$srcname to $fullpathdstdir/$dstname unsuccessful; $!\n";
Packit 3f632f
		}
Packit 3f632f
        }
Packit 3f632f
    } else {
Packit 3f632f
      warn "$NOW: WARNING: Cloning to the same place suspended. ; $!\n";
Packit 3f632f
    }
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
sub writegraphics {
Packit 3f632f
    my($router, $cfg, $rcfg, $inlast, $outlast, $time,$LOC, $opts) = @_;
Packit 3f632f
  
Packit 3f632f
    my($absmax,$maxv, $maxvi, $maxvo, $i, $period, $res);
Packit 3f632f
    my(@exec, @mxvls, @metas);
Packit 3f632f
    my(%maxin, %maxout, %maxpercent, %avin, %avout, %avmxin, %avmxout,  %avpercent, %cuin, %cuout, %cupercent);
Packit 3f632f
    my($rrdinfo);
Packit 3f632f
Packit 3f632f
    @metas = ();
Packit 3f632f
    $maxvi = $$rcfg{'maxbytes1'}{$router};
Packit 3f632f
    $maxvo = $$rcfg{'maxbytes2'}{$router};
Packit 3f632f
    if ($maxvi > $maxvo) {
Packit 3f632f
        $maxv = $maxvi;
Packit 3f632f
    } else {
Packit 3f632f
        $maxv = $maxvo;
Packit 3f632f
    }
Packit 3f632f
    $absmax = $$rcfg{'absmax'}{$router};
Packit 3f632f
    $absmax = $maxv unless defined $absmax;
Packit 3f632f
    if ($absmax < $maxv) {
Packit 3f632f
        die "$NOW: ERROR: AbsMax: $absmax is smaller than MaxBytes: $maxv\n";
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
Packit 3f632f
    # select whether the datasource gives relative or absolute return values.
Packit 3f632f
    my $up_abs="u";
Packit 3f632f
    $up_abs='m' if defined $$rcfg{'options'}{'perminute'}{$router};
Packit 3f632f
    $up_abs='h' if defined $$rcfg{'options'}{'perhour'}{$router};
Packit 3f632f
    $up_abs='d' if defined $$rcfg{'options'}{'derive'}{$router};
Packit 3f632f
    $up_abs='a' if defined $$rcfg{'options'}{'absolute'}{$router};
Packit 3f632f
    $up_abs='g' if defined $$rcfg{'options'}{'gauge'}{$router};
Packit 3f632f
Packit 3f632f
    my $dotrrd = "$$cfg{'logdir'}$$rcfg{'directory'}{$router}$router.rrd";
Packit 3f632f
    my $dotlog = "$$cfg{'logdir'}$$rcfg{'directory'}{$router}$router.log";
Packit 3f632f
    my $reallog = $$cfg{logformat} eq 'rrdtool' ? $dotrrd : $dotlog;
Packit 3f632f
Packit 3f632f
    if (defined $$cfg{maxage} and -e $reallog and time()-$$cfg{maxage} > (stat($reallog))[9]){
Packit 3f632f
         warn "$NOW: ERROR: skipping update of $router. As $reallog is older than MaxAge ($$cfg{maxage} s)\n";
Packit 3f632f
         return undef;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    if ($$cfg{logformat} eq 'rrdtool') {
Packit 3f632f
        debug('base',"start RRDtool section");
Packit 3f632f
        # make sure we got some sane default here
Packit 3f632f
        my %dstype = qw/u COUNTER a ABSOLUTE g GAUGE h COUNTER m COUNTER d DERIVE/;
Packit 3f632f
        $up_abs = $dstype{$up_abs};
Packit 3f632f
        # update the database.
Packit 3f632f
Packit 3f632f
        # set minimum/maximum values. use 'U' if we cannot get good values
Packit 3f632f
        # the lower bound is hardcoded to 0
Packit 3f632f
        my $absi = $maxvi;
Packit 3f632f
        my $abso = $maxvo;
Packit 3f632f
        $absi = $abso = $$rcfg{'absmax'}{$router}
Packit 3f632f
            if defined $$rcfg{'absmax'}{$router};
Packit 3f632f
        debug('base',"maxi:$absi, maxo:$abso");
Packit 3f632f
        $absi = 'U' if $absi == 0;
Packit 3f632f
        $abso = 'U' if $abso == 0;
Packit 3f632f
        # check to see if we already have an RRD file or have to create it
Packit 3f632f
        # maybe we can convert an .log file to the new rrd format
Packit 3f632f
        if( $RRDs::VERSION >= 1.4 and $$cfg{rrdcached} and $$cfg{rrdcached} !~ /^unix:/ ) {
Packit 3f632f
             # rrdcached in network mode.  No log conversion possible.
Packit 3f632f
             # In this mode, we cannot use absolute paths.  So, we strip logdir from the name.
Packit 3f632f
             $dotrrd = "$$rcfg{'directory'}{$router}$router.rrd";
Packit 3f632f
             if( $RRDs::VERSION < 1.49 ) {
Packit 3f632f
               # This version of RRD doesnt support info, create and tune
Packit 3f632f
               debug('base',"Unable to verify RRD file with this version of rrdcached");
Packit 3f632f
               if( !$main::verified_rrd{$dotrrd} ) {
Packit 3f632f
                 warn "WARN: Unable to verify $dotrrd with this version of RRDTool\n";
Packit 3f632f
                 $main::verified_rrd{$dotrrd} = 1;
Packit 3f632f
               }
Packit 3f632f
             } elsif( !$main::verified_rrd{$dotrrd} ) {
Packit 3f632f
               # Test to see if it exists
Packit 3f632f
               debug('base',"Attempting to verify RRD file via rrdcached");
Packit 3f632f
               $rrdinfo = RRDs::info($dotrrd,'--daemon',$$cfg{rrdcached},'--noflush');
Packit 3f632f
               if(!$rrdinfo) { # doesnt exist, or cannot be accessed
Packit 3f632f
                  my $e = RRDs::error();
Packit 3f632f
                  warn "$NOW: Cannot access $dotrrd; will attempt to (re)create it: $e\n" if $e;
Packit 3f632f
  
Packit 3f632f
                  # don't fail if interval is not set
Packit 3f632f
                  my $interval = $$cfg{interval};
Packit 3f632f
                  my $minhb = int($$cfg{interval} * 60)*2;
Packit 3f632f
                  $minhb = 600 if ($minhb <600); 
Packit 3f632f
                  my $rows = $$rcfg{'rrdrowcount'}{$router} || int( 4000 / $interval);
Packit 3f632f
                  my $rows30m = $$rcfg{'rrdrowcount30m'}{$router} || 800;
Packit 3f632f
                  my $rows2h = $$rcfg{'rrdrowcount2h'}{$router} || 800;
Packit 3f632f
                  my $rows1d = $$rcfg{'rrdrowcount1d'}{$router} || 800;
Packit 3f632f
                  my @args = ($dotrrd, '-b', $time-10, '-s', int($interval * 60),
Packit 3f632f
                               "DS:ds0:$up_abs:$minhb:0:$absi",
Packit 3f632f
                               "DS:ds1:$up_abs:$minhb:0:$abso",
Packit 3f632f
                               "RRA:AVERAGE:0.5:1:$rows",
Packit 3f632f
                               ( $interval < 30  ? ("RRA:AVERAGE:0.5:".int(30/$interval).":".$rows30m):()),
Packit 3f632f
                                 "RRA:AVERAGE:0.5:".int(120/$interval).":".$rows2h,
Packit 3f632f
                               "RRA:AVERAGE:0.5:".int(1440/$interval).":".$rows1d,
Packit 3f632f
                               "RRA:MAX:0.5:1:$rows",
Packit 3f632f
                               ( $interval < 30  ? ("RRA:MAX:0.5:".int(30/$interval).":".$rows30m):()),
Packit 3f632f
                               "RRA:MAX:0.5:".int(120/$interval).":".$rows2h,
Packit 3f632f
                               "RRA:MAX:0.5:".int(1440/$interval).":".$rows1d);
Packit 3f632f
                  # do we have holt winters rras defined here ?
Packit 3f632f
                  if (defined $$rcfg{'rrdhwrras'} and defined $$rcfg{'rrdhwrras'}{$router}){
Packit 3f632f
                      push @args, split(/\s+/, $$rcfg{'rrdhwrras'}{$router});
Packit 3f632f
                  }
Packit 3f632f
                  push @args,"--daemon", $$cfg{rrdcached};
Packit 3f632f
  
Packit 3f632f
                  debug('base',"create $dotrrd via rrdcached");
Packit 3f632f
                  debug('log', "RRDs::create(".join(',',@args).")");
Packit 3f632f
                  RRDs::create(@args);
Packit 3f632f
                  $e = RRDs::error();
Packit 3f632f
                  die "$NOW: ERROR: Cannot create RRD ".join(',',@args)."- $e\n" if $e;
Packit 3f632f
              } else {
Packit 3f632f
                  # Does the RRD file need to be tuned?
Packit 3f632f
                  if(
Packit 3f632f
                      ($rrdinfo->{"ds[ds0].max"} != $absi) 
Packit 3f632f
                      ||($rrdinfo->{"ds[ds1].max"} != $abso) 
Packit 3f632f
                      ||($rrdinfo->{"ds[ds0].type"} ne $up_abs) 
Packit 3f632f
                      ||($rrdinfo->{"ds[ds1].type"} ne $up_abs) 
Packit 3f632f
                  ) {
Packit 3f632f
                      debug('base',"RRD file needs to be tuned");
Packit 3f632f
                      warn "$NOW: RRDFile $dotrrd needs to be tuned but cannot do this remotely.\n";
Packit 3f632f
                  }
Packit 3f632f
              }
Packit 3f632f
              $main::verified_rrd{$dotrrd} = 1;
Packit 3f632f
            } else {
Packit 3f632f
               debug('base',"No need to verify this file again");
Packit 3f632f
            }
Packit 3f632f
        } elsif (-e $dotlog and not -e $dotrrd) {
Packit 3f632f
             debug('base',"converting $dotlog to RRD format");
Packit 3f632f
             if(defined $RRDs::VERSION and $RRDs::VERSION < 1.000271){
Packit 3f632f
                die "$NOW: ERROR: RRDtool version 1.0.27 or later required to perform log2rrd conversion\n";
Packit 3f632f
             }
Packit 3f632f
             log2rrd($router,$cfg,$rcfg);
Packit 3f632f
        } elsif (! -e $dotrrd) {
Packit 3f632f
            #nope it seems we have to create a new one
Packit 3f632f
            debug('base',"create $dotrrd");
Packit 3f632f
            # create the rrd if it doesn't exist
Packit 3f632f
            # don't fail if interval is not set
Packit 3f632f
            my $interval = $$cfg{interval};
Packit 3f632f
            my $minhb = int($$cfg{interval} * 60)*2;
Packit 3f632f
            $minhb = 600 if ($minhb <600); 
Packit 3f632f
            my $rows = $$rcfg{'rrdrowcount'}{$router} || int( 4000 / $interval);
Packit 3f632f
            my $rows30m = $$rcfg{'rrdrowcount30m'}{$router} || 800;
Packit 3f632f
            my $rows2h = $$rcfg{'rrdrowcount2h'}{$router} || 800;
Packit 3f632f
            my $rows1d = $$rcfg{'rrdrowcount1d'}{$router} || 800;
Packit 3f632f
            my @args = ($dotrrd, '-b', $time-10, '-s', int($interval * 60),
Packit 3f632f
                         "DS:ds0:$up_abs:$minhb:0:$absi",
Packit 3f632f
                         "DS:ds1:$up_abs:$minhb:0:$abso",
Packit 3f632f
                         "RRA:AVERAGE:0.5:1:$rows",
Packit 3f632f
                         ( $interval < 30  ? ("RRA:AVERAGE:0.5:".int(30/$interval).":".$rows30m):()),
Packit 3f632f
                         "RRA:AVERAGE:0.5:".int(120/$interval).":".$rows2h,
Packit 3f632f
                         "RRA:AVERAGE:0.5:".int(1440/$interval).":".$rows1d,
Packit 3f632f
                         "RRA:MAX:0.5:1:$rows",
Packit 3f632f
                         ( $interval < 30  ? ("RRA:MAX:0.5:".int(30/$interval).":".$rows30m):()),
Packit 3f632f
                         "RRA:MAX:0.5:".int(120/$interval).":".$rows2h,
Packit 3f632f
                         "RRA:MAX:0.5:".int(1440/$interval).":".$rows1d);
Packit 3f632f
            # do we have holt winters rras defined here ?
Packit 3f632f
            if (defined $$rcfg{'rrdhwrras'} and defined $$rcfg{'rrdhwrras'}{$router}){
Packit 3f632f
                push @args, split(/\s+/, $$rcfg{'rrdhwrras'}{$router});
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            debug('log', "RRDs::create(".join(',',@args).")");
Packit 3f632f
            RRDs::create(@args);
Packit 3f632f
            my $e = RRDs::error();
Packit 3f632f
            die "$NOW: ERROR: Cannot create RRD ".join(',',@args)."- $e\n" if $e;
Packit 3f632f
        } elsif ( -M $dotrrd > 0 ) {
Packit 3f632f
            # update the minimum/maximum according to maxbytes/absmax
Packit 3f632f
            # and (re)set the data-source-type to reflect cfg changes
Packit 3f632f
            # cost: 1 read/write cycle, but update will reuse the buffered data
Packit 3f632f
            # in daemon mode this will only happen in the first round
Packit 3f632f
            my @args = ($dotrrd, '-a', "ds0:$absi", '-a', "ds1:$abso",
Packit 3f632f
                       '-d', "ds0:$up_abs", '-d', "ds1:$up_abs");
Packit 3f632f
            debug('log', "RRDs::tune(@args)");
Packit 3f632f
            my $start = gettimeofday();
Packit 3f632f
            RRDs::tune(@args);
Packit 3f632f
	    debug('prof',sprintf("RRDs::tune $dotrrd - %.3fs",gettimeofday()-$start));
Packit 3f632f
            my $e = RRDs::error();
Packit 3f632f
            warn "$NOW: ERROR: Cannot tune logfile: $e\n" if $e;
Packit 3f632f
        }
Packit 3f632f
        # update the rrd
Packit 3f632f
        $inlast  = 'U' unless defined $inlast  and $inlast  =~ /\S/ and $inlast  ne '##UNDEF##';
Packit 3f632f
        $outlast = 'U' unless defined $outlast and $outlast =~ /\S/ and $outlast ne '##UNDEF##';
Packit 3f632f
        debug('log', "RRDs::update($dotrrd, '$time:$inlast:$outlast')");
Packit 3f632f
        my $start = gettimeofday();
Packit 3f632f
	my $rrddata = 0;
Packit 3f632f
	if ( $RRDs::VERSION >= 1.4 and $$cfg{rrdcached} ){
Packit 3f632f
	    RRDs::update($dotrrd, '--daemon', $$cfg{rrdcached}, "$time:$inlast:$outlast");
Packit 3f632f
            debug('prof',sprintf("RRDs::update $dotrrd (rrdcached) - %.3fs",gettimeofday()-$start));
Packit 3f632f
            $rrddata = \{ dummy => "" };
Packit 3f632f
	} elsif ( $RRDs::VERSION >= 1.2 ){
Packit 3f632f
	    $rrddata=RRDs::updatev($dotrrd, "$time:$inlast:$outlast");
Packit 3f632f
            debug('prof',sprintf("RRDs::updatev $dotrrd - %.3fs",gettimeofday()-$start));
Packit 3f632f
        } else {
Packit 3f632f
            RRDs::update($dotrrd, "$time:$inlast:$outlast");
Packit 3f632f
        debug('prof',sprintf("RRDs::update $dotrrd - %.3fs",gettimeofday()-$start));
Packit 3f632f
        }
Packit 3f632f
        my $e = RRDs::error(); 
Packit 3f632f
        warn "$NOW: ERROR: Cannot update $dotrrd with '$time:$inlast:$outlast' $e\n" if ($e);
Packit 3f632f
Packit 3f632f
Packit 3f632f
        # Send a copy of the time series data to graphite
Packit 3f632f
        if(defined $$cfg{sendtographite}) {
Packit 3f632f
          my @a = split ",",$$cfg{sendtographite};
Packit 3f632f
          if (not $graphiteObj) { 
Packit 3f632f
            $graphiteObj = Net::Graphite->new(
Packit 3f632f
            host                  => $a[0],
Packit 3f632f
            port                  => $a[1],
Packit 3f632f
            trace                 => 0,
Packit 3f632f
            proto                 => "tcp",
Packit 3f632f
            timeout               => 1,
Packit 3f632f
            fire_and_forget       => 1,
Packit 3f632f
            return_connect_error  => 0
Packit 3f632f
            );
Packit 3f632f
            if($graphiteObj->connect) {
Packit 3f632f
              debug('log',"successfully opened graphite socket ($graphiteObj)\n");
Packit 3f632f
            } else {
Packit 3f632f
              debug('log',"graphite connect error: $!\n");
Packit 3f632f
            }
Packit 3f632f
          }
Packit 3f632f
Packit 3f632f
	  # make a copy of the router name for use in the graphite namespace
Packit 3f632f
          my $graphiterouter = $router;
Packit 3f632f
          # periods are delimiters in the graphite namespace so change them to underscores
Packit 3f632f
          $graphiterouter =~ s/_/\./g;
Packit 3f632f
	  # commas are not allowed
Packit 3f632f
          $graphiterouter =~ s/,//g; #remove commas
Packit 3f632f
          #set up MRTG's 'in' var naming for graphite
Packit 3f632f
          my $graphitein;
Packit 3f632f
          if ($$rcfg{'legendi'}{$router}) {
Packit 3f632f
            $graphitein = $$rcfg{'legendi'}{$router};
Packit 3f632f
	    # if the 'in' var contains an underscore, change to a period so graphite will delimit on it
Packit 3f632f
            $graphitein =~ s/_/\./g;
Packit 3f632f
          } else {
Packit 3f632f
	    # if legendi is not specified, just use 'in'
Packit 3f632f
            $graphitein = "in";
Packit 3f632f
          }
Packit 3f632f
Packit 3f632f
          #set up MRTG's 'out' var naming for graphite
Packit 3f632f
          my $graphiteout;
Packit 3f632f
          if ($$rcfg{'legendo'}{$router}) {
Packit 3f632f
            $graphiteout = $$rcfg{'legendo'}{$router};
Packit 3f632f
	    # if the 'out' var contains an underscore, change to a period so graphite will delimit on it
Packit 3f632f
            $graphiteout =~ s/_/\./g;
Packit 3f632f
          } else {
Packit 3f632f
	    # if legendo is not specified, just use 'out'
Packit 3f632f
            $graphiteout = "out";
Packit 3f632f
          }
Packit 3f632f
Packit 3f632f
          my $graphitensprefix="m2g";
Packit 3f632f
Packit 3f632f
          # verify that the 'in' value is numeric (ints, floats, +, -) , and send to graphite
Packit 3f632f
          if($inlast =~ /^[+-]?([0-9]*[.])?[0-9]+$/) {
Packit 3f632f
            # send the 'in' var data to graphite, and log it appropriately
Packit 3f632f
            debug('log', "graphite->send($graphitensprefix.$graphiterouter.$graphitein,$inlast,$time)\n");
Packit 3f632f
            $graphiteObj->send(
Packit 3f632f
              path => "$graphitensprefix.$graphiterouter.$graphitein",
Packit 3f632f
              value => "$inlast",
Packit 3f632f
              time => $time,
Packit 3f632f
            );
Packit 3f632f
          } else {
Packit 3f632f
            debug('log', "WARNING - skipped graphite->send($graphitensprefix.$graphiterouter.$graphitein,$inlast,$time) because value ($inlast) is non-numeric\n");
Packit 3f632f
          }
Packit 3f632f
Packit 3f632f
          # verify that the 'out' value is numeric (ints, floats, +, -) , and send to graphite
Packit 3f632f
          if($outlast =~ /^[+-]?([0-9]*[.])?[0-9]+$/) { 
Packit 3f632f
            # send the 'out' var data to graphite, and log it appropriately
Packit 3f632f
            debug('log', "graphite->send($graphitensprefix.$graphiterouter.$graphiteout,$outlast,$time)\n");
Packit 3f632f
            $graphiteObj->send(
Packit 3f632f
              path => "$graphitensprefix.$graphiterouter.$graphiteout",
Packit 3f632f
              value => "$outlast",
Packit 3f632f
              time => $time,
Packit 3f632f
            );
Packit 3f632f
          } else {
Packit 3f632f
            debug('log', "WARNING - skipped graphite->send($graphitensprefix.$graphiterouter.$graphiteout,$outlast,$time) because value ($outlast) is non-numeric\n");
Packit 3f632f
          }
Packit 3f632f
        }
Packit 3f632f
        # done sending to graphite for this iteration
Packit 3f632f
Packit 3f632f
Packit 3f632f
Packit 3f632f
	if ( $RRDs::VERSION < 1.2 ){
Packit 3f632f
             # get the rrdtool-processed values back from rrdtool
Packit 3f632f
             # for the threshold checks (we cannot use the fetched data)
Packit 3f632f
	     $start = gettimeofday();
Packit 3f632f
             my $info =  RRDs::info($dotrrd);
Packit 3f632f
	     debug('prof',sprintf("RRDs::info $dotrrd - %.3fs",gettimeofday()-$start));
Packit 3f632f
	     my $lasttime =  $info->{last_update} - $info->{last_update} % $info->{step};        
Packit 3f632f
             debug('log', "RRDs::info($dotrrd)");
Packit 3f632f
             $e = RRDs::error(); 
Packit 3f632f
             warn "$NOW: ERROR: Cannot 'info' $dotrrd: $e\n" if ($e);
Packit 3f632f
             $start = gettimeofday();
Packit 3f632f
             my $fetch = (RRDs::fetch($dotrrd,'AVERAGE','-s',$lasttime-1,'-e',$lasttime))[3];
Packit 3f632f
             debug('prof',sprintf("RRDs::fetch $dotrrd - %.3fs",gettimeofday()-$start));
Packit 3f632f
             $e = RRDs::error(); 
Packit 3f632f
             warn "$NOW: ERROR: Cannot 'fetch' $dotrrd: $e\n" if ($e);
Packit 3f632f
             debug('log', "RRDs::fetch($dotrrd,'AVERAGE','-s',$lasttime,'-e',$lasttime)");        
Packit 3f632f
             $cuin{d}{$router} = $fetch->[0][0];
Packit 3f632f
             $cuout{d}{$router} = $fetch->[0][1];
Packit 3f632f
	} elsif ( $RRDs::VERSION >= 1.4 and $$cfg{rrdcached} ){
Packit 3f632f
             # Cannot check thresholds
Packit 3f632f
        } elsif($rrddata) {
Packit 3f632f
             my $utime = $time - ($time % int($cfg->{interval}*60));
Packit 3f632f
	     $cuin{d}{$router} = $rrddata->{"[$utime]RRA[AVERAGE][1]DS[ds0]"};
Packit 3f632f
	     $cuout{d}{$router} = $rrddata->{"[$utime]RRA[AVERAGE][1]DS[ds1]"};
Packit 3f632f
	     $cuin{d_hwfail}{$router} = $rrddata->{"[$utime]RRA[FAILURES][1]DS[ds0]"};
Packit 3f632f
	     $cuout{d_hwfail}{$router} = $rrddata->{"[$utime]RRA[FAILURES][1]DS[ds1]"};
Packit 3f632f
        }
Packit 3f632f
        my $in = defined $cuin{d}{$router} ?  $cuin{d}{$router} : "???" ;
Packit 3f632f
        my $out = defined  $cuout{d}{$router} ? $cuout{d}{$router} : "???" ;
Packit 3f632f
        debug('log', " got: $in/$out");
Packit 3f632f
        # the html pages and the graphics are created at "call time" so that's it!
Packit 3f632f
        # (the returned hashes are empty, it's just to minimize the changes to mrtg)
Packit 3f632f
        if ($$rcfg{'options'}{'dorelpercent'}{$router}) {  
Packit 3f632f
            return (\%maxin, \%maxout, \%maxpercent, \%avin, \%avout, \%avpercent, \%cuin, \%cuout, \%cupercent,  \%avmxin, \%avmxout);
Packit 3f632f
        }
Packit 3f632f
        return (\%maxin, \%maxout, \%avin, \%avout, \%cuin, \%cuout, \%avmxin, \%avmxout );
Packit 3f632f
Packit 3f632f
    }                 
Packit 3f632f
    ########## rrdtool users have left here ###############
Packit 3f632f
Packit 3f632f
    ((($MRTG_lib::OS eq 'NT' or $MRTG_lib::OS eq 'OS2') and (-e "${FindBin::Bin}${MRTG_lib::SL}rateup.exe")) or
Packit 3f632f
     (($MRTG_lib::OS eq 'NW') and (-e "SYS:/Mrtg/bin/rateup.nlm")) or
Packit 3f632f
     (-x "${FindBin::Bin}${MRTG_lib::SL}rateup")) or 
Packit 3f632f
       die "$NOW: ERROR: Can't Execute '${FindBin::Bin}${MRTG_lib::SL}rateup'\n";
Packit 3f632f
Packit 3f632f
    # rateup does not know about undef so we make inlast and outlast ready for rateup
Packit 3f632f
    #warn "$NOW: ERROR: inlast is undefined. Skipping $router\n" unless defined $inlast;
Packit 3f632f
    #warn "$NOW: ERROR: outlast is undefined. Skipping $router\n" unless defined $outlast;
Packit 3f632f
    #return undef unless defined $inlast and defined $outlast;
Packit 3f632f
Packit 3f632f
Packit 3f632f
    # set values to -1 to tell rateup about unknown values    
Packit 3f632f
    $inlast = -1 unless defined $inlast;
Packit 3f632f
    $outlast = -1 unless defined $outlast;
Packit 3f632f
    
Packit 3f632f
    # untaint in and out
Packit 3f632f
    if ($inlast =~ /^([-0-9.]+)$/) {
Packit 3f632f
        $inlast = $1;
Packit 3f632f
    }
Packit 3f632f
    if ($outlast =~ /^([-0-9.]+)$/) {
Packit 3f632f
        $outlast = $1;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
        @exec = ("${FindBin::Bin}${MRTG_lib::SL}rateup", 
Packit 3f632f
                 "$$cfg{'logdir'}$$rcfg{'directory'}{$router}","$router",
Packit 3f632f
                 $time, $$rcfg{'options'}{'unknaszero'}{$router} ? '-z':'-Z',
Packit 3f632f
                 "$up_abs"."p", $inlast, $outlast, $absmax,
Packit 3f632f
                 "C", $$rcfg{'rgb1'}{$router},$$rcfg{'rgb2'}{$router},
Packit 3f632f
                 $$rcfg{'rgb3'}{$router},$$rcfg{'rgb4'}{$router},
Packit 3f632f
                 $$rcfg{'rgb5'}{$router});
Packit 3f632f
    } else { 
Packit 3f632f
Packit 3f632f
        @exec = ("${FindBin::Bin}${MRTG_lib::SL}rateup", 
Packit 3f632f
                 "$$cfg{'logdir'}$$rcfg{'directory'}{$router}","$router",
Packit 3f632f
                 $time, $$rcfg{'options'}{'unknaszero'}{$router} ? '-z':'-Z',
Packit 3f632f
                 "$up_abs", $inlast, $outlast, $absmax,
Packit 3f632f
                 "c", $$rcfg{'rgb1'}{$router},$$rcfg{'rgb2'}{$router},
Packit 3f632f
                 $$rcfg{'rgb3'}{$router},$$rcfg{'rgb4'}{$router});
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # If this list grows anymore would it be more efficient to have an
Packit 3f632f
    # array to look up the command line option to send to rateup rather
Packit 3f632f
    # than have a long list to check?
Packit 3f632f
    push (@exec, '-t') if defined $$rcfg{'options'}{'transparent'}{$router};
Packit 3f632f
    push (@exec, '-0') if defined $$rcfg{'options'}{'withzeroes'}{$router};
Packit 3f632f
    push (@exec, '-b') if defined $$rcfg{'options'}{'noborder'}{$router};
Packit 3f632f
    push (@exec, '-a') if defined $$rcfg{'options'}{'noarrow'}{$router};
Packit 3f632f
    push (@exec, '-i') if defined $$rcfg{'options'}{'noi'}{$router};
Packit 3f632f
    push (@exec, '-o') if defined $$rcfg{'options'}{'noo'}{$router};
Packit 3f632f
    push (@exec, '-l') if defined $$rcfg{'options'}{'logscale'}{$router};
Packit 3f632f
    push (@exec, '-x') if defined $$rcfg{'options'}{'expscale'}{$router};
Packit 3f632f
    push (@exec, '-m') if defined $$rcfg{'options'}{'secondmean'}{$router};
Packit 3f632f
    push (@exec, '-p') if defined $$rcfg{'options'}{'printrouter'}{$router};
Packit 3f632f
Packit 3f632f
    my $maxx = $$rcfg{'xsize'}{$router}; 
Packit 3f632f
    my $maxy = $$rcfg{'ysize'}{$router};
Packit 3f632f
    my $xscale = $$rcfg{'xscale'}{$router}; 
Packit 3f632f
    my $yscale = $$rcfg{'yscale'}{$router}; 
Packit 3f632f
    my $growright = 0+($$rcfg{'options'}{'growright'}{$router} or 0);
Packit 3f632f
    my $bits = 0+($$rcfg{'options'}{'bits'}{$router} or 0);
Packit 3f632f
    my $integer = 0+($$rcfg{'options'}{'integer'}{$router} or 0);
Packit 3f632f
    my $step = 5*60; 
Packit 3f632f
    my $rop;
Packit 3f632f
    my $ytics = $$rcfg{'ytics'}{$router};
Packit 3f632f
    my $yticsf= $$rcfg{'yticsfactor'}{$router};
Packit 3f632f
    my $timestrfmt = $$rcfg{'timestrfmt'}{$router};
Packit 3f632f
    my $timestrpos = ${MRTG_lib::timestrpospattern}{uc $$rcfg{'timestrpos'}{$router}};
Packit 3f632f
Packit 3f632f
    if (not defined $$rcfg{'ylegend'}{$router}){
Packit 3f632f
	if ($bits){
Packit 3f632f
	    $$rcfg{'ylegend'}{$router} = &$LOC("Bits per minute")
Packit 3f632f
		if defined $$rcfg{'options'}{'perminute'}{$router};
Packit 3f632f
	    $$rcfg{'ylegend'}{$router} = &$LOC("Bits per hour")	    
Packit 3f632f
		if defined $$rcfg{'options'}{'perhour'}{$router};
Packit 3f632f
	} else {
Packit 3f632f
	    $$rcfg{'ylegend'}{$router} = &$LOC("Bytes per minute")
Packit 3f632f
		if defined $$rcfg{'options'}{'perminute'}{$router};
Packit 3f632f
	    $$rcfg{'ylegend'}{$router} = &$LOC("Bytes per hour")	    
Packit 3f632f
		if defined $$rcfg{'options'}{'perhour'}{$router};
Packit 3f632f
	}
Packit 3f632f
    }
Packit 3f632f
	
Packit 3f632f
    if ($$rcfg{'ylegend'}{$router}) {
Packit 3f632f
        push (@exec, "l", "[$$rcfg{'ylegend'}{$router}]");
Packit 3f632f
    }
Packit 3f632f
    my $sign = ($$rcfg{'unscaled'}{$router} and $$rcfg{'unscaled'}{$router} =~ /d/) ? 1 : -1;
Packit 3f632f
Packit 3f632f
    if ($$rcfg{'pngtitle'}{$router}) {
Packit 3f632f
        push (@exec, "T", "[$$rcfg{'pngtitle'}{$router}]");
Packit 3f632f
    }
Packit 3f632f
  
Packit 3f632f
    if ($$rcfg{'timezone'}{$router}) {
Packit 3f632f
        push (@exec, "Z", "$$rcfg{'timezone'}{$router}");
Packit 3f632f
    }
Packit 3f632f
  
Packit 3f632f
    if ($$rcfg{'kilo'}{$router}) {
Packit 3f632f
        push (@exec, "k", $$rcfg{'kilo'}{$router});
Packit 3f632f
    }
Packit 3f632f
    if ($$rcfg{'kmg'}{$router}) { 
Packit 3f632f
        push (@exec, "K", $$rcfg{'kmg'}{$router});
Packit 3f632f
    }
Packit 3f632f
    if ($$rcfg{'weekformat'}{$router}) {
Packit 3f632f
        push (@exec, "W", $$rcfg{'weekformat'}{$router});
Packit 3f632f
    }
Packit 3f632f
    my $SAGE = (time - $main::STARTTIME) / 3600 / 24; # current script age 
Packit 3f632f
    if (not defined $$opts{'log-only'}){
Packit 3f632f
      if (not defined $$rcfg{'suppress'}{$router} or $$rcfg{'suppress'}{$router} !~ /d/) {
Packit 3f632f
        # VMS: should work for both now
Packit 3f632f
        push (@exec, "i", "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-day.${main::GRAPHFMT}",
Packit 3f632f
              $sign*$maxvi, $sign*$maxvo, $maxx, $maxy, ,$xscale, $yscale, $growright, $step, $bits, $ytics, $yticsf, $timestrfmt, $timestrpos);
Packit 3f632f
        @mxvls = ("d");
Packit 3f632f
        push (@metas, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-day.${main::GRAPHFMT}",
Packit 3f632f
              $$cfg{'interval'});
Packit 3f632f
       }
Packit 3f632f
  
Packit 3f632f
Packit 3f632f
    if (((not -e "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-week.${main::GRAPHFMT}") or
Packit 3f632f
         ((-M "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-week.${main::GRAPHFMT}") + $SAGE  >= 0.5/24)) and
Packit 3f632f
        (not defined $$rcfg{'suppress'}{$router}  or $$rcfg{'suppress'}{$router} !~/w/)
Packit 3f632f
       ) {
Packit 3f632f
        $step=30*60;
Packit 3f632f
        $sign = (defined $$rcfg{'unscaled'}{$router}  and $$rcfg{'unscaled'}{$router} =~ /w/) ? 1 : -1;
Packit 3f632f
        push (@mxvls , "w");
Packit 3f632f
        $rop =(defined $$rcfg{'withpeak'}{$router}  and $$rcfg{'withpeak'}{$router} =~ /w/) ? "p" : "i"; 
Packit 3f632f
        push (@exec, $rop ,"$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-week.${main::GRAPHFMT}",
Packit 3f632f
              $sign*$maxvi, $sign*$maxvo,  $maxx, $maxy, $xscale, $yscale, $growright, $step, $bits, $ytics, $yticsf, $timestrfmt, $timestrpos);
Packit 3f632f
        push (@metas, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-week.${main::GRAPHFMT}", 30);
Packit 3f632f
    }
Packit 3f632f
  
Packit 3f632f
Packit 3f632f
    if (((not -e "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-month.${main::GRAPHFMT}") or
Packit 3f632f
         (( -M "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-month.${main::GRAPHFMT}") + $SAGE >= 2/24))  and
Packit 3f632f
        (not defined  $$rcfg{'suppress'}{$router} or $$rcfg{'suppress'}{$router} !~ /m/)) {
Packit 3f632f
        $step=2*60*60;
Packit 3f632f
        $sign = (defined $$rcfg{'unscaled'}{$router} and $$rcfg{'unscaled'}{$router} =~ /m/) ? 1 : -1;
Packit 3f632f
        push (@mxvls , "m");
Packit 3f632f
        $rop =(defined $$rcfg{'withpeak'}{$router} and $$rcfg{'withpeak'}{$router} =~ /m/) ? "p" : "i"; 
Packit 3f632f
        push (@exec, $rop ,"$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-month.${main::GRAPHFMT}",
Packit 3f632f
              $sign*$maxvi, $sign*$maxvo, $maxx, $maxy, $xscale, $yscale, $growright, $step, $bits, $ytics, $yticsf, $timestrfmt, $timestrpos);
Packit 3f632f
        push (@metas, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-month.${main::GRAPHFMT}", 120);
Packit 3f632f
    }
Packit 3f632f
  
Packit 3f632f
    if (((not -e "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-year.${main::GRAPHFMT}") or
Packit 3f632f
         (( -M "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-year.${main::GRAPHFMT}") + $SAGE  >= 1)) and
Packit 3f632f
        (not defined $$rcfg{'suppress'}{$router} or $$rcfg{'suppress'}{$router} !~/y/)) {
Packit 3f632f
        $step=24*60*60;
Packit 3f632f
        $sign = (defined $$rcfg{'unscaled'}{$router}  and $$rcfg{'unscaled'}{$router} =~ /y/) ? 1 : -1;
Packit 3f632f
        push (@mxvls , "y");
Packit 3f632f
        $rop =(defined $$rcfg{'withpeak'}{$router}  and $$rcfg{'withpeak'}{$router} =~ /y/) ? "p" : "i"; 
Packit 3f632f
        push (@exec, $rop, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-year.${main::GRAPHFMT}",
Packit 3f632f
              $sign*$maxvi, $sign*$maxvo, $maxx, $maxy, $xscale, $yscale, $growright, $step, $bits, $ytics, $yticsf, $timestrfmt, $timestrpos);
Packit 3f632f
        push (@metas, "$$cfg{'imagedir'}$$rcfg{'directory'}{$router}${router}-year.${main::GRAPHFMT}", 1440);
Packit 3f632f
    }
Packit 3f632f
  }
Packit 3f632f
Packit 3f632f
    # VMS: this might work now ... or does VMS NOT know about pipes?
Packit 3f632f
    # NT doesn't have fork() so an open(xxx,"-|") won't work
Packit 3f632f
    # OS2 fork() have bug with socket handles. In RunAsDaemon mode it fail
Packit 3f632f
    # after first loop (with "socket operation on non socket" message.
Packit 3f632f
Packit 3f632f
    if ($MRTG_lib::OS eq 'VMS' or $MRTG_lib::OS eq 'NT' or $MRTG_lib::OS eq 'OS2'){
Packit 3f632f
        map { s/"/\\"/; $_ = '"'.$_.'"' if /\s/ } @exec;
Packit 3f632f
        open (RATEUP, join (" ", @exec)."|") or
Packit 3f632f
           do {
Packit 3f632f
                warn "$NOW: WARNING: rateup (".(join " ", @exec ).
Packit 3f632f
                          ") did not work: $!\n";
Packit 3f632f
                return;
Packit 3f632f
           }
Packit 3f632f
    } elsif ($MRTG_lib::OS eq 'NW'){
Packit 3f632f
        map { s/"/\\"/; $_ = '"'.$_.'"' if /\s/ } @exec;
Packit 3f632f
Packit 3f632f
        # Stuff around because of Perl problems.
Packit 3f632f
Packit 3f632f
        open (NWPARMS, ">"."$$cfg{'imagedir'}$router.dat") or
Packit 3f632f
           do {
Packit 3f632f
                warn "$NOW: WARNING: Rateup parameters [$$cfg{'imagedir'}$router.dat] [open] failed.\n";
Packit 3f632f
Packit 3f632f
                return;
Packit 3f632f
           };
Packit 3f632f
        print NWPARMS join (" ", @exec);
Packit 3f632f
        close NWPARMS;
Packit 3f632f
Packit 3f632f
        # Now run Rateup with path to Parameters.
Packit 3f632f
Packit 3f632f
        open (RATEUP, "SYS:/Mrtg/bin/rateup -f $$cfg{'imagedir'}$router.dat"."|") or
Packit 3f632f
           do {
Packit 3f632f
                warn "$NOW: WARNING: SYS:/Mrtg/bin/rateup -f $$cfg{'imagedir'}$router.dat did NOT work.\n";
Packit 3f632f
Packit 3f632f
                return;
Packit 3f632f
           }
Packit 3f632f
    } else {
Packit 3f632f
        $! = undef;
Packit 3f632f
        open (RATEUP,"-|") or  
Packit 3f632f
                do { exec @exec or
Packit 3f632f
                     warn "$NOW: WARNING: rateup (".(join " ", @exec ).
Packit 3f632f
                          ") did not work: $!\n";
Packit 3f632f
                };
Packit 3f632f
Packit 3f632f
    }
Packit 3f632f
    
Packit 3f632f
    debug('log', join(" ", @exec));
Packit 3f632f
Packit 3f632f
Packit 3f632f
    if (open (HTML,"<$$cfg{'htmldir'}$$rcfg{'directory'}{$router}$router.$$rcfg{'extension'}{$router}")) {
Packit 3f632f
        for ($i=0 ; $i<200 ; $i++) {
Packit 3f632f
            last if eof(HTML);
Packit 3f632f
            $_= <HTML>;
Packit 3f632f
            if (/
Packit 3f632f
                $maxin{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            if (/
Packit 3f632f
                $maxout{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            if (/
Packit 3f632f
                $maxpercent{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            if (/
Packit 3f632f
                $avin{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            if (/
Packit 3f632f
                $avout{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            if (/
Packit 3f632f
                $avpercent{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            if (/
Packit 3f632f
                $cuin{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            if (/
Packit 3f632f
                $cuout{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
     
Packit 3f632f
            if (/
Packit 3f632f
                $cupercent{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
            if (/
Packit 3f632f
                $avmxin{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
Packit 3f632f
            if (/
Packit 3f632f
                $avmxout{$1}{$router}=$2 || 0;
Packit 3f632f
            }
Packit 3f632f
        }
Packit 3f632f
        close HTML;
Packit 3f632f
    }
Packit 3f632f
  
Packit 3f632f
    foreach $period (@mxvls) {
Packit 3f632f
        $res = <RATEUP>; 
Packit 3f632f
        if (not defined $res and eof(RATEUP)){
Packit 3f632f
            warn "$NOW: ERROR: Skipping webupdates because rateup did not return anything sensible\n";
Packit 3f632f
            close RATEUP;
Packit 3f632f
            rateupcheck $router;
Packit 3f632f
            return;
Packit 3f632f
        };
Packit 3f632f
        chomp $res;
Packit 3f632f
        $maxin{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
        chomp($res = <RATEUP>); 
Packit 3f632f
        $maxout{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
Packit 3f632f
        if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
            chomp($res = <RATEUP>); 
Packit 3f632f
            $maxpercent{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
        }
Packit 3f632f
Packit 3f632f
        chomp($res = <RATEUP>); 
Packit 3f632f
        $avin{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
        chomp($res = <RATEUP>); 
Packit 3f632f
        $avout{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
Packit 3f632f
        if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
            chomp($res = <RATEUP>); 
Packit 3f632f
            $avpercent{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
        }
Packit 3f632f
Packit 3f632f
        chomp($res = <RATEUP>); 
Packit 3f632f
        $cuin{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
        chomp($res = <RATEUP>); 
Packit 3f632f
        $cuout{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
Packit 3f632f
        if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
            chomp($res = <RATEUP>); 
Packit 3f632f
            $cupercent{$period}{$router}=sprintf("%.0f",$res || 0);
Packit 3f632f
        }
Packit 3f632f
Packit 3f632f
        chomp($res = <RATEUP>);
Packit 3f632f
        debug('avmx',"avmxin  $res");        
Packit 3f632f
        $avmxin{$period}{$router}=sprintf("%.0f",$res || 0);     
Packit 3f632f
        chomp($res = <RATEUP>);
Packit 3f632f
        debug('avmx',"avmxout $res");        
Packit 3f632f
        $avmxout{$period}{$router}=sprintf("%.0f",$res || 0);     
Packit 3f632f
        
Packit 3f632f
    }
Packit 3f632f
    close(RATEUP);
Packit 3f632f
    rateupcheck $router;
Packit 3f632f
    if ( defined $$cfg{'writeexpires'}  and $$cfg{'writeexpires'} =~ /^y/i ) {
Packit 3f632f
        my($fil,$exp);
Packit 3f632f
        while ( $fil = shift(@metas) ) {
Packit 3f632f
            $exp = &expistr(shift(@metas));
Packit 3f632f
            open(META, ">$fil.meta");
Packit 3f632f
            print META "Expires: $exp\n";
Packit 3f632f
            close(META);
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
        return (\%maxin, \%maxout, \%maxpercent, \%avin, \%avout, \%avpercent, \%cuin, \%cuout, \%cupercent, \%avmxin, \%avmxout);
Packit 3f632f
    } else {
Packit 3f632f
        return (\%maxin, \%maxout, \%avin, \%avout, \%cuin, \%cuout, \%avmxin, \%avmxout);
Packit 3f632f
    }
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
#format 10*$kilo to 10 kB/s
Packit 3f632f
sub fmi {
Packit 3f632f
    my($number, $maxbytes, $router, @foo) = @_;
Packit 3f632f
    return "?????" unless defined $number;
Packit 3f632f
    my($rcfg,$LOC)=@foo;
Packit 3f632f
    my @short= ();
Packit 3f632f
    my $mul = 1;
Packit 3f632f
    if ($$rcfg{'kmg'}{$router}) {
Packit 3f632f
        my($i);
Packit 3f632f
        if (defined $$rcfg{'shortlegend'}{$router}) {
Packit 3f632f
            foreach $i (split(/,/, $$rcfg{'kmg'}{$router})) {
Packit 3f632f
                $short[$#short+1] = "$i"."$$rcfg{'shortlegend'}{$router}";
Packit 3f632f
            }
Packit 3f632f
        }
Packit 3f632f
        elsif ($$rcfg{'options'}{'bits'}{$router}) {
Packit 3f632f
            foreach $i (split(/,/, $$rcfg{'kmg'}{$router})) {
Packit 3f632f
                if ($$rcfg{'options'}{'perminute'}{$router}) {
Packit 3f632f
                    $short[$#short+1] = "$i".&$LOC("b/min");
Packit 3f632f
                } elsif ($$rcfg{'options'}{'perhour'}{$router}) {
Packit 3f632f
                    $short[$#short+1] = "$i".&$LOC("b/h");
Packit 3f632f
                } else {
Packit 3f632f
                    $short[$#short+1] = "$i".&$LOC("b/s");
Packit 3f632f
                }
Packit 3f632f
            }
Packit 3f632f
            $mul= 8;
Packit 3f632f
        } else {
Packit 3f632f
            foreach $i (split(/,/, $$rcfg{'kmg'}{$router})) {
Packit 3f632f
                if ($$rcfg{'options'}{'perminute'}{$router}) {
Packit 3f632f
                    $short[$#short+1] = "$i".&$LOC ("B/min");
Packit 3f632f
                } elsif ($$rcfg{'options'}{'perhour'}{$router}) {
Packit 3f632f
                    $short[$#short+1] = "$i".&$LOC("B/h");
Packit 3f632f
                } else {
Packit 3f632f
                    $short[$#short+1] = "$i".&$LOC("B/s");
Packit 3f632f
                }
Packit 3f632f
            }
Packit 3f632f
            $mul= 1;
Packit 3f632f
        }
Packit 3f632f
    } else {
Packit 3f632f
        if (defined $$rcfg{'options'}{'bits'}{$router}) {
Packit 3f632f
            if ($$rcfg{'options'}{'perminute'}{$router}) {
Packit 3f632f
                @short = (&$LOC("b/min"),&$LOC("kb/min"),&$LOC("Mb/min"),&$LOC("Gb/min"));
Packit 3f632f
            } elsif (defined $$rcfg{'options'}{'perhour'}{$router}) {
Packit 3f632f
                @short = (&$LOC("b/h"),&$LOC("kb/h"),&$LOC("Mb/h"),&$LOC("Gb/h"));
Packit 3f632f
            } else {
Packit 3f632f
                @short = (&$LOC("b/s"),&$LOC("kb/s"),&$LOC("Mb/s"),&$LOC("Gb/s"));
Packit 3f632f
            }
Packit 3f632f
            $mul= 8;
Packit 3f632f
        } else {
Packit 3f632f
            if ($$rcfg{'options'}{'perminute'}{$router}) {
Packit 3f632f
                @short = (&$LOC("B/min"),&$LOC("kB/min"),&$LOC("MB/min"),&$LOC("GB/min"));
Packit 3f632f
            } elsif ($$rcfg{'options'}{'perhour'}{$router}) {
Packit 3f632f
                @short = (&$LOC("B/h"),&$LOC("kB/h"),&$LOC("MB/h"),&$LOC("GB/h"));
Packit 3f632f
            } else {
Packit 3f632f
                @short = (&$LOC("B/s"),&$LOC("kB/s"),&$LOC("MB/s"),&$LOC("GB/s"));
Packit 3f632f
            }
Packit 3f632f
            $mul= 1;
Packit 3f632f
        }
Packit 3f632f
        if ($$rcfg{'shortlegend'}{$router}) {
Packit 3f632f
            @short = ("$$rcfg{'shortlegend'}{$router}",
Packit 3f632f
                      "k$$rcfg{'shortlegend'}{$router}",
Packit 3f632f
                      "M$$rcfg{'shortlegend'}{$router}",
Packit 3f632f
                      "G$$rcfg{'shortlegend'}{$router}");
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
    my $digits=length("".$number*$mul);
Packit 3f632f
    my $divm=0;
Packit 3f632f
    #
Packit 3f632f
    #  while ($digits-$divm*3 > 4) { $divm++; }
Packit 3f632f
    #  my $divnum = $number*$mul/10**($divm*3);
Packit 3f632f
    my $divnum=$number*$mul*$$rcfg{'factor'}{$router};
Packit 3f632f
    #  while ($divnum/$$rcfg{'kilo'}{$router} >= 10*$$rcfg{'kilo'}{$router} and $divnum<$#short) {
Packit 3f632f
    while (($divnum >= 10*$$rcfg{'kilo'}{$router} or $short[$divm] =~ /^-/) and
Packit 3f632f
           $divm<$#short) {
Packit 3f632f
        $divm++;
Packit 3f632f
        $divnum /= $$rcfg{'kilo'}{$router};
Packit 3f632f
    }
Packit 3f632f
    my $perc;
Packit 3f632f
    if ($number == 0 || $maxbytes == 0) {
Packit 3f632f
        $perc = 0;
Packit 3f632f
    } else {
Packit 3f632f
        $perc = 100/$maxbytes*$number;
Packit 3f632f
    }
Packit 3f632f
    if (defined $$rcfg{'options'}{'integer'}{$router}) {
Packit 3f632f
        if ($$rcfg{'options'}{'nopercent'}{$router}) {
Packit 3f632f
            return sprintf("%.0f %s",$divnum,$short[$divm]);
Packit 3f632f
        } else {
Packit 3f632f
            return sprintf("%.0f %s (%2.1f%%)",$divnum,$short[$divm],$perc);
Packit 3f632f
        }
Packit 3f632f
    } else {
Packit 3f632f
        if (defined $$rcfg{'options'}{'nopercent'}{$router}) {
Packit 3f632f
            return sprintf("%.1f %s",$divnum,$short[$divm]); # Added: FvW
Packit 3f632f
        } else {
Packit 3f632f
            return sprintf("%.1f %s (%2.1f%%)",$divnum,$short[$divm],$perc);
Packit 3f632f
        }
Packit 3f632f
        return sprintf("%.1f %s (%2.1f%%)",$divnum,$short[$divm],$perc);
Packit 3f632f
    }
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
Packit 3f632f
sub writehtml {
Packit 3f632f
    my($router, $cfg, $rcfg, $maxin, $maxout, $maxpercent,
Packit 3f632f
       $avin, $avout, $avmxin, $avmxout, $avpercent, 
Packit 3f632f
       $cuin, $cuout, $cupercent, $uptime, $name, $LOC) = @_;
Packit 3f632f
  
Packit 3f632f
    my($VERSION,$Today,$peri);
Packit 3f632f
  
Packit 3f632f
    my($persec);
Packit 3f632f
Packit 3f632f
    if (defined $$rcfg{'options'}{'bits'}{$router}) {
Packit 3f632f
        $persec = &$LOC("Bits");
Packit 3f632f
    } else {
Packit 3f632f
        $persec = &$LOC("Bytes");
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    #  Work out the Colour legend
Packit 3f632f
    my($leg1, $leg2, $leg3, $leg4, $leg5);
Packit 3f632f
    if ($$rcfg{'legend1'}{$router}) {
Packit 3f632f
        $leg1 = $$rcfg{'legend1'}{$router};
Packit 3f632f
    } else {
Packit 3f632f
        if ($$rcfg{'options'}{'perminute'}{$router}) {
Packit 3f632f
            $leg1=&$LOC("Incoming Traffic in $persec per Minute");
Packit 3f632f
        } elsif ($$rcfg{'options'}{'perhour'}{$router}) {
Packit 3f632f
            $leg1=&$LOC("Incoming Traffic in $persec per Hour");
Packit 3f632f
        } else {
Packit 3f632f
            $leg1=&$LOC("Incoming Traffic in $persec per Second");
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
    if ($$rcfg{'legend2'}{$router}) {
Packit 3f632f
        $leg2 = $$rcfg{'legend2'}{$router};
Packit 3f632f
    } else {
Packit 3f632f
        if ($$rcfg{'options'}{'perminute'}{$router}) {
Packit 3f632f
            $leg2=&$LOC("Outgoing Traffic in $persec per Minute");
Packit 3f632f
        } elsif ($$rcfg{'options'}{'perhour'}{$router}) {
Packit 3f632f
            $leg2=&$LOC("Outgoing Traffic in $persec per Hour");
Packit 3f632f
        } else {
Packit 3f632f
            $leg2=&$LOC("Outgoing Traffic in $persec per Second");
Packit 3f632f
        }	
Packit 3f632f
    }
Packit 3f632f
    if ($$rcfg{'legend3'}{$router}) {
Packit 3f632f
        $leg3 = $$rcfg{'legend3'}{$router};
Packit 3f632f
    } else {
Packit 3f632f
        $leg3 = &$LOC("Maximal 5 Minute Incoming Traffic");
Packit 3f632f
    }
Packit 3f632f
    if ($$rcfg{'legend4'}{$router}) {
Packit 3f632f
        $leg4 = $$rcfg{'legend4'}{$router};
Packit 3f632f
    } else {
Packit 3f632f
        $leg4 = &$LOC("Maximal 5 Minute Outgoing Traffic");
Packit 3f632f
    }
Packit 3f632f
    if ($$rcfg{'legend5'}{$router}) {
Packit 3f632f
        $leg5 = $$rcfg{'legend5'}{$router};
Packit 3f632f
    } else {
Packit 3f632f
        $leg5 = "(($leg1)/($leg2))*100";
Packit 3f632f
    }
Packit 3f632f
    # Translate the color names
Packit 3f632f
    $$rcfg{'col1'}{$router}=&$LOC($$rcfg{'col1'}{$router});
Packit 3f632f
    $$rcfg{'col2'}{$router}=&$LOC($$rcfg{'col2'}{$router});
Packit 3f632f
    $$rcfg{'col3'}{$router}=&$LOC($$rcfg{'col3'}{$router});
Packit 3f632f
    $$rcfg{'col4'}{$router}=&$LOC($$rcfg{'col4'}{$router});
Packit 3f632f
    $$rcfg{'col5'}{$router}=&$LOC($$rcfg{'col5'}{$router});
Packit 3f632f
Packit 3f632f
    my $dirrel = "../" x ($$rcfg{'directory_web'}{$router} =~ tr|/|/|);
Packit 3f632f
Packit 3f632f
    $Today=&$LOC(datestr(time));
Packit 3f632f
    $VERSION = "2.17.7";
Packit 3f632f
    open (HTML,">$$cfg{'htmldir'}$$rcfg{'directory'}{$router}$router.$$rcfg{'extension'}{$router}") || 
Packit 3f632f
      do { warn ("$NOW: WARNING: Writing $router.$$rcfg{'extension'}{$router}: $!");
Packit 3f632f
      	   next };
Packit 3f632f
    # this unforutnately confuses old IE greatly ... so we have to comment
Packit 3f632f
    # it out for now ... :-(
Packit 3f632f
    # print HTML '' . "\n";
Packit 3f632f
    print HTML '' . "\n";
Packit 3f632f
    print HTML '<html lang="en">' . "\n";
Packit 3f632f
    my $interval =$$cfg{'interval'};
Packit 3f632f
    my $expiration = &expistr($interval);
Packit 3f632f
    my $refresh =  defined $$cfg{'refresh'} ? $$cfg{'refresh'} : 300;
Packit 3f632f
    my $namestring = &$LOC("the device");
Packit 3f632f
    print HTML '' . "\n";
Packit 3f632f
    print HTML '' . "\n";
Packit 3f632f
    print HTML "\t" . '<head>' . "\n";
Packit 3f632f
    print HTML "\t\t" . '<meta charset="' . &$LOC('UTF-8') . '" />' . "\n";
Packit 3f632f
    print HTML "\t\t" . '<meta http-equiv="refresh" content="' . "$refresh" . '" />' . "\n";
Packit 3f632f
# Not functional in HTML file in modern web browsers - use HTTP header instead
Packit 3f632f
#		<meta http-equiv="pragma" content="no-cache" />
Packit 3f632f
#		<meta http-equiv="cache-control" content="no-cache" />
Packit 3f632f
#		<meta http-equiv="expires" content="$expiration" />
Packit 3f632f
#		<meta http-equiv="generator" content="MRTG $VERSION" />
Packit 3f632f
#		<meta http-equiv="date" content="$expiration" />
Packit 3f632f
    print HTML "\t\t" . '<title>' . "$$rcfg{'title'}{$router}" . '</title>' . "\n";
Packit 3f632f
    foreach $peri (qw(d w m y)) {
Packit 3f632f
        print HTML <<"TEXT";
Packit 3f632f
Packit 3f632f
Packit 3f632f
TEXT
Packit 3f632f
        if ($$rcfg{'options'}{'dorelpercent'}{$router} and defined $$maxpercent{$peri}{$router}) {
Packit 3f632f
            print HTML <<"TEXT";
Packit 3f632f
Packit 3f632f
TEXT
Packit 3f632f
        }
Packit 3f632f
        print HTML <<"TEXT";
Packit 3f632f
Packit 3f632f
Packit 3f632f
TEXT
Packit 3f632f
        if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
            print HTML <<"TEXT";
Packit 3f632f
Packit 3f632f
TEXT
Packit 3f632f
        }
Packit 3f632f
        print HTML "\n"
Packit 3f632f
           if defined $$cuin{$peri}{$router};
Packit 3f632f
        print HTML "\n"
Packit 3f632f
           if defined $$cuout{$peri}{$router};
Packit 3f632f
Packit 3f632f
        if ($$rcfg{'options'}{'dorelpercent'}{$router} and $$cupercent{$peri}{$router} ) {
Packit 3f632f
            print HTML <<"TEXT";
Packit 3f632f
Packit 3f632f
TEXT
Packit 3f632f
        }
Packit 3f632f
        print HTML <<"TEXT" if  $$avmxin{$peri}{$router} and $$avmxout{$peri}{$router};
Packit 3f632f
Packit 3f632f
Packit 3f632f
TEXT
Packit 3f632f
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    $namestring = "'$name'" if $name;
Packit 3f632f
Packit 3f632f
    defined $$rcfg{backgc}{$router} or $$rcfg{backgc}{$router} = "#fff";
Packit 3f632f
Packit 3f632f
    $$rcfg{'rgb1'}{$router} = "" unless defined $$rcfg{'rgb1'}{$router};
Packit 3f632f
    $$rcfg{'rgb2'}{$router} = "" unless defined $$rcfg{'rgb2'}{$router};
Packit 3f632f
    $$rcfg{'rgb3'}{$router} = "" unless defined $$rcfg{'rgb3'}{$router};
Packit 3f632f
    $$rcfg{'rgb4'}{$router} = "" unless defined $$rcfg{'rgb4'}{$router};
Packit 3f632f
    $$rcfg{'rgb5'}{$router} = "" unless defined $$rcfg{'rgb5'}{$router};
Packit 3f632f
    $$rcfg{'rgb6'}{$router} = "" unless defined $$rcfg{'rgb6'}{$router};
Packit 3f632f
Packit 3f632f
    print HTML "		<style>
Packit 3f632f
			body {
Packit 3f632f
				background-color: $$rcfg{'backgc'}{$router};
Packit 3f632f
    ";
Packit 3f632f
    if($$rcfg{'backgc'}{$router} eq '#ffffff') {
Packit 3f632f
	print HTML "			color: #000000;";
Packit 3f632f
    } else {
Packit 3f632f
	print HTML "			color: #ffffff;";
Packit 3f632f
    }
Packit 3f632f
    print HTML "
Packit 3f632f
			}
Packit 3f632f
			div {
Packit 3f632f
				border-bottom: 2px solid #aaa;
Packit 3f632f
				padding-bottom: 10px;
Packit 3f632f
				margin-bottom: 5px;
Packit 3f632f
			}
Packit 3f632f
			div h2 {
Packit 3f632f
				font-size: 1.2em;
Packit 3f632f
			}
Packit 3f632f
			div.graph img {
Packit 3f632f
				margin: 5px 0;
Packit 3f632f
			}
Packit 3f632f
			div.graph table, div#legend table {
Packit 3f632f
				font-size: .8em;
Packit 3f632f
			}
Packit 3f632f
			div.graph table td {
Packit 3f632f
				padding: 0 10px;
Packit 3f632f
				text-align: right;
Packit 3f632f
			}
Packit 3f632f
			div table .in th, div table td span.in {
Packit 3f632f
				color: $$rcfg{'rgb1'}{$router};
Packit 3f632f
			}
Packit 3f632f
			div table .out th, div table td span.out {
Packit 3f632f
				color: $$rcfg{'rgb2'}{$router};
Packit 3f632f
			}";
Packit 3f632f
Packit 3f632f
    print HTML "
Packit 3f632f
			div table .inpeak th {
Packit 3f632f
				color: $$rcfg{'rgb3'}{$router};
Packit 3f632f
			}
Packit 3f632f
			div table .outpeak th {
Packit 3f632f
				color: $$rcfg{'rgb4'}{$router};
Packit 3f632f
			} " if defined $rcfg->{withpeak}{$router};
Packit 3f632f
Packit 3f632f
    print HTML "
Packit 3f632f
			div table .relpercent th {
Packit 3f632f
				color: $$rcfg{'rgb5'}{$router};
Packit 3f632f
			}" if ( $$rcfg{'options'}{'dorelpercent'}{$router} );
Packit 3f632f
	 
Packit 3f632f
    print HTML "
Packit 3f632f
			div#legend th {
Packit 3f632f
				text-align: right;
Packit 3f632f
			}
Packit 3f632f
			div#footer {
Packit 3f632f
				border: none;
Packit 3f632f
				font-size: .8em;
Packit 3f632f
				font-family: Arial, Helvetica, sans-serif;
Packit 3f632f
				width: 476px;
Packit 3f632f
			}
Packit 3f632f
			div#footer img {
Packit 3f632f
				border: none;
Packit 3f632f
				height: 25px;
Packit 3f632f
			}
Packit 3f632f
			div#footer address {
Packit 3f632f
				text-align: right;
Packit 3f632f
			}
Packit 3f632f
			div#footer #version {
Packit 3f632f
				margin: 0;
Packit 3f632f
				padding: 0;
Packit 3f632f
				float: left;
Packit 3f632f
				width: 88px;
Packit 3f632f
				text-align: right;
Packit 3f632f
			}
Packit 3f632f
		</style>";
Packit 3f632f
Packit 3f632f
    # allow for \n in addhead
Packit 3f632f
    defined $$rcfg{addhead}{$router} or $$rcfg{addhead}{$router} = "";
Packit 3f632f
    defined $$rcfg{pagetop}{$router} or $$rcfg{pagetop}{$router} = "";
Packit 3f632f
Packit 3f632f
    if (defined $$rcfg{bodytag}{$router}) {
Packit 3f632f
        if ($$rcfg{bodytag}{$router} !~ /
Packit 3f632f
                $$rcfg{bodytag}{$router} = "<body $$rcfg{bodytag}{$router}>";
Packit 3f632f
        }
Packit 3f632f
    } else {
Packit 3f632f
        $$rcfg{bodytag}{$router} = "<body>";
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    $$rcfg{addhead}{$router} =~ s/\\n/\n/g if defined $$rcfg{addhead}{$router};
Packit 3f632f
Packit 3f632f
    print HTML "$$rcfg{'addhead'}{$router}
Packit 3f632f
	</head>
Packit 3f632f
";
Packit 3f632f
    print HTML "
Packit 3f632f
$$rcfg{bodytag}{$router}
Packit 3f632f
    $$rcfg{'pagetop'}{$router}
Packit 3f632f
    ";
Packit 3f632f
    print HTML "

";

Packit 3f632f
    if (defined $$rcfg{'timezone'}{$router}){    
Packit 3f632f
    print HTML     
Packit 3f632f
      &$LOC("The statistics were last updated $Today $$rcfg{'timezone'}{$router}");
Packit 3f632f
    } else {
Packit 3f632f
    print HTML     
Packit 3f632f
      &$LOC("The statistics were last updated $Today");
Packit 3f632f
    }
Packit 3f632f
    if ($uptime and ! $$rcfg{options}{noinfo}{$router}) {
Packit 3f632f
        print HTML
Packit 3f632f
          ",
\n".
Packit 3f632f
        &$LOC("at which time $namestring had been up for $uptime.")
Packit 3f632f
    }
Packit 3f632f
	print HTML "

";
Packit 3f632f
    my %sample= ('d' => "`Daily' Graph (".$interval.' Minute',
Packit 3f632f
                 'w' => "`Weekly' Graph (30 Minute",
Packit 3f632f
                 'm' => "`Monthly' Graph (2 Hour",
Packit 3f632f
                 'y' => "`Yearly' Graph (1 Day");
Packit 3f632f
  
Packit 3f632f
    my %full = ('d' => 'day',
Packit 3f632f
                'w' => 'week',
Packit 3f632f
                'm' => 'month',
Packit 3f632f
                'y' => 'year');
Packit 3f632f
  
Packit 3f632f
    my $InCo;
Packit 3f632f
    if (!(defined $$rcfg{'options'}{'noi'}{$router})) {
Packit 3f632f
    if (exists $$rcfg{'legendi'}{$router}) {
Packit 3f632f
        if ($$rcfg{'legendi'}{$router} ne "") {
Packit 3f632f
            $InCo=$$rcfg{'legendi'}{$router};
Packit 3f632f
        }
Packit 3f632f
    } else {
Packit 3f632f
        $InCo=&$LOC("In");
Packit 3f632f
    }
Packit 3f632f
    }
Packit 3f632f
    
Packit 3f632f
    my $OutCo;
Packit 3f632f
    if (!(defined $$rcfg{'options'}{'noo'}{$router})) {
Packit 3f632f
    if (exists $$rcfg{'legendo'}{$router}) {
Packit 3f632f
        if ($$rcfg{'legendo'}{$router} ne "") {
Packit 3f632f
            $OutCo=$$rcfg{'legendo'}{$router};
Packit 3f632f
        }
Packit 3f632f
    } else {
Packit 3f632f
        $OutCo=&$LOC("Out");
Packit 3f632f
    }
Packit 3f632f
    }
Packit 3f632f
    my $PercentCo;
Packit 3f632f
    if (defined $$rcfg{'legend5'}{$router}) {
Packit 3f632f
        if ($$rcfg{'legend5'}{$router} ne "") {
Packit 3f632f
            $PercentCo=$$rcfg{'legend5'}{$router};
Packit 3f632f
        }
Packit 3f632f
    } else {
Packit 3f632f
        $PercentCo=&$LOC("Percentage");
Packit 3f632f
    }
Packit 3f632f
  
Packit 3f632f
    foreach $peri (qw(d w m y)) {
Packit 3f632f
        next if defined $$rcfg{'suppress'}{$router} and $$rcfg{'suppress'}{$router} =~/$peri/;
Packit 3f632f
        my $gifw;
Packit 3f632f
        if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
            $gifw=sprintf("%.0f",($$rcfg{'xsize'}{$router}*$$rcfg{'xscale'}{$router}+
Packit 3f632f
                                  +100+30) *$$rcfg{'xzoom'}{$router});
Packit 3f632f
        } else {
Packit 3f632f
            $gifw=sprintf("%.0f",($$rcfg{'xsize'}{$router}*$$rcfg{'xscale'}{$router}
Packit 3f632f
                                  +100) *$$rcfg{'xzoom'}{$router});
Packit 3f632f
        }
Packit 3f632f
        my $gifh=sprintf("%.0f",($$rcfg{'ysize'}{$router}*$$rcfg{'yscale'}{$router}+35)
Packit 3f632f
                         *$$rcfg{'yzoom'}{$router});
Packit 3f632f
                 
Packit 3f632f
        # take the image directory away from the html directory to give us relative links
Packit 3f632f
Packit 3f632f
Packit 3f632f
	my $imagepath = ( $cfg->{htmldir} ne $cfg->{imagedir} ) ? "$dirrel$$cfg{imagehtml}$$rcfg{directory_web}{$router}" : "";
Packit 3f632f
        print HTML "
Packit 3f632f
Packit 3f632f
		
Packit 3f632f
			

".&$LOC("$sample{$peri}").&$LOC(' Average)')."

Packit 3f632f
			\"$full{$peri}\"
Packit 3f632f
			
Packit 3f632f
				
Packit 3f632f
					
Packit 3f632f
					" . &$LOC("Max") . "
Packit 3f632f
					" . &$LOC("Average") . "
Packit 3f632f
					" . &$LOC("Current") . "
Packit 3f632f
				";
Packit 3f632f
        my(@foo)=($rcfg,$LOC);
Packit 3f632f
        print HTML "
Packit 3f632f
				
Packit 3f632f
					" . $InCo . "
Packit 3f632f
					".&fmi($$maxin{$peri}{$router}, $$rcfg{'maxbytes1'}{$router}, $router, @foo)."
Packit 3f632f
					".&fmi($$avin{$peri}{$router}, $$rcfg{'maxbytes1'}{$router}, $router, @foo)." 
Packit 3f632f
					".&fmi($$cuin{$peri}{$router}, $$rcfg{'maxbytes1'}{$router}, $router, @foo)." 
Packit 3f632f
				" if $InCo;
Packit 3f632f
        print HTML "
Packit 3f632f
				
Packit 3f632f
					" . $OutCo . "
Packit 3f632f
					".&fmi($$maxout{$peri}{$router}, $$rcfg{'maxbytes2'}{$router}, $router, @foo)." 
Packit 3f632f
					".&fmi($$avout{$peri}{$router}, $$rcfg{'maxbytes2'}{$router}, $router, @foo)." 
Packit 3f632f
					".&fmi($$cuout{$peri}{$router}, $$rcfg{'maxbytes2'}{$router}, $router, @foo)." 
Packit 3f632f
				" if $OutCo;
Packit 3f632f
        print HTML "
Packit 3f632f
				
Packit 3f632f
					" . $PercentCo . "
Packit 3f632f
					".sprintf("%0.1f %%",($$maxpercent{$peri}{$router} || 0))." 
Packit 3f632f
					".sprintf("%0.1f %%",($$avpercent{$peri}{$router} || 0 ))." 
Packit 3f632f
					".sprintf("%0.1f %%",($$cupercent{$peri}{$router} || 0 ))." 
Packit 3f632f
				" if ($$rcfg{'options'}{'dorelpercent'}{$router} and $PercentCo);
Packit 3f632f
print HTML "
Packit 3f632f
				
Packit 3f632f
					
Packit 3f632f
						" . &$LOC("Average max 5 min values for $sample{$peri} interval):") . "
Packit 3f632f
						$InCo " . &fmi($$avmxin{$peri}{$router}, $$rcfg{'maxbytes1'}{$router}, $router, @foo) . "/
Packit 3f632f
						$OutCo " . &fmi($$avmxout{$peri}{$router}, $$rcfg{'maxbytes2'}{$router}, $router, @foo) . "
Packit 3f632f
					
Packit 3f632f
				" if ($$rcfg{'options'}{'avgpeak'}{$router} and $InCo and $OutCo);
Packit 3f632f
        print HTML "
Packit 3f632f
			
Packit 3f632f
		
Packit 3f632f
\n";
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
    if (!(defined $$rcfg{'options'}{'nolegend'}{$router})) {
Packit 3f632f
    print HTML "
Packit 3f632f
Packit 3f632f
		
Packit 3f632f
			";
Packit 3f632f
    print HTML "
Packit 3f632f
				
Packit 3f632f
					$$rcfg{'col1'}{$router} ###
Packit 3f632f
					$leg1
Packit 3f632f
				" if $InCo;
Packit 3f632f
    print HTML "
Packit 3f632f
				
Packit 3f632f
					$$rcfg{'col2'}{$router} ###
Packit 3f632f
					$leg2
Packit 3f632f
				" if $OutCo;
Packit 3f632f
    if ($$rcfg{'withpeak'}{$router}) {
Packit 3f632f
        print HTML "
Packit 3f632f
				
Packit 3f632f
					$$rcfg{'col3'}{$router} ###
Packit 3f632f
					$leg3
Packit 3f632f
				" if $InCo;
Packit 3f632f
        print HTML "
Packit 3f632f
				
Packit 3f632f
					$$rcfg{'col4'}{$router} ###
Packit 3f632f
					$leg4
Packit 3f632f
				" if $OutCo;
Packit 3f632f
    }
Packit 3f632f
    if ($$rcfg{'options'}{'dorelpercent'}{$router}) {
Packit 3f632f
        print HTML "
Packit 3f632f
				
Packit 3f632f
					$$rcfg{'col5'}{$router} ###
Packit 3f632f
					$leg5
Packit 3f632f
				";
Packit 3f632f
    }
Packit 3f632f
        print HTML "
Packit 3f632f
			
Packit 3f632f
		
Packit 3f632f
Packit 3f632f
";
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    if (!(defined $$rcfg{'options'}{'nobanner'}{$router})) {
Packit 3f632f
    my $gifPath;
Packit 3f632f
Packit 3f632f
    if (defined $$cfg{icondir}) {
Packit 3f632f
        $gifPath = $$cfg{icondir};
Packit 3f632f
        #lets make sure there is a trailing path separator
Packit 3f632f
        $gifPath =~ s|/*$|/|;
Packit 3f632f
    } else {
Packit 3f632f
	$gifPath = "$dirrel$$cfg{imagehtml}";
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    print HTML<
Packit 3f632f
Packit 3f632f
		
Packit 3f632f
			MRTGMRTGMulti Router Traffic Grapher
Packit 3f632f
			

$VERSION

Packit 3f632f
			<address>
Packit 3f632f
				Tobias Oetiker
Packit 3f632f
				<tobi\@oetiker.ch>
Packit 3f632f
TEXT
Packit 3f632f
    print HTML &$LOC("and");
Packit 3f632f
    print HTML<
Packit 3f632f
				Dave Rand
Packit 3f632f
				<dlr\@bungi.com>
Packit 3f632f
TEXT
Packit 3f632f
Packit 3f632f
    # We don't need this any more.
Packit 3f632f
    undef $gifPath;
Packit 3f632f
Packit 3f632f
    if ($MRTG_lib::OS eq 'VMS') {
Packit 3f632f
        print HTML "
Packit 3f632f
				".&$LOC("Ported to OpenVMS Alpha by")." Werner Berger
Packit 3f632f
				<werner.berger\@cch.cerberus.ch>";
Packit 3f632f
    }
Packit 3f632f
# There is not realy any significant portion of code from Studard left and
Packit 3f632f
# none of his addresses work anymore. -- Tobi  2001-06-04
Packit 3f632f
#    if ($MRTG_lib::OS eq 'NT') {
Packit 3f632f
#        print HTML 
Packit 3f632f
#          "
Packit 3f632f
#  ".&$LOC("Ported to WindowsNT by")."
Packit 3f632f
#  <NOBR><small>Stuart Schneider
Packit 3f632f
#  
Packit 3f632f
#  <schneis\@testlab.orst.edu></NOBR>
Packit 3f632f
# ";
Packit 3f632f
#    }
Packit 3f632f
    if ( 
Packit 3f632f
        $$cfg{'language'} and 
Packit 3f632f
        defined($lang2tran::LOCALE{"\L$$cfg{'language'}\E"}) and
Packit 3f632f
        ($LOC != $lang2tran::LOCALE{"default"})) 
Packit 3f632f
    {
Packit 3f632f
        if (defined($credits::LOCALE{"\L$$cfg{'language'}\E"})) {
Packit 3f632f
            print HTML "
Packit 3f632f
				".$credits::LOCALE{"\L$$cfg{'language'}\E"};
Packit 3f632f
        } else {
Packit 3f632f
            print HTML "
Packit 3f632f
				".$credits::LOCALE{'default'};
Packit 3f632f
        }
Packit 3f632f
        ;
Packit 3f632f
    }
Packit 3f632f
    print HTML <
Packit 3f632f
			</address>
Packit 3f632f
		
Packit 3f632f
Packit 3f632f
TEXT
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    print HTML $$rcfg{'pagefoot'}{$router} if defined $$rcfg{'pagefoot'}{$router};
Packit 3f632f
    print HTML <
Packit 3f632f
	</body>
Packit 3f632f
</html>
Packit 3f632f
Packit 3f632f
TEXT
Packit 3f632f
    close HTML;
Packit 3f632f
Packit 3f632f
    if (defined $$cfg{'writeexpires'}  and $$cfg{'writeexpires'} =~ /^y/i) {
Packit 3f632f
        open(HTMLG, ">$$cfg{'htmldir'}$$rcfg{'directory'}{$router}$router.".
Packit 3f632f
	     "$$rcfg{'extension'}{$router}.meta") ||
Packit 3f632f
	       do {
Packit 3f632f
		   warn "$NOW: WARNING: Writing $$cfg{'htmldir'}$$rcfg{'directory'}{$router}$router.".
Packit 3f632f
		     "$$rcfg{'extension'}{$router}.meta: $!\n";
Packit 3f632f
		   next
Packit 3f632f
	       };
Packit 3f632f
Packit 3f632f
        print HTMLG "Expires: $expiration\n";
Packit 3f632f
        close(HTMLG);
Packit 3f632f
    }
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
Packit 3f632f
sub printusage {
Packit 3f632f
    print <
Packit 3f632f
Usage: mrtg <config-file>
Packit 3f632f
Packit 3f632f
mrtg-2.17.7 - Multi Router Traffic Grapher
Packit 3f632f
Packit 3f632f
Copyright 1995-2006 by Tobias Oetiker
Packit 3f632f
Licensed under the Gnu GPL.
Packit 3f632f
Packit 3f632f
If you want to know more about this tool, you might want
Packit 3f632f
to read the docs. You can find everything on the
Packit 3f632f
mrtg website:
Packit 3f632f
Packit 3f632f
http://oss.oetiker.ch/mrtg/
Packit 3f632f
Packit 3f632f
USAGEDESC
Packit 3f632f
    exit(1);
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
Packit 3f632f
sub lockit {
Packit 3f632f
    my ($lockfile,$templock) = @_;
Packit 3f632f
    if ($MRTG_lib::OS eq 'VMS' or $MRTG_lib::OS eq 'NT'  or $MRTG_lib::OS eq 'OS2') {
Packit 3f632f
        # too sad NT and VMS can't do links we'll do the diletants lock
Packit 3f632f
        if (-e $lockfile and not unlink $lockfile) {
Packit 3f632f
            my($lockage) = time()-(stat($lockfile))[9];
Packit 3f632f
            die "$NOW: ERROR: I guess another mrtg is running. A lockfile ($lockfile)\n".
Packit 3f632f
                 "       aged $lockage seconds is hanging around and I can't remove\n".
Packit 3f632f
                 "       it because another process is still using it.";
Packit 3f632f
        }
Packit 3f632f
      
Packit 3f632f
        open (LOCK, ">$lockfile") or 
Packit 3f632f
          die "$NOW: ERROR: Creating lockfile $lockfile: $!\n";
Packit 3f632f
        print LOCK "$$\n";
Packit 3f632f
        close LOCK;
Packit 3f632f
        open (LOCK, "<$lockfile") or 
Packit 3f632f
          die "$NOW: ERROR: Reading lockfile $lockfile for owner check: $!\n";
Packit 3f632f
        my($read)=<LOCK>;
Packit 3f632f
        chomp($read);
Packit 3f632f
        die "$NOW: ERROR: Someone else just got the lockfile $lockfile\n" 
Packit 3f632f
          unless  $$ == $read;
Packit 3f632f
    } else {
Packit 3f632f
        # now, lets do it the UNIX way ... Daves work ...
Packit 3f632f
        open(LOCK,">$templock") or die "$NOW: ERROR: Creating templock $templock: $!";
Packit 3f632f
        $main::Cleanfile = $templock;
Packit 3f632f
        if (!link($templock,$lockfile)) { # Lock file exists - deal with it.
Packit 3f632f
            my($nlink,$lockage) = (stat($lockfile))[3,9]; 
Packit 3f632f
            $lockage = time() - $lockage;
Packit 3f632f
            if ($nlink < 2 or $lockage > 30*60) { #lockfile is alone and old
Packit 3f632f
                unlink($lockfile) 
Packit 3f632f
                  || do{ unlink $templock; 
Packit 3f632f
                         die "$NOW: ERROR: Can't unlink stale lockfile ($lockfile). Permissions?\n"};
Packit 3f632f
                link($templock,$lockfile) 
Packit 3f632f
                  || do{ unlink $templock; 
Packit 3f632f
                         die "$NOW: ERROR: Can't create lockfile ($lockfile).\n".
Packit 3f632f
                           "Permission problem or another mrtg locking succesfully?\n"};
Packit 3f632f
            } else {
Packit 3f632f
                unlink $templock;
Packit 3f632f
                die "$NOW: ERROR: It looks as if you are running two copies of mrtg in parallel on\n".
Packit 3f632f
                    "       the same config file. There is a lockfile ($lockfile) and it is\n".
Packit 3f632f
                    "       is only $lockage seconds old ... Check your crontab.\n".
Packit 3f632f
                    "       (/etc/crontab and /var/spool/cron/root) \n"
Packit 3f632f
                        if $lockage < 4;
Packit 3f632f
      
Packit 3f632f
                die  "$NOW: ERROR: I guess another mrtg is running. A lockfile ($lockfile) aged\n".
Packit 3f632f
                     "$lockage seconds is hanging around. If you are sure that no other mrtg\n".
Packit 3f632f
                     "is running you can remove the lockfile\n";
Packit 3f632f
          
Packit 3f632f
            }
Packit 3f632f
        
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
sub threshmail ($$$$){
Packit 3f632f
    my $server = shift;
Packit 3f632f
    my $from = shift;
Packit 3f632f
    my $to = shift;
Packit 3f632f
    my $message = shift;
Packit 3f632f
    debug('base',"sending threshmail from $from to $to");
Packit 3f632f
    my $smtp = Net::SMTP->new([split /\s*,\s*/, $server],Timeout=>5) or
Packit 3f632f
	do { warn "$NOW: ERROR: could not send thresholdmail to $to"; return };
Packit 3f632f
    $smtp->mail($from);
Packit 3f632f
    $smtp->to(split(/\s*,\s*/, $to));
Packit 3f632f
    $smtp->data();
Packit 3f632f
    $smtp->datasend($message);
Packit 3f632f
    $smtp->dataend();
Packit 3f632f
    $smtp->quit;
Packit 3f632f
}   
Packit 3f632f
Packit 3f632f
sub threshcheck {
Packit 3f632f
    # threshold checking by Tom Muggli
Packit 3f632f
    # ... fsck'd up but fixed by Juha Laine
Packit 3f632f
    my ($cfg,$rcfg,$cfgfile,$router,$cuin,$cuout) = @_;
Packit 3f632f
    my $threshfile;
Packit 3f632f
    my %cu = ( i=> $cuin, o=>$cuout );
Packit 3f632f
    # are we going to keep state ?
Packit 3f632f
    if (defined $$cfg{'threshdir'}){
Packit 3f632f
        ensureSL(\$$cfg{'threshdir'});
Packit 3f632f
        $threshfile = $$cfg{'threshdir'}.(split /\Q$MRTG_lib::SL\E/, $cfgfile)[-1].".$router";
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # setup environment for external scripts
Packit 3f632f
    if (defined $rcfg->{'threshdesc'}{$router}) {
Packit 3f632f
        $ENV{THRESH_DESC}=$rcfg->{'threshdesc'}{$router};
Packit 3f632f
    } else {
Packit 3f632f
        delete $ENV{THRESH_DESC};
Packit 3f632f
    }
Packit 3f632f
    if (defined $rcfg->{'hwthreshdesc'}{$router}) {
Packit 3f632f
        $ENV{HWTHRESH_DESC}=$rcfg->{'hwthreshdesc'}{$router};
Packit 3f632f
    } else {
Packit 3f632f
        delete $ENV{HWTHRESH_DESC};
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    for my $dir (qw(i o)){ # in and out
Packit 3f632f
        my %thresh = (
Packit 3f632f
                thresh => $cu{$dir}{d}{$router},
Packit 3f632f
                
Packit 3f632f
        # if we are looking at an rrd with holtwinters RRAs
Packit 3f632f
        # we get a failures count.
Packit 3f632f
                hwthresh => $cu{$dir}{d_hwfail}{$router}
Packit 3f632f
        );
Packit 3f632f
        for my $type (keys %thresh){
Packit 3f632f
            for my $bound (qw(min max)){
Packit 3f632f
                # it gets set inside the loop because threshval gets modified further
Packit 3f632f
                # down in the code
Packit 3f632f
                my $threshval = $thresh{$type};
Packit 3f632f
                next if not defined $threshval;
Packit 3f632f
Packit 3f632f
                my $boundval = $rcfg->{$type.$bound.$dir}{$router};
Packit 3f632f
                next unless defined $boundval;
Packit 3f632f
    
Packit 3f632f
                my $realval = "";
Packit 3f632f
    	        my $realthresh = "";
Packit 3f632f
    
Packit 3f632f
                if ($boundval =~ s/%$//) { # defined in % of maxbytes
Packit 3f632f
                    # 2 decimals in %   
Packit 3f632f
        		    $realval = "% ($threshval)";
Packit 3f632f
	                $realthresh = "% (".sprintf("%.1f",($rcfg->{"maxbytes".($dir eq 'i' ? 1 : 2)}{$router} * $boundval / 100)).")";
Packit 3f632f
                    $threshval = sprintf "%.1f", ($threshval / $rcfg->{"maxbytes".($dir eq 'i' ? 1 : 2)}{$router} * 100); # the new code
Packit 3f632f
                }
Packit 3f632f
    	        my $msghead = "";
Packit 3f632f
                $msghead = "From: $cfg->{threshmailsender}\nTo: $rcfg->{${type}.'mailaddress'}{$router}"
Packit 3f632f
	    	        if $rcfg->{${type}.'mailaddress'}{$router} and $cfg->{threshmailsender};
Packit 3f632f
    	        my $pagetop = $rcfg->{pagetop}{$router} || '';
Packit 3f632f
    	        $pagetop =~ s|

.*?

||;
Packit 3f632f
                $pagetop =~ s|\s*\s*(.*?)\s*(.*?)\s*\s*|$1 $2\n|g;
Packit 3f632f
	        $pagetop =~ s|\s*<.+?>\s*\n?||g;
Packit 3f632f
Packit 3f632f
         	my $msgbody = <
Packit 3f632f
    
Packit 3f632f
$rcfg->{title}{$router}
Packit 3f632f
Packit 3f632f
   Target: $router
Packit 3f632f
     Type: $type
Packit 3f632f
Direction: $dir
Packit 3f632f
    Bound: $bound
Packit 3f632f
Threshold: $boundval$realthresh
Packit 3f632f
  Current: $threshval$realval
Packit 3f632f
Packit 3f632f
$pagetop
Packit 3f632f
Packit 3f632f
MESSAGE
Packit 3f632f
	            $msgbody .= "\n$rcfg->{$type.'desc'}{$router}\n" if $rcfg->{$type.'desc'}{$router};
Packit 3f632f
	
Packit 3f632f
                
Packit 3f632f
                if (($bound eq 'min' and $boundval > $threshval) or
Packit 3f632f
                    ($bound eq 'max' and $boundval < $threshval)) {
Packit 3f632f
    		        # threshold was broken...
Packit 3f632f
	    	        my $message = <
Packit 3f632f
$msghead
Packit 3f632f
Subject: [MRTG-TH] BROKEN $router $type $bound $dir ( $boundval$realthresh vs $threshval$realval )
Packit 3f632f
Packit 3f632f
Threshold BROKEN
Packit 3f632f
----------------
Packit 3f632f
$msgbody
Packit 3f632f
MESSAGE
Packit 3f632f
                    my @exec = ( $rcfg->{$type.'prog'.$dir}{$router}, $router,
Packit 3f632f
			            $rcfg->{$type.$bound.$dir}{$router}, $threshval,($rcfg->{$type.'desc'}{$router} ||"No Description"));
Packit 3f632f
 
Packit 3f632f
                    # Check if we use the status file or not...
Packit 3f632f
                    if ( defined $threshfile ) {
Packit 3f632f
		                if ( not -e $threshfile.".".$type.$bound.uc($dir) ) {
Packit 3f632f
			            # Create a file to indicate a threshold problem for the time after the problem
Packit 3f632f
			                open THRESHTOUCH, ">".$threshfile.".".$type.$bound.uc($dir)
Packit 3f632f
			                    or warn "$NOW: WARNING: Creating $threshfile.".$bound.uc($dir).": $!\n";
Packit 3f632f
			                close THRESHTOUCH;
Packit 3f632f
			                if (defined $rcfg->{$type.'prog'.$dir}{$router}){
Packit 3f632f
                                debug('base',"run threshprog$dir: ".(join ",",@exec));
Packit 3f632f
                     	        system @exec;
Packit 3f632f
			                }
Packit 3f632f
			                threshmail $cfg->{threshmailserver},$cfg->{threshmailsender},$rcfg->{$type.'mailaddress'}{$router},$message
Packit 3f632f
    			                if $rcfg->{$type.'mailaddress'}{$router}
Packit 3f632f
            	        } 
Packit 3f632f
                        else {
Packit 3f632f
			                debug('base',"NOT acting on BROKEN threshold since $threshfile.$type$bound$dir exists");
Packit 3f632f
		                }
Packit 3f632f
		            } elsif ( not defined $cfg->{$type.'hyst'} or 
Packit 3f632f
	                     ($bound eq 'min' and $boundval - $cfg->{$type.'hyst'}* $boundval < $threshval) or
Packit 3f632f
                            ($bound eq 'max' and $boundval + $cfg->{$type.'hyst'}* $boundval > $threshval)
Packit 3f632f
  			            ) {
Packit 3f632f
        		     # no threshold dir so run on every 'break'
Packit 3f632f
		                if (defined $rcfg->{$type.'prog'.$dir}{$router}){
Packit 3f632f
                            debug('base',"run ${type}prog$dir: ".(join ",",@exec));
Packit 3f632f
                            system @exec;
Packit 3f632f
          		        }
Packit 3f632f
            	        threshmail $cfg->{threshmailserver},$cfg->{threshmailsender},$rcfg->{$type.'mailaddress'}{$router},$message
Packit 3f632f
                            if $rcfg->{$type.'mailaddress'}{$router};
Packit 3f632f
		            }
Packit 3f632f
                } else {
Packit 3f632f
  		            # no threshold broken ...
Packit 3f632f
		            my @exec = ( $rcfg->{$type.'progok'.$dir}{$router}, $router,
Packit 3f632f
			                 $rcfg->{$type.$bound.$dir}{$router}, $threshval);
Packit 3f632f
		            my $message = <
Packit 3f632f
$msghead
Packit 3f632f
Subject: [MRTG-TH] UN-BROKEN $router $type $bound $dir ( $rcfg->{$type.$bound.$dir}{$router} vs $threshval)
Packit 3f632f
Packit 3f632f
Threshold UN-BROKEN
Packit 3f632f
-------------------
Packit 3f632f
$msgbody
Packit 3f632f
MESSAGE
Packit 3f632f
Packit 3f632f
		            # Check if we use the status file or not...
Packit 3f632f
		            if ( defined $threshfile ) {
Packit 3f632f
		                if ( -e $threshfile.".".$type.$bound.uc($dir) ){
Packit 3f632f
			                unlink "$threshfile.".$type.$bound.uc($dir);
Packit 3f632f
		                    if (defined $rcfg->{$type.'progok'.$dir}{$router}){
Packit 3f632f
                                debug('base',"run ${type}progok$dir: ".(join ",",@exec));
Packit 3f632f
                     	        system @exec;
Packit 3f632f
    		                }
Packit 3f632f
			                threshmail $cfg->{threshmailserver},$cfg->{threshmailsender},$rcfg->{$type.'mailaddress'}{$router},$message
Packit 3f632f
                                if $rcfg->{$type.'mailaddress'}{$router};
Packit 3f632f
		                }
Packit 3f632f
		            }   
Packit 3f632f
                }
Packit 3f632f
            } # for my $bound ...
Packit 3f632f
        } # for my $type
Packit 3f632f
    } # for my $dir
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
sub getexternal ($) {
Packit 3f632f
    my $command = shift;
Packit 3f632f
    my $in=undef;
Packit 3f632f
    my $out=undef;
Packit 3f632f
    my $uptime="unknown";
Packit 3f632f
    my $name="unknown";
Packit 3f632f
Packit 3f632f
    open (EXTERNAL , $command."|")
Packit 3f632f
	or warn "$NOW: WARNING: Running '$command': $!\n";
Packit 3f632f
Packit 3f632f
    warn "$NOW: WARNING: Could not get any data from external command ".
Packit 3f632f
	"'".$command.
Packit 3f632f
	    "'\nMaybe the external command did not even start. ($!)\n\n" if eof EXTERNAL;
Packit 3f632f
Packit 3f632f
    chomp( $in=<EXTERNAL>) unless eof EXTERNAL;
Packit 3f632f
    chomp( $out=<EXTERNAL>) unless eof EXTERNAL;
Packit 3f632f
    chomp( $uptime=<EXTERNAL>) unless eof EXTERNAL;
Packit 3f632f
    chomp( $name=<EXTERNAL>) unless eof EXTERNAL;
Packit 3f632f
Packit 3f632f
    close EXTERNAL;
Packit 3f632f
Packit 3f632f
    # strip returned date
Packit 3f632f
    $uptime  =~ s/^\s*(.*?)\s*/$1/;
Packit 3f632f
    $name  =~ s/^\s*(.*?)\s*/$1/;
Packit 3f632f
Packit 3f632f
    # do we have numbers in the external programs answer ?
Packit 3f632f
    if ( not defined $in ) {
Packit 3f632f
	warn "$NOW: WARNING: Problem with External get '$command':\n".
Packit 3f632f
	    "   Expected a Number for 'in' but nothing'\n\n";        
Packit 3f632f
    } elsif ( $in eq 'UNKNOWN' ) {
Packit 3f632f
        $in = undef;
Packit 3f632f
    } elsif ( $in !~ /([-+]?\d+(.\d+)?)/ ) {
Packit 3f632f
	warn "$NOW: WARNING: Problem with External get '$command':\n".
Packit 3f632f
	    "   Expected a Number for 'in' but got '$in'\n\n";
Packit 3f632f
	$in = undef;
Packit 3f632f
    } else {
Packit 3f632f
        $in = $1;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    if ( not defined $out ) {
Packit 3f632f
	warn "$NOW: WARNING: Problem with External get '$command':\n".
Packit 3f632f
	    "   Expected a Number for 'out' but nothing'\n\n";
Packit 3f632f
    } elsif ( $out eq 'UNKNOWN' ) {
Packit 3f632f
        $out = undef;
Packit 3f632f
    } elsif ( $out !~ /([-+]?\d+(.\d+)?)/ ) {
Packit 3f632f
	warn "$NOW: WARNING: Problem with External get '$command':\n".
Packit 3f632f
	    "   Expected a Number for 'out' but got '$out'\n\n";
Packit 3f632f
	$out = undef;
Packit 3f632f
    } else {
Packit 3f632f
        $out = $1;
Packit 3f632f
    }
Packit 3f632f
    debug('snpo',"External result:".($in||"undef")." out:".($out||"undef")." uptime:".($uptime||"undef")." name:".($name||"undef"));
Packit 3f632f
    return ($in,$out,time,$uptime,$name);
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
sub getsnmparg ($$$$){
Packit 3f632f
    my $confcache = shift;
Packit 3f632f
    my $target = shift;
Packit 3f632f
    my $cfg = shift;
Packit 3f632f
    my $populated = shift;
Packit 3f632f
    my $retry = 0;
Packit 3f632f
Packit 3f632f
    my $hostname = $$target{Host};
Packit 3f632f
    my $hostkey = "$$target{Community}\@$$target{Host}$$target{SnmpOpt}";
Packit 3f632f
Packit 3f632f
    if ($$target{ipv4only}) {
Packit 3f632f
        if (not ( $hostname =~ /^\d+\.\d+\.\d+\.\d+$/ or gethostbyname $hostname) ){
Packit 3f632f
            warn "$NOW: WARNING: Skipping host $hostname as it does not resolve to an IPv4 address\n";
Packit 3f632f
            return 'DEADHOST';
Packit 3f632f
        }
Packit 3f632f
    } else {
Packit 3f632f
         if($hostname =~ /^\[(.*)\]$/) {
Packit 3f632f
            # Numeric IPv6 address. Check that it's valid
Packit 3f632f
            $hostname = substr($hostname, 1);
Packit 3f632f
            chop $hostname;
Packit 3f632f
            if(! inet_pton(AF_INET6(), $hostname)) {
Packit 3f632f
                warn "$NOW: WARNING: Skipping host $hostname: invalid IPv6 address\n";
Packit 3f632f
                return 'DEADHOST';
Packit 3f632f
            }
Packit 3f632f
        } else {
Packit 3f632f
            # Hostname. Look it up
Packit 3f632f
            my @res;
Packit 3f632f
            my ($too,$port,$otheropts) = split(':', $$target{SnmpOpt}, 3);
Packit 3f632f
            $port = 161 unless defined $port;
Packit 3f632f
            @res = getaddrinfo($hostname, $port, Socket::AF_UNSPEC(), Socket::SOCK_DGRAM());
Packit 3f632f
            if (scalar (@res) < 5) {
Packit 3f632f
                warn "$NOW: WARNING: Skipping host $hostname as it does not resolve to an IPv4 or IPv6 address\n";
Packit 3f632f
                return 'DEADHOST';
Packit 3f632f
            }
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
  RETRY:
Packit 3f632f
    my @ifnum = ();
Packit 3f632f
    my @OID = ();
Packit 3f632f
    # Find apropriate Interface to poll from
Packit 3f632f
    for my $i (0..1) {
Packit 3f632f
	if ($$target{IfSel}[$i] eq 'If') {
Packit 3f632f
	    $ifnum[$i] = ".".$$target{Key}[$i];
Packit 3f632f
	    debug('snpo',"simple If: $ifnum[$i]");
Packit 3f632f
	} elsif($$target{IfSel}[$i] eq 'None') {
Packit 3f632f
            $ifnum[$i] = "";
Packit 3f632f
        } else {
Packit 3f632f
            $$target{Key}[$i] =~ s/\s+$//; # no trainling whitespace in keys ...
Packit 3f632f
Packit 3f632f
	    if (not defined readfromcache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i])) {
Packit 3f632f
		debug('snpo',"($i) Populate ConfCache for $$target{Host}$$target{SnmpOpt}");
Packit 3f632f
		populateconfcache($confcache,"$$target{Community}\@$$target{Host}$$target{SnmpOpt}",$$target{ipv4only},1,$$target{snmpoptions});
Packit 3f632f
		$$populated{$hostname} = 1; # set cache population to true for this cycle and host
Packit 3f632f
	    }
Packit 3f632f
 	    if (not defined readfromcache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i])) {
Packit 3f632f
                warn "$NOW: WARNING: Could not match host:'$$target{Community}\@$$target{Host}$$target{SnmpOpt}' ref:'$$target{IfSel}[$i]' key:'$$target{Key}[$i]'\n";
Packit 3f632f
		return 'NOMATCH';
Packit 3f632f
	    } else {
Packit 3f632f
		$ifnum[$i] = ".".readfromcache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i]);
Packit 3f632f
		debug('snpo',"($i) Confcache Match $$target{Key}[$i] -> $ifnum[$i]");
Packit 3f632f
	    }
Packit 3f632f
	}
Packit 3f632f
	if ($ifnum[$i] !~ /^$|^\.\d+$/) {
Packit 3f632f
	    warn "$NOW: WARNING: Can not determine".
Packit 3f632f
	      " ifNumber for $$target{Community}\@$$target{Host}$$target{SnmpOpt} \tref: '$$target{IfSel}[$i]' \tkey: '$$target{Key}[$i]'\n";
Packit 3f632f
	    return 'NOMATCH';
Packit 3f632f
	}
Packit 3f632f
    }
Packit 3f632f
    for my $i (0..1) {
Packit 3f632f
	# add ifget methodes call for a cross check;
Packit 3f632f
	for ($$target{IfSel}[$i]) {
Packit 3f632f
	    /^Eth$/ && do {
Packit 3f632f
		push @OID, "ifPhysAddress".$ifnum[$i]; last
Packit 3f632f
	    };
Packit 3f632f
	    /^Ip$/ && do {
Packit 3f632f
		push @OID, "ipAdEntIfIndex".".".$$target{Key}[$i];last
Packit 3f632f
	    };
Packit 3f632f
	    /^Descr$/ && do {
Packit 3f632f
		push @OID, "ifDescr".$ifnum[$i]; last
Packit 3f632f
	    };
Packit 3f632f
	    /^Type$/ && do {
Packit 3f632f
		push @OID, "ifType".$ifnum[$i]; last
Packit 3f632f
	    };
Packit 3f632f
	    /^Name$/ && do {
Packit 3f632f
		push @OID, "ifName".$ifnum[$i]; last
Packit 3f632f
	    };
Packit 3f632f
	}
Packit 3f632f
	push @OID ,$$target{OID}[$i].$ifnum[$i];
Packit 3f632f
    }
Packit 3f632f
    # we also want to know uptime and system name unless we are
Packit 3f632f
    if ( not defined $$cfg{nomib2} and $$cfg{logformat} ne 'rrdtool' ) {
Packit 3f632f
      if ( $OID[0] !~ /^cache.+$/ and
Packit 3f632f
           $OID[0] !~ /^\Q1.3.6.1.4.1.3495.1\E/ ) {
Packit 3f632f
           push @OID, qw(sysUptime sysName);
Packit 3f632f
      } else {
Packit 3f632f
           push @OID, qw(cacheUptime cacheSoftware cacheVersionId)
Packit 3f632f
      }
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # pull that data
Packit 3f632f
    debug('snpo',"SNMPGet from $$target{Community}\@$$target{Host}$$target{SnmpOpt} -- ".(join ",", @OID));
Packit 3f632f
    my @ret;
Packit 3f632f
    
Packit 3f632f
    # make sure we have no error messages hanging round.
Packit 3f632f
    
Packit 3f632f
    $SNMP_Session::errmsg = undef;
Packit 3f632f
    $Net_SNMP_util::ErrorMessage = undef;
Packit 3f632f
Packit 3f632f
    my $targtemp = $$target{Community}.'@'.$$target{Host}.$$target{SnmpOpt};
Packit 3f632f
    $targtemp = v4onlyifnecessary($targtemp, $$target{ipv4only});
Packit 3f632f
    
Packit 3f632f
    my @snmpoids = grep !/^(Pseudo|WaLK|GeTNEXT|CnTWaLK)|IndexPOS/, @OID;
Packit 3f632f
        
Packit 3f632f
    if (defined $$cfg{singlerequest}){
Packit 3f632f
#LH        local $BER::pretty_print_timeticks = 0;
Packit 3f632f
	foreach my $oid (@snmpoids){
Packit 3f632f
            push @ret, snmpget($targtemp,$$target{snmpoptions},$oid);
Packit 3f632f
	}
Packit 3f632f
    } else {
Packit 3f632f
	@ret = snmpget($targtemp,$$target{snmpoptions},@snmpoids);
Packit 3f632f
    }
Packit 3f632f
    my @newret;
Packit 3f632f
    for (@OID) {
Packit 3f632f
        /^PseudoZero$/ && do { push @newret, 0; next; };
Packit 3f632f
        /^PseudoOne$/ && do { push @newret, 1; next; };
Packit 3f632f
        s/^WaLK(\d*)// && do { my $idx = $1 || 0; my $oid=$_;push @newret, (split /:/, (snmpwalk($targtemp,$$target{snmpoptions},$oid))[$idx],2)[1]; 
Packit 3f632f
                          debug('snpo',"snmpwalk '$oid' -> ".($newret[-1]||'UNDEF'));next};
Packit 3f632f
        s/^GeTNEXT// && do { my $oid=$_;push @newret, (split /:/, snmpgetnext($targtemp,$$target{snmpoptions},$oid),2)[1]; 
Packit 3f632f
                          debug('snpo',"snmpgetnext '$oid' -> ".($newret[-1]||'UNDEF'));next};
Packit 3f632f
	s/^CnTWaLK// && do { my $oid=$_;my @insts= (snmpwalk($targtemp,$$target{snmpoptions},$_)); 
Packit 3f632f
	    		undef @insts if( $insts[1] || '') =~/no/i; push @newret, scalar @insts;
Packit 3f632f
			debug('snpo',"snmpCountwalk '$oid' -> ".($newret[-1]||'UNDEF'));next};
Packit 3f632f
        /IndexPOS.*\.(\d*)/ && do { my $idx=$1; s/IndexPOS/$idx/; s/\.\d*$//; push @newret, snmpget($targtemp,$$target{snmpoptions},$_); 
Packit 3f632f
                          debug('snpo', "snmpget of oid '$_' after replacement of IndexPOS"); next};
Packit 3f632f
        push @newret, shift @ret;
Packit 3f632f
    }
Packit 3f632f
    @ret = @newret;
Packit 3f632f
    debug('snpo',"SNMPfound -- ".(join ", ", map {"'".($_||"undef")."'"}  @ret));
Packit 3f632f
    $ret[-2] = $ret[-2].' '.$ret[-1] if $OID[-1] and $OID[-1] eq 'cacheVersionId';
Packit 3f632f
    my $time = time;
Packit 3f632f
    my @final;
Packit 3f632f
    # lets do some reality check
Packit 3f632f
    for my $i (0..1) {
Packit 3f632f
	# some ifget methodes call for a cross check;
Packit 3f632f
	for ($$target{IfSel}[$i]) {
Packit 3f632f
	    /^Eth$/ && do {
Packit 3f632f
		my $bin = shift @ret || 0xff;
Packit 3f632f
		my $eth = unpack 'H*', $bin;
Packit 3f632f
		my @eth;
Packit 3f632f
		while ($eth =~ s/^..//){
Packit 3f632f
		    push @eth, $&;
Packit 3f632f
		}
Packit 3f632f
		my $phys=join '-', @eth;
Packit 3f632f
		if ($phys ne $$target{Key}[$i]) {
Packit 3f632f
		    debug('snpo', "($i) eth if crosscheck got $phys expected $$target{Key}[$i]");
Packit 3f632f
		    if (not $retry) {
Packit 3f632f
			$retry=1;
Packit 3f632f
			# remove broken entry
Packit 3f632f
			storeincache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i],undef);
Packit 3f632f
			debug('repo',"($i) goto RETRY force if cache repopulation");
Packit 3f632f
			goto RETRY;
Packit 3f632f
		    } else {
Packit 3f632f
			warn "$NOW: WARNING: could not match&get".
Packit 3f632f
			    " $$target{Host}$$target{SnmpOpt}/$$target{OID}[$i] for Eth $$target{Key}[$i]\n";
Packit 3f632f
			return 'NOMATCH';
Packit 3f632f
		    }
Packit 3f632f
		};
Packit 3f632f
		debug ('snpo',"($i) Eth crosscheck OK");
Packit 3f632f
	    };
Packit 3f632f
	    /^Ip$/ && do {
Packit 3f632f
		my $if = shift @ret || 'none';
Packit 3f632f
		if ($ifnum[$i] ne '.'.$if) {
Packit 3f632f
		    debug('repo', "($i) IP if crosscheck got .$if expected $ifnum[$i]");
Packit 3f632f
		    if (not $retry) {
Packit 3f632f
			$retry=1;
Packit 3f632f
			# remove broken entry
Packit 3f632f
			storeincache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i],undef);   
Packit 3f632f
			debug('repo',"($i) goto RETRY force if cache repopulation");
Packit 3f632f
			goto RETRY;
Packit 3f632f
		    } else {
Packit 3f632f
			warn "$NOW: WARNING: could not match&get".
Packit 3f632f
			    " $$target{Host}$$target{SnmpOpt}/$$target{OID}[$i] for IP $$target{Key}[$i]\n";
Packit 3f632f
			return 'NOMATCH';
Packit 3f632f
		    }
Packit 3f632f
		}
Packit 3f632f
		debug ('snpo',"($i) IP crosscheck OK");
Packit 3f632f
	    };
Packit 3f632f
	    /^(Descr|Name|Type)$/ && do {
Packit 3f632f
		my $descr = shift @ret || 'Empty';
Packit 3f632f
                $descr =~ s/[\0- ]+$//; # remove excess spaces and stuff
Packit 3f632f
		if ($descr ne $$target{Key}[$i]) {
Packit 3f632f
		    debug('repo', "($i) $_ if crosscheck got $descr expected $$target{Key}[$i]");
Packit 3f632f
		    if (not $retry) {
Packit 3f632f
			$retry=1;
Packit 3f632f
			# remove broken entry
Packit 3f632f
			storeincache($confcache,$hostkey,$$target{IfSel}[$i],$$target{Key}[$i],undef);   
Packit 3f632f
			debug('repo',"($i) goto RETRY force if cache repopulation");
Packit 3f632f
			goto RETRY;
Packit 3f632f
		    } else {
Packit 3f632f
			warn "$NOW: WARNING: could not match&get".
Packit 3f632f
			    " $$target{Host}$$target{SnmpOpt}/$$target{OID}[$i] for $_ '$$target{Key}[$i]'\n";
Packit 3f632f
			return 'NOMATCH';
Packit 3f632f
		    }
Packit 3f632f
		} 
Packit 3f632f
		debug ('snpo',"($i) $_ crosscheck OK");
Packit 3f632f
	    };
Packit 3f632f
	}
Packit 3f632f
	# no sense continuing here ... if there is no data ...      
Packit 3f632f
 	if (defined $SNMP_Session::errmsg and $SNMP_Session::errmsg =~ /no response received/){
Packit 3f632f
            $SNMP_Session::errmsg = undef;
Packit 3f632f
	    warn "$NOW: WARNING: skipping because at least the query for $OID[0] on  $$target{Host} did not succeed\n";
Packit 3f632f
	    return 'DEADHOST';
Packit 3f632f
        }
Packit 3f632f
 	if (defined $Net_SNMP_util::ErrorMessage and $Net_SNMP_util::ErrorMessage =~ /No response from remote/){
Packit 3f632f
            $Net_SNMP_util::ErrorMessage = undef;
Packit 3f632f
	    warn "$NOW: WARNING: skipping because at least the query for $OID[0] on  $$target{Host} did not succeed\n";
Packit 3f632f
	    return 'DEADHOST';
Packit 3f632f
	}	
Packit 3f632f
	if ($$target{OID}[$i] =~ /if(Admin|Oper)Hack/) {
Packit 3f632f
	    push @final, ((shift @ret) == 1) ? 1:0;
Packit 3f632f
	} else {
Packit 3f632f
	    push @final, shift @ret;
Packit 3f632f
	}
Packit 3f632f
    }
Packit 3f632f
    
Packit 3f632f
    my @res = ( @final,$time, @ret);
Packit 3f632f
    
Packit 3f632f
    # Convert in and out values to integers with a user-defined subroutine
Packit 3f632f
    # specified by the Conversion target key
Packit 3f632f
    if( $target->{ Conversion } ) {
Packit 3f632f
        foreach my $ri( 0..1 ) {
Packit 3f632f
            next unless defined $res[ $ri ];
Packit 3f632f
	    local $SIG{__DIE__};
Packit 3f632f
            my $exp = "&MRTGConversion::$target->{ Conversion }( \$res[\$ri] )";
Packit 3f632f
            $res[ $ri ] = eval $exp;
Packit 3f632f
            warn "$NOW: WARNING: evaluation of \"$exp\" failed\n$@\n" if $@;
Packit 3f632f
        }
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
    # have some cleanup first, it seems that some agents
Packit 3f632f
    # are adding newlines to what they return
Packit 3f632f
    map{ $_ =~ s/\n|\r//g if defined $_ } @res;
Packit 3f632f
    map{ $_ =~ s/^\s+//g if defined $_ } @res;
Packit 3f632f
    map{ $_ =~ s/\s+$//g if defined $_ } @res;
Packit 3f632f
    
Packit 3f632f
    # in and out should be numbers only
Packit 3f632f
	for my $ri (0..1){
Packit 3f632f
	    # for folks using rrdtool I am allowing numbers 
Packit 3f632f
	    # with decimals here
Packit 3f632f
	    if ( defined $res[$ri] and $res[$ri] !~ /^[-+]?\d+(.\d+)?$/ ) {
Packit 3f632f
		warn "$NOW: WARNING: Expected a number but got '$res[$ri]'\n";
Packit 3f632f
		$res[$ri] = undef;
Packit 3f632f
		
Packit 3f632f
	    }
Packit 3f632f
	}
Packit 3f632f
	return @res;
Packit 3f632f
    }
Packit 3f632f
Packit 3f632f
Packit 3f632f
# read target function ...
Packit 3f632f
sub readtargets ($$$) {
Packit 3f632f
    my ($confcache,$target,$cfg) = @_;
Packit 3f632f
    my $forks = $$cfg{forks};
Packit 3f632f
    my $trgnum = $#{$target}+1;
Packit 3f632f
    if (defined $forks and $forks > 1  and $trgnum > 1){
Packit 3f632f
        $forks = $trgnum if $forks > $trgnum;
Packit 3f632f
        my $split = int($trgnum / $forks) + 1;       
Packit 3f632f
	my @hand;
Packit 3f632f
	# get them forks to work ... 
Packit 3f632f
	for (my $i = 0; $i < $forks;$i++) {
Packit 3f632f
	    local *D;
Packit 3f632f
            my $sleep_count=0;
Packit 3f632f
            my $pid;
Packit 3f632f
            do {
Packit 3f632f
               $pid = open(D, "-|");
Packit 3f632f
                unless (defined $pid) {
Packit 3f632f
                    warn "$NOW: WARNING cannot fork: $!\n";
Packit 3f632f
                    die "$NOW: ERROR bailing out after 6 failed forkattempts"
Packit 3f632f
                         if $sleep_count++ > 6;
Packit 3f632f
                    sleep 10;
Packit 3f632f
                }
Packit 3f632f
            } until defined $pid;
Packit 3f632f
	    if ($pid) { # parent
Packit 3f632f
     		$hand[$i] = *D; # funky file handle magic ... 
Packit 3f632f
		debug ('fork',"Parent $$ after fork of child $i");
Packit 3f632f
	    } else {  # child
Packit 3f632f
		debug ('fork',"Child $i ($$) after fork");
Packit 3f632f
		my $res = "";
Packit 3f632f
                my %deadhost;
Packit 3f632f
                my %populated;
Packit 3f632f
		for (my $ii = $i * $split; 
Packit 3f632f
		     $ii < ($i+1) * $split and $ii < $trgnum;
Packit 3f632f
		     $ii++){
Packit 3f632f
		    my $targ = $$target[$ii];
Packit 3f632f
		    my @res;
Packit 3f632f
		    if ($$targ{Methode} eq 'EXEC') {
Packit 3f632f
			@res = getexternal($$targ{Command});
Packit 3f632f
		    } else { # parent
Packit 3f632f
                        if (not $deadhost{$$targ{Community}.$$targ{Host}}) {      
Packit 3f632f
        	  	    @res = getsnmparg($confcache,$targ,$cfg,\%populated);
Packit 3f632f
                            if ( $res[0] and $res[0] eq 'DEADHOST') {
Packit 3f632f
                                # guess we got a blank here
Packit 3f632f
                                @res = ( undef,undef,time,undef,undef);
Packit 3f632f
                                $deadhost{$$targ{Community}.$$targ{Host}} = 1;
Packit 3f632f
                                warn "$NOW: WARNING: no data for $$targ{OID}[0]&$$targ{OID}[1]:$$targ{Community}\@$$targ{Host}. Skipping further queries for Host $$targ{Host} in this round.\n"
Packit 3f632f
                            } elsif ($res[0] and $res[0] eq 'NOMATCH'){
Packit 3f632f
                                @res = (undef,undef,time,undef,undef);
Packit 3f632f
                            }
Packit 3f632f
                        } else {
Packit 3f632f
                            @res = ( undef,undef,time,undef,undef);
Packit 3f632f
                        }
Packit 3f632f
		    }
Packit 3f632f
		
Packit 3f632f
		    for (my $iii=0;$iii<5;$iii++){
Packit 3f632f
			if (defined $res[$iii]){
Packit 3f632f
                            $res .= "$res[$iii]\n";
Packit 3f632f
			} else {
Packit 3f632f
                            $res .= "##UNDEF##\n";
Packit 3f632f
			}
Packit 3f632f
		    }
Packit 3f632f
		}
Packit 3f632f
		debug ('fork',"Child $i ($$) waiting to deliver");
Packit 3f632f
		print $res; # we only talk after the work has been done to
Packit 3f632f
                  	    # otherwhise we might get blocked 
Packit 3f632f
                # return updated hosts from confcache
Packit 3f632f
                writeconfcache($confcache,'&STDOUT')
Packit 3f632f
                        if defined $$confcache{___updated};
Packit 3f632f
		exit 0;
Packit 3f632f
	    }
Packit 3f632f
	    
Packit 3f632f
	}
Packit 3f632f
	# happy reaping ... 
Packit 3f632f
        my $vin =''; # vector of pipe file-descriptors from children
Packit 3f632f
	for (my $i = 0; $i < $forks;$i++) {
Packit 3f632f
            vec($vin, fileno($hand[$i]), 1) = 1;
Packit 3f632f
        }
Packit 3f632f
        my $left = $forks;
Packit 3f632f
        while ($left) {
Packit 3f632f
            my $rout = $vin; # read vector
Packit 3f632f
            my $eout = $vin; # exception vector
Packit 3f632f
            my $nfound = select($rout, undef, $eout, undef); # no timeout
Packit 3f632f
            if (1 > $nfound) {
Packit 3f632f
               die sprintf("$NOW: ERROR: select returned %d: $!\n", $nfound);
Packit 3f632f
            }
Packit 3f632f
	    for (my $i = 0; $i < $forks; $i++) {
Packit 3f632f
                next unless defined $hand[$i] and defined fileno($hand[$i]);
Packit 3f632f
# this does not seem to work reliably
Packit 3f632f
#                if (vec($eout, fileno($hand[$i]), 1)) {
Packit 3f632f
#		   die "$NOW: ERROR: fork $i has died ahead of time?\n";
Packit 3f632f
#                }
Packit 3f632f
                next unless vec($rout, fileno($hand[$i]), 1);
Packit 3f632f
Packit 3f632f
                vec($vin, fileno($hand[$i]), 1) = 0; # remove this child fd
Packit 3f632f
Packit 3f632f
	        debug ('fork',"Parent reading child $i");
Packit 3f632f
	        my $h = $hand[$i];
Packit 3f632f
	        for (my $ii = $i * $split; 
Packit 3f632f
		     $ii < ($i+1) * $split and $ii < $trgnum;
Packit 3f632f
		     $ii++){ 
Packit 3f632f
		    my $targ = $$target[$ii];
Packit 3f632f
		    my @res;
Packit 3f632f
		    for (0..4){
Packit 3f632f
		        my $line = <$h>; # must be a simple scalar here else it wont work
Packit 3f632f
		        die "$NOW: ERROR: fork $i has died ahead of time ...\n" if not defined $line;
Packit 3f632f
		        chomp $line;
Packit 3f632f
    #                    debug ('fork',"reading for $ii $line");
Packit 3f632f
		        $line = undef if $line eq "##UNDEF##";                
Packit 3f632f
		        push @res,$line;
Packit 3f632f
		    };
Packit 3f632f
    
Packit 3f632f
		    ($$targ{_IN_},
Packit 3f632f
		     $$targ{_OUT_},
Packit 3f632f
		     $$targ{_TIME_},
Packit 3f632f
		     $$targ{_UPTIME_},
Packit 3f632f
		     $$targ{_NAME_}) = @res; 
Packit 3f632f
                     if ($] >= 5.0061){
Packit 3f632f
                         $$targ{_IN_} = Math::BigFloat->new($$targ{_IN_}) if $$targ{_IN_};
Packit 3f632f
                         $$targ{_OUT_} = Math::BigFloat->new($$targ{_OUT_}) if $$targ{_OUT_};
Packit 3f632f
                     }
Packit 3f632f
                }     
Packit 3f632f
                # feed confcache entries
Packit 3f632f
                my $lasthost ="";
Packit 3f632f
                while (<$h>){
Packit 3f632f
                    chomp;
Packit 3f632f
                    my ($host,$method,$key,$value) = split (/\t/, $_);
Packit 3f632f
                    if ($host ne $lasthost){
Packit 3f632f
        	         debug ('fork',"start clearing confcache on first entry for target $host");
Packit 3f632f
                         clearfromcache($confcache,$host);
Packit 3f632f
        	         debug ('fork',"finished clearing confcache");        
Packit 3f632f
                    }
Packit 3f632f
                    $lasthost = $host;
Packit 3f632f
                    storeincache($confcache,$host,$method,$key,$value);
Packit 3f632f
                 }
Packit 3f632f
                 close $h;
Packit 3f632f
                 --$left;
Packit 3f632f
            }
Packit 3f632f
        }
Packit 3f632f
	            
Packit 3f632f
    } else {
Packit 3f632f
        my %deadhost;
Packit 3f632f
        my %populated;
Packit 3f632f
	foreach my $targ (@$target) {
Packit 3f632f
	    if ($$targ{Methode} eq 'EXEC') {
Packit 3f632f
		debug('snpo', "run external $$targ{Command}");
Packit 3f632f
		($$targ{_IN_},
Packit 3f632f
		 $$targ{_OUT_},
Packit 3f632f
		 $$targ{_TIME_},
Packit 3f632f
		 $$targ{_UPTIME_},
Packit 3f632f
		 $$targ{_NAME_}) = getexternal($$targ{Command});
Packit 3f632f
	    } elsif ($$targ{Methode} eq 'SNMP' and not $deadhost{$$targ{Host}}) {
Packit 3f632f
		debug('snpo', "run snmpget from $$targ{OID}[0]&$$targ{OID}[1]:$$targ{Community}\@$$targ{Host}");
Packit 3f632f
		($$targ{_IN_},
Packit 3f632f
		 $$targ{_OUT_},
Packit 3f632f
		 $$targ{_TIME_},
Packit 3f632f
		 $$targ{_UPTIME_},
Packit 3f632f
		 $$targ{_NAME_}) = getsnmparg($confcache,$targ,$cfg,\%populated);
Packit 3f632f
               if ( $$targ{_IN_} and $$targ{_IN_} eq 'DEADHOST') {
Packit 3f632f
                   $$targ{_IN_} = undef;
Packit 3f632f
                   $$targ{_TIME_} =time;
Packit 3f632f
                   # guess we got a blank here
Packit 3f632f
                   $deadhost{$$targ{Host}} = 1;
Packit 3f632f
                   warn "$NOW: WARNING: no data for $$targ{OID}[0]&$$targ{OID}[1]:$$targ{Community}\@$$targ{Host}. Skipping further queries for Host $$targ{Host} in this round.\n"
Packit 3f632f
               } 
Packit 3f632f
               if (  $$targ{_IN_} and $$targ{_IN_} eq 'NOMATCH') {   
Packit 3f632f
                   $$targ{_IN_} = undef;
Packit 3f632f
                   $$targ{_TIME_} =time;
Packit 3f632f
               }
Packit 3f632f
       
Packit 3f632f
	    } else {
Packit 3f632f
                 $$targ{_IN_} = undef;
Packit 3f632f
                 $$targ{_OUT_} = undef;
Packit 3f632f
                 $$targ{_TIME_} = time;
Packit 3f632f
                 $$targ{_UPTIME_} = undef;
Packit 3f632f
                 $$targ{_NAME_} = undef;
Packit 3f632f
            }
Packit 3f632f
            if ($] >= 5.008 ){
Packit 3f632f
                    $$targ{_IN_} = new Math::BigFloat "$$targ{_IN_}" if $$targ{_IN_};
Packit 3f632f
                    $$targ{_OUT_} = new Math::BigFloat "$$targ{_OUT_}" if $$targ{_OUT_};
Packit 3f632f
            }
Packit 3f632f
                
Packit 3f632f
	}       
Packit 3f632f
    }
Packit 3f632f
        
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
sub imggen ($) {
Packit 3f632f
        my $dir = shift;
Packit 3f632f
        if ( ! -r "$dir${main::SL}mrtg-l.png" and  open W, ">$dir${main::SL}mrtg-l.png" ){
Packit 3f632f
                binmode W;
Packit 3f632f
                print W unpack ('u', <<'UUENC');
Packit 3f632f
MB5!.1PT*&@H    -24A$4@   #\    9! ,   !TA.O'    &%!,5$5]9GTT
Packit 3f632f
M79A?8HB(9WFR;6G_=DWM=%35<5R_M[A2     6)+1T0'%F&(ZP   1%)1$%4
Packit 3f632f
M>-JMDKUOPD ,Q:E4]CH?S0PMG8-.$6L1A*YMJ,D<T>Q%5?[_ON>$Y (2$R>=
Packit 3f632f
MY;-^OF=;GNCM\SFY#_#GW$IU0WMP/#O5HSGNW8"9R)/92$NQ\Z:GUDG/@.@!
Packit 3f632f
M)CP#4H\ >LT>)NB!A0]8,"]&0.(#WY92V<\$=FM4
Packit 3f632f
MX.<2+4VH!U01B-LYX#V3B*U(1N 5[K,/?(G,)1!!9-%WX0.HYX7 :0!"]0&4
Packit 3f632f
MMV*/Z"/N@&8$P,N8!:FD[!4\ #7EN$G1 
Packit 3f632f
M+KI@K$9V#B"P03V,!\5)T]1T#*A,8P"P.%JZ1USGL%%IPTC.#
Packit 3f632f
M6*MJXQ-D&    $-T15AT4V]F='=A
Packit 3f632f
M(#DY+S Y+S Q(&-R:7-T>4!M>7-T:6,N97,N9'5P;VYT+F-O;>WHV?     J
Packit 3f632f
M=$58=%-I9VYA='5R90!D,C(W8S
Packit 3f632f
K8ULTB'X    .=$58=%!A9V4 -C-X,C4K,"LP&!)XE     !)14Y$KD)@@F(Y
Packit 3f632f
UUENC
Packit 3f632f
close W;
Packit 3f632f
        }
Packit 3f632f
        if ( ! -r "$dir${main::SL}mrtg-m.png" and  open W, ">$dir${main::SL}mrtg-m.png" ){
Packit 3f632f
                binmode W;
Packit 3f632f
                print W unpack ('u', <<'UUENC');
Packit 3f632f
MB5!.1PT*&@H    -24A$4@   !D    9! ,    VQYA0    &%!,5$5]9GTT
Packit 3f632f
M79A588QN9(*7:73_=DWL=%31
Packit 3f632f
M>-IC"$4"!0P$>"E&2B:I,%Z((!"(I$)X88H@GJ :A)<$Y@@*I8)YAA">("N(
Packit 3f632f
M%PYD"#L+"IJ#Y4!FN(86N4',# )J"4TO*R\O!_$"@::'@HTEQ /K _&$0+P 
Packit 3f632f
M(.T:6@A2@62?H#B*6TRQN#,
Packit 3f632f
M0W1%6'13;V9T=V%R90! *",I26UA9V5-86=I8VL@-"XR+CD@.3DO,#DO,#$@
Packit 3f632f
M8W)I<W1Y0&UY<W1I8RYE<RYD=7!O;G0N8V]M[>C9\    "IT15AT4VEG;F%T
Packit 3f632f
M=7)E #1E,S8X-S$P,38Q-S)A96%B.3,Y8SEA,F5D-31B86(U@DWZ,@    ET
Packit 3f632f
M15AT1&5L87D ,C4P(RC.$P    YT15AT4&%G90 R-7@R-2LP*S"#D2 ?    
Packit 3f632f
) $E%3D2N0F""
Packit 3f632f
UUENC
Packit 3f632f
close W;
Packit 3f632f
        }
Packit 3f632f
        if ( ! -r "$dir${main::SL}mrtg-r.png" and  open W, ">$dir${main::SL}mrtg-r.png" ){
Packit 3f632f
                binmode W;
Packit 3f632f
                print W unpack ('u', <<'UUENC');
Packit 3f632f
MB5!.1PT*&@H    -24A$4@   80    9! ,   ##'$3)    &%!,5$4T79@\
Packit 3f632f
M8YQ5=JAPC;>:K\S\_?[5WNFZR-PB%CO!     6)+1T0'%F&(ZP  !=5)1$%4
Packit 3f632f
M>-KM6$ESVE@0;BW 58: K_)"YDH(.%=YL/"511)7O""N3AS!WY_^NM^3Q)+,
Packit 3f632f
M4C55DZJ1*2&]U]O7Z\,4T"]__0_A;US.O\7$$#H*PR=R[_'@#? A9X3KLW,K
Packit 3f632f
MNRX_*L=MGK^#PQ)[$USW+J@'U)E,!JI<V>GS9"+RG0^B!(NDM,ZMB'G,M_?6
Packit 3f632f
MF@^[_#7D[U)*!V_N!#+4$)>M@+Z(.J/1)PNAI4]=5K# 0_,)'Z(4UXH*A<#/
Packit 3f632f
M2SQ\3+?[=!F4Q&M?Z!8@2-?4X+O*L^Q\$PPQ;MA.R= 65RRWR/:[U&#PTVR_
Packit 3f632f
MR4*JI#3?9#E-$U)#W)5*GE&3[Y&!T%P+?QR2)U;UUOB(0@A0"-Z*.AOVC)=^
Packit 3f632f
MY=L&-T/L"$G !,KBW"V-3PU[.\8W@5N7J)W(?L'&WB5LP6_*X10OP+2L21G/
Packit 3f632f
MH7OA=#:1&M)F-1FI\^A+8B&H %;A+\U>LP8A)HN^RZOC9^BZY#=#_&10NA8"
Packit 3f632f
M.5E !^R7H/2R=0G!6PH%1\%-!W@<"GU+PN4Q.Z2D6-K!2-;D]-=J"-2H?&C>
Packit 3f632f
M7"B$ABCW."HV-PX@%"6$YHS<3:@.K!$K2;N"4-0A\)X'.R[?%R4$MXQ"TT9,
Packit 3f632f
M7*Y:IP)!8N0L=Z0IVUJH(9!51H%B1)9A]$%,S3QB[_P0 EA;B\ W*KM/%?%Q
Packit 3f632f
M%*@8'$*0K?Y@54'0*+ !XZ@&P;C'2N$W?SU&\BX"Z"YKH08ATBB,^WCHW[U5
Packit 3f632f
MCK6U$!U'H3$WA9<<1\%+2I8R"H:]@ZT=Q8%9LK1%Z!1AA< XH902XAM@X#<;
Packit 3f632f
MA?;J) HL-F[!KJ*U%KC:D
Packit 3f632f
M4XWWZ^$U)]+-]? "M9#5YI*_+%^LE''@S[5Q]&951\J&PYL0-FJ],-<4J>DD
Packit 3f632f
M_NQ\.9M$RD9?TE!AX\HJ8E,+IJE^'Q6+.H1X\K#A;V\FI.B6F=)&B$+E>'9T
Packit 3f632f
M51>-EPD:$VVE;#C>'CJ2:=.FJ?9>1_'20-CQ'_ESAN"5Y?Q4LT'=SFS?^.7*
Packit 3f632f
MYFU%;!(IFTP>!K!Q%=8AL.)7D@8/AL;K:#3A#LW#*>0H> <0(-"]YF!:*>X2
Packit 3f632f
MUG&GD;D08Z0] ,((4XWG0O;)0-@2UTPW8@V^G0NG46BO^FNB,@I.7A$?EO.W
Packit 3f632f
MK+1)V<4R&H<$E]MR-K7@GD!HB;DL!4G%N>VP;?YJCPE?\''#<:4C!?S7?-IH
Packit 3f632f
MXG%'2N"B.&2Y/^M(*ZE!6PM.]L..5#4997
Packit 3f632f
M+B$% [N;Y?E&PQ<80[RJG)_Z(@Q;TERV&)DG48AJY>R@5W:5"SWE* JV([U5
Packit 3f632f
M*6W8H>EBM=_O>9B8CF2C0)M:.1L)@-*(!$_\^+C?S8TF.FJJO;6?& AP20*A
Packit 3f632f
MB6DR[*FS':G[7)5<
Packit 3f632f
M^! "2],!%$B88CAS9?S S>_,&2F1-N>:+LBJ2^+#Z1Q1?WV02(3PR2/
Packit 3f632f
M8Q.O/]<@&#R
Packit 3f632f
M3V<3W\H#'^=H&(1Z-F<D4PNA"F+#Y+TKRSC#,!DG/8=#*D;C73LC60B>'*IX
Packit 3f632f
M=,_1!P+ %2,A]5Q'TBSR49QN_$P5\?$9Z>2 P=;DXN8B..I(+ 2/'76SBU,P
Packit 3f632f
MC9=6BD28R\^O)=+1&2E2"#/C%CX7M++)J&#SFMP*GD^F,_SCC+.'42'H+;&)
Packit 3f632f
M0LH]YTU8>HM#"!3_GI@4.:R%*_3\U\EC:M+I8_I]-,T&9*3H0:4U/RYG:-+9
Packit 3f632f
M):7)9D,JX$_9*=,TW>)74"X0F@ Y50B83W?\'H!$"]80*XF;"P2P>%NUJ&2_
Packit 3f632f
M?-51V7N3)7)?E!]B_$V:OMMJ^,+CZMYPMK??9;'SXBG"J;4C%PBPVX5^T]1"
Packit 3f632f
M6U-M/;K_[#>U>Q4<$?_I=?&SS>NP_(5\X=Z<
Packit 3f632f
MO\3U!QLJ>FT="M4^    0W1%6'13;V9T=V%R90! *",I26UA9V5-86=I8VL@
Packit 3f632f
M-"XR+CD@.3DO,#DO,#$@8W)I<W1Y0&UY<W1I8RYE<RYD=7!O;G0N8V]M[>C9
Packit 3f632f
M\    "IT15AT4VEG;F%T=7)E #$R,3
Packit 3f632f
M9F,T,S9ELPXRP0    ]T15AT4&%G90 S.#AX,C4K,"LP4K-IB0    !)14Y$
Packit 3f632f
$KD)@@C9E
Packit 3f632f
UUENC
Packit 3f632f
close W;
Packit 3f632f
        }
Packit 3f632f
Packit 3f632f
}
Packit 3f632f
Packit 3f632f
# Local Variables:
Packit 3f632f
# mode: cperl
Packit 3f632f
# eval: (cperl-set-style "PerlStyle")
Packit 3f632f
# mode: flyspell
Packit 3f632f
# mode: flyspell-prog
Packit 3f632f
# End:
Packit 3f632f
#
Packit 3f632f
# vi: sw=4