#!/usr/bin/env perl
use strict;
use warnings;
use diagnostics;

use lib "../../lib";
use HotSaNICparser;
use HotSaNICdiagram;
use RRDs;

# read global settings
#
my $MODNAME=HotSaNICparser::get_module_name();
my %CONFIG=HotSaNICparser::get_config("../..");

my $OUTDIR=$CONFIG{"WEBDIR"}."/".lc $MODNAME;
if ( ! -e $OUTDIR ) { mkdir "$OUTDIR",0755; }

my $IMGFMT=lc $CONFIG{"IMAGEFORMAT"};
my $TEMPNAME="$OUTDIR/temp.$IMGFMT";

my (@ITEMS,$name,$range,$descr,$CPUGRAPH,$NUMCPU);
my $FORCE=@ARGV;

my ($draw_cpu, $draw_load, $draw_proc, $draw_mem, $draw_users) = 0;
my ($draw_irq, $draw_uptime) = 0;

# read module-specific settings
#
foreach (HotSaNICparser::read_settings(".")) {
  my ($var,$value)=HotSaNICparser::parse_line($_);
  if ($var eq "CPUGRAPH") { $CPUGRAPH=$value; }
  if ($var eq "NUMCPU") { $NUMCPU=$value; }
  if ($var eq "IRQ") {
    my ($num,$descr)=split /,/,$value;
    $ITEMS[$num]=$descr;
    }
  if ($var eq "SECTIONS") {
    my @sections = split " ", $value;
    foreach (@sections){
      if ($_ eq "cpu")    {$draw_cpu=1}
      if ($_ eq "load")   {$draw_load=1}
      if ($_ eq "proc")   {$draw_proc=1}
      if ($_ eq "mem")    {$draw_mem=1} 
      if ($_ eq "users")  {$draw_users=1}
      if ($_ eq "int")    {$draw_irq=1}
      if ($_ eq "uptime") {$draw_uptime=1}
      }
    }
  }


if ($NUMCPU < 1) { $NUMCPU=1; }

# generate diagrams
#

if ($draw_load)   {plot_load()}
if ($draw_proc)   {plot_proc()}
if ($draw_cpu)    {plot_cpu()}
if ($draw_mem)    {plot_mem()}
if ($draw_mem)    {plot_swap()}
if ($draw_users)  {plot_user()}
if ($draw_irq)    {plot_irq()}
if ($draw_uptime) {plot_uptime()}

exit 0;




