diff --git a/14all-1.1.cgi b/14all-1.1.cgi
new file mode 100644
index 0000000..17a7dd5
--- /dev/null
+++ b/14all-1.1.cgi
@@ -0,0 +1,974 @@
+#!/usr/bin/perl -w
+#
+# 14all.cgi
+#
+# create html pages and graphics with rrdtool for mrtg + rrdtool
+#
+# (c) 1999-2002 bawidama@users.sourceforge.net
+#
+# use freely, but: NO WARRANTY - USE AT YOUR OWN RISK!
+# license: GPL
+
+# if MRTG_lib.pm (from mrtg) is not in the module search path (@INC)
+# uncomment the following line and change the path appropriatly:
+use lib qw(/usr/lib/mrtg2);
+
+# if RRDs (rrdtool perl module) is not in the module search path (@INC)
+# uncomment the following line and change the path appropriatly
+# or use a LibAdd: setting in the config file
+#use lib qw(/usr/local/rrdtool-1.0.38/lib/perl);
+
+# RCS History - removed as it's available on the web
+
+my $rcsid = '$Id: 14all.cgi,v 2.25 2003/01/05 18:39:51 bawidama Exp $';
+my $subversion = (split(/ /,$rcsid))[2];
+$subversion =~ m/^\d+\.(\d+)$/;
+my $version = "14all.cgi 1.1p$1";
+
+# my $DEBUG = 0; has gone - use config "14all*GraphErrorsToBrowser: 1"
+
+use strict;
+use CGI;
+BEGIN { eval { require CGI::Carp; import CGI::Carp qw/fatalsToBrowser/ }
+ if $^O !~ m/Win/i };
+use MRTG_lib "2.090003";
+
+sub main();
+sub set_graph_params($$$$);
+sub show_graph($$$);
+sub show_log($$$);
+sub show_dir($$$);
+
+sub print_error($@);
+sub intmax(@);
+sub yesorno($);
+sub get_graph_params($$$);
+sub getdirwriteable($$);
+sub getpngsize($);
+sub errorpng();
+sub gettextpic($);
+sub log_rrdtool_call($$@);
+
+# global, static vars
+my ($cfgfile, $cfgfiledir);
+my (@author, @style);
+
+### where the mrtg.cfg file is
+# anywhere in the filespace
+#$cfgfile = '/home/mrtg/mrtg.cfg';
+# relative to the script
+#$cfgfile = 'mrtg.cfg';
+# use this so 14all.cgi gets the cfgfile name from the script name
+# (14all.cgi -> 14all.cfg)
+$cfgfile = '/etc/mrtg/mrtg.cfg';
+
+# if you want to store your config files in a different place than your cgis:
+$cfgfiledir = '';
+
+### customize the html pages
+@author = ( -author => 'bawidama@users.sourceforge.net');
+# one possibility to enable stylesheets (second is to use "AddHead[_]:..." in mrtg.cfg)
+#@style = ( -style => { -src => 'general.css' });
+###
+
+# static data
+my @headeropts = (@author, @style);
+
+my %myrules = (
+ '14all*errorpic' =>
+ [sub{$_[0] && (-r $_[0] )}, sub{"14all*ErrorPic '$_[0]' not found/readable"}],
+ '14all*grapherrorstobrowser' => [sub{1}, sub{"Internal Error"}],
+ '14all*columns' =>
+ [sub{int($_[0]) >= 1}, sub{"14all*Columns must be at least 1 (is '$_[0]')"}],
+ '14all*rrdtoollog' =>
+ [sub{$_[0] && (!-d $_[0] )}, sub{"14all*RRDToolLog must be a writable file"}],
+ '14all*background' =>
+ [sub{$_[0] =~ /^#[0-9a-f]{6}$/i}, sub{"14all*background colour not in form '#xxxxxx', x in [a-f0-9]"}],
+ '14all*logarithmic[]' => [sub{1}, sub{"Internal Error"}],
+ '14all*graphtotal[]' => [sub{1}, sub{"Internal Error"}],
+ '14all*dontshowindexgraph[]' => [sub{1}, sub{"Internal Error"}],
+ '14all*indexgraph[]' => [sub{1}, sub{"Internal Error"}],
+ '14all*indexgraphsize[]' =>
+ [sub{$_[0] =~ m/^\d+[,\s]+\d+$/o}, sub{"14all*indexgraphsize: need two numbers"}],
+ '14all*maxrules[]' => [sub{1}, sub{"Internal Error"}],
+ '14all*stackgraph[]' => [sub{1}, sub{"Internal Error"}],
+);
+
+my %graphparams = (
+ 'daily' => ['-2000m', 'now', 300],
+ 'weekly' => ['-12000m','now', 1800],
+ 'monthly' => ['-800h', 'now', 7200],
+ 'yearly' => ['-400d', 'now', 86400],
+ 'daily.s' => ['-1250m', 'now', 300],
+);
+
+# the footer we print on every page
+my $footer_template = <<"EOT";
+
+
+EOT
+
+# global vars, persistent for speecyCGI/mod_perl
+%my14all::config_cache = ();
+$my14all::meurl = '';
+
+
+# run main
+main();
+exit(0);
+# end.
+
+sub main() {
+ if (!$cfgfile && $#ARGV == 0 && $ARGV[0] !~ m/=/ && !exists($ENV{QUERY_STRING})) {
+ $cfgfile = shift @ARGV;
+ }
+
+ my %setup;
+ # initialize CGI
+ my $q = new CGI;
+ $setup{q} = $q;
+
+ # change for mrtg-2.9.*
+ # look for the config file
+ $my14all::meurl = $q->url(-relative => 1);
+ ensureSL(\$cfgfiledir);
+ my $l_cfgfile; # don't change what is set above in the CGI
+ if (defined $q->param('cfg')) {
+ $l_cfgfile = $q->param('cfg');
+ # security fix: don't allow ./ in the config file name
+ print_error($q, "Illegal characters in cfg param: ./")
+ if $l_cfgfile =~ m'(^/)|(\./)';
+ $l_cfgfile = $cfgfiledir.$l_cfgfile unless -r $l_cfgfile;
+ print_error($q, "Cannot find the given config file: \$l_cfgfile\")
+ unless -r $l_cfgfile;
+ } elsif (!$cfgfile) {
+ $l_cfgfile = $my14all::meurl;
+ $l_cfgfile =~ s|.*\Q$MRTG_lib::SL\E||;
+ $l_cfgfile =~ s/\.(cgi|pl|perl)$/.cfg/;
+ #$my14all::meurl =~ m{\Q$MRTG_lib::SL\E([^\Q$MRTG_lib::SL\E]*)\.(cgi|pl)$};
+ #$l_cfgfile = $1 . '.cfg';
+ $l_cfgfile = $cfgfiledir.$l_cfgfile unless -r $l_cfgfile;
+ } else {
+ $l_cfgfile = $cfgfile;
+ }
+
+ # now we have the name of the config file.
+ # we might already have it with speedyCGI or mod_perl
+ my $read_file = 1;
+ my @cfg_stat = stat($l_cfgfile);
+ if (exists $my14all::config_cache{config}{$l_cfgfile}{mtime} &&
+ $cfg_stat[9] <= $my14all::config_cache{config}{$l_cfgfile}{mtime})
+ {
+ $read_file = 0;
+ }
+
+ # read the config file
+ if ($read_file) {
+ # wipe old config
+ delete $my14all::config_cache{config}{$l_cfgfile}
+ if exists $my14all::config_cache{config}{$l_cfgfile};
+ my (@sorted, %config, %targets);
+ readcfg($l_cfgfile, \@sorted, \%config, \%targets, "14all", \%myrules);
+ my @processed_targets;
+ cfgcheck(\@sorted, \%config, \%targets, \@processed_targets);
+ # set default refresh
+ if (exists $config{refresh} && yesorno($config{refresh})
+ && $config{refresh} !~ m/^\d*[1-9]\d*$/o) {
+ $config{refresh} = $config{interval} * 60;
+ }
+ # store config in "cache"
+ $my14all::config_cache{config}{$l_cfgfile}{sorted} = \@sorted;
+ $my14all::config_cache{config}{$l_cfgfile}{config} = \%config;
+ $my14all::config_cache{config}{$l_cfgfile}{targets} = \%targets;
+ $my14all::config_cache{config}{$l_cfgfile}{processed_targets} = \@processed_targets;
+ $my14all::config_cache{config}{$l_cfgfile}{mtime} = $cfg_stat[9];
+
+ # add LibAdd from config for RRDs.pm
+ if ($config{libadd}) {
+ unshift @INC, $config{libadd};
+ }
+ # load the rrdtool perl extension
+ eval "use RRDs 1.00038";
+ }
+ my $cfg = $my14all::config_cache{config}{$l_cfgfile};
+
+ my $footer = $footer_template;
+ # make sure icondir is set (should be done by mrtg)
+ $cfg->{config}{icondir} ||= $cfg->{config}{workdir};
+ # put icondir into footer
+ $footer =~ s/##ICONDIR##/$cfg->{config}{icondir}/g;
+
+ my $log = '_';
+ if (defined $q->param('log')) {
+ $log = $q->param('log');
+ }
+ # set timezone for rrdtool
+ if ($cfg->{targets}{timezone}{$log}) {
+ $ENV{"TZ"} = $cfg->{targets}{timezone}{$log};
+ }
+
+ ### the main switch
+ # the modes:
+ # if parameter "dir" is given show a list of the targets in this "directory"
+ # elsif parameter "png" is given show a graphic for the target given w/ parameter "log"
+ # elsif parameter "log" is given show the page for this target
+ # else show a list of directories and of targets w/o directory
+ # parameter "cfg" can hold the name of the config file to use
+ if (defined $q->param('dir')) {
+ show_dir($cfg, $q, $q->param('dir'));
+ } elsif (defined $q->param('png')) {
+ show_graph($cfg, $q, $q->param('png'));
+ exit(0); # don't show (html) footer
+ } elsif (defined $q->param('log')) {
+ show_log($cfg, $q, $q->param('log'));
+ } else {
+ show_dir($cfg, $q, '');
+ }
+ if (!$cfg->{targets}{options}{nobanner}{$log}) {
+ print $footer;
+ }
+ print $q->end_html();
+ exit(0);
+}
+
+sub set_graph_params($$$$) {
+ # calculate graph params and store in config
+ my ($cfg, $log, $png, $small) = @_;
+ unless (exists $cfg->{targets}{target}{$log}) {
+ return "target '$log' unknown";
+ }
+ my ($start, $end, $maxage);
+ my $graphparams = $cfg->{targets}{"graph*$png"}{$log};
+ if ($graphparams) {
+ ($start, $end, $maxage) = split(/[,\s]+/, $graphparams, 3);
+ }
+ unless ($start && $end && $maxage) {
+ unless (exists $graphparams{$png}) {
+ return "CGI call error: graph '$png' unknown";
+ }
+ ($start, $end, $maxage) = @{$graphparams{$png}};
+ }
+ my ($xs, $ys);
+ if ($small) {
+ ($xs, $ys) = (250, 100);
+ ($xs, $ys) = ($cfg->{targets}{'14all*indexgraphsize'}{$log} =~ m/(\d+)[,\s]+(\d+)/)
+ if $cfg->{targets}{'14all*indexgraphsize'}{$log};
+ } else {
+ ($xs, $ys) = ($cfg->{targets}{xsize}{$log}, $cfg->{targets}{ysize}{$log});
+ }
+ unless ($xs && $ys) {
+ return "cannot get image sizes for graph $png / target $log";
+ }
+ my $rrd = $cfg->{config}{logdir}.$cfg->{targets}{directory}{$log} . $log . '.rrd';
+ # escape ':' and '\' with \ in $rrd
+ # (rrdtool replaces '\:' by ':' and '\\' by '\')
+ $rrd =~ s/([:\\])/\\$1/g;
+ my $pngdir = getdirwriteable($cfg->{config}{imagedir}, $cfg->{targets}{directory}{$log});
+ $png .= '-i' if $small;
+ my $pngfile = "${pngdir}${log}-${png}.png";
+
+ # build the rrd command line: set the starttime and the graphics format (PNG)
+ my @args = ($pngfile, '-s', $start, '-e', $end, '-a', 'PNG');
+ # if it's not a small picture set the legends
+ my ($l1,$l2,$l3,$l4,$li,$lo) = ('','','','','','');
+ my ($ri, $ro) = ('','');
+
+ # set the size of the graph
+ push @args, '-w', $xs, '-h', $ys;
+ # set scale factor and legend defaults
+ my $per_unit = 'Second';
+ my $persec = 'Bytes';
+ my $factor = 1; # should we scale the values?
+ if ($cfg->{targets}{options}{perminute}{$log}) {
+ $factor = 60; # perminute -> 60x
+ $per_unit = 'Minute';
+ } elsif ($cfg->{targets}{options}{perhour}{$log}) {
+ $factor = 3600; # perhour -> 3600x
+ $per_unit = 'Hour';
+ }
+ if ($cfg->{targets}{options}{bits}{$log}) {
+ $factor *= 8; # bits instead of bytes -> 8x
+ $persec = 'Bits';
+ }
+ # let the user give an arbitrary factor:
+ if ($cfg->{targets}{factor}{$log} and
+ $cfg->{targets}{factor}{$log} =~ m/^[-+]?\d+(.\d+)?([eE][+-]?\d+)?$/)
+ {
+ $factor *= 0+$cfg->{targets}{factor}{$log};
+ }
+
+ # check if only one value should be graphed (set vars for fast access)
+ my $noi = $cfg->{targets}{options}{noi}{$log};
+ my $noo = $cfg->{targets}{options}{noo}{$log};
+
+ # prepare the legends
+ if (!$small && !$cfg->{targets}{options}{nolegend}{$log}) {
+ foreach (qw/legend1 legend2 legend3 legend4 legendi legendo legendy shortlegend/) {
+ if ($cfg->{targets}{$_}{$log}) {
+ $cfg->{targets}{$_}{$log} =~ s' ' 'go; #'
+ $cfg->{targets}{$_}{$log} =~ s/%/%%/go;
+ }
+ }
+ if ($cfg->{targets}{ylegend}{$log}) {
+ push @args, '-v', $cfg->{targets}{ylegend}{$log};
+ } else {
+ push @args, '-v', "$persec per $per_unit";
+ }
+
+ if ($cfg->{targets}{legend1}{$log}) {
+ $l1 = ":".$cfg->{targets}{legend1}{$log}."\\l"; }
+ else {
+ $l1 = ":Incoming Traffic in $persec per $per_unit\\l"; }
+ if ($cfg->{targets}{legend2}{$log}) {
+ $l2 = ":".$cfg->{targets}{legend2}{$log}."\\l"; }
+ else {
+ $l2 = ":Outgoing Traffic in $persec per $per_unit\\l"; }
+ if ($cfg->{targets}{legend3}{$log}) {
+ $l3 = ":".$cfg->{targets}{legend3}{$log}."\\l"; }
+ else {
+ $l3 = ":Maximal 5 Minute Incoming Traffic\\l"; }
+ if ($cfg->{targets}{legend4}{$log}) {
+ $l4 = ":".$cfg->{targets}{legend4}{$log}."\\l"; }
+ else {
+ $l4 = ":Maximal 5 Minute Outgoing Traffic\\l"; }
+
+ if (exists $cfg->{targets}{legendi}{$log}) {
+ $li = $cfg->{targets}{legendi}{$log}; }
+ else { $li = "In: "; }
+ $li =~ s':'\\:'; # ' quote :
+ if (exists $cfg->{targets}{legendo}{$log}) {
+ $lo = $cfg->{targets}{legendo}{$log}; }
+ else { $lo = "Out:"; }
+ $lo =~ s':'\\:'; # ' quote :
+
+ if ($cfg->{targets}{options}{integer}{$log}) {
+ $li .= ' %9.0lf' if $li;
+ $lo .= ' %9.0lf' if $lo;
+ $ri = '%3.0lf%%';
+ $ro = '%3.0lf%%';
+ } else {
+ $li .= ' %8.3lf' if $li;
+ $lo .= ' %8.3lf' if $lo;
+ $ri = '%6.2lf%%';
+ $ro = '%6.2lf%%';
+ }
+ if (!exists($cfg->{targets}{kmg}{$log}) || $cfg->{targets}{kmg}{$log}) {
+ $li .= ' %s' if $li;
+ $lo .= ' %s' if $lo;
+ if ($cfg->{targets}{kilo}{$log}) {
+ push @args, '-b', $cfg->{targets}{kilo}{$log};
+ }
+ if ($cfg->{targets}{shortlegend}{$log}) {
+ $li .= $cfg->{targets}{shortlegend}{$log} if $li;
+ $lo .= $cfg->{targets}{shortlegend}{$log} if $lo;
+ }
+ }
+ }
+ my $pngchar = substr($png,0,1);
+ if ($pngchar and $cfg->{targets}{unscaled}{$log} and
+ $cfg->{targets}{unscaled}{$log} =~ m/$pngchar/) {
+ my $max = intmax($cfg->{targets}{maxbytes}{$log},
+ $cfg->{targets}{maxbytes1}{$log},
+ $cfg->{targets}{maxbytes2}{$log},
+ $cfg->{targets}{absmax}{$log});
+ $max *= $factor;
+ push @args, '-l', 0, '-u', $max, '-r';
+ } elsif (yesorno($cfg->{targets}{'14all*logarithmic'}{$log})) {
+ push @args, '-o';
+ }
+ push @args,'--alt-y-mrtg','--lazy','-c','MGRID#ee0000','-c','GRID#000000';
+ # contributed by Henry Chen: option to stack the two values
+ # set the mode of the second line from config
+ my $line2 = 'LINE1:';
+ if (yesorno($cfg->{targets}{'14all*stackgraph'}{$log})) {
+ $line2 = 'STACK:';
+ }
+ # now build the graph calculation commands
+ # ds0/ds1 hold the normal data sources to graph/gprint
+ my ($ds0, $ds1) = ('in', 'out');
+ push @args, "DEF:$ds0=$rrd:ds0:AVERAGE", "DEF:$ds1=$rrd:ds1:AVERAGE";
+ if (defined $cfg->{targets}{options}{unknaszero}{$log}) {
+ push @args, "CDEF:uin=$ds0,UN,0,$ds0,IF",
+ "CDEF:uout=$ds1,UN,0,$ds1,IF";
+ ($ds0, $ds1) = ('uin', 'uout');
+ }
+ if ($factor != 1) {
+ # scale the values. we need a CDEF for this
+ push @args, "CDEF:fin=$ds0,$factor,*","CDEF:fout=$ds1,$factor,*";
+ ($ds0, $ds1) = ('fin', 'fout');
+ }
+ my $maximum0 = $cfg->{targets}{maxbytes1}{$log} || $cfg->{targets}{maxbytes}{$log};
+ my $maximum1 = $cfg->{targets}{maxbytes2}{$log} || $cfg->{targets}{maxbytes}{$log};
+ $maximum0 = 1 unless $maximum0;
+ $maximum1 = 1 unless $maximum1;
+ # ps0/ps1 hold the percentage data source for gprint
+ my ($ps0, $ps1) = ('pin', 'pout');
+ push @args, "CDEF:pin=$ds0,$maximum0,/,100,*,$factor,/",
+ "CDEF:pout=$ds1,$maximum1,/,100,*,$factor,/";
+
+ if (yesorno($cfg->{targets}{'14all*graphtotal'}{$log})
+ && $small) {
+ push @args, "CDEF:total=$ds0,$ds1,+", "LINE1:total#ffa050:Total AVG\\l";
+ }
+ # now for the peak graphs / maximum values
+ # mx0/mx1 hold the maximum data source for graph/gprint
+ my ($mx0, $mx1) = ($ds0, $ds1);
+ # px0/px1 hold the maximum pecentage data source for gprint
+ my ($px0, $px1) = ($ps0, $ps1);
+ if (!$small) {
+ # the defs for the maximum values: for the legend ('MAX') and probabely
+ # for the 'withpeak' graphs
+ push @args, "DEF:min=$rrd:ds0:MAX", "DEF:mout=$rrd:ds1:MAX";
+ ($mx0, $mx1) = ('min', 'mout');
+ if (defined $cfg->{targets}{options}{unknaszero}{$log}) {
+ push @args, "CDEF:umin=$mx0,UN,0,$mx0,IF",
+ "CDEF:umout=$mx1,UN,0,$mx1,IF";
+ ($mx0, $mx1) = ('umin', 'umout');
+ }
+ if ($factor != 1) {
+ # scale the values. we need a CDEF for this
+ push @args, "CDEF:fmin=$mx0,$factor,*","CDEF:fmout=$mx1,$factor,*";
+ ($mx0, $mx1) = ('fmin', 'fmout');
+ }
+ # draw peak lines if configured
+ if ($cfg->{targets}{withpeak}{$log} &&
+ substr($png,0,1) =~ /[$cfg->{targets}{withpeak}{$log} ]/) {
+ push @args, "AREA:".$mx0.$cfg->{targets}{rgb3}{$log}.$l3 unless $noi;
+ push @args, $line2.$mx1.$cfg->{targets}{rgb4}{$log}.$l4 unless $noo;
+ if (yesorno($cfg->{targets}{'14all*graphtotal'}{$log})) {
+ push @args, "CDEF:mtotal=$mx0,$mx1,+", "LINE1:mtotal#ff5050:Total MAX\\l";
+ }
+ }
+ push @args, "CDEF:pmin=$mx0,$maximum0,/,100,*,$factor,/",
+ "CDEF:pmout=$mx1,$maximum1,/,100,*,$factor,/";
+ ($px0, $px1) = ('pmin', 'pmout');
+ }
+ # the commands to draw the values
+ my (@hr1, @hr2);
+ if (!$small && yesorno($cfg->{targets}{'14all*maxrules'}{$log})) {
+ chop $l1; chop $l1; chop $l2; chop $l2;
+ @hr1 = (sprintf("HRULE:%d#ff4400: MaxBytes1\\l",$maximum0*$factor));
+ @hr2 = (sprintf("HRULE:%d#aa0000: MaxBytes2\\l",$maximum1*$factor));
+ }
+ push @args, "AREA:".$ds0.$cfg->{targets}{rgb1}{$log}.$l1, @hr1 unless $noi;
+ push @args, $line2.$ds1.$cfg->{targets}{rgb2}{$log}.$l2, @hr2 unless $noo;
+ if (!$small && !$cfg->{targets}{options}{nolegend}{$log}) {
+ # print the legends
+ # order matters so noi/noo makes this ugly
+ if ($cfg->{targets}{options}{nopercent}{$log}) {
+ push @args, "GPRINT:$mx0:MAX:Maximal $li" if $li && !$noi;
+ push @args, "GPRINT:$mx1:MAX:Maximal $lo\\l" if $lo && !$noo;
+ push @args, "GPRINT:$ds0:AVERAGE:Average $li" if $li && !$noi;
+ push @args, "GPRINT:$ds1:AVERAGE:Average $lo\\l" if $lo && !$noo;
+ push @args, "GPRINT:$ds0:LAST:Current $li" if $li && !$noi;
+ push @args, "GPRINT:$ds1:LAST:Current $lo\\l" if $lo && !$noo;
+ } else {
+ push @args,
+ "GPRINT:$mx0:MAX:Maximal $li",
+ "GPRINT:$px0:MAX:($ri)" if $li && !$noi;
+ push @args,
+ "GPRINT:$mx1:MAX:Maximal $lo",
+ "GPRINT:$px1:MAX:($ro)\\l" if $lo && !$noo;
+ push @args,
+ "GPRINT:$ds0:AVERAGE:Average $li",
+ "GPRINT:$ps0:AVERAGE:($ri)" if $li && !$noi;
+ push @args,
+ "GPRINT:$ds1:AVERAGE:Average $lo",
+ "GPRINT:$ps1:AVERAGE:($ro)\\l" if $lo && !$noo;
+ push @args,
+ "GPRINT:$ds0:LAST:Current $li",
+ "GPRINT:$ps0:LAST:($ri)" if $li && !$noi;
+ push @args,
+ "GPRINT:$ds1:LAST:Current $lo",
+ "GPRINT:$ps1:LAST:($ro)\\l" if $lo && !$noo;
+ }
+ }
+
+ # store rrdtool arg list for speedCGI/mod_perl mode
+ $cfg->{rrdargs}{$log}{$png}{args} = \@args;
+ $cfg->{rrdargs}{$log}{$png}{pngdir} = $pngdir;
+ $cfg->{rrdargs}{$log}{$png}{pngfile} = $pngfile;
+ $cfg->{rrdargs}{$log}{$png}{maxage} = $maxage;
+ return '';
+}
+
+sub show_graph($$$) {
+ # send a graphic, create it if necessary
+ my ($cfg, $q, $png) = @_;
+ my $log = $q->param('log');
+ my $small = $q->param('small') ? '-i' : '';
+
+ my $errstr = '';
+
+ if (!$log) {
+ $errstr="CGI call error: missing param 'log'";
+ goto ERROR;
+ }
+ unless (exists $cfg->{targets}{target}{$log}) {
+ $errstr="target '$log' unknown";
+ goto ERROR;
+ }
+ # fix a problem with indexmaker
+ if ($small) {
+ my %imaker = qw/day.s daily.s week.s weekly month.s monthly year.s yearly/;
+ if (exists $imaker{$png}) {
+ $png = $imaker{$png};
+ }
+ }
+ my $argsref;
+ if (!exists $cfg->{rrdargs}{$log}{"$png$small"}{args}) {
+ $errstr = set_graph_params($cfg, $log, $png, $small);
+ goto ERROR if $errstr;
+ }
+ $argsref = $cfg->{rrdargs}{$log}{"$png$small"}{args};
+
+ # fire up rrdtool
+ my ($a, $rrdx, $rrdy) = RRDs::graph(@$argsref);
+ my $e = RRDs::error();
+ log_rrdtool_call($cfg->{config}{'14all*rrdtoollog'},$e,'graph',$argsref);
+ my $pngfile = $cfg->{rrdargs}{$log}{"$png$small"}{pngfile};
+ if ($e) {
+ my $pngdir = $cfg->{rrdargs}{$log}{"$png$small"}{pngdir};
+ if (!-w $pngdir) {
+ $errstr = "cannot write to graph dir $pngdir\nrrdtool error: $e";
+ } elsif (-e $pngfile and !-w _) {
+ $errstr = "cannot write $pngfile\nrrdtool error: $e";
+ } elsif (-e $pngfile) {
+ if (unlink($pngfile)) {
+ # try rrdtool a second time
+ ($a, $rrdx, $rrdy) = RRDs::graph(@$argsref);
+ $e = RRDs::error();
+ log_rrdtool_call($cfg->{config}{'14all*rrdtoollog'},$e,'graph',$argsref);
+ $errstr = $e ? $errstr."\nrrdtool error from 2. call: $e" : '';
+ } else {
+ $errstr = "cannot delete file $pngfile: $!";
+ }
+ } else {
+ $errstr = "cannot create graph\nrrdtool error: $e";
+ }
+ }
+ unless ($errstr) {
+ if (open(PNG, "<$pngfile")) {
+ my $maxage = $cfg->{rrdargs}{$log}{"$png$small"}{maxage};
+ print $q->header(-type => "image/png", -expires => "+${maxage}s");
+ binmode(PNG); binmode(STDOUT);
+ while(read PNG, my $buf, 16384) { print STDOUT $buf; }
+ close PNG;
+ return;
+ }
+ $errstr = "cannot read graph file: $!";
+ }
+ ERROR:
+ if (yesorno($cfg->{config}{'14all*grapherrorstobrowser'})) {
+ my ($errpic, $format) = gettextpic($errstr);
+ print $q->header(-type => $format, -expires => 'now');
+ binmode(STDOUT);
+ print $errpic;
+ return;
+ }
+ $log ||= '_';
+ if (defined $cfg->{targets}{options}{'14all*errorpic'}{$log} &&
+ open(PNG, $cfg->{targets}{options}{'14all*errorpic'}{$log})) {
+ print $q->header(-type => "image/png", -expires => 'now');
+ binmode(PNG); binmode(STDOUT);
+ while(read PNG, my $buf,16384) { print STDOUT $buf; }
+ close PNG;
+ return;
+ }
+ print $q->header(-type => "image/png", -expires => 'now');
+ binmode(STDOUT);
+ print pack("C*", errorpng());
+}
+
+sub show_log($$$) {
+ # show the graphics for one target
+ my ($cfg, $q, $log) = @_;
+ print_error($q,"Target '$log' unknown") if (!exists $cfg->{targets}{target}{$log});
+ my $title;
+ # user defined title?
+ if ($cfg->{targets}{title}{$log}) {
+ $title = $cfg->{targets}{title}{$log};
+ } else {
+ $title = "MRTG/RRD - Target $log";
+ }
+ my @httphead;
+ push @httphead, (-expires => '+' . int($cfg->{config}{interval}) . 'm');
+ if (yesorno($cfg->{config}{refresh})) {
+ push @httphead, (-refresh => $cfg->{config}{refresh});
+ }
+ my @htmlhead = (-title => $title, @headeropts,
+ -bgcolor => $cfg->{targets}{background}{$log});
+ if ($cfg->{targets}{addhead}{$log}) {
+ push @htmlhead, (-head => $cfg->{targets}{addhead}{$log});
+ }
+ print $q->header(@httphead), $q->start_html(@htmlhead);
+ # user defined header line? (should exist as mrtg requires it)
+ print $cfg->{targets}{pagetop}{$log},"\n";
+ my $rrd = $cfg->{config}{logdir}.$cfg->{targets}{directory}{$log} . $log . '.rrd';
+ my $lasttime = RRDs::last($rrd);
+ log_rrdtool_call($cfg->{config}{'14all*rrdtoollog'},'','last',$rrd);
+ print $q->hr,
+ "The statistics were last updated: ",$q->b(scalar(localtime($lasttime))),
+ $q->hr if $lasttime;
+ my $sup = $cfg->{targets}{suppress}{$log} || '';
+ my $url = "$my14all::meurl?log=$log";
+ my $tmpcfg = $q->param('cfg');
+ $url .= "&cfg=$tmpcfg" if defined $tmpcfg;
+ $url .= "&png";
+ # the header lines and tags for the graphics
+ my $pngdir = getdirwriteable($cfg->{config}{imagedir}, $cfg->{targets}{directory}{$log});
+ if ($sup !~ /d/) {
+ print $q->h2("'Daily' graph (5 Minute Average)"),"\n",
+ $q->img({src => "$url=daily", alt => "daily-graph",
+ getpngsize("$pngdir$log-daily.png")}
+ ), "\n";
+ }
+ if ($sup !~ /w/) {
+ print $q->h2("'Weekly' graph (30 Minute Average)"),"\n",
+ $q->img({src => "$url=weekly", alt => "weekly-graph",
+ getpngsize("$pngdir$log-weekly.png")}
+ ), "\n";
+ }
+ if ($sup !~ /m/) {
+ print $q->h2("'Monthly' graph (2 Hour Average)"),"\n",
+ $q->img({src => "$url=monthly", alt => "monthly-graph",
+ getpngsize("$pngdir$log-monthly.png")}
+ ), "\n";
+ }
+ if ($sup !~ /y/) {
+ print $q->h2("'Yearly' graph (1 Day Average)"),"\n",
+ $q->img({src => "$url=yearly", alt => "yearly-graph",
+ getpngsize("$pngdir$log-yearly.png")}
+ ), "\n";
+ }
+ if ($cfg->{targets}{pagefoot}{$log}) {
+ print $cfg->{targets}{pagefoot}{$log};
+ }
+}
+
+sub show_dir($$$) {
+ # if no parameter - show a list of directories and targets
+ # without "Directory[...]" (aka root-targets)
+ # else show a list of targets in the given directory
+ my ($cfg, $q, $dir) = @_;
+ my @httphead;
+ push @httphead, (-expires =>
+ ($dir ? '+' . int($cfg->{config}{interval}) . 'm' : '+1d') );
+ if (yesorno($cfg->{config}{refresh})) {
+ push @httphead, (-refresh => $cfg->{config}{refresh});
+ }
+ push @headeropts, (-bgcolor => ($cfg->{config}{'14all*background'} || '#ffffff'));
+ my @htmlhead = (-title =>
+ ($dir ? "MRTG/14all - Group $dir" : "MRTG/14all $version"),
+ @headeropts);
+ print $q->header(@httphead), $q->start_html(@htmlhead);
+ my (@dirs, %dirs, @logs);
+ # get the list of directories and "root"-targets
+ # or get list of targets from given directory
+ foreach my $tar (@{$cfg->{sorted}}) {
+ next if $tar =~ m/^[_\$\^]$/; # pseudo targets
+ if ($cfg->{targets}{directory}{$tar}) {
+ if ($dir) {
+ # show a specified dir. check this targets dir against specified
+ if ($dir eq $cfg->{targets}{directory}{$tar}) {
+ # target is from specified dir
+ push @logs, $tar;
+ }
+ next;
+ }
+ next if exists $dirs{$cfg->{targets}{directory}{$tar}};
+ $dirs{$cfg->{targets}{directory}{$tar}} = $tar;
+ push @dirs, $cfg->{targets}{directory}{$tar};
+ } elsif (!$dir) {
+ # showing 'homepage', add this target
+ push @logs, $tar;
+ }
+ }
+ my $cfgstr = (defined $q->param('cfg') ? "&cfg=".$q->param('cfg') : '');
+ print $q->h1("Available Targets"),"\n";
+ my $confcolumns = $cfg->{config}{'14all*columns'} || 2;
+ if ($#dirs > -1) {
+ print $q->h2("Directories"),"\n\\n";
+ my $column = 0;
+ foreach my $tar (@dirs) {
+ print '' if $column == 0;
+ (my $link = $tar) =~ s/ /\+/g;
+ chop $tar; # remove / for display (from ensureSL)
+ print $q->td($q->a({href => "$my14all::meurl?dir=$link$cfgstr"},
+ $tar)),"\n";
+ $column++;
+ if ($column >= $confcolumns) {
+ $column = 0;
+ print '
';
+ }
+ }
+ if ($column != 0 and $column < $confcolumns) {
+ print ' | ' x ($confcolumns - $column),"\\n";
+ }
+ print '
';
+ }
+ my $pngdir = getdirwriteable($cfg->{config}{imagedir},$dir);
+ if ($#logs > -1) {
+ print $q->h2("Targets"),"\n\\n";
+ my $column = 0;
+ foreach my $tar (@logs) {
+ my $small = 0;
+ unless (yesorno($cfg->{targets}{'14all*dontshowindexgraph'}{$tar})) {
+ $small = $cfg->{targets}{'14all*indexgraph'}{$tar};
+ $small = 'daily.s' unless $small;
+ }
+ next if $tar =~ m/^[\$\^_]$/; # _ is not a real target
+ print '' if $column == 0;
+ print '',
+ $q->p($q->a({href => "$my14all::meurl?log=$tar$cfgstr"}, $cfg->{targets}{title}{$tar}));
+ print $q->a({href => "$my14all::meurl?log=$tar$cfgstr"},
+ $q->img({src => "$my14all::meurl?log=$tar&png=$small&small=1$cfgstr",
+ alt => "index-graph",
+ getpngsize("$pngdir$tar-$small-i.png")}))
+ if $small;
+ print "\ | \n";
+ $column++;
+ if ($column >= $confcolumns) {
+ $column = 0;
+ print '
';
+ }
+ }
+ if ($column != 0 and $column < $confcolumns) {
+ print ' | ' x ($confcolumns - $column),"\\n";
+ }
+ print '
';
+ }
+}
+
+sub print_error($@)
+{
+ my $q = shift;
+ print $q->header(),
+ $q->start_html(
+ -title => 'MRTG/RRD index.cgi - Script error',
+ -bgcolor => '#ffffff'
+ ),
+ $q->h1('Script Error'),
+ @_, $q->end_html();
+ exit 0;
+}
+
+sub intmax(@)
+{
+ my (@p) = @_;
+ my $max = 0;
+ foreach my $n (@p) {
+ $max = int($n) if defined $n and int($n) > $max;
+ }
+ return $max;
+}
+
+sub yesorno($)
+{
+ my $opt = shift;
+ return 0 unless defined $opt;
+ return 0 if $opt =~ /^((no?)|(false)|0)$/i;
+ return 1;
+}
+
+sub getdirwriteable($$)
+{
+ my ($base, $sub) = @_;
+ $base .= $MRTG_lib::SL . $sub if $sub;
+ ensureSL(\$base);
+ if (!-w $base) {
+ if ($^O =~ m/Win/i) {
+ $base = $ENV{'TEMP'};
+ $base = $ENV{'TMP'} unless $base;
+ $base = $MRTG_lib::SL unless $base;
+ ensureSL(\$base);
+ } else {
+ $base = '/tmp/';
+ }
+ }
+ return $base;
+}
+
+use IO::File;
+
+sub pngstring() { return chr(137)."PNG".chr(13).chr(10).chr(26).chr(10); };
+
+sub getpngsize($)
+{
+ my ($file) = @_;
+ my $fh = new IO::File $file;
+ return () unless defined $fh;
+ my $line;
+ if (sysread($fh, $line, 8) != 8 or $line ne pngstring()) {
+ $fh->close;
+ return ();
+ }
+ CHUNKS: while(1) {
+ last CHUNKS if (sysread($fh, $line, 8) != 8);
+ my ($chunksize, $type) = unpack "Na4", $line;
+ if ($type ne "IHDR") {
+ last CHUNKS if (sysread($fh, $line, $chunksize + 4) != $chunksize + 4);
+ next CHUNKS;
+ }
+ last CHUNKS if (sysread($fh, $line, 8) != 8);
+ $fh->close;
+ my ($x, $y) = unpack("NN", $line);
+ return ('-width' => "$x", '-height' => "$y");
+ }
+ $fh->close;
+ return ();
+}
+
+# this data contains a small png with the text:
+# "error: cannot create graph"
+
+sub errorpng()
+{
+ return (
+ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,187,0,0,0,29,4,3,0,
+ 0,0,0,251,0,170,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,30,80,
+ 76,84,69,255,0,0,255,93,93,255,128,128,255,155,155,255,176,176,255,195,
+ 195,255,212,212,255,227,227,255,241,241,255,255,255,17,191,146,253,0,0,
+ 0,56,116,69,88,116,83,111,102,116,119,97,114,101,0,88,86,32,86,101,114,
+ 115,105,111,110,32,51,46,49,48,97,32,32,82,101,118,58,32,49,50,47,50,57,
+ 47,57,52,32,40,80,78,71,32,112,97,116,99,104,32,49,46,50,41,221,21,46,73,
+ 0,0,2,40,73,68,65,84,120,218,237,147,177,107,219,64,20,198,159,34,233,92,
+ 109,130,180,132,108,55,180,78,189,169,113,8,220,166,80,106,208,230,102,
+ 48,237,118,56,246,153,219,28,7,2,183,165,77,23,109,142,101,157,244,254,
+ 219,62,73,198,113,106,211,150,144,108,254,166,143,167,79,63,221,125,167,
+ 3,216,107,175,189,94,65,136,56,223,26,58,166,224,207,71,6,114,3,175,148,
+ 220,10,136,66,47,183,134,44,254,115,114,48,252,55,126,87,192,92,248,24,
+ 254,237,173,70,110,246,95,120,182,184,17,231,242,4,103,160,79,34,213,12,
+ 117,148,224,204,205,211,159,96,205,18,24,254,162,26,105,189,198,66,29,149,
+ 96,80,10,172,29,64,154,91,55,83,30,22,92,124,43,33,152,60,86,75,229,196,
+ 172,204,68,42,83,85,114,157,70,4,97,182,218,121,121,150,187,56,41,0,111,
+ 75,254,253,54,141,197,13,64,203,154,184,138,78,114,223,158,47,222,229,156,
+ 28,128,95,104,235,150,182,115,159,244,133,53,211,160,208,215,27,71,43,153,
+ 253,36,238,223,23,96,250,250,42,84,43,188,55,58,180,174,117,16,202,208,
+ 156,166,97,114,87,237,185,211,239,72,138,230,78,217,30,126,200,220,204,
+ 35,199,225,227,67,139,240,167,189,11,33,197,244,120,17,60,180,178,39,229,
+ 60,128,136,217,156,74,211,117,227,53,30,18,164,29,211,115,11,186,155,1,
+ 155,87,120,93,157,123,204,104,77,145,65,194,215,14,68,228,90,119,9,30,173,
+ 148,108,22,72,246,20,63,167,4,91,64,71,234,213,48,116,204,89,193,31,241,
+ 57,28,173,240,46,167,104,214,237,30,229,135,21,158,92,8,162,239,85,209,
+ 100,22,72,17,251,187,241,94,93,14,64,151,6,250,171,143,108,225,173,241,
+ 235,114,146,233,177,172,162,142,13,174,91,85,57,228,160,41,39,3,205,147,
+ 166,156,77,60,98,86,227,65,163,13,117,243,189,35,196,31,30,150,107,124,
+ 36,176,228,111,170,67,71,12,235,232,172,133,101,118,128,146,28,253,160,
+ 77,52,193,84,138,20,227,77,188,82,106,232,73,104,115,120,171,46,160,71,
+ 3,26,58,131,49,135,193,229,136,238,141,130,17,244,184,171,46,193,165,39,
+ 78,239,170,142,142,67,71,125,30,194,32,38,71,249,193,200,82,212,31,183,
+ 99,241,101,76,247,207,219,125,223,158,41,49,111,126,134,202,70,47,9,110,
+ 228,151,230,238,21,241,123,237,245,162,250,13,181,158,203,16,233,3,210,
+ 153,0,0,0,7,116,73,77,69,7,208,1,19,13,28,15,223,54,180,209,0,0,0,0,73,
+ 69,78,68,174,66,96,130
+ );
+}
+
+sub gettextpic($) {
+ my ($text) = @_;
+ my @textsplit = split(/\n/, $text);
+ my $len = 0;
+ my $max = sub { $_[0] > $_[1] ? $_[0] : $_[1] };
+ my @rrdargs;
+ foreach (@textsplit) {
+ $len = &$max($len, length($_));
+ push @rrdargs, "COMMENT:$_\\l";
+ }
+ eval { require GD; 1; };
+ unless ($@) {
+ my $ys = @textsplit * (GD::gdMediumBoldFont()->height + 5);
+ my $xs = $len * GD::gdMediumBoldFont()->width();
+ my $im = new GD::Image($xs + 20, $ys + 20);
+ my $back = $im->colorAllocate(255,255,255);
+ $im->transparent($back);
+ my $red = $im->colorAllocate(255,0,0);
+ $im->filledRectangle(0,0,$xs-1,$ys-1,$back);
+ my $starty = 10;
+ foreach $text (@textsplit) {
+ $im->string(GD::gdMediumBoldFont(), 10, $starty, $text, $red);
+ $starty += 5 + GD::gdMediumBoldFont()->height;
+ }
+ binmode(STDOUT);
+ if ($GD::VERSION lt '1.20') {
+ #eval 'print $im->gif';
+ return ($im->gif(), 'image/gif');
+ } elsif ($GD::VERSION ge '1.20') {
+ return ($im->png(), 'image/png');
+ }
+ }
+ if ($ENV{MOD_PERL}) {
+ # forking a RRDs child doesn't work with mod_perl
+ return (pack("C*", errorpng()), 'image/png');
+ }
+ # create a graphic with rrdtool
+ $len = &$max($len*6-60,50);
+ unshift @rrdargs, ('-', '-w', $len, '-h', 10, '-c', 'FONT#ff0000');
+ my $pid = open(P, "-|");
+ unless (defined $pid) {
+ return (pack("C*", errorpng()), 'image/png');
+ }
+ unless ($pid) {
+ RRDs::graph(@rrdargs);
+ exit 0;
+ }
+ local $/ = undef;
+ my $png = ;
+ close P;
+ unless (defined $png) {
+ return (pack("C*", errorpng()), 'image/png');
+ }
+ return ($png, 'image/png');
+}
+
+sub log_rrdtool_call($$@) {
+ my ($logfile, $error, @args) = @_;
+ return unless yesorno($logfile);
+ unless (open(LOG, '>>'.$logfile)) {
+ print STDERR "cannot log rrdtool call: $!\n";
+ return;
+ }
+ print LOG "\n# call to rrdtool:\nrrdtool ";
+ foreach my $arg (@args) {
+ if (ref($arg) eq 'ARRAY') {
+ print LOG join(' ',@$arg),' ';
+ } else {
+ print LOG $arg," ";
+ }
+ }
+ print LOG "\n";
+ if ($error) {
+ print LOG "# gave ERROR: $error\n";
+ } else {
+ print LOG "# completed without error\n";
+ }
+ close LOG;
+}
diff --git a/README.md b/README.md
index 43dae8c..615c02c 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,8 @@
# mrtg
+The Multi Router Traffic Grapher (MRTG) is a tool to monitor the traffic load on network-links.
+MRTG generates HTML pages containing graphical images which provide a LIVE visual representation of this traffic.
+Check http://www.ee.ethz.ch/stats/mrtg/ for an example.
+MRTG is based on Perl and C and works under UNIX and Windows NT.
+MRTG is being successfully used on many sites around the net.
+
diff --git a/mrtg-2.14.6-makefile.patch b/mrtg-2.14.6-makefile.patch
new file mode 100644
index 0000000..34c484e
--- /dev/null
+++ b/mrtg-2.14.6-makefile.patch
@@ -0,0 +1,13 @@
+--- mrtg-2.14.6/Makefile.in 2006-09-06 08:10:28.000000000 +0200
++++ mrtg-2.14.6/Makefile.in.fix 2006-09-06 15:01:10.000000000 +0200
+@@ -126,8 +126,8 @@
+ svn copy -m "tagging version $(VER)" svn://svn.ee.ethz.ch/mrtg/trunk/src svn://svn.ee.ethz.ch/mrtg/tags/$(VER)
+ cp CHANGES ${HOME}/public_html/webtools/mrtg/pub/
+ md5sum $(ARCHIVE).tar.gz >$(ARCHIVE).tar.gz.md5
+- pgps $(ARCHIVE).tar.gz.md5
+- chmod 644 $(ARCHIVE).tar.gz.md5*
++ pgps $(ARCHIVE).tar.gz.md5
++ chmod 644 $(ARCHIVE).tar.gz.md5*
+ scp $(ARCHIVE).* oposs@james.oetiker.ch:public_html/mrtg/pub/
+ ssh oposs@james.oetiker.ch "cd public_html/mrtg/pub; rm mrtg.tar.gz;ln -s $(ARCHIVE).tar.gz mrtg.tar.gz"
+
diff --git a/mrtg-initscript b/mrtg-initscript
new file mode 100644
index 0000000..5f1c31d
--- /dev/null
+++ b/mrtg-initscript
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# chkconfig: 2345 65 15
+# description: Multi Router Traffic Grapher
+# processname: mrtg
+
+# Copyright (c) 2003-2006 by Silvan Calarco
+# Copyright (c) 2004-2006 by Davide Madrisan
+
+# source function library
+. /etc/rc.d/init.d/functions
+
+RETVAL=0
+
+case "$1" in
+ start)
+ echo -n "Starting mrtg daemon: "
+ loadproc env LANG=C mrtg --daemon /etc/mrtg/mrtg.cfg \
+ --logging /var/log/mrtg.log > /dev/null
+ evaluate_retval
+ RETVAL=$?
+ [ $RETVAL -eq 0 ] && touch /var/lock/subsys/mrtg
+ echo
+ ;;
+ stop)
+ echo -n "Shutting down mrtg daemon: "
+ killproc mrtg
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mrtg
+ ;;
+ restart|reload)
+ $0 stop
+ $0 start
+ RETVAL=$?
+ ;;
+ status)
+ status mrtg
+ RETVAL=$?
+ ;;
+ *)
+ gprintf "Usage: mrtg {start|stop|status|restart|reload}\n"
+ exit 1
+esac
+
+exit $RETVAL
+
diff --git a/mrtg.spec b/mrtg.spec
new file mode 100644
index 0000000..492a65d
--- /dev/null
+++ b/mrtg.spec
@@ -0,0 +1,203 @@
+%define with_rrdtool 0
+
+Name: mrtg
+Version: 2.17.4
+Release: 1mamba
+Summary: Multi Router Traffic Grapher
+Group: Network/Monitoring
+Vendor: openmamba
+Distribution: openmamba
+Packager: Silvan Calarco
+Source0: http://oss.oetiker.ch/mrtg/pub/mrtg-%{version}.tar.gz
+Source1: mrtg-initscript
+Source2: http://my14all.sourceforge.net/14all-1.1.cgi
+Patch: %{name}-2.14.6-makefile.patch
+URL: http://people.ee.ethz.ch/~oetiker/webtools/mrtg/
+License: GPL
+Requires: apache >= 2.0.48
+Requires: net-snmp >= 5.1
+Requires: libgd >= 2.0.17
+Requires: perl >= 5.8.0
+BuildRequires: libgd-devel >= 2.0.17
+%if %with_rrdtool
+Requires: rrdtool >= 1.2.0
+%endif
+Requires: perl-Net-SNMP
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+
+%description
+The Multi Router Traffic Grapher (MRTG) is a tool to monitor the traffic load on network-links.
+MRTG generates HTML pages containing graphical images which provide a LIVE visual representation of this traffic.
+Check http://www.ee.ethz.ch/stats/mrtg/ for an example.
+MRTG is based on Perl and C and works under UNIX and Windows NT.
+MRTG is being successfully used on many sites around the net.
+
+%prep
+%setup -q
+#%patch -p1 -b .makefile
+
+cat > find_provides.sh << _EOF
+#! /bin/sh
+%{__find_provides} %{buildroot} %{_target_cpu} | grep -v "perl(Pod"
+_EOF
+
+chmod +x find_provides.sh
+
+%define __perl_provides %{_builddir}/mrtg-%{version}/find_provides.sh
+
+%build
+%configure
+%make
+
+%install
+[ "%{buildroot}" != / ] && rm -rf "%{buildroot}"
+%makeoldinstall
+
+install -d %{buildroot}%{_sysconfdir}/mrtg
+install -d %{buildroot}/var/www/html/mrtg
+
+install -d %{buildroot}%{_initrddir}
+install -m744 %{S:1} %{buildroot}%{_initrddir}/mrtg
+
+%if %with_rrdtool
+install -d %{buildroot}/var/www/cgi-bin
+install -m755 %{S:2} %{buildroot}/var/www/cgi-bin/14all.cgi
+%endif
+install -d %{buildroot}/var/www/icons/
+install -m644 %{buildroot}%{_datadir}/mrtg2/icons/* \
+ %{buildroot}/var/www/icons/
+
+%clean
+[ "%{buildroot}" != / ] && rm -rf "%{buildroot}"
+
+%post
+# new install case: make configuration and start the server
+if [ $1 -eq 1 ]; then
+ # NOTE1: if snmpd is not running, an empty configuration
+ # file for MRTG will be created!
+ # NOTE2: the default snmp ro community is `hostname -d`
+ # (see the net-snmp specfile)
+ if [ ! -e %{_sysconfdir}/mrtg/mrtg.cfg ]; then
+ cfgmaker \
+ --global="WorkDir: /var/www/html/mrtg/" \
+ --global="IconDir: /icons/" \
+%if %with_rrdtool
+ --global="LogFormat: rrdtool" \
+%endif
+ --ifref=descr \
+ --output %{_sysconfdir}/mrtg/mrtg.cfg \
+ `hostname -d`@localhost
+
+# sed -i 's|# WorkDir: /home/.*|WorkDir: /var/www/html/mrtg/|' \
+# %{_sysconfdir}/mrtg/mrtg.cfg 2>/dev/null
+ fi
+
+ if [ ! -e /var/www/html/mrtg/index.html ]; then
+ indexmaker \
+ --enumerate \
+ --columns=1 \
+%if %with_rrdtool
+ --rrdviewer=/cgi-bin/14all.cgi \
+%endif
+ --output=/var/www/html/mrtg/index.html \
+ %{_sysconfdir}/mrtg/mrtg.cfg
+ fi
+
+ #chkconfig --add mrtg
+ #%{_initrddir}/mrtg start
+fi
+exit 0
+
+%preun
+# erase case: erase configuration and stop the server
+if [ $1 -eq 0 ]; then
+ chkconfig --del mrtg
+ [ -e /var/lock/subsys/mrtg ] && %{_initrddir}/mrtg stop
+fi
+exit 0
+
+%postun
+# update case: just restart the server
+if [ $1 -eq 1 ]; then
+ [ -e /var/lock/subsys/mrtg ] && \
+ %{_initrddir}/mrtg restart
+fi
+exit 0
+
+%files
+%defattr(-,root,root)
+%{_bindir}/*
+%dir %{_datadir}/mrtg2
+%{_datadir}/mrtg2/*
+%dir %{_libdir}/mrtg2
+%{_libdir}/mrtg2/*
+%dir /var/www/html/mrtg
+%if %with_rrdtool
+/var/www/cgi-bin/*
+%endif
+/var/www/icons/*
+%{_initrddir}/mrtg
+%dir %{_sysconfdir}/mrtg
+%dir %{_docdir}/mrtg2
+%{_docdir}/mrtg2/*
+%{_mandir}/man?/*
+
+%changelog
+* Wed Aug 08 2012 Automatic Build System 2.17.4-1mamba
+- automatic version update by autodist
+
+* Fri Dec 09 2011 Automatic Build System 2.17.3-1mamba
+- automatic version update by autodist
+
+* Mon Feb 21 2011 Automatic Build System 2.17.2-1mamba
+- automatic update by autodist
+
+* Fri Dec 17 2010 Automatic Build System 2.17.0-1mamba
+- automatic update by autodist
+
+* Sun Jun 06 2010 Automatic Build System 2.16.4-1mamba
+- automatic update by autodist
+
+* Fri Jan 22 2010 Automatic Build System 2.16.3-1mamba
+- automatic update by autodist
+
+* Thu Jan 01 2009 Silvan Calarco 2.16.2-1mamba
+- automatic update by autodist
+
+* Wed Sep 06 2006 Davide Madrisan 2.14.6-1qilnx
+- update to version 2.14.6 by autospec
+- added a new runtime requirement: perl-Net-SNMP
+
+* Thu Jul 27 2006 Davide Madrisan 2.10.15-2qilnx
+- initscript fixed: the mrtg daemon must be run in a environment with UTF-8
+ disabled
+
+* Tue Nov 30 2004 Silvan Calarco 2.10.15-1qilnx
+- update to version 2.10.15 by autospec
+- removed provides for perl(Pod::*) because it conflicts with Perl package
+ libraries
+
+* Mon Jul 20 2004 Davide Madrisan 2.10.14-2qilnx
+- added the cgi module 14all.cgi needed to integrate mrtg with rrdtool
+- %post script modified again
+
+* Thu Jul 15 2004 Davide Madrisan 2.10.14-1qilnx
+- update to 2.10.14
+- fixed %post script
+
+* Fri Jan 09 2004 Davide Madrisan 2.10.12-1qilnx
+- specfile fix: restart mrtg only if it is active
+- package updated
+
+* Fri Jul 11 2003 Silvan Calarco 2.9.29-4qilnx
+- modified initscript so that mrtg logs to /var/log/mrtg.log
+
+* Tue Jun 12 2003 Silvan Calarco 2.9.29-3qilnx
+- added automatic index creation
+
+* Mon Jun 09 2003 Silvan Calarco 2.9.29-2qilnx
+- made %post automatic service configuration for localhost
+
+* Fri Jun 06 2003 Silvan Calarco 2.9.29-1qilnx
+- creation of mrtg package
+