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