sub plot_load {

  print "creating images for loadavg...\n";

  opendir(DIR,"./rrd");
  my @files=readdir(DIR);
  closedir(DIR);
  my @results=grep /load.*\.rrd/,@files;
  foreach (@results) { s/\.rrd//g; }

  # if database exists, create images...
  if (@results) {
    foreach my $dev (@results) {

      print "  $dev:\n";

      foreach $range ("1h","6h","1day","1week","1month","1year") {
        my ($descr,$file,$build,$fullrange,$DATESTRING)=HotSaNICdiagram::get_diagram_properties($range);
  
        my $FILENAME="$OUTDIR/$dev-$file.$IMGFMT";
  
        my $make=$FORCE;
        if ($range eq "1h") { $make++; }
        elsif (! -e "$FILENAME") { $make++; }
        else  {
          my (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef) = stat( "$FILENAME" );
          if (time > ($mtime+$build)) { $make++; }
          }
  
        if ($make>0) {

          my ($prints,$xs,$ys);

          if ($range eq "1h") {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-a", uc($IMGFMT), "-u 1", "--alt-autoscale-max", "-l 0", "--title", "system-load - last $descr ($DATESTRING)",
              "DEF:ld1=rrd/$dev.rrd:load1:AVERAGE",
              "DEF:ld2=rrd/$dev.rrd:load5:AVERAGE",
              "DEF:ld3=rrd/$dev.rrd:load15:AVERAGE",
              "AREA:ld1#ff0000: 1 min avg",
              "GPRINT:ld1:MIN:(min\\:%1.2lf",
              "GPRINT:ld1:MAX:max\\:%1.2lf)\\n",
              "LINE2:ld2#aa0000: 5 min avg",
              "GPRINT:ld2:MIN:(min\\:%1.2lf",
              "GPRINT:ld2:MAX:max\\:%1.2lf)\\n",
              "LINE2:ld3#330000:15 min avg",
              "GPRINT:ld3:MIN:(min\\:%1.2lf",
              "GPRINT:ld3:MAX:max\\:%1.2lf)\\n",
              "HRULE:0#000000" or die "$!";
            }
          else {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-a", uc($IMGFMT), "-u 1", "--alt-autoscale-max", "-l 0", "--title", "system-load - last $descr ($DATESTRING)",
              "DEF:avg1=rrd/$dev.rrd:load1:AVERAGE",
              "DEF:min1=rrd/$dev.rrd:load1:MIN",
              "DEF:max1=rrd/$dev.rrd:load1:MAX",
              "DEF:avg5=rrd/$dev.rrd:load5:AVERAGE",
              "DEF:avg15=rrd/$dev.rrd:load15:AVERAGE",
              "AREA:max1#ffc0c0:min/max",
              "LINE1:max1#a0a0a0:",
              "AREA:min1#ffffff:",
              "LINE1:min1#a0a0a0:",
              "GPRINT:min1:MIN:(min\\:%1.2lf",
              "GPRINT:min1:MAX:-  %1.2lf",
              "GPRINT:max1:MIN:    max\\:%1.2lf",
              "GPRINT:max1:MAX:-  %1.2lf)",
              "LINE1:avg1#ff0000:avg (1 min)",
              "LINE1:avg5#aa0000:avg (5 min)",
              "LINE1:avg15#330000:avg (15 min)",
              "HRULE:0#000000" or die "$!";
            }

          rename $TEMPNAME,$FILENAME;
          printf "  %-7s %d"."x%d %s\n",$descr,$xs,$ys,$FILENAME;

          }
        }
      }
    }
  else { print "  No database found\n  Please check if the daemon is running.\n"; }
  print "\n";
  }


sub plot_proc {

  print "creating images for processes...\n";

  opendir(DIR,"./rrd");
  my @files=readdir(DIR);
  closedir(DIR);
  my @results=grep /proc.*\.rrd/,@files;
  foreach (@results) { s/\.rrd//g; }

  # if database exists, create images...
  if (@results) {
    foreach my $dev (@results) {

      print "  $dev:\n";

      foreach $range ("1h","6h","1day","1week","1month","1year") {
        my ($descr,$file,$build,$fullrange,$DATESTRING)=HotSaNICdiagram::get_diagram_properties($range);
  
        my $FILENAME="$OUTDIR/$dev-$file.$IMGFMT";
  
        my $make=$FORCE;
        if ($range eq "1h") { $make++; }
        elsif (! -e "$FILENAME") { $make++; }
        else  {
          my (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef) = stat( "$FILENAME" );
          if (time > ($mtime+$build)) { $make++; }
          }
  
        if ($make>0) {

          my ($prints,$xs,$ys);

          ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i",
            "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
            "-a", uc($IMGFMT), "-l 0", "--title", "processes - last $descr ($DATESTRING)",
            "DEF:slpmin=rrd/$dev.rrd:procslp:MIN",
            "DEF:slpavg=rrd/$dev.rrd:procslp:AVERAGE",
            "DEF:slpmax=rrd/$dev.rrd:procslp:MAX",
            "DEF:runmin=rrd/$dev.rrd:procrun:MIN",
            "DEF:runavg=rrd/$dev.rrd:procrun:AVERAGE",
            "DEF:runmax=rrd/$dev.rrd:procrun:MAX",
            "DEF:zmbmin=rrd/$dev.rrd:proczmb:MIN",
            "DEF:zmbavg=rrd/$dev.rrd:proczmb:AVERAGE",
            "DEF:zmbmax=rrd/$dev.rrd:proczmb:MAX",
            "DEF:stpmin=rrd/$dev.rrd:procstp:MIN",
            "DEF:stpavg=rrd/$dev.rrd:procstp:AVERAGE",
            "DEF:stpmax=rrd/$dev.rrd:procstp:MAX",
            "DEF:dscmin=rrd/$dev.rrd:procdsc:MIN",
            "DEF:dscavg=rrd/$dev.rrd:procdsc:AVERAGE",
            "DEF:dscmax=rrd/$dev.rrd:procdsc:MAX",
            "AREA:slpavg#00ff00:sleeping",
            "GPRINT:slpmin:MIN:(min\\:%3.0lf,",
            "GPRINT:slpavg:AVERAGE:avg\\:%3.0lf,",
            "GPRINT:slpmax:MAX: max\\:%3.0lf)\\n",
            "STACK:dscavg#008800:disc    ",
            "GPRINT:dscmin:MIN:(min\\:%3.0lf,",
            "GPRINT:dscavg:AVERAGE:avg\\:%3.0lf,",
            "GPRINT:dscmax:MAX: max\\:%3.0lf)\\n",
            "STACK:runavg#0000ff:running ",
            "GPRINT:runmin:MIN:(min\\:%3.0lf,",
            "GPRINT:runavg:AVERAGE:avg\\:%3.0lf,",
            "GPRINT:runmax:MAX: max\\:%3.0lf)\\n",
            "STACK:zmbavg#ff0000:zombie  ",
            "GPRINT:zmbmin:MIN:(min\\:%3.0lf,",
            "GPRINT:zmbavg:AVERAGE:avg\\:%3.0lf,",
            "GPRINT:zmbmax:MAX: max\\:%3.0lf)\\n",
            "STACK:stpavg#505050:stopped ",
            "GPRINT:stpmin:MIN:(min\\:%3.0lf,",
            "GPRINT:stpavg:AVERAGE:avg\\:%3.0lf,",
            "GPRINT:stpmax:MAX: max\\:%3.0lf)\\n",
            "HRULE:0#000000";

          rename $TEMPNAME,$FILENAME;
          printf "  %-7s %d"."x%d %s\n",$descr,$xs,$ys,$FILENAME;

          }
        }
      }
    }
  else { print "  No database found\n  Please check if the daemon is running.\n"; }
  print "\n";
  }


sub plot_cpu {

  print "creating images for CPU-usage...\n";

  my ($PERCENT,$SIGN,$SIGN1);

  if ($CPUGRAPH eq "percent" ) { $PERCENT="100"; $SIGN=" (%)"; $SIGN1=" %% "; }
  else { $PERCENT="1";   $SIGN="";     $SIGN1=""; }

  opendir(DIR,"./rrd");
  my @files=readdir(DIR);
  closedir(DIR);
  my @results=grep /cpu.*\.rrd/,@files;
  foreach (@results) { s/\.rrd//g; }

  # if database exists, create images...
  if (@results) {
    foreach my $dev (@results) {

      print "  $dev:\n";

      foreach $range ("1h","6h","1day","1week","1month","1year") {
        my ($descr,$file,$build,$fullrange,$DATESTRING)=HotSaNICdiagram::get_diagram_properties($range);
  
        my $FILENAME="$OUTDIR/$dev-$file.$IMGFMT";
  
        my $make=$FORCE;
        if ($range eq "1h") { $make++; }
        elsif (! -e "$FILENAME") { $make++; }
        else  {
          my (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef) = stat( "$FILENAME" );
          if (time > ($mtime+$build)) { $make++; }
          }
  
        if ($make>0) {

          my ($prints,$xs,$ys);

          # for multicpu: plot range 0..1 for cpu0, cpu1, ... else range 0...$NUMCPU
          #
          my $NUM=$NUMCPU;
          if ( $dev =~ /[0-9]/ ) { $NUM=1; }

	  if ( ($^O eq "linux") || ($^O eq "solaris") ) {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-u $NUMCPU", "-l 0", "-r", "--title", "CPU usage - last $descr ($DATESTRING)", 
              "-a", uc($IMGFMT),
              "DEF:usrdat=rrd/$dev.rrd:cpuusr:AVERAGE",
              "DEF:nicdat=rrd/$dev.rrd:cpunic:AVERAGE",
              "DEF:sysdat=rrd/$dev.rrd:cpusys:AVERAGE",
              "DEF:idldat=rrd/$dev.rrd:cpuidl:AVERAGE",
              "CDEF:usravg=usrdat,$NUM,$PERCENT,*,*",
              "CDEF:nicavg=nicdat,$NUM,$PERCENT,*,*",
              "CDEF:sysavg=sysdat,$NUM,$PERCENT,*,*",
              "CDEF:idlavg=idldat,$NUM,$PERCENT,*,*",
#             "DEF:usrdx=rrd/$dev.rrd:cpuusr:MAX",
#             "DEF:nicdx=rrd/$dev.rrd:cpunic:MAX",
#             "DEF:sysdt=rrd/$dev.rrd:cpusys:MAX",
#             "CDEF:usrmax=usrdx,$NUM,$PERCENT,*,*",
#             "CDEF:nicmax=nicdx,$NUM,$PERCENT,*,*",
#             "CDEF:sysmax=sysdx,$NUM,$PERCENT,*,*",
              "AREA:sysavg#ff0000:system\\g",
              "GPRINT:sysavg:MIN: (min\\:%7.2lf$SIGN1,\\g",
              "GPRINT:sysavg:AVERAGE: avg\\:%7.2lf$SIGN1,\\g",
              "GPRINT:sysavg:MAX: max\\:%7.2lf$SIGN1)\\n",
              "STACK:usravg#0000ff:user\\g",
              "GPRINT:usravg:MIN:   (min\\:%7.2lf$SIGN1,\\g",
              "GPRINT:usravg:AVERAGE: avg\\:%7.2lf$SIGN1,\\g",
              "GPRINT:usravg:MAX: max\\:%7.2lf$SIGN1)\\n",
              "STACK:nicavg#ffff00:nice\\g",
              "GPRINT:nicavg:MIN:   (min\\:%7.2lf$SIGN1,\\g",
              "GPRINT:nicavg:AVERAGE: avg\\:%7.2lf$SIGN1,\\g",
              "GPRINT:nicavg:MAX: max\\:%7.2lf$SIGN1)\\n",
              "STACK:idlavg#00ff00:idle\\g",
              "GPRINT:idlavg:MIN:   (min\\:%7.2lf$SIGN1,\\g",
              "GPRINT:idlavg:AVERAGE: avg\\:%7.2lf$SIGN1,\\g",
              "GPRINT:idlavg:MAX: max\\:%7.2lf$SIGN1)\\n",
#             "LINE1:sysmax#ff0000:",
#             "LINE1:usrmax#0000ff:",
#             "LINE1:nicmax#ffff00:",
              "HRULE:0#000000";
	    }
	  elsif ( ($^O eq "freebsd") || ($^O eq "netbsd")) {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-u $NUMCPU", "-l 0", "--title", "CPU usage - last $descr ($DATESTRING)", 
              "-a", uc($IMGFMT),
              "DEF:usravg=rrd/$dev.rrd:cpuusr:AVERAGE",
              "DEF:nicavg=rrd/$dev.rrd:cpunic:AVERAGE",
              "DEF:sysavg=rrd/$dev.rrd:cpusys:AVERAGE",
              "DEF:idlavg=rrd/$dev.rrd:cpuidl:AVERAGE",
              "DEF:intavg=rrd/$dev.rrd:cpuint:AVERAGE",
              "AREA:sysavg#ff0000:system",
              "GPRINT:sysavg:MIN:(min\\:%1.2lf,",
              "GPRINT:sysavg:AVERAGE:avg\\:%1.2lf,",
              "GPRINT:sysavg:MAX: max\\:%1.2lf)\\n",
              "STACK:intavg#ff8c05:interrupt",
              "GPRINT:intavg:MIN:(min\\:%1.2lf,",
              "GPRINT:intavg:AVERAGE:avg\\:%1.2lf,",
              "GPRINT:intavg:MAX: max\\:%1.2lf)\\n",
              "STACK:usravg#0000ff:user",
              "GPRINT:usravg:MIN:(min\\:%1.2lf,",
              "GPRINT:usravg:AVERAGE:avg\\:%1.2lf,",
              "GPRINT:usravg:MAX: max\\:%1.2lf)\\n",
              "STACK:nicavg#ffff00:nice",
              "GPRINT:nicavg:MIN:(min\\:%1.2lf,",
              "GPRINT:nicavg:AVERAGE:avg\\:%1.2lf,",
              "GPRINT:nicavg:MAX: max\\:%1.2lf)\\n",
              "STACK:idlavg#00ffff:idle",
              "GPRINT:idlavg:MIN:(min\\:%1.2lf,",
              "GPRINT:idlavg:AVERAGE:avg\\:%1.2lf,",
              "GPRINT:idlavg:MAX: max\\:%1.2lf)\\n",
              "HRULE:0#000000";
	    }

          rename $TEMPNAME,$FILENAME;
          printf "  %-7s %d"."x%d %s\n",$descr,$xs,$ys,$FILENAME;

          }
        }
      }
    }
  else { print "  No database found\n  Please check if the daemon is running.\n"; }
  print "\n";
  }


sub plot_mem {

  print "creating images for memory-usage...\n";

  opendir(DIR,"./rrd");
  my @files=readdir(DIR);
  closedir(DIR);
  my @results=grep /mem.*\.rrd/,@files;
  foreach (@results) { s/\.rrd//g; }

  # if database exists, create images...
  if (@results) {
    foreach my $dev (@results) {

      print "  $dev:\n";

      foreach $range ("1h","6h","1day","1week","1month","1year") {
        my ($descr,$file,$build,$fullrange,$DATESTRING)=HotSaNICdiagram::get_diagram_properties($range);
  
        my $FILENAME="$OUTDIR/$dev-$file.$IMGFMT";
  
        my $make=$FORCE;
        if ($range eq "1h") { $make++; }
        elsif (! -e "$FILENAME") { $make++; }
        else  {
          my (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef) = stat( "$FILENAME" );
          if (time > ($mtime+$build)) { $make++; }
          }
  
        if ($make>0) {

          my ($prints,$xs,$ys);

	  if ($^O eq "linux") {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-u 1", "--alt-autoscale-max", "-l 0", "--title", "memory usage - last $descr ($DATESTRING)", 
              "-a", uc($IMGFMT),
              "DEF:memfre=rrd/$dev.rrd:memfre:AVERAGE",
              "DEF:memshr=rrd/$dev.rrd:memshr:AVERAGE",
              "DEF:membuf=rrd/$dev.rrd:membuf:AVERAGE",
              "DEF:memcac=rrd/$dev.rrd:memcac:AVERAGE",
              "AREA:memcac#ffa000:cached  ",
              "GPRINT:memcac:MIN:(min\\:%7.2lf%s,",
              "GPRINT:memcac:AVERAGE:avg\\:%7.2lf%s,",
              "GPRINT:memcac:MAX: max\\:%7.2lf%s)\\n",
              "STACK:memshr#ffff00:shared  ",
              "GPRINT:memshr:MIN:(min\\:%7.2lf%s,",
              "GPRINT:memshr:AVERAGE:avg\\:%7.2lf%s,",
              "GPRINT:memshr:MAX: max\\:%7.2lf%s)\\n",
              "STACK:membuf#00ff00:buffered",
              "GPRINT:membuf:MIN:(min\\:%7.2lf%s,",
              "GPRINT:membuf:AVERAGE:avg\\:%7.2lf%s,",
              "GPRINT:membuf:MAX: max\\:%7.2lf%s)\\n",
              "STACK:memfre#00c000:free    ",
              "GPRINT:memfre:MIN:(min\\:%7.2lf%s,",
              "GPRINT:memfre:AVERAGE:avg\\:%7.2lf%s,",
              "GPRINT:memfre:MAX: max\\:%7.2lf%s)\\n",
              "HRULE:0#000000";
	    }
	  if ($^O eq "solaris") {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-u 1", "--alt-autoscale-max", "-l 0", "--title", "memory usage - last $descr ($DATESTRING)", 
              "-a", uc($IMGFMT),
              "DEF:memfre=rrd/$dev.rrd:memfre:AVERAGE",
              "DEF:memshr=rrd/$dev.rrd:memshr:AVERAGE",
              "AREA:memshr#ff0000:used  ",
              "GPRINT:memshr:MIN:(min\\:%7.2lf%s,",
              "GPRINT:memshr:AVERAGE:avg\\:%7.2lf%s,",
              "GPRINT:memshr:MAX: max\\:%7.2lf%s)\\n",
              "STACK:memfre#00c000:free    ",
              "GPRINT:memfre:MIN:(min\\:%7.2lf%s,",
              "GPRINT:memfre:AVERAGE:avg\\:%7.2lf%s,",
              "GPRINT:memfre:MAX: max\\:%7.2lf%s)\\n",
              "HRULE:0#000000";
	    }
	  elsif ($^O eq "freebsd") {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-u 1", "--alt-autoscale-max", "-l 0", "--title", "memory usage - last $descr ($DATESTRING)", 
              "-a", uc($IMGFMT),
              "DEF:memfree=rrd/$dev.rrd:memfree:AVERAGE",
              "DEF:memwire=rrd/$dev.rrd:memwire:AVERAGE",
              "DEF:memactv=rrd/$dev.rrd:memactv:AVERAGE",
              "DEF:meminac=rrd/$dev.rrd:meminac:AVERAGE",
              "DEF:memcach=rrd/$dev.rrd:memcach:AVERAGE",
              "AREA:memwire#0000ff:wired",
              "GPRINT:memwire:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memwire:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memwire:MAX: max\\:%1.2lf%s)\\n",
              "STACK:memactv#ff0000:active",
              "GPRINT:memactv:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memactv:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memactv:MAX: max\\:%1.2lf%s)\\n",
              "STACK:memcach#ffa000:cached",
              "GPRINT:memcach:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memcach:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memcach:MAX: max\\:%1.2lf%s)\\n",
              "STACK:meminac#00ff00:inactive",
              "GPRINT:meminac:MIN:(min\\:%1.2lf%s,",
              "GPRINT:meminac:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:meminac:MAX: max\\:%1.2lf%s)\\n",
              "STACK:memfree#00c000:free",
              "GPRINT:memfree:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memfree:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memfree:MAX: max\\:%1.2lf%s)\\n",
              "HRULE:0#000000";
	    }
	  elsif ($^O eq "netbsd") {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-u 1", "--alt-autoscale-max", "-l 0", "--title", "memory usage - last $descr ($DATESTRING)", 
              "-a", uc($IMGFMT),
              "DEF:memfree=rrd/$dev.rrd:memfree:AVERAGE",
              "DEF:meminac=rrd/$dev.rrd:meminac:AVERAGE",
              "DEF:memacti=rrd/$dev.rrd:memacti:AVERAGE",
              "DEF:memwire=rrd/$dev.rrd:memwire:AVERAGE",
              "DEF:memcach=rrd/$dev.rrd:memcach:AVERAGE",
              "AREA:memcach#0000ff:cached",
              "GPRINT:memcach:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memcach:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memcach:MAX: max\\:%1.2lf%s)\\n",
              "STACK:memwire#00dd55:wired",
              "GPRINT:memwire:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memwire:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memwire:MAX: max\\:%1.2lf%s)\\n",
              "STACK:memacti#ff0000:active",
              "GPRINT:memacti:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memacti:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memacti:MAX: max\\:%1.2lf%s)\\n",
              "STACK:meminac#993300:inactive",
              "GPRINT:meminac:MIN:(min\\:%1.2lf%s,",
              "GPRINT:meminac:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:meminac:MAX: max\\:%1.2lf%s)\\n",
              "STACK:memfree#00ff00:free",
              "GPRINT:memfree:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memfree:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memfree:MAX: max\\:%1.2lf%s)\\n",
              "HRULE:0#000000";
	    }
	  elsif ($^O eq "darwin") {
            ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
              "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
              "-u 1", "--alt-autoscale-max", "-l 0", "--title", "memory usage - last $descr ($DATESTRING)", 
              "-a", uc($IMGFMT),
              "DEF:memfree=rrd/$dev.rrd:memfree:AVERAGE",
              "DEF:memwire=rrd/$dev.rrd:memwire:AVERAGE",
              "DEF:memactv=rrd/$dev.rrd:memactv:AVERAGE",
              "DEF:meminac=rrd/$dev.rrd:meminac:AVERAGE",
              "AREA:memwire#0000ff:wired",
              "GPRINT:memwire:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memwire:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memwire:MAX: max\\:%1.2lf%s)\\n",
              "STACK:memactv#ff0000:active",
              "GPRINT:memactv:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memactv:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memactv:MAX: max\\:%1.2lf%s)\\n",
              "STACK:meminac#00ff00:inactive",
              "GPRINT:meminac:MIN:(min\\:%1.2lf%s,",
              "GPRINT:meminac:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:meminac:MAX: max\\:%1.2lf%s)\\n",
              "STACK:memfree#00c000:free",
              "GPRINT:memfree:MIN:(min\\:%1.2lf%s,",
              "GPRINT:memfree:AVERAGE:avg\\:%1.2lf%s,",
              "GPRINT:memfree:MAX: max\\:%1.2lf%s)\\n",
              "HRULE:0#000000";
	    }

          rename $TEMPNAME,$FILENAME;
          printf "  %-7s %d"."x%d %s\n",$descr,$xs,$ys,$FILENAME;

          }
        }
      }
    }
  else { print "  No database found\n  Please check if the daemon is running.\n"; }
  print "\n";
  }


sub plot_swap {

  print "creating images for swapfile-usage...\n";

  opendir(DIR,"./rrd");
  my @files=readdir(DIR);
  closedir(DIR);
  my @results=grep /mem.*\.rrd/,@files;
  foreach (@results) { s/\.rrd//g; }

  # if database exists, create images...
  if (@results) {
    foreach my $dev (@results) {

      print "  $dev:\n";

      foreach $range ("1h","6h","1day","1week","1month","1year") {
        my ($descr,$file,$build,$fullrange,$DATESTRING)=HotSaNICdiagram::get_diagram_properties($range);
  
	(my $dev1=$dev) =~ s/^mem/swap/g;

        my $FILENAME="$OUTDIR/$dev1-$file.$IMGFMT";
  
        my $make=$FORCE;
        if ($range eq "1h") { $make++; }
        elsif (! -e "$FILENAME") { $make++; }
        else  {
          my (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef) = stat( "$FILENAME" );
          if (time > ($mtime+$build)) { $make++; }
          }
  
        if ($make>0) {

          my ($prints,$xs,$ys);

          ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
            "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
            "-u 1", "--alt-autoscale-max", "-l 0", "--title", "swapfile usage - last $descr ($DATESTRING)", 
            "-a", uc($IMGFMT),
            "DEF:swpfre=rrd/$dev.rrd:swpfre:AVERAGE",
            "DEF:swpuse=rrd/$dev.rrd:swpuse:AVERAGE",
            "DEF:maxswpuse=rrd/$dev.rrd:swpuse:MAX",
            "AREA:swpuse#c00000:used    ",
            "GPRINT:swpuse:MIN:(min\\:%7.2lf%s,",
            "GPRINT:swpuse:AVERAGE:avg\\:%7.2lf%s,",
            "GPRINT:swpuse:MAX: max\\:%7.2lf%s)\\n",
            "STACK:swpfre#00c000:free    ",
            "GPRINT:swpfre:MIN:(min\\:%7.2lf%s,",
            "GPRINT:swpfre:AVERAGE:avg\\:%7.2lf%s,",
            "GPRINT:swpfre:MAX: max\\:%7.2lf%s)\\n",
            "LINE1:maxswpuse#c0c000:max used",
            "GPRINT:maxswpuse:MIN:(min\\:%7.2lf%s,",
            "GPRINT:maxswpuse:AVERAGE:avg\\:%7.2lf%s,",
            "GPRINT:maxswpuse:MAX: max\\:%7.2lf%s)\\n",
            "HRULE:0#000000";

          rename $TEMPNAME,$FILENAME;
          printf "  %-7s %d"."x%d %s\n",$descr,$xs,$ys,$FILENAME;

          }
        }
      }
    }
  else { print "  No database found\n  Please check if the daemon is running.\n"; }
  print "\n";
  }


sub plot_user {

  print "creating images for user-stats...\n";

  opendir(DIR,"./rrd");
  my @files=readdir(DIR);
  closedir(DIR);
  my @results=grep /users.*\.rrd/,@files;
  foreach (@results) { s/\.rrd//g; }

  # if database exists, create images...
  if (@results) {
    foreach my $dev (@results) {

      print "  $dev:\n";

      foreach $range ("1h","6h","1day","1week","1month","1year") {
        my ($descr,$file,$build,$fullrange,$DATESTRING)=HotSaNICdiagram::get_diagram_properties($range);
  
        my $FILENAME="$OUTDIR/$dev-$file.$IMGFMT";
  
        my $make=$FORCE;
        if ($range eq "1h") { $make++; }
        elsif (! -e "$FILENAME") { $make++; }
        else  {
          my (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef) = stat( "$FILENAME" );
          if (time > ($mtime+$build)) { $make++; }
          }
  
        if ($make>0) {

          my ($prints,$xs,$ys);

          ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b", "1024",
            "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
            "-u 1", "--alt-autoscale-max", "-l 0", "--title", "users - last $descr ($DATESTRING)", 
            "-a", uc($IMGFMT),
            "DEF:ttymin=rrd/$dev.rrd:tty:MIN",
            "DEF:ttyavg=rrd/$dev.rrd:tty:AVERAGE",
            "DEF:ttymax=rrd/$dev.rrd:tty:MAX",
            "DEF:ptymin=rrd/$dev.rrd:pty:MIN",
            "DEF:ptyavg=rrd/$dev.rrd:pty:AVERAGE",
            "DEF:ptymax=rrd/$dev.rrd:pty:MAX",
            "DEF:ptsmin=rrd/$dev.rrd:pts:MIN",
            "DEF:ptsavg=rrd/$dev.rrd:pts:AVERAGE",
            "DEF:ptsmax=rrd/$dev.rrd:pts:MAX",
            "AREA:ttymax#000000:tty users",
            "GPRINT:ttymin:MIN:(min\\:%3.0lf%s,",
            "GPRINT:ttyavg:AVERAGE:avg\\:%3.0lf%s,",
            "GPRINT:ttymax:MAX: max\\:%3.0lf%s)\\n",
            "STACK:ptymax#808080:pty users",
            "GPRINT:ptymin:MIN:(min\\:%3.0lf%s,",
            "GPRINT:ptyavg:AVERAGE:avg\\:%3.0lf%s,",
            "GPRINT:ptymax:MAX: max\\:%3.0lf%s)\\n",
            "STACK:ptsmax#d0d0d0:pts users",
            "GPRINT:ptsmin:MIN:(min\\:%3.0lf%s,",
            "GPRINT:ptsavg:AVERAGE:avg\\:%3.0lf%s,",
            "GPRINT:ptsmax:MAX: max\\:%3.0lf%s)\\n",
#           "CDEF:totavg=ttyavg,ptyavg,ptsavg,+,+",
#           "LINE1:totavg#c00000:total average",
#           "GPRINT:totavg:MIN:(min\\:%3.0lf%s,",
#           "GPRINT:totavg:AVERAGE:avg\\:%3.0lf%s,",
#           "GPRINT:totavg:MAX: max\\:%3.0lf%s)\\n",
            "HRULE:0#000000";

          rename $TEMPNAME,$FILENAME;
          printf "  %-7s %d"."x%d %s\n",$descr,$xs,$ys,$FILENAME;

          }
        }
      }
    }
  else { print "  No database found\n  Please check if the daemon is running.\n"; }
  print "\n";
  }


sub plot_irq {

  print "creating images for interrupts...\n";

  for (my $nn=0;$nn<18;$nn++) { 
    if (!defined $ITEMS[$nn]) { $ITEMS[$nn]="?"; }
    if ($ITEMS[$nn] eq "") { $ITEMS[$nn]="?"; }
    $ITEMS[$nn]=substr("(".substr($ITEMS[$nn],0,5).")          ",0,7);
    } 
  
  my $LEGEND="irq/s";
  
  # if database exists, create images...
  if ( -e "./rrd/irq.rrd") {
  
    foreach $range ("1h","6h","1day","1week","1month","1year") {
      my ($descr,$file,$build,$fullrange,$DATESTRING)=HotSaNICdiagram::get_diagram_properties($range);
  
      my $FILENAME="$OUTDIR/irq-$file.$IMGFMT";
  
      my $make=$FORCE;
      if ($range eq "1h") { $make++; }
      elsif (! -e "$FILENAME") { $make++; }
      else  {
        my (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef) = stat( "$FILENAME" );
        if (time > ($mtime+$build)) { $make++; }
        }
  
      if ($make>0) {
  	
      my ($prints,$xs,$ys);
  
          ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i", "-b","1024", "-v", $LEGEND,
            "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
            "-l 0", "--title", "total IRQ/s - last $descr ($DATESTRING)",
            "-a", uc($IMGFMT),
            "DEF:irqiall=rrd/irq.rrd:irqall:MIN",
            "DEF:irqaall=rrd/irq.rrd:irqall:AVERAGE",
            "DEF:irqxall=rrd/irq.rrd:irqall:MAX",
            "DEF:irqa00=rrd/irq.rrd:irq00:AVERAGE",
            "DEF:irqa01=rrd/irq.rrd:irq01:AVERAGE",
            "DEF:irqa02=rrd/irq.rrd:irq02:AVERAGE",
            "DEF:irqa03=rrd/irq.rrd:irq03:AVERAGE",
            "DEF:irqa04=rrd/irq.rrd:irq04:AVERAGE",
            "DEF:irqa05=rrd/irq.rrd:irq05:AVERAGE",
            "DEF:irqa06=rrd/irq.rrd:irq06:AVERAGE",
            "DEF:irqa07=rrd/irq.rrd:irq07:AVERAGE",
            "DEF:irqa08=rrd/irq.rrd:irq08:AVERAGE",
            "DEF:irqa09=rrd/irq.rrd:irq09:AVERAGE",
            "DEF:irqa10=rrd/irq.rrd:irq10:AVERAGE",
            "DEF:irqa11=rrd/irq.rrd:irq11:AVERAGE",
            "DEF:irqa12=rrd/irq.rrd:irq12:AVERAGE",
            "DEF:irqa13=rrd/irq.rrd:irq13:AVERAGE",
            "DEF:irqa14=rrd/irq.rrd:irq14:AVERAGE",
            "DEF:irqa15=rrd/irq.rrd:irq15:AVERAGE",
            "AREA:irqxall#c0c0ff:total",
            "AREA:irqiall#ffffff:\\g",
            "GPRINT:irqiall:MIN:  (min\\:%7.2lf %s /\\g",
            "GPRINT:irqaall:AVERAGE: avg\\:%7.2lf %s /\\g",
            "GPRINT:irqxall:MAX: max\\:%7.2lf %s $LEGEND)\\n",
            "LINE1:irqxall#ff0000:",
            "LINE1:irqiall#00ff00:",
            "LINE1:irqaall#000000:",
            "COMMENT:Averages (min/max)\\:\\n",
            "LINE2:irqa00#a00000:00".$ITEMS[0],
            "GPRINT:irqa00:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa00:MAX:%5.1lf%s",
            "LINE2:irqa01#ff0000:01".$ITEMS[1],
            "GPRINT:irqa01:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa01:MAX:%5.1lf%s",
            "LINE2:irqa02#ff5050:02".$ITEMS[2],
            "GPRINT:irqa02:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa02:MAX:%5.1lf%s",
            "LINE2:irqa03#ffa0a0:03".$ITEMS[3],
            "GPRINT:irqa03:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa03:MAX:%5.1lf%s\\n",
            "LINE2:irqa04#00a000:04".$ITEMS[4],
            "GPRINT:irqa04:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa04:MAX:%5.1lf%s",
            "LINE2:irqa05#00ff00:05".$ITEMS[5],
            "GPRINT:irqa05:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa05:MAX:%5.1lf%s",
            "LINE2:irqa06#50ff50:06".$ITEMS[6],
            "GPRINT:irqa06:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa06:MAX:%5.1lf%s",
            "LINE2:irqa07#a0ffa0:07".$ITEMS[7],
            "GPRINT:irqa07:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa07:MAX:%5.1lf%s\\n",
            "LINE2:irqa08#0000a0:08".$ITEMS[8],
            "GPRINT:irqa08:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa08:MAX:%5.1lf%s",
            "LINE2:irqa09#0000ff:09".$ITEMS[9],
            "GPRINT:irqa09:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa09:MAX:%5.1lf%s",
            "LINE2:irqa10#5050ff:10".$ITEMS[10],
            "GPRINT:irqa10:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa10:MAX:%5.1lf%s",
            "LINE2:irqa11#a0a0ff:11".$ITEMS[11],
            "GPRINT:irqa11:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa11:MAX:%5.1lf%s\\n",
            "LINE2:irqa12#a000a0:12".$ITEMS[12],
            "GPRINT:irqa12:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa12:MAX:%5.1lf%s",
            "LINE2:irqa13#ff00ff:13".$ITEMS[13],
            "GPRINT:irqa13:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa13:MAX:%5.1lf%s",
            "LINE2:irqa14#ff50ff:14".$ITEMS[14],
            "GPRINT:irqa14:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa14:MAX:%5.1lf%s",
            "LINE2:irqa15#ffa0ff:15".$ITEMS[15],
            "GPRINT:irqa15:MIN:%5.1lf%s/\\g",
            "GPRINT:irqa15:MAX:%5.1lf%s",
            "HRULE:0#000000";
            
        rename $TEMPNAME,$FILENAME;
        printf "  %-7s %d"."x%d %s\n",$descr,$xs,$ys,$FILENAME;

        }
      }
    }
  else { print "  No database found\n  Please check if the daemon is running.\n"; }
  print "\n";
  }

sub plot_uptime {

  print "creating images for uptime...\n";

  opendir(DIR,"./rrd");
  my @files=readdir(DIR);
  closedir(DIR);
  my @results=grep /uptime.*\.rrd/,@files;
  foreach (@results) { s/\.rrd//g; }

  # if database exists, create images...
  if (@results) {
    foreach my $dev (@results) {

      print "  $dev:\n";

      foreach $range ("1day","1week","1month","1year") {
        my ($descr,$file,$build,$fullrange,$DATESTRING)=HotSaNICdiagram::get_diagram_properties($range);
  
        my $FILENAME="$OUTDIR/$dev-$file.$IMGFMT";
  
        my $make=$FORCE;
        if ($range eq "1h") { $make++; }
        elsif (! -e "$FILENAME") { $make++; }
        else  {
          my (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef) = stat( "$FILENAME" );
          if (time > ($mtime+$build)) { $make++; }
          }
  
        if ($make>0) {

          my ($prints,$xs,$ys)=RRDs::graph $TEMPNAME, "-i",
            "-s","-$range", "-w",$CONFIG{"WIDTH"}, "-h",$CONFIG{"HEIGHT"},
            "-u 2", "--alt-autoscale-max", "-l 0", "--title", "system-uptime - last $descr ($DATESTRING)",
            "-a", uc($IMGFMT),
            "DEF:up=rrd/$dev.rrd:up:AVERAGE",
            "DEF:idle=rrd/$dev.rrd:idle:AVERAGE",
            "AREA:up#00c000:uptime",
            "GPRINT:up:MAX:(%1.2lf days)\\n",
            "AREA:idle#aa0000:idle time",
            "GPRINT:idle:MAX:(%1.2lf days)\\n",
            "HRULE:0#000000";

          rename $TEMPNAME,$FILENAME;
          printf "  %-7s %d"."x%d %s\n",$descr,$xs,$ys,$FILENAME;

          }
        }
      }
    }
  else { print "  No database found\n  Please check if the daemon is running.\n"; }
  print "\n";
  }
