Annotation of embedaddon/dnsmasq/contrib/dnslist/dnslist.pl, revision 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>