/[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

Contents of /monshow.cgi

Parent Directory Parent Directory | Revision Log Revision Log


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

1 #!/usr/bin/perl -T
2 #
3 # monshow - concise, user view-based opstatus summary
4 #
5 # Jim Trocki, trockij@transmeta.com
6 #
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 #
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 my $WAP = 1; # force wap output
93
94 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 if ($WAP) {
226 print <<EOF;
227 Content-type: text/vnd.wap.wml
228
229 $OUT_BUF
230 EOF
231 }
232 elsif ($CGI)
233 {
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 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 {
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 $OUT_BUF .= <<EOF if (! $WAP);
642 <h2> All systems OK </h2>
643 <p>
644
645 EOF
646 $OUT_BUF .= "<b> All systems OK </b>" if ($WAP);
647 }
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 $OUT_BUF = <<EOF if (! $WAP);
864 <html>
865 <head>
866 <title> Operational Status </title>
867 EOF
868
869 $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 if ($CF->{"refresh"})
876 {
877 $OUT_BUF .= <<EOF if (! $WAP);
878 <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
879 <META HTTP-EQUIV="Refresh" CONTENT=$CF->{refresh}>
880 EOF
881 }
882
883 $OUT_BUF .= <<EOF if (! $WAP);
884 </head>
885 <body bgcolor="#$CF->{'bg'}">
886 EOF
887
888 if ($CF->{"html-header"} ne "")
889 {
890 $OUT_BUF .= $CF->{"html-header"} if (! $WAP);
891 }
892
893 $OUT_BUF .= <<EOF if (! $WAP);
894 <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 # 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 if ($GLOBAL->{"view-name"} ne "")
928 {
929 $OUT_BUF .= <<EOF if (! $WAP);
930 <tr>
931 <td align=right><b>View:</b></td>
932 <td><b>$GLOBAL->{"view-name"}</b></td>
933 </tr>
934 EOF
935 $OUT_BUF .= <<EOF if (! $WAP);
936 <b>View:</b> $GLOBAL->{"view-name"}
937 EOF
938 }
939
940 $OUT_BUF .= <<EOF if (! $WAP);
941 </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
966 }
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 $OUT_BUF .= <<EOF if (! $WAP);
1112
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 my @wml;
1130
1131 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 if (! $WAP)
1232 {
1233 if ($SUMMARY =~ /^[\s\n]*$/)
1234 {
1235 $SUMMARY = "<pre> </pre>";
1236 }
1237
1238 else
1239 {
1240 $SUMMARY = "<small>$SUMMARY</small>";
1241 }
1242
1243 if ($bgcolor ne "")
1244 {
1245 $bgcolor = "bgcolor=\"#$bgcolor\"";
1246 }
1247 }
1248 $OUT_BUF .= <<EOF if (! $WAP);
1249
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 # 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 }
1287 }
1288
1289 if ($CGI)
1290 {
1291 $OUT_BUF .= <<EOF if (! $WAP);
1292 </table>
1293
1294 EOF
1295 # generate page-by-page output
1296 my $on_page=10;
1297 my $max_page=int(($#wml + $on_page) / $on_page) - 1;
1298
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 for (my $i = 1; $i <= $max_page; $i++) {
1309 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 }
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 <br/>
1334 Nothing is disabled.
1335 EOF
1336 $OUT_BUF .= "<p>" if (! $WAP);
1337 }
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 $OUT_BUF .= <<EOF if (! $WAP);
1352
1353 <h2> Disabled Watches </h2>
1354
1355 EOF
1356
1357 $OUT_BUF .= "<b> Disabled Watches </b>" if ($WAP);
1358
1359 }
1360
1361 else
1362 {
1363 print "\nDISABLED WATCHES:\n";
1364 }
1365
1366 foreach my $watch (keys %{$disabled->{"watches"}})
1367 {
1368 if ($CGI)
1369 {
1370 $OUT_BUF .= "$watch <br/>\n";
1371 }
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
1399 $OUT_BUF .= "<b> Disabled Services </b>" if ($WAP);
1400
1401 }
1402
1403 else
1404 {
1405 print "\nDISABLED SERVICES\n";
1406 }
1407 for (@disabled_services)
1408 {
1409 if ($CGI)
1410 {
1411 $OUT_BUF .= "$_ <br/>\n";
1412 }
1413
1414 else
1415 {
1416 print "$_\n";
1417 }
1418 }
1419 }
1420
1421 if (keys %{$disabled->{"hosts"}})
1422 {
1423 if ($CGI)
1424 {
1425 $OUT_BUF .= <<EOF if (! $WAP);
1426
1427 <h2> Disabled Hosts </h2>
1428
1429 EOF
1430 $OUT_BUF .= <<EOF if ($WAP);
1431
1432 <p><b> Disabled Hosts </b></p>
1433
1434 EOF
1435 }
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 $OUT_BUF .= sprintf ("%-15s %s <br/>\n", $group, "@HOSTS");
1451 }
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 $OUT_BUF .= <<EOF if (! $WAP);
1466 </body>
1467 </html>
1468 EOF
1469 $OUT_BUF .= <<EOF if ($WAP);
1470 </wml>
1471 EOF
1472 }
1473 }
1474
1475
1476 sub compose_detail {
1477 my ($args, $st) = @_;
1478
1479 my ($group, $service, $optarg) = split (/,/, $args, 3);
1480
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 if ($CGI && !$WAP && $sref->{$k} =~ /^\s*$/)
1506 {
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 $OUT_BUF .= <<EOF if (! $WAP);
1545
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 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
1581 if ($d->{"ack"}) {
1582 my $comment = pre_pad_if_empty ($d->{"ackcomment"});
1583
1584 $OUT_BUF .= <<EOF if (! $WAP);
1585 <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 $wml .= <<EOF if ($WAP);
1594 <p><b>Acknowledgment of failure</b>: $comment</p>
1595 EOF
1596 }
1597
1598 $OUT_BUF .= <<EOF if (! $WAP);
1599 <table cellpadding=2 cellspacing=1 bgcolor="#CCCCCC" width="100%">
1600 EOF
1601 $wml .= <<EOF if ($WAP);
1602 <p>
1603 EOF
1604
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 $OUT_BUF .= <<EOF if (! $WAP);
1641 <tr>
1642 <td align=right width="15%"><b>$k->[1]:</b></td>
1643 <td> $$v </td>
1644 EOF
1645 $wml .= "<br/><b>$k->[1]:</b> $$v" if ($WAP);
1646 }
1647
1648 $OUT_BUF .= <<EOF if (! $WAP);
1649 </table>
1650 EOF
1651 $wml .= <<EOF if ($WAP);
1652 </p>
1653 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 $OUT_BUF .= <<EOF if (! $WAP);
1663 <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 $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 }
1675
1676 else
1677 {
1678 $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 <p>
1685 <a href="$CF->{links}->{$group}->{$service}->{link}">$CF->{links}->{$group}->{$service}->{link}</a>
1686 </p>
1687
1688 EOF
1689 }
1690 }
1691
1692 $OUT_BUF .= <<EOF if (! $WAP);
1693 <p>
1694 <a href="$ENV{SCRIPT_NAME}">Back to summary table</a>
1695 <p>
1696
1697 EOF
1698 # 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 }
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 return "<pre> </pre>" if ($l =~ /^\s*$/ && !$WAP);
1824 $l;
1825 }

  ViewVC Help
Powered by ViewVC 1.1.26