#!/usr/bin/perl
#------------------------------------------------------------------------------
#    sysusage - Full system monitoring with RRDTOOL
#    Copyright (C) 2003-2009 Gilles Darold
#
#    This program is provided WITHOUT WARRANTY of any kind, either
#    expressed or implied. It is free software, and you are welcome
#    to modify or re-distribute it under same terms of Perl itself.
#
# Author: Gilles Darold <gilles@darold.net>
#
#------------------------------------------------------------------------------
#
# This script is used to generate graphics based on datas
# received from the sysusage report tool.
#
#------------------------------------------------------------------------------
use strict;

use Getopt::Long;
use RRDs;
use POSIX qw(locale_h);
setlocale(LC_ALL, 'C');


my $VERSION = '2.10';

$| = 1;

my $VERBOSE      = 0;

my $CONF_FILE = '/etc/sysusage.cfg';
if (!-e $CONF_FILE) {
        $CONF_FILE = '/usr/local/etc/sysusage.cfg';
        if (!-e $CONF_FILE) {
                $CONF_FILE = '/etc/sysusage.cfg';
        }
}

my $GRAPH_FORMAT = 'PNG';
my @DIMENSIONS   = (550, 200);
my @COLORS       = (
	'000000',
	'232323',
	'212121',
	'969696',
	'8C8C8C',
	'FF0000',
	'FFFFFF',
	'000000',
	'FF0000',
	'FF0000',
	'FFFFFF',
	'00B6E4'
);
my %CMD         = ();
my @PERIODS     = ('-1day', '-1week', '-1month', '-1year');
my $HELP        = 0;
my $SHOWVER     = 0;
my @LINKS       = ();
my $bgcolor     = '#000000';
my $fgcolor     = '#FFFFFF';
my $lkcolor     = '#FFFF99';
my %Config      = ();

# Get command line arguments
&check_args();

&debug("main(): Using default image format: $GRAPH_FORMAT\n");
&debug("main(): Reading configuration file $CONF_FILE\n");

# Read configuration file
&read_config();

# Check if an other instance is running
&check_running();

my $uptime = &get_uptime();
my $hostname = `$Config{'GENERAL'}{'HOSTNAME'}`;
chomp($hostname);

# Starting the main loop
&debug("main(): Starting the main loop process\n");

# Read database directory
&debug("main(): Looking for rrdtool databases into $Config{'GENERAL'}{'DATA_DIR'}\n");
unless(opendir(DIR, "$Config{'GENERAL'}{'DATA_DIR'}")) {
	unlink("$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid");
	die "Error: can't opendir $Config{'GENERAL'}{'DATA_DIR'}: $!";
}
my @bases = grep { !/^\./ && !/kernel.txt/ && -f "$Config{'GENERAL'}{'DATA_DIR'}/$_" } readdir(DIR);
closedir DIR;

if (!-d "$Config{'GENERAL'}{'DEST_DIR'}") {
	unless(mkdir("$Config{'GENERAL'}{'DEST_DIR'}", 0755)) {
		die "ERROR: can't create directory $Config{'GENERAL'}{'DEST_DIR'}, $!\n";;
	}
}

