/[mon-modules]/monshow.cgi
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /monshow.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations)
Thu Oct 3 10:01:22 2002 UTC (21 years, 6 months ago) by dpavlin
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +2 -2 lines
fixed number of pages in title

1 dpavlin 1.1 #!/usr/bin/perl -T
2     #
3     # monshow - concise, user view-based opstatus summary
4     #
5     # Jim Trocki, trockij@transmeta.com
6 dpavlin 1.2 #
7     # Midified to produce WAP (wml) output by
8     # Dobrica Pavlinusic <dpavlin@rot13.org>
9     # http://www.rot13.org/~dpavlin/sysadm.html
10     #
11     # Since it users <b>...</b> tags in wml outout, this script will NOT WORK
12     # on Nokia 7110.
13 dpavlin 1.1 #
14     # $Id: monshow 1.7 Sun, 24 Jun 2001 22:41:40 -0400 trockij $
15     #
16     # Copyright (C) 1998, Jim Trocki
17     #
18     # This program is free software; you can redistribute it and/or modify
19     # it under the terms of the GNU General Public License as published by
20     # the Free Software Foundation; either version 2 of the License, or
21     # (at your option) any later version.
22     #
23     # This program is distributed in the hope that it will be useful,
24     # but WITHOUT ANY WARRANTY; without even the implied warranty of
25     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26     # GNU General Public License for more details.
27     #
28     # You should have received a copy of the GNU General Public License
29     # along with this program; if not, write to the Free Software
30     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31     #
32     use strict "vars";
33    
34     use Getopt::Long;
35     use English;
36     use CGI;
37     use Text::Wrap;
38     use Mon::Client;
39     use Data::Dumper;
40    
41     #
42     # forward declarations
43     #
44     sub usage;
45     sub get_auth;
46     sub read_cf;
47     sub err_die;
48     sub expand_watch;
49     sub secs_to_hms;
50     sub display_allok;
51     sub compose_detail;
52     sub compose_header;
53     sub compose_disabled;
54     sub compose_table;
55     sub compose_trailer;
56     sub get_client_status;
57     sub opstatus_color;
58     sub pre_pad_if_empty;
59     sub tdiff_string;
60    
61     #
62     # set this to the path of your view configuration files
63     #
64     my $VIEWPATH = "/etc/mon/monshow";
65    
66     my %OPSTAT = %Mon::Client::OPSTAT;
67     my $WORD = '[a-zA-Z0-9_-]+';
68     my $OUT_BUF = "";
69     my $e;
70     $= = 1000;
71     $SIG{INT} = \&handle_sig;
72     $SIG{TERM} = \&handle_sig;
73    
74     # safe $PATH for taint mode
75     $ENV{PATH} = '/usr/local/bin:/usr/bin:/bin';
76    
77     my ($DEP, $GROUP, $SERVICE, $STATUS, $TIME, $NEXT, $ALERTS, $SUMMARY, $DESC);
78    
79     # Untaint args, tainting is just for stuff which comes from CGI.
80     for (@ARGV) {
81     /(.*)/s or die;
82     $_ = $1;
83     }
84    
85     my %opt;
86     GetOptions (\%opt, "showall", "auth", "help", "full", "disabled",
87     "rcfile=s", "login=s", "server=s", "port=i", "prot=s",
88     "detail=s", "view=s") || usage;
89    
90     @ARGV == 0 || usage "No non-switch args expected\n";
91    
92 dpavlin 1.2 my $WAP = 1; # force wap output
93    
94 dpavlin 1.1 my $CGI;
95     my %QUERY_ARGS;
96     if (defined $ENV{"REQUEST_METHOD"})
97     {
98     unless ($CGI = new CGI)
99     {
100     $CGI = 1;
101     err_die ("Can't create CGI object\n");
102     }
103     }
104    
105     if (!$CGI && $opt{"help"})
106     {
107     usage;
108     }
109    
110     if ($CGI)
111     {
112     foreach my $e (split (/\?/, $ENV{"QUERY_STRING"}))
113     {
114     next if ($e !~ /=/);
115    
116     my ($var, $val) = split (/=/, $e);
117    
118     $QUERY_ARGS{$var} = $val;
119     }
120     }
121    
122     my $CF = {
123     "host" => "localhost",
124     "full" => 0,
125     "show-disabled" => 0,
126     "bg" => "d5d5d5",
127     "bg-ok" => "a0d0a0",
128     "bg-fail" => "e088b7",
129     "bg-untested" => "e0e0e0",
130     "table-color" => "cccccc",
131     "summary-len" => 20,
132     };
133    
134     my $GLOBAL = {
135     "view-name" => undef,
136     };
137    
138     #
139     # read config file
140     #
141     my ($e, $what) = read_cf ($CF);
142    
143     if ($e ne "")
144     {
145     err_die ("while reading config file, $e");
146     }
147    
148     #
149     # cmdline args override config file
150     #
151     if (!$CGI)
152     {
153     $CF->{"all"} = 1 if ($opt{"showall"});
154     $CF->{"full"} = 1 if ($opt{"full"});
155     $CF->{"detail"} = $opt{"detail"} if ($opt{"detail"} ne "");
156     $CF->{"host"} = $opt{"server"} if ($opt{"server"});
157     $CF->{"port"} = $opt{"port"} if ($opt{"port"});
158     $CF->{"prot"} = $opt{"prot"} if ($opt{"prot"});
159     }
160    
161     #
162     # retrieve client status
163     #
164     my ($e, $st) = get_client_status ($what);
165    
166     if ($e ne "")
167     {
168     err_die ($e);
169     }
170    
171     expand_watch ($what, $st);
172    
173     my $rows = select_table ($what, $st);
174    
175     compose_header ($st->{"state"});
176    
177     #
178     # CGI invocation
179     #
180     if ($CGI)
181     {
182     if ($QUERY_ARGS{"disabled"})
183     {
184     compose_disabled ($st->{"disabled"});
185     }
186    
187     elsif (!$QUERY_ARGS{"detail"})
188     {
189     compose_table ($rows, $st);
190    
191     compose_disabled ($st->{"disabled"}) if ($CF->{"show-disabled"});
192     }
193    
194     elsif ($QUERY_ARGS{"detail"})
195     {
196     compose_detail ($QUERY_ARGS{"detail"}, $st);
197     }
198     }
199    
200     #
201     # cmdline invocation
202     #
203     else
204     {
205     if ($opt{"disabled"})
206     {
207     compose_disabled ($st->{"disabled"});
208     }
209    
210     elsif ($CF->{"detail"} ne "")
211     {
212     compose_detail ($CF->{"detail"}, $st);
213     }
214    
215     else
216     {
217     compose_table ($rows, $st);
218    
219     compose_disabled ($st->{"disabled"}) if ($CF->{"show-disabled"});
220     }
221     }
222    
223     compose_trailer;
224    
225 dpavlin 1.2 if ($WAP) {
226     print <<EOF;
227     Content-type: text/vnd.wap.wml
228    
229     $OUT_BUF
230     EOF
231     }
232     elsif ($CGI)
233 dpavlin 1.1 {
234     print <<EOF;
235     Content-type: text/html
236    
237     $OUT_BUF
238     EOF
239     }
240    
241     else
242     {
243     print "\n";
244     }
245    
246     exit;
247    
248     #-----------------------------------------------------------------------------
249    
250     format STDOUT_TOP =
251    
252     GROUP SERVICE STATUS LAST NEXT ALERTS SUMMARY
253     .
254    
255    
256     #
257     # usage
258     #
259     sub usage
260     {
261     print STDERR @_, <<EOF;
262    
263     usage: monshow [--auth] [--showall] [--full] [--login user] [--disabled]
264     [--server host] [--port num] [--rcfile file]
265     [--detail group,service] [--view name]
266     --showall do not read rcfile and show opstatus of all services
267     --full show disabled, failures, successes, and untested
268     --detail g,s show detail (alert acks, etc.) for group,service
269     --view name display a pre-defined view
270     --auth authenticate to mon server
271     --disabled show disabled
272     --prot ver set protocol version, must match 1.2.3 format
273     --login user use "login" as username while authenticating
274     --server host use "host" as monhost, instead of MONHOST
275     --port num use "num" as port number instead of default
276     --rcfile file use "file" as config file instead of \$HOME/.monshowrc
277    
278     EOF
279    
280     exit 1;
281     }
282    
283    
284     #
285     # signal handler
286     #
287     sub handle_sig
288     {
289     system "stty echo" unless ($CGI);
290     exit;
291     }
292    
293    
294     #
295     # get auth info
296     #
297     # returns a list "error", "login", "password"
298     #
299     sub get_auth
300     {
301     my ($login, $pass);
302    
303     if ($CGI)
304     {
305     $login = $CGI->query ("login");
306     $pass = $CGI->query ("password");
307     }
308    
309     else
310     {
311     if ($opt{"login"})
312     {
313     $login = $opt{"login"};
314     }
315    
316     else
317     {
318     return "could not determine username"
319     if (!defined ($login = getpwuid($EUID)));
320     }
321    
322     if (-t STDIN)
323     {
324     system "stty -echo";
325     print "Password: ";
326     chop ($pass = <STDIN>);
327     print "\n";
328     system "stty echo";
329     return "invalid password" if ($pass =~ /^\s*$/);
330     }
331    
332     else
333     {
334     my $cmd;
335    
336     while (defined ($cmd = <>))
337     {
338     chomp $cmd;
339     if ($cmd =~ /^user=(\S+)$/i)
340     {
341     $login = $1;
342     }
343    
344     elsif ($cmd =~ /^pass=(\S+)$/i)
345     {
346     $pass = $1;
347     }
348    
349     last if (defined ($login) && defined ($pass));
350     }
351     }
352     }
353    
354     return "inadequate authentication information supplied"
355     if ($login eq "" || $pass eq "");
356    
357     return ("", $login, $pass);
358     }
359    
360     #
361     # config file
362     #
363     sub read_cf
364     {
365     my $CF = shift;
366    
367     my ($group, $service);
368     my @RC;
369     my $view = 0;
370    
371     my $RC = "/etc/mon/monshowrc";
372    
373     if ($CGI)
374     {
375     if ($ENV{"PATH_INFO"} =~ /^\/\S+/)
376     {
377     my $p=$ENV{"PATH_INFO"};
378     $p =~ s/^[.\/]*//;
379     $p =~ s/\/*$//;
380     $p =~ s/\.\.//g;
381     $RC = "$VIEWPATH/$p";
382     $GLOBAL->{"view-name"} = $p;
383     $view = 1;
384     }
385    
386     elsif ($QUERY_ARGS{"view"} ne "")
387     {
388     $QUERY_ARGS{"view"} =~ s/^[.\/]*//;
389     $QUERY_ARGS{"view"} =~ s/\.\.//g;
390     $GLOBAL->{"view-name"} = $QUERY_ARGS{"view"};
391     $RC = "$VIEWPATH/$QUERY_ARGS{view}";
392     $view = 1;
393     }
394    
395     elsif (-f ".monshowrc")
396     {
397     $RC = ".monshowrc";
398     }
399     }
400    
401     else
402     {
403     if ($opt{"rcfile"})
404     {
405     $RC = $opt{"rcfile"};
406     }
407    
408     elsif ($opt{"view"} ne "")
409     {
410     $RC = "$VIEWPATH/$opt{view}";
411     $GLOBAL->{"view-name"} = $opt{"view"};
412     $view = 1;
413     }
414    
415     elsif (-f "$ENV{HOME}/.monshowrc")
416     {
417     $RC = "$ENV{HOME}/.monshowrc";
418     }
419     }
420    
421     if ($opt{"old"})
422     {
423     $CF->{"prot"} = "0.37.0";
424     $CF->{"port"} = 32777;
425     }
426    
427     if (-f $RC)
428     {
429     open (IN, $RC) || return "could not read $RC: $!";
430    
431     my $html_header = 0;
432     my $link_text = 0;
433     my $link_group = "";
434     my $link_service = "";
435    
436     while (<IN>)
437     {
438     next if (/^\s*#/ || /^\s*$/);
439    
440     if ($html_header)
441     {
442     if (/^END\s*$/)
443     {
444     $html_header = 0;
445     next;
446     }
447    
448     else
449     {
450     $CF->{"html-header"} .= $_;
451     next;
452     }
453     }
454    
455     elsif ($link_text)
456     {
457     if (/^END\s*$/)
458     {
459     $link_text = 0;
460     next;
461     }
462    
463     else
464     {
465     $CF->{"links"}->{$link_group}->{$link_service}->{"link-text"} .= $_;
466     next;
467     }
468     }
469    
470     else
471     {
472     chomp;
473     s/^\s*//;
474     s/\s*$//;
475     }
476    
477     if (/^set \s+ (\S+) \s* (\S+)?/ix)
478     {
479     my $cmd = $1;
480     my $arg = $2;
481     if ($cmd eq "show-disabled") { }
482     elsif ($cmd eq "host") { }
483     elsif ($cmd eq "prot") { }
484     elsif ($cmd eq "port") { }
485     elsif ($cmd eq "full") { }
486     elsif ($cmd eq "bg") { }
487     elsif ($cmd eq "bg-ok") { }
488     elsif ($cmd eq "bg-fail") { }
489     elsif ($cmd eq "bg-untested") { }
490     elsif ($cmd eq "table-color") { }
491     elsif ($cmd eq "html-header") { $html_header = 1; next; }
492     elsif ($cmd eq "refresh") { }
493     elsif ($cmd eq "summary-len") { }
494     else
495     {
496     print STDERR "unknown set, line $.\n";
497     next;
498     }
499    
500     if ($arg ne "")
501     {
502     $CF->{$cmd} = $arg;
503     }
504    
505     else
506     {
507     $CF->{$cmd} = 1;
508     }
509     }
510    
511     elsif (/^watch \s+ (\S+)/x)
512     {
513     push (@RC, [$1]);
514     }
515    
516     elsif (/^service \s+ (\S+) \s+ (\S+)/x)
517     {
518     push (@RC, [$1, $2]);
519     }
520    
521     elsif (/^link \s+ (\S+) \s+ (\S+) \s+ (.*)\s*/ix)
522     {
523     $CF->{"links"}->{$1}->{$2}->{"link"} = $3;
524     }
525    
526     elsif (/^link-text \s+ (\S+) \s+ (\S+)/ix)
527     {
528     $link_text = 1;
529     $link_group = $1;
530     $link_service = $2;
531     next;
532     }
533    
534     else
535     {
536     my $lnum = $.;
537     close (IN);
538     err_die ("error in config file, line $.");
539     }
540     }
541     close (IN);
542     }
543    
544     elsif (! -f $RC && $view)
545     {
546     err_die ("no view found");
547     }
548    
549     return ("", \@RC);
550     }
551    
552    
553     sub secs_to_hms
554     {
555     my ($s) = @_;
556     my ($dd, $hh, $mm, $ss);
557    
558     $dd = int ($s / 86400);
559     $s -= $dd * 86400;
560    
561     $hh = int ($s / 3600);
562     $s -= $hh * 3600;
563    
564     $mm = int ($s / 60);
565     $s -= $mm * 60;
566    
567     $ss = $s;
568    
569     if ($dd == 0)
570     {
571     sprintf("%02d:%02d", $hh, $mm);
572     }
573    
574     else
575     {
576     sprintf("%d days, %02d:%02d", $dd, $hh, $mm);
577     }
578     }
579    
580    
581     #
582     # exit displaying error in appropriate output format
583     #
584     sub err_die
585     {
586     my $msg = shift;
587    
588 dpavlin 1.2 if ($WAP) {
589     print <<EOF;
590     Content-type: text/vnd.wap.wml
591    
592     <?xml version="1.0"?>
593     <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
594     <wml>
595     <card id="error" title="Error">
596     <p>
597     $msg
598     </p>
599     </card>
600     </wml>
601     EOF
602     }
603     elsif ($CGI)
604 dpavlin 1.1 {
605     print <<EOF;
606     Content-type: text/html
607    
608     <html>
609     <head>
610     <title> Error </title>
611     </head>
612     <body>
613     <h2> Error </h2>
614     <pre>
615     $msg
616     </pre>
617     </body>
618     </html>
619     EOF
620     }
621    
622     else
623     {
624     print <<EOF;
625     Error: $msg
626    
627     EOF
628     }
629    
630     exit 1;
631     }
632    
633    
634     #
635     # everything is cool
636     #
637     sub display_allok
638     {
639     if ($CGI)
640     {
641 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
642 dpavlin 1.1 <h2> All systems OK </h2>
643     <p>
644    
645     EOF
646 dpavlin 1.2 $OUT_BUF .= "<b> All systems OK </b>" if ($WAP);
647 dpavlin 1.1 }
648    
649     else
650     {
651     print "\nAll systems OK\n";
652     }
653     }
654    
655    
656     #
657     # client status
658     #
659     # return ("", $state, \%opstatus, \%disabled, \%deps, \%groups, \%descriptions);
660     #
661     sub get_client_status {
662     my $what = shift;
663    
664     my $cl;
665    
666     if (!defined ($cl = Mon::Client->new))
667     {
668     return "could not create client object: $@";
669     }
670    
671     my ($username, $pass);
672    
673     if ($opt{"auth"} && !$CGI)
674     {
675     my $e;
676     ($e, $username, $pass) = get_auth;
677     if ($e ne "")
678     {
679     return "$e";
680     }
681     $cl->username ($username);
682     $cl->password ($pass);
683     }
684    
685     $cl->host ($CF->{"host"}) if (defined $CF->{"host"});
686     $cl->port ($CF->{"port"}) if (defined $CF->{"port"});
687     $cl->port ($CF->{"prot"}) if (defined $CF->{"prot"});
688    
689     $cl->connect;
690    
691     if ($cl->error) {
692     return "Could not connect to server: " . $cl->error;
693     }
694    
695     #
696     # authenticate self to the server if necessary
697     #
698     if ($opt{"auth"} && !defined ($cl->login)) {
699     my $e = $cl->error;
700     $cl->disconnect;
701     return "Could authenticate: $e";
702     }
703    
704     #
705     # get disabled things
706     #
707     my %disabled = $cl->list_disabled;
708     if ($cl->error) {
709     my $e = $cl->error;
710     $cl->disconnect;
711     return "could not get disabled: $e";
712     }
713    
714     #
715     # get state
716     #
717     my ($running, $t) = $cl->list_state;
718     if ($cl->error) {
719     my $e = $cl->error;
720     $cl->disconnect;
721     return "could not get state: $e";
722     }
723    
724     my $state;
725     if ($running) {
726     $state = $t;
727     }
728    
729     else
730     {
731     $state = "scheduler stopped since " . localtime ($t);
732     }
733    
734     #
735     # group/service list
736     #
737     my @watch = $cl->list_watch;
738    
739     if ($cl->error) {
740     my $e = $cl->error;
741     $cl->disconnect;
742     return "could not get opstatus: $e";
743     }
744    
745     #
746     # get opstatus
747     #
748     my %opstatus;
749     if (@{$what} == 0)
750     {
751     %opstatus = $cl->list_opstatus;
752     if ($cl->error) {
753     my $e = $cl->error;
754     $cl->disconnect;
755     return "could not get opstatus: $e";
756     }
757     }
758    
759     else
760     {
761     my @list;
762     foreach my $r (@{$what})
763     {
764     if (@{$r} == 2)
765     {
766     push @list, $r;
767     }
768    
769     else
770     {
771     foreach my $w (@watch)
772     {
773     next if ($r->[0] ne $w->[0]);
774     push @list, $w;
775     }
776     }
777     }
778    
779     %opstatus = $cl->list_opstatus (@list);
780     if ($cl->error) {
781     my $e = $cl->error;
782     $cl->disconnect;
783     return "could not get opstatus: $e";
784     }
785     }
786    
787     #
788     # dependencies
789     #
790     my %deps;
791     if ($opt{"deps"}) {
792     %deps = $cl->list_deps;
793     if ($cl->error) {
794     my $e = $cl->error;
795     $cl->disconnect;
796     return "could not list deps: $e";
797     }
798     }
799    
800     #
801     # descriptions
802     #
803     my %desc;
804     %desc = $cl->list_descriptions;
805     if ($cl->error) {
806     my $e = $cl->error;
807     $cl->disconnect;
808     return "could not list descriptions: $e";
809     }
810    
811     #
812     # groups
813     #
814     my %groups;
815    
816     if ($QUERY_ARGS{"detail"} || $CF->{"detail"} ne "")
817     {
818     foreach my $g (keys %opstatus)
819     {
820     my @g = $cl->list_group ($g);
821     if ($cl->error)
822     {
823     my $e = $cl->error;
824     $cl->disconnect;
825     return "could not list group: $e";
826     }
827    
828     grep {s/\*//} @g;
829     $groups{$g} = [@g];
830     }
831     }
832    
833     #
834     # log out
835     #
836     if (!defined $cl->disconnect) {
837     return "error while disconnecting: " . $cl->error;
838     }
839    
840    
841     return ("", {
842     "state" => $state,
843     "opstatus" => \%opstatus,
844     "disabled" => \%disabled,
845     "deps" => \%deps,
846     "groups" => \%groups,
847     "desc" => \%desc,
848     "watch" => \@watch,
849     });
850     }
851    
852    
853     sub compose_header {
854     my $state = shift;
855    
856     my $t = localtime;
857    
858     #
859     # HTML stuff
860     #
861     if ($CGI)
862     {
863 dpavlin 1.2 $OUT_BUF = <<EOF if (! $WAP);
864 dpavlin 1.1 <html>
865     <head>
866     <title> Operational Status </title>
867     EOF
868    
869 dpavlin 1.2 $OUT_BUF = <<EOF if ($WAP);
870     <?xml version="1.0"?>
871     <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
872     <wml>
873     EOF
874    
875 dpavlin 1.1 if ($CF->{"refresh"})
876     {
877 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
878 dpavlin 1.1 <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
879     <META HTTP-EQUIV="Refresh" CONTENT=$CF->{refresh}>
880     EOF
881     }
882    
883 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
884 dpavlin 1.1 </head>
885     <body bgcolor="#$CF->{'bg'}">
886     EOF
887    
888     if ($CF->{"html-header"} ne "")
889     {
890 dpavlin 1.2 $OUT_BUF .= $CF->{"html-header"} if (! $WAP);
891 dpavlin 1.1 }
892    
893 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
894 dpavlin 1.1 <h1><FONT FACE="sans-serif">Operational Status</font></h1>
895    
896     <table width="100%">
897     <tr>
898     <td>
899     <table>
900     <tr>
901     <td align=right><b>Server:</b></td>
902     <td> $CF->{host} </td>
903     </tr>
904     <tr>
905     <td align=right><b>Time:</b></td>
906     <td> $t </td>
907     </tr>
908     <tr>
909     <td align=right><b>State:</b></td>
910     <td> $state </td>
911     </tr>
912     EOF
913    
914 dpavlin 1.2 # skip overview card if detail page is used or next page navigation
915     $OUT_BUF .= <<EOF if ($WAP && !$QUERY_ARGS{"detail"} && !$QUERY_ARGS{"p"});
916     <card id="status" title="Operational Status" ontimer="#display">
917     <timer value="10"/>
918     <p>
919     <b>Server:</b> $CF->{host}
920     <br/><b>Time:</b> $t
921     <br/><b>State:</b> $state
922     </p>
923     <p><a href="#display">Display status</a></p>
924     </card>
925     EOF
926    
927 dpavlin 1.1 if ($GLOBAL->{"view-name"} ne "")
928     {
929 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
930 dpavlin 1.1 <tr>
931     <td align=right><b>View:</b></td>
932     <td><b>$GLOBAL->{"view-name"}</b></td>
933     </tr>
934     EOF
935 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
936     <b>View:</b> $GLOBAL->{"view-name"}
937     EOF
938 dpavlin 1.1 }
939    
940 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
941 dpavlin 1.1 </table>
942     </td>
943    
944     <td>
945     <table>
946     <tr>
947     <td><FONT FACE="sans-serif">Color legend</FONT></td>
948     </tr>
949     <tr>
950     <td bgcolor="#$CF->{'bg-ok'}"> all is OK </td>
951     </tr>
952     <tr>
953     <td bgcolor="#$CF->{'bg-fail'}"> failure </td>
954     </tr>
955     <tr>
956     <td bgcolor="#$CF->{'bg-untested'}"> untested </td>
957     </tr>
958     </table>
959     </td>
960     </tr>
961     </table>
962     <p>
963     <hr>
964     EOF
965 dpavlin 1.2
966 dpavlin 1.1 }
967    
968     else
969     {
970     print <<EOF;
971    
972     server: $CF->{host}
973     time: $t
974     state: $state
975     EOF
976     }
977     }
978    
979    
980     sub select_table {
981     my ($what, $st) = @_;
982    
983     my @rows;
984    
985     #
986     # display everything real nice
987     #
988     if ($CF->{"all"} || @{$what} == 0)
989     {
990     foreach my $group (keys %{$st->{"opstatus"}})
991     {
992     foreach my $service (keys %{$st->{"opstatus"}->{$group}})
993     {
994     push (@rows, [$group, $service]);
995     }
996     }
997     }
998    
999     else
1000     {
1001     @rows = @{$what};
1002     }
1003    
1004     my (%DEP, %DEPROOT);
1005    
1006     foreach my $l (@rows)
1007     {
1008     my ($group, $service) = @{$l};
1009    
1010     my $sref = \%{$st->{"opstatus"}->{$group}->{$service}};
1011    
1012     next if (!defined $sref->{"opstatus"});
1013    
1014     #
1015     # disabled things
1016     #
1017     # fuckin' Perl, man. Just be referencing
1018     # $st->{"disabled"}->{"watches"}->{$group}, perl automagically
1019     # defines that hash element for you. Great.
1020     #
1021     if (defined ($st->{"disabled"}->{"watches"}) &&
1022     defined ($st->{"disabled"}->{"watches"}->{$group}))
1023     {
1024     next;
1025     }
1026    
1027     elsif (defined ($st->{"disabled"}->{"services"}) &&
1028     defined ($st->{"disabled"}->{"services"}->{$group}) &&
1029     defined ($st->{"disabled"}->{"services"}->{$service}))
1030     {
1031     next;
1032     }
1033    
1034     #
1035     # potential root dependencies
1036     #
1037     elsif ($sref->{"depend"} eq "")
1038     {
1039     push (@{$DEPROOT{$sref->{"opstatus"}}}, ["R", $group, $service]);
1040     }
1041    
1042     #
1043     # things which have dependencies
1044     #
1045     else
1046     {
1047     push (@{$DEP{$sref->{"opstatus"}}}, ["D", $group, $service]);
1048     }
1049     }
1050    
1051     if ($CF->{"full"})
1052     {
1053     [
1054     @{$DEPROOT{$OPSTAT{"fail"}}},
1055     @{$DEPROOT{$OPSTAT{"linkdown"}}},
1056     @{$DEPROOT{$OPSTAT{"timeout"}}},
1057     @{$DEPROOT{$OPSTAT{"coldstart"}}},
1058     @{$DEPROOT{$OPSTAT{"warmstart"}}},
1059     @{$DEPROOT{$OPSTAT{"untested"}}},
1060     @{$DEPROOT{$OPSTAT{"unknown"}}},
1061    
1062     @{$DEP{$OPSTAT{"fail"}}},
1063     @{$DEP{$OPSTAT{"linkdown"}}},
1064     @{$DEP{$OPSTAT{"timeout"}}},
1065     @{$DEP{$OPSTAT{"coldstart"}}},
1066     @{$DEP{$OPSTAT{"warmstart"}}},
1067    
1068     @{$DEPROOT{$OPSTAT{"ok"}}},
1069     @{$DEP{$OPSTAT{"ok"}}},
1070     @{$DEP{$OPSTAT{"untested"}}},
1071     @{$DEP{$OPSTAT{"unknown"}}},
1072     ];
1073     }
1074    
1075     else
1076     {
1077     [
1078     @{$DEPROOT{$OPSTAT{"fail"}}},
1079     @{$DEPROOT{$OPSTAT{"linkdown"}}},
1080     @{$DEPROOT{$OPSTAT{"timeout"}}},
1081     @{$DEPROOT{$OPSTAT{"coldstart"}}},
1082     @{$DEPROOT{$OPSTAT{"warmstart"}}},
1083    
1084     @{$DEP{$OPSTAT{"fail"}}},
1085     @{$DEP{$OPSTAT{"linkdown"}}},
1086     @{$DEP{$OPSTAT{"timeout"}}},
1087     @{$DEP{$OPSTAT{"coldstart"}}},
1088     @{$DEP{$OPSTAT{"warmstart"}}},
1089     ];
1090     }
1091     }
1092    
1093    
1094     #
1095     # build the table
1096     #
1097     sub compose_table {
1098     my ($rows, $st) = @_;
1099    
1100     if (@{$rows} == 0)
1101     {
1102     display_allok;
1103     return;
1104     }
1105    
1106     #
1107     # display the failure table
1108     #
1109     if ($CGI)
1110     {
1111 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1112 dpavlin 1.1
1113     <table cellpadding=2 cellspacing=1 bgcolor="#$CF->{'table-color'}" width="100%">
1114     <tr>
1115     <th><FONT FACE="sans-serif">Dep</FONT></th>
1116     <th><FONT FACE="sans-serif">Group</FONT></th>
1117     <th><FONT FACE="sans-serif">Service</FONT></th>
1118     <th><FONT FACE="sans-serif">Desc.</FONT></th>
1119     <th><FONT FACE="sans-serif">Last check</FONT></th>
1120     <th><FONT FACE="sans-serif">Next check</FONT></th>
1121     <th><FONT FACE="sans-serif">Alerts</FONT></th>
1122     <th><FONT FACE="sans-serif">Status</FONT></th>
1123     <th><FONT FACE="sans-serif">Summary</FONT></th>
1124     </tr>
1125    
1126     EOF
1127     }
1128    
1129 dpavlin 1.2 my @wml;
1130    
1131 dpavlin 1.1 foreach my $l (@{$rows})
1132     {
1133     my ($depstate, $group, $service) = @{$l};
1134    
1135     my $sref = \%{$st->{"opstatus"}->{$group}->{$service}};
1136    
1137     $STATUS = "unknown";
1138     $TIME = "";
1139     $DEP = $depstate;
1140     my $last = "";
1141     my $bgcolor = opstatus_color ($sref->{"opstatus"});
1142    
1143     if ($sref->{"opstatus"} == $OPSTAT{"untested"})
1144     {
1145     $STATUS = "untested";
1146     $TIME = "untested";
1147     }
1148    
1149     elsif ($sref->{"opstatus"} == $OPSTAT{"ok"})
1150     {
1151     $STATUS = "-";
1152     }
1153    
1154     elsif ($sref->{"opstatus"} == $OPSTAT{"fail"})
1155     {
1156     if ($sref->{"ack"})
1157     {
1158     if ($CGI) {
1159     $STATUS = "<a href=\"$ENV{SCRIPT_NAME}?detail=$group,$service\">" .
1160     "<b>ACK FAIL</b></a>";
1161     } else {
1162     $STATUS = "ACK FAIL";
1163     }
1164     }
1165    
1166     else
1167     {
1168     $STATUS = "FAIL";
1169     }
1170     }
1171    
1172     if ($depstate eq "")
1173     {
1174     $DEP = "-";
1175     }
1176    
1177     $GROUP = $group;
1178     $SERVICE = $service;
1179     $DESC = $st->{"desc"}->{$group}->{$service};
1180    
1181     $DESC = pre_pad_if_empty ($DESC) if ($CGI);
1182    
1183    
1184     if ($TIME eq "")
1185     {
1186     $TIME = tdiff_string (time - $sref->{"last_check"});
1187     }
1188    
1189     if ($sref->{"timer"} < 60)
1190     {
1191     $NEXT = "$sref->{timer}s";
1192     }
1193    
1194     else
1195     {
1196     $NEXT = secs_to_hms ($sref->{"timer"});
1197     }
1198    
1199     if (length ($sref->{"last_summary"}) > $CF->{"summary-len"})
1200     {
1201     $SUMMARY = substr ($sref->{"last_summary"}, 0, $CF->{"summary-len"}) . "...";
1202     }
1203    
1204     else
1205     {
1206     $SUMMARY = $sref->{"last_summary"};
1207     }
1208    
1209    
1210     $ALERTS = $sref->{"alerts_sent"} || "none";
1211    
1212     my $fmt;
1213     if (!$CGI)
1214     {
1215     $fmt = <<EOF;
1216     format STDOUT =
1217     @ @<<<<<<<<<<<<<< @<<<<<<<<<<< @<<<<<<<<< @<<<<<<< @<<<<<<<<< @<<< @
1218     EOF
1219     chomp $fmt;
1220     $fmt .= "<" x length($SUMMARY) . "\n";
1221     $fmt .= <<'EOF';
1222     $DEP, $GROUP, $SERVICE, $STATUS, $TIME, $NEXT, $ALERTS, $SUMMARY
1223     .
1224     EOF
1225     eval $fmt;
1226     write;
1227     }
1228    
1229     else
1230     {
1231 dpavlin 1.2 if (! $WAP)
1232 dpavlin 1.1 {
1233 dpavlin 1.2 if ($SUMMARY =~ /^[\s\n]*$/)
1234     {
1235     $SUMMARY = "<pre> </pre>";
1236     }
1237 dpavlin 1.1
1238 dpavlin 1.2 else
1239     {
1240     $SUMMARY = "<small>$SUMMARY</small>";
1241     }
1242 dpavlin 1.1
1243 dpavlin 1.2 if ($bgcolor ne "")
1244     {
1245     $bgcolor = "bgcolor=\"#$bgcolor\"";
1246     }
1247 dpavlin 1.1 }
1248 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1249 dpavlin 1.1
1250     <tr $bgcolor>
1251     <td> $DEP </td>
1252     <td> $GROUP </td>
1253     <td> <a href="$ENV{SCRIPT_NAME}?detail=$group,$service">$SERVICE</a> </td>
1254     <td> <small>$DESC</small> </td>
1255     <td> $TIME </td>
1256     <td> $NEXT </td>
1257     <td> $ALERTS </td>
1258     <td> $STATUS </td>
1259     <td> $SUMMARY </td>
1260     </tr>
1261     EOF
1262    
1263 dpavlin 1.2 # dump just failuers to wap mobile
1264     if ($WAP) {
1265     if ($sref->{"opstatus"} == $OPSTAT{"fail"}) {
1266     push @wml,<<EOF;
1267     <p>
1268     <b>$GROUP
1269     <a href="$ENV{SCRIPT_NAME}?detail=$group,$service">$SERVICE</a></b>
1270     $TIME/$NEXT
1271     <b>$STATUS</b>
1272     $SUMMARY
1273     </p>
1274     EOF
1275     } else {
1276     push @wml,<<EOF;
1277     <p>
1278     $GROUP
1279     <a href="$ENV{SCRIPT_NAME}?detail=$group,$service">$SERVICE</a>
1280     </p>
1281     EOF
1282    
1283     }
1284     }
1285    
1286 dpavlin 1.1 }
1287     }
1288    
1289     if ($CGI)
1290     {
1291 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1292 dpavlin 1.1 </table>
1293    
1294     EOF
1295 dpavlin 1.2 # generate page-by-page output
1296     my $on_page=10;
1297 dpavlin 1.3 my $max_page=int(($#wml + $on_page) / $on_page) - 1;
1298 dpavlin 1.2
1299     if ($WAP) {
1300     my $p = $QUERY_ARGS{"p"} || 1; # current page
1301    
1302     $OUT_BUF .= "<card id=\"display\" title=\"Monitoring $p/$max_page\">";
1303     for (my $i = 0; $i < $on_page; $i++) {
1304     $OUT_BUF .= $wml[$i + ($p-1) * $on_page];
1305     }
1306     # navigation
1307     $OUT_BUF .= "<p>";
1308 dpavlin 1.3 for (my $i = 1; $i <= $max_page; $i++) {
1309 dpavlin 1.2 if ($i == $p) {
1310     $OUT_BUF .= "<b>$i</b> ";
1311     } else {
1312     $OUT_BUF .= "<a href=\"$ENV{SCRIPT_NAME}?p=$i\">$i</a> ";
1313     }
1314     }
1315     $OUT_BUF .= "</p>";
1316    
1317     $OUT_BUF .= "</card>";
1318     }
1319 dpavlin 1.1 }
1320     }
1321    
1322    
1323     sub compose_disabled {
1324     my $disabled = shift;
1325    
1326     if (!keys %{$disabled->{"watches"}} &&
1327     !keys %{$disabled->{"services"}} &&
1328     !keys %{$disabled->{"hosts"}})
1329     {
1330     if ($CGI)
1331     {
1332     $OUT_BUF .= <<EOF;
1333 dpavlin 1.2 <br/>
1334 dpavlin 1.1 Nothing is disabled.
1335     EOF
1336 dpavlin 1.2 $OUT_BUF .= "<p>" if (! $WAP);
1337 dpavlin 1.1 }
1338    
1339     else
1340     {
1341     print "\nNothing is disabled.\n";
1342     }
1343    
1344     return;
1345     }
1346    
1347     if (keys %{$disabled->{"watches"}})
1348     {
1349     if ($CGI)
1350     {
1351 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1352 dpavlin 1.1
1353     <h2> Disabled Watches </h2>
1354    
1355     EOF
1356 dpavlin 1.2
1357     $OUT_BUF .= "<b> Disabled Watches </b>" if ($WAP);
1358    
1359 dpavlin 1.1 }
1360    
1361     else
1362     {
1363     print "\nDISABLED WATCHES:\n";
1364     }
1365    
1366     foreach my $watch (keys %{$disabled->{"watches"}})
1367     {
1368     if ($CGI)
1369     {
1370 dpavlin 1.2 $OUT_BUF .= "$watch <br/>\n";
1371 dpavlin 1.1 }
1372    
1373     else
1374     {
1375     print "$watch\n";
1376     }
1377     }
1378     }
1379    
1380     my @disabled_services;
1381     foreach my $watch (keys %{$disabled->{"services"}})
1382     {
1383     foreach my $service (keys %{$disabled->{"services"}{$watch}})
1384     {
1385     push (@disabled_services, "$watch $service");;
1386     }
1387     }
1388    
1389     if (@disabled_services)
1390     {
1391     if ($CGI)
1392     {
1393     $OUT_BUF .= <<EOF;
1394    
1395     <h2> Disabled Services </h2>
1396    
1397     EOF
1398 dpavlin 1.2
1399     $OUT_BUF .= "<b> Disabled Services </b>" if ($WAP);
1400    
1401 dpavlin 1.1 }
1402    
1403     else
1404     {
1405     print "\nDISABLED SERVICES\n";
1406     }
1407     for (@disabled_services)
1408     {
1409     if ($CGI)
1410     {
1411 dpavlin 1.2 $OUT_BUF .= "$_ <br/>\n";
1412 dpavlin 1.1 }
1413    
1414     else
1415     {
1416     print "$_\n";
1417     }
1418     }
1419     }
1420    
1421     if (keys %{$disabled->{"hosts"}})
1422     {
1423     if ($CGI)
1424     {
1425 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1426 dpavlin 1.1
1427     <h2> Disabled Hosts </h2>
1428    
1429     EOF
1430 dpavlin 1.2 $OUT_BUF .= <<EOF if ($WAP);
1431    
1432     <p><b> Disabled Hosts </b></p>
1433    
1434     EOF
1435 dpavlin 1.1 }
1436    
1437     else
1438     {
1439     print "\nDISABLED HOSTS:\n";
1440     }
1441     foreach my $group (keys %{$disabled->{"hosts"}})
1442     {
1443     my @HOSTS = ();
1444     foreach my $host (keys %{$disabled->{"hosts"}{$group}})
1445     {
1446     push (@HOSTS, $host);
1447     }
1448     if ($CGI)
1449     {
1450 dpavlin 1.2 $OUT_BUF .= sprintf ("%-15s %s <br/>\n", $group, "@HOSTS");
1451 dpavlin 1.1 }
1452    
1453     else
1454     {
1455     printf ("%-15s %s\n", $group, "@HOSTS");
1456     }
1457     }
1458     }
1459     }
1460    
1461    
1462     sub compose_trailer {
1463     if ($CGI)
1464     {
1465 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1466 dpavlin 1.1 </body>
1467     </html>
1468     EOF
1469 dpavlin 1.2 $OUT_BUF .= <<EOF if ($WAP);
1470     </wml>
1471     EOF
1472 dpavlin 1.1 }
1473     }
1474    
1475    
1476     sub compose_detail {
1477     my ($args, $st) = @_;
1478    
1479 dpavlin 1.2 my ($group, $service, $optarg) = split (/,/, $args, 3);
1480 dpavlin 1.1
1481     if (!defined ($st->{"opstatus"}->{$group}->{$service}))
1482     {
1483     err_die ("$group/$service not a valid service");
1484     }
1485    
1486     my $sref = \%{$st->{"opstatus"}->{$group}->{$service}};
1487    
1488     my $d;
1489    
1490     my $bgcolor = opstatus_color ($sref->{"opstatus"});
1491    
1492     $bgcolor = "bgcolor=\"#$bgcolor\"" if ($bgcolor ne "");
1493    
1494     foreach my $k (keys %OPSTAT)
1495     {
1496     if ($OPSTAT{$k} == $sref->{"opstatus"})
1497     {
1498     $sref->{"opstatus"} = "$k ($sref->{opstatus})";
1499     last;
1500     }
1501     }
1502    
1503     foreach my $k (qw (opstatus exitval last_check timer ack ackcomment))
1504     {
1505 dpavlin 1.2 if ($CGI && !$WAP && $sref->{$k} =~ /^\s*$/)
1506 dpavlin 1.1 {
1507     $d->{$k} = "<pre> </pre>";
1508     }
1509    
1510     else
1511     {
1512     $d->{$k} = $sref->{$k};
1513     }
1514     }
1515    
1516     my $t = time;
1517    
1518     $d->{"last_check"} = tdiff_string ($t - $d->{"last_check"}) . " ago";
1519     $d->{"timer"} = "in " . tdiff_string ($d->{"timer"});
1520    
1521     foreach my $k (qw (last_success last_failure first_failure last_alert))
1522     {
1523     if ($sref->{$k})
1524     {
1525     $d->{$k} = localtime ($sref->{$k});
1526     }
1527     }
1528    
1529     if ($sref->{"first_failure"})
1530     {
1531     $d->{"failure_duration"} = secs_to_hms ($sref->{"failure_duration"});
1532     }
1533    
1534    
1535     #
1536     # HTML output
1537     #
1538     if ($CGI)
1539     {
1540     my $sum = pre_pad_if_empty ($sref->{"last_summary"});
1541     my $descr = pre_pad_if_empty ($st->{"desc"}->{$group}->{$service});
1542     my $hosts = pre_pad_if_empty ("@{$st->{groups}->{$group}}");
1543    
1544 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1545 dpavlin 1.1
1546     <h2><FONT FACE="sans-serif">Detail for $group/$service</font></h2>
1547    
1548     <table width="100%">
1549     <tr $bgcolor>
1550     <td align=right width="15%"> <b> Description: </b> <td> $descr
1551     <tr $bgcolor>
1552     <td align=right width="15%"> <b> Summary: </b> <td> $sum
1553     <tr $bgcolor>
1554     <td align=right width="15%"> <b> Hosts: </b> <td> $hosts
1555     <tr $bgcolor>
1556     <td valign=top align=right width="15%"> <b> Detail: </b>
1557     <td>
1558     <pre>
1559     $sref->{last_detail}
1560     </pre>
1561     </table>
1562     EOF
1563 dpavlin 1.2 my $wml = <<EOF;
1564     <p><b>Description:</b> $descr</p>
1565     <p><b>Summary:</b> $sum</p>
1566     <p><b>Hosts:</b> $hosts</p>
1567     <p><b>Detail: </b>
1568     EOF
1569     my $wml_detail = "no detail -- bug!";
1570     if ($WAP) {
1571     if ($optarg eq "full") {
1572     $wml_detail = $sref->{last_detail};
1573     } elsif (length $sref->{last_detail} > 200) {
1574     $wml .= substr($sref->{last_detail},0,200) . "... [<a href=\"$ENV{SCRIPT_NAME}?detail=$group,$service,full\">more</a>]";
1575     } else {
1576     $wml .= $sref->{last_detail};
1577     }
1578     }
1579     $wml .= "</p>";
1580 dpavlin 1.1
1581     if ($d->{"ack"}) {
1582     my $comment = pre_pad_if_empty ($d->{"ackcomment"});
1583    
1584 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1585 dpavlin 1.1 <table width="100%">
1586     <tr>
1587     <td align=right width="15%"> <h2>Acknowledgment of failure</h2> </td>
1588     <tr>
1589     <td align=right width="15%"> $comment
1590     </table>
1591    
1592     EOF
1593 dpavlin 1.2 $wml .= <<EOF if ($WAP);
1594     <p><b>Acknowledgment of failure</b>: $comment</p>
1595     EOF
1596 dpavlin 1.1 }
1597    
1598 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1599 dpavlin 1.1 <table cellpadding=2 cellspacing=1 bgcolor="#CCCCCC" width="100%">
1600     EOF
1601 dpavlin 1.2 $wml .= <<EOF if ($WAP);
1602     <p>
1603     EOF
1604 dpavlin 1.1
1605     #
1606     # 0 = nothing special
1607     # 1 = do not display if zero
1608     # 2 = do not display if eq ""
1609     #
1610     foreach my $k (
1611     ["opstatus", "Operational Status", 0],
1612     ["exitval", "Exit Value", 0],
1613     ["depend", "Dependency", 2],
1614     ["monitor", "Monitor Program", 2],
1615     ["last_check", "Last Check", 2],
1616     ["timer", "Next Check", 2],
1617     ["last_success", "Last Success", 2],
1618     ["last_failure", "Last Failure", 2],
1619     ["first_failure", "First Failure", 2],
1620     ["failure_duration", "Failure Duration", 2],
1621     ["interval", "Schedule Interval", 0],
1622     ["exclude_period", "Exclude Period", 2],
1623     ["exclude_hosts", "Exclude Hosts", 2],
1624     ["randskew", "Random Skew", 1],
1625     ["alerts_sent", "Alerts Sent", 1],
1626     ["last_alert", "Last Alert", 2])
1627     {
1628     my $v = undef;
1629    
1630     if ($d->{$k->[0]} ne "") {
1631     $v = \$d->{$k->[0]};
1632    
1633     } elsif ($sref->{$k->[0]} ne "") {
1634     $v = \$sref->{$k->[0]};
1635     }
1636    
1637     next if ($k->[2] == 1 && $$v == 0);
1638     next if ($k->[2] == 2 && $$v eq "");
1639    
1640 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1641 dpavlin 1.1 <tr>
1642     <td align=right width="15%"><b>$k->[1]:</b></td>
1643     <td> $$v </td>
1644     EOF
1645 dpavlin 1.2 $wml .= "<br/><b>$k->[1]:</b> $$v" if ($WAP);
1646 dpavlin 1.1 }
1647    
1648 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1649 dpavlin 1.1 </table>
1650 dpavlin 1.2 EOF
1651     $wml .= <<EOF if ($WAP);
1652     </p>
1653 dpavlin 1.1 EOF
1654    
1655     #
1656     # custom links
1657     #
1658     if (defined ($CF->{"links"}->{$group}->{$service}))
1659     {
1660     if (defined ($CF->{"links"}->{$group}->{$service}->{"link-text"}))
1661     {
1662 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1663 dpavlin 1.1 <p>
1664     <h2><a href=\"$CF->{links}->{$group}->{$service}->{link}\">More Information</a></h2>
1665     $CF->{links}->{$group}->{$service}->{'link-text'}
1666    
1667     EOF
1668 dpavlin 1.2 $wml .= <<EOF if ($WAP);
1669     <p>
1670     <b><a href=\"$CF->{links}->{$group}->{$service}->{link}\">More Information</a></b>
1671     $CF->{links}->{$group}->{$service}->{'link-text'}
1672     </p>
1673     EOF
1674 dpavlin 1.1 }
1675    
1676     else
1677     {
1678 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1679     <p>
1680     <a href="$CF->{links}->{$group}->{$service}->{link}">$CF->{links}->{$group}->{$service}->{link}</a>
1681    
1682     EOF
1683     $wml .= <<EOF if ($WAP);
1684 dpavlin 1.1 <p>
1685     <a href="$CF->{links}->{$group}->{$service}->{link}">$CF->{links}->{$group}->{$service}->{link}</a>
1686 dpavlin 1.2 </p>
1687 dpavlin 1.1
1688     EOF
1689     }
1690     }
1691    
1692 dpavlin 1.2 $OUT_BUF .= <<EOF if (! $WAP);
1693 dpavlin 1.1 <p>
1694     <a href="$ENV{SCRIPT_NAME}">Back to summary table</a>
1695     <p>
1696    
1697     EOF
1698 dpavlin 1.2 # dump out wml
1699     if ($optarg eq "full") {
1700     $wml_detail =~ s/[\n\r]+/<br\/>/g;
1701     $wml = "<p>$wml_detail</p>";
1702     }
1703    
1704     $OUT_BUF .= <<EOF if ($WAP);
1705     <card id="display" title="Detail for $group/$service">
1706     $wml
1707     <do type="prev" label="Back to summary table"><prev/></do>
1708     </card>
1709     EOF
1710 dpavlin 1.1 }
1711    
1712     #
1713     # text output
1714     #
1715     else
1716     {
1717     my $n;
1718     $Text::Wrap::columns = 70;
1719     $n->{"desc"} = wrap (" ", " ", $st->{"desc"}->{$group}->{$service});
1720     $n->{"last_summary"} = wrap (" ", " ", $sref->{"last_summary"});
1721     $n->{"hosts"} = wrap (" ", " ", join (" ", @{$st->{groups}->{$group}}));
1722    
1723     print <<EOF;
1724    
1725     Detail for group $group service $service
1726    
1727     description
1728     -----------
1729     $n->{desc}
1730     summary
1731     -------
1732     $n->{last_summary}
1733     hosts
1734     -----
1735     $n->{hosts}
1736    
1737     -----DETAIL-----
1738     $sref->{last_detail}
1739     -----DETAIL-----
1740    
1741     EOF
1742     if ($d->{"ack"})
1743     {
1744     print <<EOF;
1745     alert ack: $d->{ackcomment}
1746    
1747     EOF
1748     }
1749    
1750     print <<EOF;
1751     opstatus: $d->{opstatus}
1752     exitval: $d->{exitval}
1753     depend: $d->{depend}
1754     monitor: $d->{monitor}
1755     last check: $d->{last_check}
1756     next_check: $d->{timer}
1757    
1758     EOF
1759     }
1760     }
1761    
1762    
1763     sub opstatus_color {
1764     my $o = shift;
1765    
1766     my %color_hash = (
1767     $OPSTAT{"untested"} => $CF->{"bg-untested"},
1768     $OPSTAT{"ok"} => $CF->{"bg-ok"},
1769     $OPSTAT{"fail"} => $CF->{"bg-fail"},
1770     );
1771    
1772     $color_hash{$o} || "";
1773     }
1774    
1775    
1776     sub tdiff_string {
1777     my $time = shift;
1778    
1779     my $s;
1780    
1781     if ($time <= 90)
1782     {
1783     $s = "${time}s";
1784     }
1785    
1786     else
1787     {
1788     $s = secs_to_hms ($time);
1789     }
1790     }
1791    
1792    
1793     #
1794     # for each watch entry which specifies only "group",
1795     # expand it into "group service"
1796     #
1797     sub expand_watch {
1798     my $what = shift;
1799     my $st = shift;
1800    
1801     for (my $i=0; $i<@{$what}; $i++)
1802     {
1803     if (@{$what->[$i]} == 1)
1804     {
1805     my @list;
1806     foreach my $l (@{$st->{"watch"}})
1807     {
1808     if ($l->[0] eq $what->[$i]->[0])
1809     {
1810     push @list, $l;
1811     }
1812     }
1813     splice (@{$what}, $i, 1, @list);
1814     }
1815     }
1816     }
1817    
1818    
1819     sub pre_pad_if_empty
1820     {
1821     my $l = shift;
1822    
1823 dpavlin 1.2 return "<pre> </pre>" if ($l =~ /^\s*$/ && !$WAP);
1824 dpavlin 1.1 $l;
1825     }

  ViewVC Help
Powered by ViewVC 1.1.26