Simon Kelley | feba5c1 | 2004-07-27 20:28:58 +0100 | [diff] [blame] | 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@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. |