# Find what to do with the database found
if ($#bases >= 0) {
	&debug("main(): Found " . $#bases + 1 . " rrdtool databases\n");
} else {
	&debug("main(): No rrdtool databases found. You need to run sysusage.pl first\n");
}
foreach my $b (@bases) {
  	&debug("main(): Starting scan for base $b\n");
	&createGraphic($b);
	&createHTML($b);
}
if (!$Config{'GENERAL'}{'DEBUG'}) {
	&debug("main(): Generating HTML index\n");
	&createIndex();
}

&debug("main(): Exiting sysusagegraph\n");
unlink("$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid");
exit 0;

sub debug
{
	my ($str) = @_;

	if ($Config{'GENERAL'}{'DEBUG'}) {
		print $str;
	}
}

sub createGraphic
{
	my ($target) = @_;

	# reconfiguring text options
	my $vlabel = '';
	my $title = '';
	my $legend1 = '';
	my $legend2 = '';
	my $legend3 = '';
	my $legend_A = '';
	my $legend_B = '';
	my $legend_C = '';

	if ($target =~ /^cpu/) {
		$target =~ /^cpu(\d+)/;
		my $name = $1;
		$vlabel  = 'Percentage cpu used';
		$title   = "CPU $name percentage used";
		$legend_A = 'Percentage total cpu used';
		$legend_B = 'Percentage user';
		$legend_C = 'Percentage system';
		$legend1 = 'percent';
		$legend2 = 'percent';
		$legend3 = 'percent';
	} elsif ($target =~ /^wait/) {
		$target =~ /^wait(\d+)/;
		my $name = $1;
		$vlabel  = 'Percentage cpu iowait/idle/steal';
		$title   = "CPU $name iowait/idle/steal percentage";
		$legend_A = 'Percentage iowait';
		$legend_B = 'Percentage idle';
		$legend_C = 'Percentage steal';
		$legend1 = 'percent iowait';
		$legend2 = 'percent idle';
		$legend3 = 'percent steal';
	} elsif ($target =~ /^net_(.*)/) {
		my $name = $1 || '';
		$title   = "Network interface $name usage";
		$vlabel  = 'Byte / second';
		$legend_A = 'In byte per second';
		$legend_B = 'Out byte per second';
		$legend1 = 'In B/s';
		$legend2 = 'Out B/s';
	} elsif ($target =~ /^err_(.*)/) {
		my $name = $1 || '';
		$vlabel  = 'Packet / second';
		$title   = "Network interface $name bad packet";
		$legend_A = 'In packet per second';
		$legend_B = 'Out packet per second';
		$legend1 = 'In Pkt/s';
		$legend2 = 'Out Pkt/s';
	} elsif ($target =~ /^drop_(.*)/) {
		my $name = $1 || '';
		$vlabel  = 'Packets / second';
		$title   = "Network interface $name packet dropped";
		$legend_A = 'In packet per second';
		$legend_B = 'Out packet per second';
		$legend1 = 'In Pkt/s';
		$legend2 = 'Out Pkt/s';
	} elsif ($target =~ /^coll_(.*)/) {
		my $name = $1 || '';
		$vlabel  = 'Packet / second';
		$title   = "Network interface $name collision";
		$legend_A = 'packet per second';
		$legend1 = 'In Pkt/s';
	} elsif ($target eq 'load') {
		$vlabel  = 'Load';
		$title   = 'Load Average';
		$legend_A = 'Last minute load';
		$legend_B = 'Last 5 minutes load';
		$legend_C = 'Last 15 minutes load';
		$legend1 = 'Load';
		$legend2 = 'Load';
		$legend3 = 'Load';
	} elsif ($target eq 'mem') {
		$vlabel  = 'Bytes used';
		$title   = 'Memory usage';
		$legend_A = 'Total memory used (memory + cache)';
		$legend_B = 'Memory used (memory - cache)';
		$legend1 = 'Bytes';
		$legend2 = 'Bytes';
	} elsif ($target eq 'work') {
		$vlabel  = 'Bytes needed';
		$title   = 'Memory needed for workload';
		$legend_A = 'Bytes needed';
		$legend1 = 'Bytes';
	} elsif ($target =~ /^swap/) {
		$vlabel  = 'Percentage swap used';
		$title   = "Swap usage";
		$legend_A = 'Percent used';
		$legend1 = 'percent';
	} elsif ($target =~ /^dev_/) {
		$target =~ /^dev_(.*)/;
		my $dev = $1;
		$dev =~ s#__#{TMPCHAR}#g;
		$dev =~ s#_#/#g;
		$dev =~ s#\{TMPCHAR\}#_#g;
		$vlabel  = 'Percentage CPU used';
		$title   = "Device $dev CPU usage";
		$legend_A = 'Percent used';
		$legend1 = 'percent';
	} elsif ($target =~ /^disk/) {
		$target =~ /^disk(.*)/;
		my $dev = $1;
		$dev =~ s#__#{TMPCHAR}#g;
		$dev =~ s#_#/#g;
		$dev =~ s#\{TMPCHAR\}#_#g;
		$vlabel  = 'Percentage space used';
		$title   = "Disk space percentage in used on $dev";
		$legend_A = 'Percent used';
		$legend1 = 'percent used';
	} elsif ($target =~ /^queue/) {
		$target =~ /^queue(.*)/;
		my $dir = $1;
		$dir =~ s#__#{TMPCHAR}#g;
		$dir =~ s#_#/#g;
		$dir =~ s#\{TMPCHAR\}#_#g;
		$vlabel  = 'Number of files';
		$title   = "Number of files in queue $dir";
		$legend_A = 'files';
		$legend1 = 'files';
	} elsif ($target =~ /^share/) {
		$vlabel  = 'Percentage Share Memory used';
		$title   = "Share Memory percentage in used";
		$legend_A = 'Percent used';
		$legend1 = 'percent';
	} elsif ($target eq 'sock') {
		$vlabel  = 'Sockets';
		$title   = 'Number of open socket';
		$legend_A = 'Total open socket';
		$legend_B = 'TCP sockets';
		$legend_C = 'UDP sockets';
	} elsif ($target eq 'io') {
		$vlabel  = 'Requests / second';
		$title   = 'I/O request usage';
		$legend_A = 'Read request per second';
		$legend_B = 'Write request per second';
		$legend1 = 'read/s';
		$legend2 = 'write/s';
	} elsif ($target eq 'bio') {
		$vlabel  = 'Blocks / second';
		$title   = 'I/O block usage';
		$legend_A = 'Read block per second';
		$legend_B = 'Write block per second';
		$legend1 = 'read/s';
		$legend2 = 'write/s';
	} elsif ($target eq 'pswap') {
		$vlabel  = 'Page swap / second';
		$title   = 'I/O Page swap usage';
		$legend_A = 'Page read per second';
		$legend_B = 'Page write per second';
		$legend1 = 'read/s';
		$legend2 = 'write/s';
	} elsif ($target eq 'file') {
		$vlabel  = 'Percentage of open file';
		$title   = 'Percentage of open file regarding file-max';
		$legend_A = 'Percentage of open file';
		$legend1 = 'percent';
	} elsif ($target eq 'filen') {
		$vlabel  = 'Number of open file';
		$title   = 'Number of open file';
		$legend_A = 'Open files';
		$legend1 = 'open files';
	} elsif ($target eq 'page') {
		$vlabel  = 'I/O page / second';
		$title   = 'I/O page usage';
		$legend_A = 'Page read per second';
		$legend_B = 'Page write per second';
		$legend1 = 'read/s';
		$legend2 = 'write/s';
	} elsif ($target eq 'pcrea') {
		$vlabel  = 'Process / second';
		$title   = 'Number of process created per second';
		$legend_A = 'Process per second';
		$legend1 = 'Proc/s';
	} elsif ($target =~ /^proc_(.*)/) {
		$target =~ /^proc_(.*)/;
		my $proc = $1 || '';
		$vlabel  = 'Running process';
		$title   = "Running $proc process";
		$legend_A = 'running process';
		$legend1 = 'Proc';
	} elsif ($target eq 'cswch') {
		$vlabel  = 'Context Switches / second';
		$title   = 'Context Switches per second';
		$legend_A = 'context switch';
		$legend1 = 'cswch/s';
	} elsif ($target eq 'intr') {
		$vlabel  = 'Interrupts / second';
		$title   = 'Interrupts per second';
		$legend_A = 'interrupt';
		$legend1 = 'intr/s';
	} elsif ($target =~ /^hddtemp/) {
		$target =~ /^hddtemp_(.*)/;
		my $device = $1;
		$device =~ s#_#/#g;
		$vlabel  = 'Temperature C';
		$title   = "Hard drive temperature for $device";
		$legend_A = 'C';
		$legend1 = 'C';
	} elsif ($target =~ /^sensors/) {
		$target =~ /^sensors_(.*)/;
		my $device = $1;
		$device =~ s#_# #g;
		if ($device =~ /\bfan\d*\b/i) {
			$vlabel  = 'RPM';
			$title   = "$device";
			$legend_A = 'RPM';
			$legend1  = 'RPM';
		} else {
			$vlabel  = 'Temperature C';
			$device .= "erature" if ($device =~ /\btemp\b/i);
			$title   = "$device";
			$legend_A = 'C' . " $device 1";
			$legend1  = 'C' . " $device 1";
			$legend_B = 'C' . " $device 2";
			$legend2  = 'C' . " $device 2";
		}
	}
	push(@LINKS, { ('title' => $title, 'url' => "$target.html") } );

	#my $opt_rigid = $CMD{$target}->[1] || 0;
	my $opt_rigid = 0;

	# reconfiguring dimension
	my $dim_width  = $DIMENSIONS[0];
	my $dim_height = $DIMENSIONS[1];

	# reconfiguring colors
	my $color_back   ="#".$COLORS[0];
	my $color_canvas ="#".$COLORS[1];
	my $color_shadea ="#".$COLORS[2];
	my $color_shadeb ="#".$COLORS[3];
	my $color_grid   ="#".$COLORS[4];
	my $color_mgrid  ="#".$COLORS[5];
	my $color_font   ="#".$COLORS[6];
	my $color_frame  ="#".$COLORS[7];
	my $color_arrow  ="#".$COLORS[8];
	my $color_A     ="#".$COLORS[9];
	my $color_B    ="#".$COLORS[10];
	my $color_C    ="#".$COLORS[11];

	my $img_ext = lc($GRAPH_FORMAT);

	# end of reconfigure
	foreach my $start (@PERIODS) {
		my @GRAPH_DETAIL1 = ();
		my @GRAPH_DETAIL2 = ();
		if ($legend_B) {
			push(@GRAPH_DETAIL1, "LINE2:DB$color_B:$legend_B");
			push(@GRAPH_DETAIL2,
				"GPRINT:DB:LAST:Current\\: %.2lf $legend2",
				"GPRINT:DB:AVERAGE:Avg\\: %.2lf $legend2",
				"GPRINT:DB:MAX:Max\\: %.2lf $legend2\\l"
			);
		}
		if ($legend_C) {
			push(@GRAPH_DETAIL1, "LINE2:DC$color_C:$legend_C");
			push(@GRAPH_DETAIL2,
				"GPRINT:DC:LAST:Current\\: %.2lf $legend3",
				"GPRINT:DC:AVERAGE:Avg\\: %.2lf $legend3",
				"GPRINT:DC:MAX:Max\\: %.2lf $legend3\\l"
			);
		}
		my $endofline = '\l';
		if ($#GRAPH_DETAIL1 >= 0) {
			$GRAPH_DETAIL1[-1] .= $endofline;
			$endofline = '';
		}
		&debug("Creating $Config{'GENERAL'}{'DEST_DIR'}/$target-$start.$img_ext\n");
		my $answer = RRDs::graph("$Config{'GENERAL'}{'DEST_DIR'}/$target-$start.$img_ext",
			'--imgformat', $GRAPH_FORMAT, '--base', 1000, '--upper-limit', $opt_rigid,
			'--start', $start, '--end', "-$Config{'GENERAL'}{'INTERVAL'}", '--width', $dim_width, '--height', $dim_height,
			'--color', "BACK$color_back", '--color', "CANVAS$color_canvas", '--color', "SHADEA$color_shadea",
			'--color', "SHADEB$color_shadeb", '--color', "GRID$color_grid", '--color', "MGRID$color_mgrid",
			'--color', "FONT$color_font", '--color', "FRAME$color_frame", '--color', "ARROW$color_arrow",
			'--vertical-label', $vlabel, '--title', $title,
                        "DEF:DA=$Config{'GENERAL'}{'DATA_DIR'}/$target:A:AVERAGE",
                        "DEF:DB=$Config{'GENERAL'}{'DATA_DIR'}/$target:B:AVERAGE",
                        "DEF:DC=$Config{'GENERAL'}{'DATA_DIR'}/$target:C:AVERAGE",
                        "LINE2:DA$color_A:$legend_A$endofline",
			@GRAPH_DETAIL1,
			"GPRINT:DA:LAST:Current\\: %.2lf $legend1",
			"GPRINT:DA:AVERAGE:Avg\\: %.2lf $legend1",
			"GPRINT:DA:MAX:Max\\: %.2lf $legend1\\l",
			@GRAPH_DETAIL2
		);
		my $e = RRDs::error();
		if ($e) {
			unlink("$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid");
			die "ERROR: Cannot create graph $Config{'GENERAL'}{'DEST_DIR'}/$target-$start.$img_ext: $e\n";
		}
	}
}

sub createHTML
{
	my ($target) = @_;

	my $img_ext = lc($GRAPH_FORMAT);

	my $title = '';

	if ($target =~ /^cpu/) {
		$target =~ /^cpu(\d+)/;
		my $name = $1;
		$title   = "CPU $name usage";
	} elsif ($target =~ /^net_(.*)/) {
		my $name = $1 || '';
		$title   = "Network interface $name usage";
	} elsif ($target =~ /^err_(.*)/) {
		my $name = $1 || '';
		$title   = "Network interface $name bad packet";
	} elsif ($target =~ /^drop_(.*)/) {
		my $name = $1 || '';
		$title   = "Network interface $name packet dropped";
	} elsif ($target =~ /^coll_(.*)/) {
		my $name = $1 || '';
		$title   = "Network interface $name collision";
	} elsif ($target eq 'load') {
		$title   = 'Load Average';
	} elsif ($target eq 'mem') {
		$title   = 'Memory usage';
	} elsif ($target eq 'work') {
		$title   = 'Memory needed';
	} elsif ($target eq 'swap') {
		$title   = 'Swap usage';
	} elsif ($target =~ /^disk/) {
		$target =~ /^disk(.*)/;
		my $dev = $1;
		$dev =~ s#__#{TMPCHAR}#g;
		$dev =~ s#_#/#g;
		$dev =~ s#\{TMPCHAR\}#_#g;
		$title   = "Disk space percentage used on $dev";
	} elsif ($target =~ /^dev_/) {
		$target =~ /^dev_(.*)/;
		my $dev = $1;
		$dev =~ s#__#{TMPCHAR}#g;
		$dev =~ s#_#/#g;
		$dev =~ s#\{TMPCHAR\}#_#g;
		$title   = "Device $dev CPU usage";
	} elsif ($target =~ /^queue/) {
		$target =~ /^queue(.*)/;
		my $dir = $1;
		$dir =~ s#__#{TMPCHAR}#g;
		$dir =~ s#_#/#g;
		$dir =~ s#\{TMPCHAR\}#_#g;
		$title   = "Number of files in $dir";
	} elsif ($target eq 'share') {
		$title   = 'Share Memory usage';
	} elsif ($target eq 'sock') {
		$title   = 'Number of open socket';
	} elsif ($target eq 'io') {
		$title   = 'I/O request usage';
	} elsif ($target eq 'bio') {
		$title   = 'I/O block usage';
	} elsif ($target eq 'pswap') {
		$title   = 'Swap page usage';
	} elsif ($target eq 'file') {
		$title   = 'Percentage of open file regarding file-max';
	} elsif ($target eq 'filen') {
		$title   = 'Number of open file';
	} elsif ($target eq 'page') {
		$title   = 'I/O page usage';
	} elsif ($target eq 'pcrea') {
		$title   = 'Number of process created per second';
	} elsif ($target eq 'cswch') {
		$title   = 'Context Switches per second';
	} elsif ($target eq 'intr') {
		$title   = 'Interrupts per second';
	} elsif ($target =~ /^proc_(.*)/) {
		$target =~ /^proc_(.*)/;
		my $proc = $1 || '';
		$title   = "Number of running $proc process";
	} elsif ($target =~ /^hddtemp/) {
		$target =~ /^hddtemp_(.*)/;
		my $device = $1;
		$device =~ s#_#/#g;
		$target =~ s#/#_#g;
		$title   = "Hard drive temperature for $device";
	} elsif ($target =~ /^sensors/) {
		$target =~ /^sensors_(.*)/;
		my $device = $1;
		$device =~ s#_# #g;
		$device .= "erature" if ($device =~ /\btemp\b/i);
		$title   = "$device";
	}

	my $date = localtime(time);

	unless(open(HFILE, ">$Config{'GENERAL'}{'DEST_DIR'}/$target.html")) {
		unlink("$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid");
		die "Error: can't write to file $Config{'GENERAL'}{'DEST_DIR'}/$target.html, $!\n";
	}
	
	print HFILE qq{
<html>
<head>
<title>$title</title>
<meta NAME="robots" CONTENT="noindex,nofollow">
<meta HTTP-EQUIV="Refresh" CONTENT="300">
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
<meta HTTP-EQUIV="Cache-Control" content="no-cache">
<meta HTTP-EQUIV="Expires" CONTENT="$date">
<meta HTTP-EQUIV="Generator" CONTENT="Sysusage $VERSION">
<meta HTTP-EQUIV="Date" CONTENT="$date">
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
</head>
<body BGCOLOR="$bgcolor" TEXT="$fgcolor" LINK="$lkcolor" VLINK="$lkcolor" HLINK="$lkcolor">
<font color="$lkcolor">
<h1>$title</h1>
This page will refresh automatically every 5 minutes.<p>
The statistics were last updated <b>$date</b>,<br>
at which time <b>'$hostname'</b> had been up for <b>$uptime</b>.
</font>
<hr>
};
	foreach my $start (@PERIODS) {
		if ($start eq '-1day') {
			print HFILE qq{
<b>Daily Graph (1 Minute Average)</b><br>
<img vspace=10 align=top SRC="$target-$start.$img_ext" TITLE="day" ALT="day">
<hr>
};
		} elsif ($start eq '-1week') {
			print HFILE qq{
<b>Weekly Graph (30 Minute Average)</b><br>
<img vspace=10 align=top SRC="$target-$start.$img_ext" TITLE="week" ALT="week">
<hr>
};
		} elsif ($start eq '-1month') {
			print HFILE qq{
<b>Monthly Graph (2 Hour Average)</b><br>
<img vspace=10 align=top SRC="$target-$start.$img_ext" TITLE="month" ALT="month">
<hr>
};
		} elsif ($start eq '-1year') {
			print HFILE qq{
<b>Yearly Graph (1 Day Average)</b><br>
<img vspace=10 align=top SRC="$target-$start.$img_ext" TITLE="year" ALT="year">
<hr>
};
		}
	}
	my $foot = &footer();
	print HFILE qq{
$foot
</body>
</html>
};

}

sub createIndex
{
	my ($target) = @_;

	my $date = localtime(time);

	# Get the kernel version
	unless(open(KFILE, "$Config{'GENERAL'}{'DATA_DIR'}/kernel.txt")) {
		unlink("$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid");
		die "ERROR: Can't open file $Config{'GENERAL'}{'DATA_DIR'}/kernel.txt\n";
	}
	my $kernel = <KFILE>;
	close(KFILE);

	unless(open(HFILE, ">$Config{'GENERAL'}{'DEST_DIR'}/index.html")) {
		die "Error: can't write to file $Config{'GENERAL'}{'DEST_DIR'}/index.html, $!\n";
		unlink("$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid");
	}
	
	print HFILE qq{
<html>
<head>
<title>System Usage on $hostname</title>
<meta NAME="robots" CONTENT="noindex,nofollow">
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
<meta HTTP-EQUIV="Cache-Control" content="no-cache">
<meta HTTP-EQUIV="Expires" CONTENT="$date">
<meta HTTP-EQUIV="Generator" CONTENT="Sysusage $VERSION">
<meta HTTP-EQUIV="Date" CONTENT="$date">
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
</head>
<body BGCOLOR="$bgcolor" TEXT="$fgcolor" LINK="$lkcolor" VLINK="$lkcolor" HLINK="$lkcolor">
<h1>System Usage on $hostname</h1>
The statistics were last updated <b>$date</b>,<br>
at which time <b>'$hostname'</b> had been up for <b>$uptime</b>.<br>
<b>$kernel</b>
<hr>
Select link bellow to see graphical report of usage.<p>
<ul>
};
	foreach my $link (sort { $a->{title} cmp $b->{title} } @LINKS) {
		print HFILE qq{
<li><a href="$link->{url}">$link->{title}</a></li>
};
	}
	my $foot = &footer();
	print HFILE qq{
</ul>
<hr>
$foot
</body>
</html>
};

}


####
# Function used to check command line argument and configuration
####
sub check_args {
        GetOptions(
                "c=s"    => \$CONF_FILE,
                "d!"     => \$VERBOSE,
                "debug!" => \$VERBOSE,
                "h!"     => \$HELP,
		"help!"  => \$HELP,
		"v!"     => \$SHOWVER
        ) || &usage();
        &usage() if ($HELP);

        if ($SHOWVER) {
                print "Sysusage v$VERSION\n";
                exit 0;
        }

	# Check configuration
	if (! -f $CONF_FILE) {
		print "ERROR: Configuration file $CONF_FILE doesn't exists.\n";
		&usage();
	}

}


####
# Function used to return command line usage 
####
sub usage
{
	print qq{
Usage: sysusagegraph [-c conf_file] [-h|--help] [-v]

	-c file    : Path to config file. Def: /usr/local/etc/sysusage.cfg
	-d|--debug : Verbose output.
	-h|--help  : Output this message and exit
	-v         : Show Sysusagegraph version

};
	unlink("$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid");

	exit 0;
}


####
# Function used to return uptime
# Just return the day part of the uptime command
####
sub get_uptime
{
	my $getuptime = `$Config{'GENERAL'}{'UPTIME'}`;
	if ($getuptime =~ /^\s+\d+:\d+.+\s+up\s+(\d+)\s+(\w+),/) {
		return $1 . " " . $2;
	} elsif ($getuptime =~ /^\s+\d+:\d+.+\s+up\s+(\d+:\d+),/) {
		return $1;
	} else {
		return "Uptime can not be computed";
	}
}

sub footer
{
	return qq{
This file was generated by <a href="http://freshmeat.net/projects/sysusage/">SysUsage v$VERSION</a>
<p>
Author: Gilles Darold - gilles\@darold.net<br>
Copyright (c) 2003-2009 Gilles Darold - All rights reserved.
<p>
This program is provided WITHOUT WARRANTY of any kind, either<br>
expressed or implied. It is free software, and you are welcome<br>
to re-distribute it under same terms of Perl itself.
};

}


sub check_running
{
	if (-e "$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid") {
		my @ret = `ps -ef | grep sysusagegraph | grep -v grep`;
		if ($#ret > 0) {
			print qq{
	An other instance of sysusagegraph is running. Please wait...
	exiting...
};
		} else {
			print qq{
	Found $Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid and no instance
	of sysusagegraph is running. Removing it...
};
			unlink("$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid");
		}
		exit 0;
	} else {
		open(PIDF, ">$Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid") or die "Error: can't write into $Config{'GENERAL'}{'PID_DIR'}/sysusagegraph.pid\n";
		print PIDF "$$";
		close(PIDF);
	}
}

####
# Function used to load sysusage configuration
####
sub read_config
{
	my $part = '';

	unless(open(CONF, "$CONF_FILE")) {
		die "ERROR: can't open file $CONF_FILE, $!\n";
	}
	while (my $l = <CONF>) {
		chomp($l);
		$l =~ s/
//;
		# Skip empty line and comments
		next if (!$l || ($l =~ /^[\s\t]*#/));
		if ($l =~ /\[GENERAL\]/i) {
			$part = 'GENERAL';
			next;
		} elsif ($l =~ /\[ALARM\]/i) {
			$part = 'ALARM';
			next;
		} elsif ($l =~ /\[MONITOR\]/i) {
			$part = 'MONITOR';
			next;
		}
		if ($part eq 'MONITOR') {
			# type:ThresholdMax:ThresholdMin
			my ($type, $thres_max, $thres_min, $other) = split(/:/, $l);
			if ($type eq 'queue') {
				$type = "queue_$thres_max";
				$thres_max = $thres_min;
				$thres_min = '';
			} elsif ($type eq 'proc') {
				$type = "proc_$thres_max";
				$thres_max = $thres_min;
				$thres_min = $other;
			} elsif ($type eq 'hddtemp') {
				$type = "hddtemp_$thres_max";
				$thres_max = $thres_min;
				$thres_min = $other;
			} elsif ($type eq 'sensors') {
				$type = "sensors_$thres_max";
				$thres_max = $thres_min;
				$thres_min = $other;
			}
			push(@{$CMD{$type}}, $thres_max, $thres_min);
		} else {
			if (!$part) {
				die "ERROR: Invalid configuration file syntax, please read documentation\n";
			}
			my ($var, $val) = split(/\s*=\s*/, $l, 2);
			$Config{$part}{"\U$var\E"} = $val; 
		}
	}
	close(CONF);

	if (! -d $Config{'GENERAL'}{'DEST_DIR'}) {
		unless(mkdir($Config{'GENERAL'}{'DEST_DIR'}, 0755)) {
			print "ERROR: Output graph directory $Config{'GENERAL'}{'DEST_DIR'} doesn't exists.\n";
			&usage();
		}
	}
	if (! -d $Config{'GENERAL'}{'DATA_DIR'}) {
		print "ERROR: RRD database directory $Config{'GENERAL'}{'DATA_DIR'} doesn't exists.\n";
		&usage();
	}
        if (!-x $Config{'GENERAL'}{'UPTIME'}) {
                print "ERROR: uptime command not found at $Config{'GENERAL'}{'UPTIME'}\n";
		&usage();
        } elsif (!-x $Config{'GENERAL'}{'HOSTNAME'}) {
                print "ERROR: hostname command not found at $Config{'GENERAL'}{'HOSTNAME'}\n";
		&usage();
        }
	if ($VERBOSE) {
		$Config{'GENERAL'}{'DEBUG'} = 1;
	}

}
