Initial import from FreeBSD RELENG_4:
[games.git] / contrib / ntp / scripts / support / bin / monl
1 #!/local/bin/perl
2
3 %service = ( 0, "unspec",
4              1, "Active",
5              2, "Passive",
6              3, "Client",
7              4, "Server",
8              5, "Broadcast",
9              6, "Control",
10              7, "Private" );
11 %nc = ();
12 @ignpat = ();
13 $noname = 0;
14 $verbose = 0;
15 $retries = 5;
16 $lastkey = 0;
17
18 sub timedelta {
19   local($tm, $days, $h, $m, $s);
20
21   $tm = @_[$[];
22   $days = 0;
23   $days = sprintf("%dd+", $days) if $days = int($tm / (60*60*24));
24   $days = "" unless $days;
25   $tm = $tm % (60*60*24);
26   $h  = int($tm / (60*60));
27   $tm = $tm % (60*60);
28   $m  = int($tm / 60);
29   $s  = $tm % 60;
30
31   return sprintf("%s%02d:%02d:%02d", $days, $h, $m, $s);
32 }
33
34 sub listentry {
35   local($host, $mode) = split("$;" , @_[$[]);
36   local($count, $version, $firsttime) = split("$;" , $_[$[+1]);
37   local($name);
38
39   if (grep($host =~ m/$_/, @ignpat))
40     {
41       print "ignored $host ...\n" if $verbose;
42       return;
43     }
44
45   return if ! $count;
46
47   if (defined($nc{$host}))
48     {
49       $name = $nc{$host};
50     }
51   else
52     {
53       if ($noname)
54         {
55           $nc{$host} = $name = $host;
56         }
57       else
58         {
59           $name = (gethostbyaddr(pack("C4", split(/\./, $host)), 2))[$[];
60           $nc{$host} = $name = $host if ! defined($name);
61         }
62     }
63
64   printf ($fmt, ($lastkey eq $host) ? "" : $name, $service{$mode}, $count, $version, &timedelta($firsttime), $firsttime / $count);
65
66   if (@_[$[+2])
67     {
68       $hostcnt++ if $lastkey ne $host;
69       $packcnt += $count;
70       $maxtime = $firsttime if $firsttime > $maxtime;
71     }
72
73   $lastkey = $host;
74 }
75
76 while ($ARGV[$[] =~ /^-[nvid]$/)
77   {
78     if ($ARGV[$[] eq "-i")
79       {
80         shift;
81         push(@ignpat, shift) unless ! defined($ARGV[$[]);
82       }
83     elsif ($ARGV[$[] eq "-d")
84       {
85         shift;
86         $dir = shift unless ! defined($ARGV[$[]);
87       }
88     elsif ($ARGV[$[] eq "-n")
89       {
90         shift;
91         $noname = 1;
92       }
93     elsif ($ARGV[$[] eq "-v")
94       {
95         shift;
96         $verbose = 1;
97       }
98   }
99
100 $dir     = "/tmp" unless defined($dir);
101 $gone     = 60*60*48;
102 $fmt = "%48s %10s %7d %7d %13s %14.3f\n";
103 $sfmt = "%48s %10s %7s %7s %13s %14s\n";
104 @lbl = ("Host", "Mode", "Count", "Version", "Time active", "Packetinterval");
105
106 if (!defined($ARGV[$[]))
107   {
108     $hostname = `hostname`;
109     chop($hostname);
110     unshift(@ARGV, $hostname);
111   }
112
113 foreach $hostname (@ARGV)
114   {
115     $dbmfile = $dir . "/monlstats-" . $hostname;
116     $monl = "xntpdc -c 'hostnames no' -c monl $hostname | tail +3 |";
117     $hostcnt = 0;
118     $packcnt = 0;
119     $maxtime = 0;
120     %Seen = ();
121     %New = ();
122     %Old = ();
123
124     print "Monitor Status of $hostname\n\n";
125
126     $cnt = $retries;
127     do
128       {
129         open(MONL, $monl) || die("$monl failed $!");
130         @monlout = <MONL>;
131         close(MONL);
132       } while (! @monlout && $cnt--);
133
134     if (! @monlout)
135       {
136         print "not available.\n";
137         next;
138       }
139
140     dbmopen(Clients, $dbmfile, 0644) || die("dbmopen(.., $dbmfile, ...): $!");
141
142     foreach (@monlout)
143     {
144       chop;
145       split;
146       ($host, $count, $mode, $version, $lasttime, $firsttime) =
147           (@_[$[, $[+2 .. $[+4, $#_-1,$#_]);
148       
149       $Seen{$host, $mode} = 1;
150
151       if (!defined($Clients{$host, $mode}))
152         {
153           if ($lasttime <= $gone)
154             {
155               ## got a new one
156               $Clients{$host, $mode} = $New{$host, $mode} = join("$;", $count, $version, $firsttime, $lasttime);
157             }
158         }
159       else
160         {
161           ## throw out the old ones
162           if ($lasttime > $gone)
163             {
164               $Old{$host, $mode} = $Clients{$host, $mode};
165               delete $Clients{$host, $mode};
166             }
167           else
168             {
169               $Clients{$host, $mode} = join("$;", $count, $version, $firsttime, $lasttime);
170             }
171         }
172     }
173
174     grep(($Seen{$_} || ($Old{$_} = delete $Clients{$_})), keys(%Clients));
175
176     if (grep(($tmp = $_ , !grep($tmp =~ m/$_/, @ignpat)), keys(%New)))
177       {
178         print "New customers\n";
179         print "-------------\n";
180         printf $sfmt, @lbl;
181         grep( &listentry($_, $New{$_}, 1), sort(keys(%New)) );
182         print "\n";
183       }
184
185   
186     if (grep((!defined($New{$_}) && ($tmp = $_, !grep($tmp =~ m/$_/, @ignpat))), keys(%Clients)))
187       {
188         print "Current customers\n";
189         print "-----------------\n";
190         printf $sfmt, @lbl;
191         grep( defined($New{$_}) || &listentry($_, $Clients{$_}, 1) , sort(keys(%Clients)) );
192         print "\n";
193       }
194
195     if (grep(($tmp = $_, !grep($tmp =~ m/$_/, @ignpat)), keys(%Old)))
196       {
197         print "Discarded customers\n";
198         print "-------------------\n";
199         printf $sfmt, @lbl;
200         grep( &listentry($_, $Old{$_}, 0) , sort(keys(%Old)) );
201         print "\n";
202       }
203
204     dbmclose(Clients);
205
206     print "\nSummary:\n";
207     print "--------\n";
208     printf("Elapsed time: %13s\n", &timedelta($maxtime));
209     printf("       Hosts: %13d\n", $hostcnt);
210     printf("     Packets: %13d\n", $packcnt);
211     printf("        Rate: %13.2f\n", $packcnt / $maxtime) if $maxtime;
212     print "\n";
213   }