summaryrefslogtreecommitdiff
path: root/perl/manager/manager.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl/manager/manager.pm')
-rw-r--r--perl/manager/manager.pm1051
1 files changed, 1051 insertions, 0 deletions
diff --git a/perl/manager/manager.pm b/perl/manager/manager.pm
new file mode 100644
index 0000000..0450625
--- /dev/null
+++ b/perl/manager/manager.pm
@@ -0,0 +1,1051 @@
+package NetSNMP::manager;
+
+use strict ();
+use warnings;
+use Apache::Constants qw(:common);
+use CGI qw(:standard delete_all);
+use SNMP ();
+use DBI ();
+use NetSNMP::manager::displaytable qw(displaytable displaygraph);
+
+# globals
+$NetSNMP::manager::hostname = 'localhost'; # Host that serves the mSQL Database
+$NetSNMP::manager::dbname = 'snmp'; # mySQL Database name
+$NetSNMP::manager::user = 'root';
+# $NetSNMP::manager::pass = "password";
+$NetSNMP::manager::imagebase = "/home/hardaker/src/snmp/manager"; # <=== CHANGE ME ====
+$NetSNMP::manager::redimage = "/graphics/red.gif";
+$NetSNMP::manager::greenimage = "/graphics/green.gif";
+#$NetSNMP::manager::verbose = 1;
+$NetSNMP::manager::tableparms = "border=1 bgcolor=\"#c0c0e0\"";
+$NetSNMP::manager::headerparms = "border=1 bgcolor=\"#b0e0b0\"";
+
+# init the snmp library
+$SNMP::save_descriptions=1;
+#SNMP::init_mib();
+
+%NetSNMP::manager::myorder = qw(id 0 oidindex 1 host 2 updated 3);
+
+sub handler {
+ my $r = shift;
+ Apache->request($r);
+
+ # get info from handler
+ my $hostname = $r->dir_config('hostname') || $NetSNMP::manager::hostname;
+ my $dbname = $r->dir_config('dbname') || $NetSNMP::manager::dbname;
+ my $sqluser = $r->dir_config('user') || $NetSNMP::manager::user;
+ my $pass = $r->dir_config('pass') || $NetSNMP::manager::pass;
+ my $verbose = $r->dir_config('verbose') || $NetSNMP::manager::verbose;
+
+#===========================================================================
+# Global defines
+#===========================================================================
+
+my ($dbh, $query, $remuser);
+
+$remuser = $ENV{'REMOTE_USER'};
+$remuser = "guest" if (!defined($remuser) || $remuser eq "");
+
+#===========================================================================
+# Connect to the mSQL database with the appropriate driver
+#===========================================================================
+($dbh = DBI->connect("DBI:mysql:database=$dbname;host=$hostname", $sqluser, $pass))
+ or die "\tConnect not ok: $DBI::errstr\n";
+
+#===========================================================================
+# stats Images, for inclusion on another page. (ie, slashdot user box)
+#===========================================================================
+if (my $group = param('groupstat')) {
+ $r->content_type("image/gif");
+ $r->send_http_header();
+ my $cur = getcursor($dbh, "select host from usergroups as ug, hostgroups as hg where ug.groupname = '$group' and hg.groupname = '$group' and user = '$remuser'");
+ while (my $row = $cur->fetchrow_hashref ) {
+ if (checkhost($dbh, $group, $row->{'host'})) {
+ open(I, "$NetSNMP::manager::imagebase$NetSNMP::manager::redimage");
+ while(read(I, $_, 4096)) { print; }
+ close(I);
+ }
+ }
+ open(I, "$NetSNMP::manager::imagebase$NetSNMP::manager::greenimage");
+ while(read(I, $_, 4096)) { print; }
+ close(I);
+ return OK();
+}
+
+
+sub date_format {
+ my $time = shift;
+ my @out = localtime($time);
+ my $ret = $out[4] . "-" . $out[3] . "-" . $out[5] . " " . $out[2] . " " . $out[1];
+# print STDERR "$time: $ret\n";
+ return $ret;
+}
+
+
+#
+# Graphing of historical data
+#
+if ((param('displaygraph') || param('dograph')) && param('table')) {
+ my $host = param('host');
+ my $group = param('group');
+ if (!isuser($dbh, $remuser, $group)) {
+ $r->content_type("image/png");
+ $r->send_http_header();
+ print "Unauthorized access to that group ($group)\n";
+ return Exit($dbh, $group);
+ }
+ my $table = param('table');
+ my @columns;
+
+ if (!param('dograph')) {
+ $r->content_type("text/html");
+ $r->send_http_header();
+ print "<body bgcolor=\"#ffffff\">\n";
+ print "<form>\n";
+ print "<table border=1><tr><td>\n";
+
+ print "<table>\n";
+ print "<tr align=top><th></th><th>Select indexes<br>to graph</th></tr>\n";
+
+ my $handle = getcursor($dbh, "SELECT sql_small_result distinct(oidindex) FROM $table where host = '$host'");
+ my @cols;
+ while ( $row = $handle->fetchrow_hashref ) {
+ print "<tr><td>$row->{oidindex}</td><td><input type=checkbox value=1 name=" . 'graph_' . displaytable::to_unique_key($row->{'oidindex'}) . "></td></tr>\n";
+ }
+ print "</table>\n";
+
+ print "</td><td>\n";
+
+ print "<table>\n";
+ print "<tr align=top><th></th><th>Select Columns<br>to graph</th></tr>\n";
+ my $handle = getcursor($dbh, "SELECT * FROM $table limit 1");
+ my $row = $handle->fetchrow_hashref;
+ map { print "<tr><td>$_</td><td><input type=checkbox value=1 name=column_" . displaytable::to_unique_key($_) . "></td></tr>\n"; } keys(%$row);
+ print "</table>\n";
+
+ print "</td></tr></table>\n";
+
+ print "<br>Graph as a Rate: <input type=checkbox value=1 name=graph_as_rate><br>\n";
+ print "<br>Maximum Y Value: <input type=text value=inf name=max_y><br>\n";
+ print "<br>Minimum Y Value: <input type=text value=-inf name=min_y><br>\n";
+
+ print "<input type=hidden name=table value=\"$table\">\n";
+ print "<input type=hidden name=host value=\"$host\">\n";
+ print "<input type=hidden name=dograph value=1>\n";
+ print "<input type=hidden name=group value=\"$group\">\n";
+ print "<input type=submit name=\"Make Graph\">\n";
+
+ print "</form>\n";
+
+ my $handle = getcursor($dbh, "SELECT distinct(oidindex) FROM $table where host = '$host' order by oidindex");
+ return Exit($dbh, $group);
+ }
+ if (param('graph_all_data')) {
+ $clause = "host = '$host'";
+ } else {
+ my $handle = getcursor($dbh, "SELECT distinct(oidindex) FROM $table where host = '$host'");
+ $clause = "where (";
+ while ( $row = $handle->fetchrow_hashref ) {
+# print STDERR "graph test: " . $row->{'oidindex'} . "=" . "graph_" . displaytable::to_unique_key($row->{'oidindex'}) . "=" . param("graph_" . displaytable::to_unique_key($row->{'oidindex'})) . "\n";
+ if (param("graph_" . displaytable::to_unique_key($row->{'oidindex'}))) {
+ $clause .= " or oidindex = " . $row->{'oidindex'} . "";
+ }
+ }
+
+ my $handle = getcursor($dbh, "SELECT * FROM $table limit 1");
+ my $row = $handle->fetchrow_hashref;
+ map { push @columns, $_ if (param('column_' . displaytable::to_unique_key($_))) } keys(%$row);
+
+ $clause .= ")";
+ $clause =~ s/\( or /\(/;
+ if ($clause =~ /\(\)/ || $#columns == -1) {
+ $r->content_type("text/html");
+ $r->send_http_header();
+ print "<body bgcolor=\"#ffffff\">\n";
+ print "<h1>No Data to Graph</h1>\n";
+ print STDERR "No data to graph: $clause, $#columns\n";
+ return Exit($dbh, "$group");
+ }
+ $clause .= " and host = '$host'";
+ }
+
+# print STDERR "graphing clause: $clause\n";
+
+ # all is ok, display the graph
+
+ $r->content_type("image/png");
+ $r->send_http_header();
+
+ print STDERR "graphing clause: $clause, columns: ", join(", ",@columns), "\n";
+ my @args;
+ push (@args, '-rate', '60') if (param('graph_as_rate'));
+ push (@args, '-max', param('max_y')) if (param('max_y') && param('max_y') =~ /^[-.\d]+$/);
+ push (@args, '-min', param('min_y')) if (param('min_y') && param('min_y') =~ /^[-.\d]+$/);
+
+ my $ret =
+ displaygraph($dbh, $table,
+# '-xcol', "date_format(updated,'%m-%d-%y %h:%i')",
+ '-xcol', "unix_timestamp(updated)",
+ '-pngparms', [
+ 'x_labels_vertical', '1',
+ 'x_tick_number', 6,
+ 'x_number_format', \&date_format,
+ 'y_label', 'Count/Min',
+ 'title', $table,
+# 'y_min_value', 0,
+ ],
+ '-clauses', "$clause order by updated",
+ @args,
+ '-columns', \@columns,
+ '-indexes', ['oidindex']);
+ print STDERR "$ret rows graphed\n";
+ return OK();
+}
+
+#===========================================================================
+# Start HTML.
+#===========================================================================
+$r->content_type("text/html");
+$r->send_http_header();
+print "<body bgcolor=\"#ffffff\">\n";
+print "<h1>UCD-SNMP Management Console</h1>\n";
+print "<hr>\n";
+
+#===========================================================================
+# Display mib related data information
+#===========================================================================
+if (param('displayinfo')) {
+ makemibtable(param('displayinfo'));
+ return Exit($dbh, "");
+}
+
+#===========================================================================
+# Display a generic sql table of any kind (debugging).
+#===========================================================================
+# if (my $disptable = param('displaytable')) {
+# if (param('editable') == 1) {
+# print "<form submit=dont>\n";
+# displaytable($disptable, -editable, 1);
+# print "</form>\n";
+# } else {
+# displaytable($disptable);
+# }
+# return Exit($dbh, "");
+# }
+
+#===========================================================================
+# Get host and group from CGI query.
+#===========================================================================
+my $host = param('host');
+my $group = param('group');
+
+#===========================================================================
+# Editable user information
+#===========================================================================
+
+if (param('setuponcall')) {
+ print "<title>oncall schedule for user: $remuser</title>\n";
+ print "<h2>oncall schedule for user: $remuser</h2>\n";
+ print "<p>Please select your oncall schedule and mailing addresses for your groups below:";
+ if (!isexpert($remuser)) {
+ print "<ul>\n";
+ print "<li>Values for the days/hours fields can be comma seperated lists of hours/days/ranges. EG: hours: 7-18,0-4.\n";
+ print "</ul>\n";
+ }
+ print "<form method=post><input type=hidden name=setuponcall value=1>\n";
+ displaytable($dbh, 'oncall',
+ '-clauses',"where user = '$remuser' order by groupname",
+ '-select','id, user, groupname, email, pager, days, hours',
+ '-selectorder', 1,
+ '-notitle', 1,
+ '-editable', 1,
+ '-indexes', ['id','user','groupname'],
+ '-CGI', $CGI::Q
+ );
+ print "<input type=submit value=\"submit changes\">\n";
+ print "</form>\n";
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# show the list of groups a user belongs to.
+#===========================================================================
+if (!defined($group)) {
+ my @groups = getgroupsforuser($dbh, $remuser);
+ print "<title>Net-SNMP Group List</title>\n";
+ print "<h2>Host groupings you may access:</h2>\n";
+ if (!isexpert($remuser)) {
+ print "<ul>\n";
+ print "<li>Click on a group to operate or view the hosts in that group.\n";
+ print "<li>Click on a red status light below to list the problems found.\n";
+ print "</ul>\n";
+ }
+
+ if ($#groups > 0) {
+ displaytable($dbh, 'usergroups',
+ '-clauses', "where (user = '$remuser')",
+ '-select', 'distinct groupname',
+ '-notitle', 1,
+ '-printonly', ['groupname'],
+ '-datalink', sub { my $q = self_url();
+ my $key = shift;
+ my $h = shift;
+ return if ($key ne "groupname");
+ return addtoken($q,"group=$h");
+ },
+ '-beginhook',
+ sub {
+ my $q = self_url();
+ my($dbh, $junk, $data) = @_;
+ if (!defined($data)) {
+ print "<th>Status</th>";
+ return;
+ }
+ my ($cur, $row);
+ $cur = getcursor($dbh, "select host from hostgroups where groupname = '$data->{groupname}'");
+ while ( $row = $cur->fetchrow_hashref ) {
+ if (checkhost($dbh, $data->{'groupname'},
+ $row->{'host'})) {
+ print "<td><a href=\"" . addtoken($q,"group=$data->{groupname}&summarizegroup=1") . "\"><img border=0 src=$NetSNMP::manager::redimage></a></td>\n";
+ return;
+ }
+ }
+ print "<td><img src=$NetSNMP::manager::greenimage></td>\n";
+ }
+ );
+ $dbh->disconnect();
+ return Exit($dbh, $group);
+ } else {
+ if ($#groups == -1) {
+ print "You are not configured to use the Net-SNMP-manager, please contact your system administrator.";
+ return Exit($dbh, $group);
+ }
+ $group = $groups[0];
+ }
+}
+
+#===========================================================================
+# reject un-authorized people accessing a certain group
+#===========================================================================
+if (!isuser($dbh, $remuser, $group)) {
+ print "Unauthorized access to that group ($group)\n";
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# add a new host to a group
+#===========================================================================
+if (defined(my $newhost = param('newhost'))) {
+ if (isadmin($dbh, $remuser, $group)) {
+ if ($dbh->do("select * from hostgroups where host = '$newhost' and groupname = '$group'") eq "0E0") {
+ $dbh->do("insert into hostgroups(host,groupname) values('$newhost','$group')") ;
+ } else {
+ print "<b>ERROR: host $newhost already in $group</b>\n";
+ }
+ CGI::delete('newhost');
+ }
+}
+
+#===========================================================================
+# display setup configuration for a group
+#===========================================================================
+if (defined(param('setupgroup'))) {
+ if (isadmin($dbh, $remuser, $group)) {
+ setupgroup($dbh, $group);
+ } else {
+ print "<h2>You're not able to perform setup operations for group $group\n";
+ }
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# save configuration information submitted about a group
+#===========================================================================
+if (defined(param('setupgroupsubmit')) &&
+ isadmin($dbh, $remuser, $group)) {
+ setupgroupsubmit($dbh, $group);
+ delete_all();
+ param(-name => 'group', -value => $group);
+ print "<a href=\"" . self_url() . "\">Entries submitted</a>";
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# user preferences
+#===========================================================================
+if (defined(param('userprefs'))) {
+ setupuserpreferences($dbh, $remuser, $group);
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# save submitted user preferences
+#===========================================================================
+if (defined(param('setupuserprefssubmit')) &&
+ isadmin($dbh, $remuser, $group)) {
+ setupusersubmit($dbh, $remuser, $group);
+ delete_all();
+ param(-name => 'group', -value => $group);
+ print "<a href=\"" . self_url() . "\">Entries submitted</a>";
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# summarize problems in a group
+#===========================================================================
+if (defined(param('summarizegroup'))) {
+ print "<title>group problem summary: $group</title>\n";
+ print "<h2>The following is a list of problems in the group \"$group\":</h2>\n";
+ summarizeerrors($dbh, "where groupname = '$group'");
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# summarize problems on a host
+#===========================================================================
+if (defined($host) && defined(param('summarizehost'))) {
+ print "<title>host summary: $host</title>\n";
+ print "<h2>The following is a list of problems for the host \"$host\":</h2>\n";
+ summarizeerrors($dbh, "where groupname = '$group' and host = '$host'");
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# display a list of hosts in a group
+#===========================================================================
+if (!defined($host)) {
+ print "<title>Net-SNMP Host $host</title>\n";
+ print "<h2>Hosts in the group \"$group\":</h2>\n";
+ if (!isexpert($remuser)) {
+ print "<ul>\n";
+ if (isadmin($dbh, $remuser, $group)) {
+ my $q = self_url();
+ $q =~ s/\?.*//;
+ print "<li>Make sure you <a href=\"" . addtoken($q,"group=$group&setupgroup=1") . "\">set up the host</a> for the SNMP tables you want to monitor.\n";
+ }
+ print "<li>Click on a hostname to operate on or view the information tables associated with that group.\n";
+ print "<li>Click on a red status light below to list the problems found in with a particular host.\n";
+ print "</ul>\n";
+ }
+ displaytable($dbh, 'hostgroups',
+ '-notitle',0,
+ '-clauses', "where (groupname = '$group')",
+ '-select', 'distinct host, sysObjectId, sysDescr, sysUpTime, versionTag',
+ '-datalink', sub { my $q = self_url();
+ my $key = shift;
+ my $h = shift;
+ return if ($key ne "host");
+ return addtoken($q,"host=$h");
+ },
+ '-beginhook',
+ sub {
+ my $q = self_url();
+ my($dbh, $junk, $data) = @_;
+ if (!defined($data)) {
+ print "<th>Status</th>";
+ return;
+ }
+ if (checkhost($dbh, $group, $data->{'host'})) {
+ print "<td><a href=\"" . addtoken($q,"group=$group&summarizehost=1&host=$data->{host}") . "\"><img border=0 src=$NetSNMP::manager::redimage></a></td>\n";
+ } else {
+ print "<td><img src=$NetSNMP::manager::greenimage></td>\n";
+ }
+ }
+ );
+ if (isadmin($dbh, $remuser, $group)) {
+ addhostentryform($group);
+ my $q = self_url();
+ $q =~ s/\?.*//;
+ print "<a href=\"" . addtoken($q,"group=$group&setupgroup=1") . "\">setup group $group</a>\n";
+ }
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# setup the host's history records
+#===========================================================================
+if (param('setuphost')) {
+ print "<title>Net-SNMP history setup for host: $host</title>\n";
+ print "<h2>Net-SNMP history setup for the host: \"$host\"</h2>\n";
+ print "<p>Enter the number of days to keep the data for a given table for the host \"$host\":\n";
+ if (!isexpert($remuser)) {
+ print "<ul>\n";
+ print "<li>Numbers must be greater than or equal to 1 to enable history logging.\n";
+ print "</ul>\n";
+ }
+ print "<form method=post><input type=hidden name=setuphost value=1><input type=hidden name=host value=\"$host\"><input type=hidden name=group value=\"$group\">\n";
+ displaytable($dbh, 'hosttables',
+ '-clauses',"where host = '$host' and groupname = '$group'",
+ '-select','groupname, host, tablename, keephistory',
+ '-selectorder', 1,
+ '-notitle', 1,
+ '-editable', 1,
+ '-indexes', ['groupname','host','tablename'],
+ '-CGI', $CGI::Q
+ );
+ print "<input type=submit value=\"submit changes\">\n";
+ print "</form>\n";
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# display a huge table of history about something
+#===========================================================================
+if (param('displayhistory')) {
+ if (!isuser($dbh, $remuser, $group)) {
+ print "Unauthorized access to that group ($group)\n";
+ return Exit($dbh, $group);
+ }
+ displaytable($dbh, param('table'),
+ '-clauses', "where (host = '$host')",
+ '-dolink', \&linktodisplayinfo,
+ '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'"
+ );
+ return Exit($dbh, $group);
+}
+
+#===========================================================================
+# display inforamation about a host
+# optionally add new collection tables
+#===========================================================================
+showhost($dbh, $host, $group, $remuser);
+if (isadmin($dbh, $remuser, $group)) {
+ if (param('newtables')) {
+ my $x = param('newtables');
+ $x =~ s/,/ /g;
+ if (/[^\w\s]/) {
+ print "<br>Illegal table names in addition list: $x<br>\n"
+ } else {
+ my @x = split(/\s+/,$x);
+ foreach my $i (@x) {
+ $dbh->do("insert into hosttables(host, groupname, tablename, keephistory) values('$host','$group','$i','0')");
+ }
+ print "<br>adding: ",join(", ",@x),"<br>\n";
+ }
+ } else {
+ print "<br>Add new MIB Tables or Groups that you want to collect for this host: <form><input type=hidden name=host value=\"$host\"><input type=hidden name=group value=\"$group\"><input name=\"newtables\" type=text><br><input type=submit value=\"add tables\"></form>\n";
+ }
+ my $q = self_url();
+ $q =~ s/\?.*//;
+ print "<a href=\"" . addtoken($q, "setuphost=1&host=$host&group=$group") . "\">setup host $host</a>\n";
+}
+return Exit($dbh, $group);
+
+#===========================================================================
+# END of handler
+#===========================================================================
+
+}
+
+# add a token to a url string. Use either a ? or an & depending on
+# existence of ?.
+sub addtoken {
+ my $url = shift;
+ my $token = shift;
+ return "$url&$token" if ($url =~ /\?/);
+ return "$url?$token";
+}
+
+#
+# summarizeerrors(DB-HANDLE, CLAUSE):
+# summarize the list of errors in a given CLAUSE
+#
+sub summarizeerrors {
+ my $dbh = shift;
+ my $clause = shift;
+ $clause = "where" if ($clause eq "");
+ my $clause2 = $clause;
+ $clause2 =~ s/ host / hosterrors.host /;
+
+ # Major errors
+ displaytable($dbh, 'hosterrors, hostgroups', # , hostgroups
+ '-select', "hosterrors.host as host, errormsg",
+ '-notitle', 1,
+ '-title', "Fatal Errors",
+ '-clauses', "$clause2 and hosterrors.host = hostgroups.host",
+ '-beginhook', sub {
+ if ($#_ < 2) {
+ #doing header;
+ print "<td></td>";
+ } else {
+ print "<td><img src=\"$NetSNMP::manager::redimage\"></td>\n";
+ }});
+
+ my $tabletop = "<br><table $NetSNMP::manager::tableparms><tr $NetSNMP::manager::headerparms><th><b>Host</b></th><th><b>Table</b></th><th><b>Description</b></th></tr>\n";
+ my $donetop = 0;
+ my $cursor =
+ getcursor($dbh, "SELECT * FROM hosttables $clause");
+
+ while (my $row = $cursor->fetchrow_hashref ) {
+
+ my $exprs = getcursor($dbh, "SELECT * FROM errorexpressions where (tablename = '$row->{tablename}')");
+
+ while (my $expr = $exprs->fetchrow_hashref ) {
+ my $errors = getcursor($dbh, "select * from $row->{tablename} where $expr->{expression} and host = '$row->{host}'");
+ while (my $error = $errors->fetchrow_hashref ) {
+ print $tabletop if ($donetop++ == 0);
+ print "<tr><td>$row->{host}</td><td>$row->{tablename}</td><td>$expr->{returnfield}: $error->{$expr->{returnfield}}</td></tr>";
+ }
+ }
+ }
+ print "</table>";
+}
+
+#
+# getcursor(CMD):
+# genericlly get a cursor for a given sql command, displaying and
+# printing errors where necessary.
+#
+sub getcursor {
+ my $dbh = shift;
+ my $cmd = shift;
+ my $cursor;
+ ( $cursor = $dbh->prepare( $cmd ))
+ or print "\nnot ok: $DBI::errstr\n";
+ ( $cursor->execute )
+ or print( "\tnot ok: $DBI::errstr\n" );
+ return $cursor;
+}
+
+#
+# mykeysort($a, $b)
+# sorts $a and $b against the order in the mib or against the hard
+# coded special list.
+#
+sub mykeysort {
+ my $a = $displaytable::a;
+ my $b = $displaytable::b;
+ my $mb = $SNMP::MIB{SNMP::translateObj($b)};
+ my $ma = $SNMP::MIB{SNMP::translateObj($a)};
+
+ return $NetSNMP::manager::myorder{$a} <=> $NetSNMP::manager::myorder{$b} if ((defined($NetSNMP::manager::myorder{$a}) || !defined($ma->{'subID'})) && (defined($NetSNMP::manager::myorder{$b}) || !defined($mb->{'subID'})));
+ return 1 if (defined($NetSNMP::manager::myorder{$b}) || !defined($mb->{'subID'}));
+ return -1 if (defined($NetSNMP::manager::myorder{$a}) || !defined($ma->{'subID'}));
+
+ $ma->{'subID'} <=> $mb->{'subID'};
+}
+
+#
+# checkhost(GROUP, HOST):
+# if anything in a host is an error, as defined by the
+# errorexpressions table, return 1, else 0
+#
+sub checkhost {
+ my $dbh = shift;
+ my $group = shift;
+ my $host = shift;
+ my ($tblh);
+
+ return 2 if ($dbh->do("select * from hosterrors where host = '$host'") ne "0E0");
+
+ # get a list of tables we want to display
+ $tblh = getcursor($dbh, "SELECT * FROM hosttables where (host = '$host' and groupname = '$group')");
+
+ # table data
+ my($exprs, $tablelist);
+ while ( $tablelist = $tblh->fetchrow_hashref ) {
+ $exprs = getcursor($dbh, "SELECT * FROM errorexpressions where (tablename = '$tablelist->{tablename}')");
+ while(my $expr = $exprs->fetchrow_hashref) {
+ if ($dbh->do("select * from $tablelist->{tablename} where $expr->{expression} and host = '$host'") ne "0E0") {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+#
+# showhost(HOST):
+#
+# display all the tables monitored for a given host (in a group).
+#
+sub showhost {
+ my $dbh = shift;
+ my $host = shift;
+ my $group = shift;
+ my $remuser = shift;
+ my $q = self_url();
+ $q =~ s/\?.*//;
+ # host header
+ print "<title>Net-SNMP manager report for host: $host</title>\n";
+ print "<h2>Monitored information for the host $host</h2>\n";
+ if (!isexpert($remuser)) {
+ print "<ul>\n";
+ print "<li>Click on a column name for information about the data in that column.\n";
+ print "<li>Click on a column name or table name for information about the data in the table.\n";
+ print "<li>If you are <a href=\"" . addtoken($q, "setuphost=1&host=$host&group=$group") . "\">collecting past history</a> for a data set, links will appear below the table that allow you to view and/or graph the historic data.\n";
+ print "</ul>\n";
+ }
+
+ # does the host have a serious error?
+
+ my $errlist = getcursor($dbh, "SELECT * FROM hosterrors where (host = '$host')");
+ if ( $dbh->do("SELECT * FROM hosterrors where (host = '$host')") ne "0E0") {
+ displaytable($dbh, 'hosterrors',
+ '-clauses', "where (host = '$host')",
+ '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'",
+ '-beginhook', sub {
+ if ($#_ < 2) {
+ #doing header;
+ print "<td></td>";
+ } else {
+ print "<td><img src=\"$NetSNMP::manager::redimage\"></td>\n";
+ }});
+ }
+
+ # get a list of tables we want to display
+ my $tblh = getcursor($dbh, "SELECT * FROM hosttables where (host = '$host' and groupname = '$group')");
+
+ # table data
+ my($tablelist);
+ while ( $tablelist = $tblh->fetchrow_hashref ) {
+
+ displaytable($dbh, $tablelist->{'tablename'},
+ '-clauses', "where (host = '$host') order by oidindex",
+ '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'",
+ '-sort', \&mykeysort,
+ '-dolink', \&linktodisplayinfo,
+ '-beginhook', \&printredgreen);
+ if ($tablelist->{'keephistory'}) {
+ my $q = self_url();
+ $q =~ s/\?.*//;
+ print "history: ";
+ print "<a href=\"" . addtoken($q, "displayhistory=1&host=$host&group=$group&table=$tablelist->{'tablename'}hist") . "\">[table]</a>\n";
+ print "<a href=\"" . addtoken($q, "displaygraph=1&host=$host&group=$group&table=$tablelist->{'tablename'}hist") . "\">[graph]</a>\n";
+ print "<br>\n";
+ }
+ }
+}
+
+#
+# linktodisplayinfo(STRING):
+#
+# returns a url to the appropriate displayinfo link if STRING is a
+# mib node.
+#
+sub linktodisplayinfo {
+ return if (exists($NetSNMP::manager::myorder{shift}));
+ return self_url() . "&displayinfo=" . shift;
+}
+
+# printredgreen(TABLENAME, DATA):
+#
+# display a red or a green dot in a table dependent on the table's
+# values and associated expression
+#
+# DATA is NULL when in a header row (displaying header names).
+#
+sub printredgreen {
+ my $dbh = shift;
+ my $tablename = shift;
+ my $data = shift;
+ my ($exprs, $expr, $img);
+
+ if (!defined($data)) {
+ #doing header;
+ print "<td></td>";
+ return;
+ }
+
+ my $cmd = "SELECT * FROM errorexpressions where (tablename = '$tablename')";
+ print " $cmd\n" if ($NetSNMP::manager::verbose);
+ ( $exprs = $dbh->prepare( $cmd ) )
+ or die "\nnot ok: $DBI::errstr\n";
+ ( $exprs->execute )
+ or print( "\tnot ok: $DBI::errstr\n" );
+
+ $img = $NetSNMP::manager::greenimage;
+ while($expr = $exprs->fetchrow_hashref) {
+ if ($dbh->do("select oidindex from $tablename where host = '$data->{host}' and oidindex = '$data->{oidindex}' and $expr->{expression}") ne "0E0") {
+ $img = $NetSNMP::manager::redimage;
+ }
+ }
+ print "<td><img src=$img></td>";
+}
+
+#
+# display information about a given mib node as a table.
+#
+sub makemibtable {
+ my $dispinfo = shift;
+ # display information about a data type in a table
+ my $mib = $SNMP::MIB{SNMP::translateObj($dispinfo)};
+ print "<table $NetSNMP::manager::tableparms><tr><td>\n";
+ foreach my $i (qw(label type access status units hint moduleID description enums)) {
+# foreach my $i (keys(%$mib)) {
+ next if (!defined($$mib{$i}) || $$mib{$i} eq "");
+ next if (ref($$mib{$i}) eq "HASH" && $#{keys(%{$$mib{$i}})} == -1);
+ print "<tr><td>$i</td><td>";
+ if (ref($$mib{$i}) eq "HASH") {
+ print "<table $NetSNMP::manager::tableparms><tr><td>\n";
+ foreach my $j (sort { $$mib{$i}{$a} <=> $$mib{$i}{$b} } keys(%{$$mib{$i}})) {
+ print "<tr><td>$$mib{$i}{$j}</td><td>$j</td></tr>";
+ }
+ print "</table>\n";
+ } else {
+ print "$$mib{$i}";
+ }
+ print "</td></tr>\n";
+ }
+ print "</table>\n";
+}
+
+# given a user, get all the groups he belongs to.
+sub getgroupsforuser {
+ my (@ret, $cursor, $row);
+ my ($dbh, $remuser) = @_;
+ ( $cursor = $dbh->prepare( "SELECT * FROM usergroups where (user = '$remuser')"))
+ or die "\nnot ok: $DBI::errstr\n";
+ ( $cursor->execute )
+ or print( "\tnot ok: $DBI::errstr\n" );
+
+ while ( $row = $cursor->fetchrow_hashref ) {
+ push(@ret, $row->{'groupname'});
+ }
+ @ret;
+}
+
+# given a host, get all the groups it belongs to.
+sub gethostsforgroup {
+ my (@ret, $cursor, $row);
+ my ($dbh, $group) = @_;
+ ( $cursor = $dbh->prepare( "SELECT * FROM hostgroups where (groupname = '$group')"))
+ or die "\nnot ok: $DBI::errstr\n";
+ ( $cursor->execute )
+ or print( "\tnot ok: $DBI::errstr\n" );
+
+ while ( $row = $cursor->fetchrow_hashref ) {
+ push(@ret, $row->{'host'});
+ }
+ @ret;
+}
+
+# display the host add entry box
+sub addhostentryform {
+ my $group = shift;
+ print "<form method=\"get\" action=\"" . self_url() . "\">\n";
+ print "Add a new host to the group \"$group\": <input type=\"text\" name=\"newhost\"><br>";
+ print "<input type=\"hidden\" name=\"group\" value=\"$group\">";
+ print "<input type=submit value=\"Add Hosts\">\n";
+ print "</form>";
+}
+
+#is an expert user?
+sub isexpert {
+ return 0;
+}
+
+#is remuser a admin?
+sub isadmin {
+ my ($dbh, $remuser, $group) = @_;
+ return 0 if (!defined($remuser) || !defined($group));
+ return 1 if ($dbh->do("select * from usergroups where user = '$remuser' and groupname = '$group' and isadmin = 'Y'") ne "0E0");
+ return 0;
+}
+
+#is user a member of this group?
+sub isuser {
+ my ($dbh, $remuser, $group) = @_;
+ return 0 if (!defined($remuser) || !defined($group));
+ return 1 if ($dbh->do("select * from usergroups where user = '$remuser' and groupname = '$group'") ne "0E0");
+ return 0;
+}
+
+# displayconfigarray(HOSTS, NAMES, CONFIG):
+#
+# displays an array of generic check buttons to turn on/off certain
+# variables.
+sub displayconfigarray {
+ my $dbh = shift;
+ my $hosts = shift;
+ my $names = shift;
+ my %config = @_;
+
+ my $cmd;
+ if ($config{'-check'}) {
+ ( $cmd = $dbh->prepare( $config{'-check'} ) )
+ or die "\nnot ok: $DBI::errstr\n";
+ }
+
+ print "<table $NetSNMP::manager::tableparms>\n";
+ print "<tr><td></td>";
+ my ($i, $j);
+ foreach $j (@$names) {
+ my $nj = $j;
+ $nj = $j->[0] if ($config{'-arrayrefs'} || $config{'-arrayref2'});
+ print "<td>$nj</td>";
+ }
+ foreach my $i (@$hosts) {
+ my $ni = $i;
+ $ni = $i->[0] if ($config{'-arrayrefs'} || $config{'-arrayref1'});
+ print "<tr><td>$ni</td>";
+ foreach $j (@$names) {
+ my $nj = $j;
+ $nj = $j->[0] if ($config{'-arrayrefs'} || $config{'-arrayref2'});
+ my $checked = "checked" if (defined($cmd) && $cmd->execute($ni,$nj) ne "0E0");
+ print "<td><input type=checkbox $checked value=y name=" . $config{prefix} . $ni . $nj . "></td>\n";
+ }
+ print "</tr>\n";
+ }
+ print "</tr>";
+ print "</table>";
+}
+
+sub adddefaulttables {
+ my ($dbh, $names) = @_;
+ my $row;
+ # add in known expression tables.
+ my $handle = getcursor($dbh, "SELECT * FROM errorexpressions");
+
+ expr:
+ while($row = $handle->fetchrow_hashref) {
+ foreach $i (@$names) {
+ if ($i->[0] eq $row->{tablename}) {
+ next expr;
+ }
+ }
+ push @$names, [$row->{tablename}];
+ }
+}
+
+#
+# display the setup information page for a given group.
+#
+sub setupgroup {
+ my $dbh = shift;
+ my $group = shift;
+
+ my ($hosts, $names) = gethostandgroups($dbh, $group);
+ adddefaulttables($dbh, $names);
+
+ print "<form method=\"post\" action=\"" . self_url() . "\">\n";
+ print "<input type=hidden text=\"setupgroupsubmit\" value=\"y\">";
+ displayconfigarray($dbh, $hosts, $names,
+ -arrayrefs, 1,
+ -check, "select * from hosttables where (host = ? and tablename = ? and groupname = '$group')");
+ print "<input type=hidden name=group value=\"$group\">\n";
+ print "<input type=submit value=submit name=\"setupgroupsubmit\">\n";
+ print "</form>";
+}
+
+# a wrapper around fetching arrays of everything in a table.
+sub getarrays {
+ my $dbh = shift;
+ my $table = shift;
+ my %config = @_;
+ my $selectwhat = $config{'-select'} || "*";
+ my $handle;
+
+ $handle = getcursor($dbh, "SELECT $selectwhat FROM $table $config{-clauses}");
+ return $handle->fetchall_arrayref;
+}
+
+#
+# get a list of all tablenames and hostnames for a given group.
+#
+sub gethostandgroups {
+ my $dbh = shift;
+ my $group = shift;
+ my ($tbnms);
+
+ my $names = getarrays($dbh, 'hosttables',
+ "-select", 'distinct tablename',
+ "-clauses", "where groupname = '$group'");
+
+ my $hosts = getarrays($dbh, 'hostgroups',
+ "-select", 'distinct host',
+ "-clauses", "where groupname = '$group'");
+
+ return ($hosts, $names);
+}
+
+sub setupgroupsubmit {
+ my $dbh = shift;
+ my $group = shift;
+
+ my ($hosts, $names) = gethostandgroups($dbh, $group);
+ adddefaulttables($dbh, $names);
+
+ foreach my $i (@$hosts) {
+ $dbh->do("delete from hosttables where host = '${$i}[0]' and groupname = '$group'");
+ }
+ my $rep = $dbh->prepare("insert into hosttables(host,tablename,groupname) values(?,?,'$group')");
+
+ foreach my $i (@$hosts) {
+ foreach my $j (@$names) {
+ if (param("${$i}[0]" . "${$j}[0]")) {
+ print "test: ","${$i}[0] : ${$j}[0]<br>\n";
+ $rep->execute("${$i}[0]", "${$j}[0]") || print "$! $DBI::errstr<br>\n";
+ }
+ }
+ }
+
+}
+
+#
+# save user pref data submitted by the user
+#
+sub setupusersubmit {
+ my ($dbh, $remuser, $group) = @_;
+ my $tables = getarrays($dbh, 'hosttables',
+ "-select", 'distinct tablename',
+ "-clauses", "where groupname = '$group'");
+
+ $dbh->do("delete from userprefs where user = '$remuser' and groupname = '$group'");
+ my $rep = $dbh->prepare("insert into userprefs(user, groupname, tablename, columnname, displayit) values('$remuser', '$group', ?, ?, 'N')");
+
+ my ($i, $j);
+ foreach my $i (@$tables) {
+ my $sth = $dbh->prepare("select * from ${$i}[0] where 1 = 0");
+ $sth->execute();
+
+ foreach $j (@{$sth->{NAME}}) {
+ if (param("${$i}[0]" . "$j")) {
+ $rep->execute("${$i}[0]", "$j");
+ }
+ }
+ }
+}
+
+sub Exit {
+ my ($dbh, $group) = @_;
+ my $tq = self_url();
+ $tq =~ s/\?.*//;
+ print "<hr>\n";
+ print "<a href=\"$tq\">[TOP]</a>\n";
+ print "<a href=\"$tq?userprefs=1&group=$group\">[display options]</a>\n";
+ print "<a href=\"$tq?setuponcall=1\">[setup oncall schedule]</a>\n";
+ if (defined($group)) {
+ print "<a href=\"$tq?group=$group\">[group: $group]</a>\n";
+ print "<a href=\"$tq?group=$group&summarizegroup=1\">[summarize errors]</a>\n";
+ }
+ $dbh->disconnect() if (defined($dbh));
+ return OK();
+# exit shift;
+}
+
+#
+# setup user preferences by displaying a configuration array of
+# checkbuttons for each table.
+#
+sub setupuserpreferences {
+ my ($dbh, $remuser, $group) = @_;
+ my $tables = getarrays($dbh, 'hosttables',
+ "-select", 'distinct tablename',
+ "-clauses", "where groupname = '$group'");
+
+ print "<h3>Select the columns from the tables that you want to <b>hide</b> below and click on submit:</h3>\n";
+ print "<form method=\"post\" action=\"" . self_url() . "\">\n";
+
+ my ($i, $j);
+ foreach my $i (@$tables) {
+ my $sth = $dbh->prepare("select * from ${$i}[0] where 1 = 0");
+ $sth->execute();
+ displayconfigarray($dbh, [${$i}[0]], $sth->{NAME},
+ -check, "select * from userprefs where (tablename = ? and columnname = ? and user = '$remuser' and groupname = '$group' and displayit = 'N')");
+ print "<br>\n";
+ }
+ print "<input type=hidden name=group value=\"$group\">\n";
+ print "<input type=submit value=submit name=\"setupuserprefssubmit\">\n";
+ print "</form>";
+}