1ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#!/usr/bin/perl
2ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
3ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# dnslist - Read state file from dnsmasq and create a nice web page to display
4ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#           a list of DHCP clients.
5ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
6ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Copyright (C) 2004  Thomas Tuttle
7ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
8ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# This program is free software; you can redistribute it and/or modify
9ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# it under the terms of the GNU General Public License as published by
10ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# the Free Software Foundation; either version 2 of the License, or
11ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# (at your option) any later version.
12ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
13ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# This program is distributed in the hope that it will be useful,
14ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# but WITHOUT ANY WARRANTY; without even the implied warranty of
15ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# GNU General Public License for more details.
17ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
18ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# You should have received a copy of the GNU General Public License
19ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# along with this program*; if not, write to the Free Software
20ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
22ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# * The license is in fact included at the end of this file, and can
23ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#   either be viewed by reading everything after "__DATA__" or by
24ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#   running dnslist with the '-l' option.
25ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
26ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Version: 0.2
27ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Author:  Thomas Tuttle
28ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Email:   dnslist.20.thinkinginbinary@spamgourmet.org
29ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# License: GNU General Public License, version 2.0
30ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
31ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# v. 0.0: Too ugly to publish, thrown out.
32ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
33ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# v. 0.1: First rewrite.
34ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#         Added master host list so offline hosts can still be displayed.
35ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#         Fixed modification detection (a newer modification time is lower.)
36ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
37ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# v. 0.2: Fixed Client ID = "*" => "None"
38ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#         Fixed HTML entities (a client ID of ????<? screwed it up)
39ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#         Fixed command-line argument processing (apparently, "shift @ARGV" !=
40ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#             "$_ = shift @ARGV"...)
41ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#         Added license information.
42ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
43ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatuse Template;
44ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
45ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Location of state file.  (This is the dnsmasq default.)
46ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Change with -s <file>
47ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmy $dnsmasq_state_file = '/var/lib/misc/dnsmasq.leases';
48ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Location of template.  (Assumed to be in current directory.)
49ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Change with -t <file>
50ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmy $html_template_file = 'dnslist.tt2';
51ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# File to write HTML page to.  (This is where Slackware puts WWW pages.  It may
52ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# be different on other systems.  Make sure the permissions are set correctly
53ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# for it.)
54ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmy $html_output_file = '/var/www/htdocs/dhcp.html';
55ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Time to wait after each page update.  (The state file is checked for changes
56ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# before each update but is not read in each time, in case it is very big.  The
57ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# page is rewritten just so the "(updated __/__ __:__:__)" text changes ;-)
58ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmy $wait_time = 2;
59ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
60ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Read command-line arguments.
61ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatwhile ($_ = shift @ARGV) {
62ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if (/-s/) { $dnsmasq_state_file = shift; next; }
63ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if (/-t/) { $html_template_file = shift; next; }
64ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if (/-o/) { $html_output_file = shift;   next; }
65ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if (/-d/) { $wait_time = shift;          next; }
66ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if (/-l/) { show_license();              exit; }
67ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	die "usage: dnslist [-s state_file] [-t template_file] [-o output_file] [-d delay_time]\n";
68ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
69ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
70ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Master list of clients, offline and online.
71ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmy $list = {};
72ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Sorted host list.  (It's actually sorted by IP--the sub &byip() compares two
73ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# IP addresses, octet by octet, and figures out which is higher.)
74ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmy @hosts = ();
75ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Last time the state file was changed.
76ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmy $last_state_change;
77ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
78ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Check for a change to the state file.
79ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsub check_state {
80ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if (defined $last_state_change) {
81ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		if (-M $dnsmasq_state_file < $last_state_change) {
82ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			print "check_state: state file has been changed.\n";
83ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			$last_state_change = -M $dnsmasq_state_file;
84ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			return 1;
85ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		} else {
86ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			return 0;
87ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		}
88ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	} else {
89ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		# Last change undefined, so we are running for the first time.
90ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		print "check_state: reading state file at startup.\n";
91ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		read_state();
92ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$last_state_change = -M $dnsmasq_state_file;
93ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		return 1;
94ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
95ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
96ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
97ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Read data in state file.
98ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsub read_state {
99ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my $old;
100ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my $new;
101ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Open file.
102ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	unless (open STATE, $dnsmasq_state_file) {
103ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		warn "read_state: can't open $dnsmasq_state_file!\n";
104ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		return 0;
105ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
106ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Mark all hosts as offline, saving old state.
107ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	foreach $ether (keys %{$list}) {
108ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'old_online'} = $list->{$ether}->{'online'};
109ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'online'} = 0;
110ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
111ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Read hosts.
112ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	while (<STATE>) {
113ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		chomp;
114ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		@host{qw/raw_lease ether_addr ip_addr hostname raw_client_id/} = split /\s+/;
115ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$ether = $host{ether_addr};
116ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		# Mark each online host as online.
117ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'online'} = 1;
118ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		# Copy data to master list.
119ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		foreach $key (keys %host) {
120ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			$list->{$ether}->{$key} = $host{$key};
121ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		}
122ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
123ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	close STATE;
124ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Handle changes in offline/online state.  (The sub &do_host() handles
125ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# all of the extra stuff to do with a host's data once it is read.
126ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	foreach $ether (keys %{$list}) {
127ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$old = $list->{$ether}->{'old_online'};
128ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$new = $list->{$ether}->{'online'};
129ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		if (not $old) {
130ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			if (not $new) {
131ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat				do_host($ether, 'offline');
132ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			} else {
133ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat				do_host($ether, 'join');
134ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			}
135ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		} else {
136ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			if (not $new) {
137ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat				do_host($ether, 'leave');
138ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			} else {
139ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat				do_host($ether, 'online');
140ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			}
141ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		}
142ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
143ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Sort hosts by IP ;-)
144ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	@hosts = sort byip values %{$list};
145ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Copy sorted list to template data store.
146ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	$data->{'hosts'} = [ @hosts ];
147ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
148ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
149ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Do stuff per host.
150ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsub do_host {
151ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my ($ether, $status) = @_;
152ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
153ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Find textual representation of DHCP client ID.
154ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if ($list->{$ether}->{'raw_client_id'} eq '*') {
155ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'text_client_id'} = 'None';
156ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	} else {
157ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		my $text = "";
158ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		foreach $char (split /:/, $list->{$ether}->{'raw_client_id'}) {
159ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			$char = pack('H2', $char);
160ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			if (ord($char) >= 32 and ord($char) <= 127) {
161ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat				$text .= $char;
162ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			} else {
163ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat				$text .= "?";
164ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			}
165ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		}
166ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'text_client_id'} = $text;
167ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
168ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
169ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Convert lease expiration date/time to text.
170ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if ($list->{$ether}->{'raw_lease'} == 0) {
171ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'text_lease'} = 'Never';
172ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	} else {
173ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'text_lease'} = nice_time($list->{$ether}->{'raw_lease'});
174ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
175ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
176ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if ($status eq 'offline') {
177ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		# Nothing to do.
178ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	} elsif ($status eq 'online') {
179ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		# Nothing to do.
180ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	} elsif ($status eq 'join') {
181ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		# Update times for joining host.
182ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		print "do_host: $ether joined the network.\n";
183ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'join_time'} = time;
184ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'since'} = nice_time(time);
185ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	} elsif ($status eq 'leave') {
186ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		# Update times for leaving host.
187ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		print "do_host: $ether left the network.\n";
188ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'leave_time'} = time;
189ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$list->{$ether}->{'since'} = nice_time(time);
190ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
191ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
192ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
193ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
194ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Convert time to a string representation.
195ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsub nice_time {
196ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my $time = shift;
197ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime($time);
198ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	$sec = pad($sec, '0', 2);
199ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	$min = pad($min, '0', 2);
200ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	$hour = pad($hour, '0', 2);
201ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	$mon = pad($mon, '0', 2);
202ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	$mday = pad($mday, '0', 2);
203ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	return "$mon/$mday $hour:$min:$sec";
204ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
205ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
206ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Pad string to a certain length by repeatedly prepending another string.
207ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsub pad {
208ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my ($text, $pad, $length) = @_;
209ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	while (length($text) < $length) {
210ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$text = "$pad$text";
211ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
212ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	return $text;
213ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
214ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
215ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Compare two IP addresses.  (Uses $a and $b from sort.)
216ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsub byip {
217ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Split into octets.
218ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my @a = split /\./, $a->{ip_addr};
219ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my @b = split /\./, $b->{ip_addr};
220ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Compare octets.
221ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	foreach $n (0..3) {
222ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		return $a[$n] <=> $b[$n] if ($a[$n] != $b[$n]);
223ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
224ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# If we get here there is no difference.
225ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	return 0;
226ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
227ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
228ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Output HTML file.
229ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsub write_output {
230ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Create new template object.
231ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	my $template = Template->new(
232ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		{
233ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			ABSOLUTE => 1, # /var/www/... is an absolute path
234ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			OUTPUT => $html_output_file # put it here, not STDOUT
235ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		}
236ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	);
237ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	$data->{'updated'} = nice_time(time); # add "(updated ...)" to file
238ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	unless ($template->process($html_template_file, $data)) { # do it
239ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		warn "write_output: Template Toolkit error: " . $template->error() . "\n";
240ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		return 0;
241ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
242ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	print "write_output: page updated.\n";
243ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	return 1;
244ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
245ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
246ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsub show_license {
247ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	while (<DATA>) {
248ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		print;
249ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		$line++;
250ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		if ($line == 24) { <>; $line = 1; }
251ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
252ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
253ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
254ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# Main loop.
255ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatwhile (1) {
256ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	# Check for state change.
257ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if (check_state()) {
258ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		read_state();
259ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		sleep 1; # Sleep for a second just so we don't wear anything
260ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		         # out.  (By not sleeping the whole time after a change
261ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			 # we can detect rapid changes more easily--like if 300
262ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			 # hosts all come back online, they show up quicker.)
263ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	} else {
264ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		sleep $wait_time; # Take a nap.
265ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	}
266ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	write_output(); # Write the file anyway.
267ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat}
268ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat__DATA__
269ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		    GNU GENERAL PUBLIC LICENSE
270ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		       Version 2, June 1991
271ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
272ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat Copyright (C) 1989, 1991 Free Software Foundation, Inc.
273ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
274ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat Everyone is permitted to copy and distribute verbatim copies
275ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat of this license document, but changing it is not allowed.
276ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
277ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			    Preamble
278ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
279ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  The licenses for most software are designed to take away your
280ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatfreedom to share and change it.  By contrast, the GNU General Public
281ffd68729961f7383f2e35494a03ccdef20f86c98San MehatLicense is intended to guarantee your freedom to share and change free
282ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsoftware--to make sure the software is free for all its users.  This
283ffd68729961f7383f2e35494a03ccdef20f86c98San MehatGeneral Public License applies to most of the Free Software
284ffd68729961f7383f2e35494a03ccdef20f86c98San MehatFoundation's software and to any other program whose authors commit to
285ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatusing it.  (Some other Free Software Foundation software is covered by
286ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthe GNU Library General Public License instead.)  You can apply it to
287ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatyour programs, too.
288ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
289ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  When we speak of free software, we are referring to freedom, not
290ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatprice.  Our General Public Licenses are designed to make sure that you
291ffd68729961f7383f2e35494a03ccdef20f86c98San Mehathave the freedom to distribute copies of free software (and charge for
292ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthis service if you wish), that you receive source code or can get it
293ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatif you want it, that you can change the software or use pieces of it
294ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatin new free programs; and that you know you can do these things.
295ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
296ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  To protect your rights, we need to make restrictions that forbid
297ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatanyone to deny you these rights or to ask you to surrender the rights.
298ffd68729961f7383f2e35494a03ccdef20f86c98San MehatThese restrictions translate to certain responsibilities for you if you
299ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatdistribute copies of the software, or if you modify it.
300ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
301ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  For example, if you distribute copies of such a program, whether
302ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatgratis or for a fee, you must give the recipients all the rights that
303ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatyou have.  You must make sure that they, too, receive or can get the
304ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsource code.  And you must show them these terms so they know their
305ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatrights.
306ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
307ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  We protect your rights with two steps: (1) copyright the software, and
308ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat(2) offer you this license which gives you legal permission to copy,
309ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatdistribute and/or modify the software.
310ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
311ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  Also, for each author's protection and ours, we want to make certain
312ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthat everyone understands that there is no warranty for this free
313ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsoftware.  If the software is modified by someone else and passed on, we
314ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatwant its recipients to know that what they have is not the original, so
315ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthat any problems introduced by others will not reflect on the original
316ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatauthors' reputations.
317ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
318ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  Finally, any free program is threatened constantly by software
319ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatpatents.  We wish to avoid the danger that redistributors of a free
320ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatprogram will individually obtain patent licenses, in effect making the
321ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatprogram proprietary.  To prevent this, we have made it clear that any
322ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatpatent must be licensed for everyone's free use or not licensed at all.
323ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
324ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  The precise terms and conditions for copying, distribution and
325ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmodification follow.
326ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
327ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		    GNU GENERAL PUBLIC LICENSE
328ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
329ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
330ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  0. This License applies to any program or other work which contains
331ffd68729961f7383f2e35494a03ccdef20f86c98San Mehata notice placed by the copyright holder saying it may be distributed
332ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatunder the terms of this General Public License.  The "Program", below,
333ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatrefers to any such program or work, and a "work based on the Program"
334ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmeans either the Program or any derivative work under copyright law:
335ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthat is to say, a work containing the Program or a portion of it,
336ffd68729961f7383f2e35494a03ccdef20f86c98San Mehateither verbatim or with modifications and/or translated into another
337ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatlanguage.  (Hereinafter, translation is included without limitation in
338ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthe term "modification".)  Each licensee is addressed as "you".
339ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
340ffd68729961f7383f2e35494a03ccdef20f86c98San MehatActivities other than copying, distribution and modification are not
341ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcovered by this License; they are outside its scope.  The act of
342ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatrunning the Program is not restricted, and the output from the Program
343ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatis covered only if its contents constitute a work based on the
344ffd68729961f7383f2e35494a03ccdef20f86c98San MehatProgram (independent of having been made by running the Program).
345ffd68729961f7383f2e35494a03ccdef20f86c98San MehatWhether that is true depends on what the Program does.
346ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
347ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  1. You may copy and distribute verbatim copies of the Program's
348ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsource code as you receive it, in any medium, provided that you
349ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatconspicuously and appropriately publish on each copy an appropriate
350ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcopyright notice and disclaimer of warranty; keep intact all the
351ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatnotices that refer to this License and to the absence of any warranty;
352ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatand give any other recipients of the Program a copy of this License
353ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatalong with the Program.
354ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
355ffd68729961f7383f2e35494a03ccdef20f86c98San MehatYou may charge a fee for the physical act of transferring a copy, and
356ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatyou may at your option offer warranty protection in exchange for a fee.
357ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
358ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  2. You may modify your copy or copies of the Program or any portion
359ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatof it, thus forming a work based on the Program, and copy and
360ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatdistribute such modifications or work under the terms of Section 1
361ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatabove, provided that you also meet all of these conditions:
362ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
363ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    a) You must cause the modified files to carry prominent notices
364ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    stating that you changed the files and the date of any change.
365ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
366ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    b) You must cause any work that you distribute or publish, that in
367ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    whole or in part contains or is derived from the Program or any
368ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    part thereof, to be licensed as a whole at no charge to all third
369ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    parties under the terms of this License.
370ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
371ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    c) If the modified program normally reads commands interactively
372ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    when run, you must cause it, when started running for such
373ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    interactive use in the most ordinary way, to print or display an
374ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    announcement including an appropriate copyright notice and a
375ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    notice that there is no warranty (or else, saying that you provide
376ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    a warranty) and that users may redistribute the program under
377ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    these conditions, and telling the user how to view a copy of this
378ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    License.  (Exception: if the Program itself is interactive but
379ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    does not normally print such an announcement, your work based on
380ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    the Program is not required to print an announcement.)
381ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
382ffd68729961f7383f2e35494a03ccdef20f86c98San MehatThese requirements apply to the modified work as a whole.  If
383ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatidentifiable sections of that work are not derived from the Program,
384ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatand can be reasonably considered independent and separate works in
385ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthemselves, then this License, and its terms, do not apply to those
386ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsections when you distribute them as separate works.  But when you
387ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatdistribute the same sections as part of a whole which is a work based
388ffd68729961f7383f2e35494a03ccdef20f86c98San Mehaton the Program, the distribution of the whole must be on the terms of
389ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthis License, whose permissions for other licensees extend to the
390ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatentire whole, and thus to each and every part regardless of who wrote it.
391ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
392ffd68729961f7383f2e35494a03ccdef20f86c98San MehatThus, it is not the intent of this section to claim rights or contest
393ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatyour rights to work written entirely by you; rather, the intent is to
394ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatexercise the right to control the distribution of derivative or
395ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcollective works based on the Program.
396ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
397ffd68729961f7383f2e35494a03ccdef20f86c98San MehatIn addition, mere aggregation of another work not based on the Program
398ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatwith the Program (or with a work based on the Program) on a volume of
399ffd68729961f7383f2e35494a03ccdef20f86c98San Mehata storage or distribution medium does not bring the other work under
400ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthe scope of this License.
401ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
402ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  3. You may copy and distribute the Program (or a work based on it,
403ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatunder Section 2) in object code or executable form under the terms of
404ffd68729961f7383f2e35494a03ccdef20f86c98San MehatSections 1 and 2 above provided that you also do one of the following:
405ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
406ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    a) Accompany it with the complete corresponding machine-readable
407ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    source code, which must be distributed under the terms of Sections
408ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    1 and 2 above on a medium customarily used for software interchange; or,
409ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
410ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    b) Accompany it with a written offer, valid for at least three
411ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    years, to give any third party, for a charge no more than your
412ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    cost of physically performing source distribution, a complete
413ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    machine-readable copy of the corresponding source code, to be
414ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    distributed under the terms of Sections 1 and 2 above on a medium
415ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    customarily used for software interchange; or,
416ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
417ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    c) Accompany it with the information you received as to the offer
418ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    to distribute corresponding source code.  (This alternative is
419ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    allowed only for noncommercial distribution and only if you
420ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    received the program in object code or executable form with such
421ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    an offer, in accord with Subsection b above.)
422ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
423ffd68729961f7383f2e35494a03ccdef20f86c98San MehatThe source code for a work means the preferred form of the work for
424ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmaking modifications to it.  For an executable work, complete source
425ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcode means all the source code for all modules it contains, plus any
426ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatassociated interface definition files, plus the scripts used to
427ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcontrol compilation and installation of the executable.  However, as a
428ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatspecial exception, the source code distributed need not include
429ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatanything that is normally distributed (in either source or binary
430ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatform) with the major components (compiler, kernel, and so on) of the
431ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatoperating system on which the executable runs, unless that component
432ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatitself accompanies the executable.
433ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
434ffd68729961f7383f2e35494a03ccdef20f86c98San MehatIf distribution of executable or object code is made by offering
435ffd68729961f7383f2e35494a03ccdef20f86c98San Mehataccess to copy from a designated place, then offering equivalent
436ffd68729961f7383f2e35494a03ccdef20f86c98San Mehataccess to copy the source code from the same place counts as
437ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatdistribution of the source code, even though third parties are not
438ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcompelled to copy the source along with the object code.
439ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
440ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  4. You may not copy, modify, sublicense, or distribute the Program
441ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatexcept as expressly provided under this License.  Any attempt
442ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatotherwise to copy, modify, sublicense or distribute the Program is
443ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatvoid, and will automatically terminate your rights under this License.
444ffd68729961f7383f2e35494a03ccdef20f86c98San MehatHowever, parties who have received copies, or rights, from you under
445ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthis License will not have their licenses terminated so long as such
446ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatparties remain in full compliance.
447ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
448ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  5. You are not required to accept this License, since you have not
449ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsigned it.  However, nothing else grants you permission to modify or
450ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatdistribute the Program or its derivative works.  These actions are
451ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatprohibited by law if you do not accept this License.  Therefore, by
452ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmodifying or distributing the Program (or any work based on the
453ffd68729961f7383f2e35494a03ccdef20f86c98San MehatProgram), you indicate your acceptance of this License to do so, and
454ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatall its terms and conditions for copying, distributing or modifying
455ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthe Program or works based on it.
456ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
457ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  6. Each time you redistribute the Program (or any work based on the
458ffd68729961f7383f2e35494a03ccdef20f86c98San MehatProgram), the recipient automatically receives a license from the
459ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatoriginal licensor to copy, distribute or modify the Program subject to
460ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthese terms and conditions.  You may not impose any further
461ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatrestrictions on the recipients' exercise of the rights granted herein.
462ffd68729961f7383f2e35494a03ccdef20f86c98San MehatYou are not responsible for enforcing compliance by third parties to
463ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthis License.
464ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
465ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  7. If, as a consequence of a court judgment or allegation of patent
466ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatinfringement or for any other reason (not limited to patent issues),
467ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatconditions are imposed on you (whether by court order, agreement or
468ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatotherwise) that contradict the conditions of this License, they do not
469ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatexcuse you from the conditions of this License.  If you cannot
470ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatdistribute so as to satisfy simultaneously your obligations under this
471ffd68729961f7383f2e35494a03ccdef20f86c98San MehatLicense and any other pertinent obligations, then as a consequence you
472ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmay not distribute the Program at all.  For example, if a patent
473ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatlicense would not permit royalty-free redistribution of the Program by
474ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatall those who receive copies directly or indirectly through you, then
475ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthe only way you could satisfy both it and this License would be to
476ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatrefrain entirely from distribution of the Program.
477ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
478ffd68729961f7383f2e35494a03ccdef20f86c98San MehatIf any portion of this section is held invalid or unenforceable under
479ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatany particular circumstance, the balance of the section is intended to
480ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatapply and the section as a whole is intended to apply in other
481ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcircumstances.
482ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
483ffd68729961f7383f2e35494a03ccdef20f86c98San MehatIt is not the purpose of this section to induce you to infringe any
484ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatpatents or other property right claims or to contest validity of any
485ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsuch claims; this section has the sole purpose of protecting the
486ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatintegrity of the free software distribution system, which is
487ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatimplemented by public license practices.  Many people have made
488ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatgenerous contributions to the wide range of software distributed
489ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthrough that system in reliance on consistent application of that
490ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatsystem; it is up to the author/donor to decide if he or she is willing
491ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatto distribute software through any other system and a licensee cannot
492ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatimpose that choice.
493ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
494ffd68729961f7383f2e35494a03ccdef20f86c98San MehatThis section is intended to make thoroughly clear what is believed to
495ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatbe a consequence of the rest of this License.
496ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
497ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  8. If the distribution and/or use of the Program is restricted in
498ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcertain countries either by patents or by copyrighted interfaces, the
499ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatoriginal copyright holder who places the Program under this License
500ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmay add an explicit geographical distribution limitation excluding
501ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthose countries, so that distribution is permitted only in or among
502ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatcountries not thus excluded.  In such case, this License incorporates
503ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthe limitation as if written in the body of this License.
504ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
505ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  9. The Free Software Foundation may publish revised and/or new versions
506ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatof the General Public License from time to time.  Such new versions will
507ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatbe similar in spirit to the present version, but may differ in detail to
508ffd68729961f7383f2e35494a03ccdef20f86c98San Mehataddress new problems or concerns.
509ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
510ffd68729961f7383f2e35494a03ccdef20f86c98San MehatEach version is given a distinguishing version number.  If the Program
511ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatspecifies a version number of this License which applies to it and "any
512ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatlater version", you have the option of following the terms and conditions
513ffd68729961f7383f2e35494a03ccdef20f86c98San Mehateither of that version or of any later version published by the Free
514ffd68729961f7383f2e35494a03ccdef20f86c98San MehatSoftware Foundation.  If the Program does not specify a version number of
515ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthis License, you may choose any version ever published by the Free Software
516ffd68729961f7383f2e35494a03ccdef20f86c98San MehatFoundation.
517ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
518ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  10. If you wish to incorporate parts of the Program into other free
519ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatprograms whose distribution conditions are different, write to the author
520ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatto ask for permission.  For software which is copyrighted by the Free
521ffd68729961f7383f2e35494a03ccdef20f86c98San MehatSoftware Foundation, write to the Free Software Foundation; we sometimes
522ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmake exceptions for this.  Our decision will be guided by the two goals
523ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatof preserving the free status of all derivatives of our free software and
524ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatof promoting the sharing and reuse of software generally.
525ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
526ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat			    NO WARRANTY
527ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
528ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
529ffd68729961f7383f2e35494a03ccdef20f86c98San MehatFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
530ffd68729961f7383f2e35494a03ccdef20f86c98San MehatOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
531ffd68729961f7383f2e35494a03ccdef20f86c98San MehatPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
532ffd68729961f7383f2e35494a03ccdef20f86c98San MehatOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
533ffd68729961f7383f2e35494a03ccdef20f86c98San MehatMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
534ffd68729961f7383f2e35494a03ccdef20f86c98San MehatTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
535ffd68729961f7383f2e35494a03ccdef20f86c98San MehatPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
536ffd68729961f7383f2e35494a03ccdef20f86c98San MehatREPAIR OR CORRECTION.
537ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
538ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
539ffd68729961f7383f2e35494a03ccdef20f86c98San MehatWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
540ffd68729961f7383f2e35494a03ccdef20f86c98San MehatREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
541ffd68729961f7383f2e35494a03ccdef20f86c98San MehatINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
542ffd68729961f7383f2e35494a03ccdef20f86c98San MehatOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
543ffd68729961f7383f2e35494a03ccdef20f86c98San MehatTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
544ffd68729961f7383f2e35494a03ccdef20f86c98San MehatYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
545ffd68729961f7383f2e35494a03ccdef20f86c98San MehatPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
546ffd68729961f7383f2e35494a03ccdef20f86c98San MehatPOSSIBILITY OF SUCH DAMAGES.
547ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
548ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat		     END OF TERMS AND CONDITIONS
549ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
550ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	    How to Apply These Terms to Your New Programs
551ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
552ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  If you develop a new program, and you want it to be of the greatest
553ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatpossible use to the public, the best way to achieve this is to make it
554ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatfree software which everyone can redistribute and change under these terms.
555ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
556ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  To do so, attach the following notices to the program.  It is safest
557ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatto attach them to the start of each source file to most effectively
558ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatconvey the exclusion of warranty; and each file should have at least
559ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatthe "copyright" line and a pointer to where the full notice is found.
560ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
561ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    <one line to give the program's name and a brief idea of what it does.>
562ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    Copyright (C) <year>  <name of author>
563ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
564ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    This program is free software; you can redistribute it and/or modify
565ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    it under the terms of the GNU General Public License as published by
566ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    the Free Software Foundation; either version 2 of the License, or
567ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    (at your option) any later version.
568ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
569ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    This program is distributed in the hope that it will be useful,
570ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    but WITHOUT ANY WARRANTY; without even the implied warranty of
571ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
572ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    GNU General Public License for more details.
573ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
574ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    You should have received a copy of the GNU General Public License
575ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    along with this program; if not, write to the Free Software
576ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
577ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
578ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
579ffd68729961f7383f2e35494a03ccdef20f86c98San MehatAlso add information on how to contact you by electronic and paper mail.
580ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
581ffd68729961f7383f2e35494a03ccdef20f86c98San MehatIf the program is interactive, make it output a short notice like this
582ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatwhen it starts in an interactive mode:
583ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
584ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    Gnomovision version 69, Copyright (C) year name of author
585ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
586ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    This is free software, and you are welcome to redistribute it
587ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    under certain conditions; type `show c' for details.
588ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
589ffd68729961f7383f2e35494a03ccdef20f86c98San MehatThe hypothetical commands `show w' and `show c' should show the appropriate
590ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatparts of the General Public License.  Of course, the commands you use may
591ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatbe called something other than `show w' and `show c'; they could even be
592ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatmouse-clicks or menu items--whatever suits your program.
593ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
594ffd68729961f7383f2e35494a03ccdef20f86c98San MehatYou should also get your employer (if you work as a programmer) or your
595ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatschool, if any, to sign a "copyright disclaimer" for the program, if
596ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatnecessary.  Here is a sample; alter the names:
597ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
598ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
599ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  `Gnomovision' (which makes passes at compilers) written by James Hacker.
600ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
601ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  <signature of Ty Coon>, 1 April 1989
602ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat  Ty Coon, President of Vice
603ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
604ffd68729961f7383f2e35494a03ccdef20f86c98San MehatThis General Public License does not permit incorporating your program into
605ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatproprietary programs.  If your program is a subroutine library, you may
606ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatconsider it more useful to permit linking proprietary applications with the
607ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatlibrary.  If this is what you want to do, use the GNU Library General
608ffd68729961f7383f2e35494a03ccdef20f86c98San MehatPublic License instead of this License.
609