Annotation of embedaddon/dnsmasq/contrib/dnslist/dnslist.pl, revision 1.1.1.1

1.1       misho       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.

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>