--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+Changes sinds 2.8:
+ - license
+ - cleanups from Erik Bos @ xs4all
+ - build improvements from Wichert Akkerman
+ - open sourcing
+
+changes since 2.7.1:
+ - pipe backend now has 'pipe-regex'
+ - pipe backend honours query-logging
+ - axfr timeout could cause crashes when transferring zone from
+ master
+ - improved pipebackend documentation
+
+changes since 2.6.1:
+ - controlsocket now owned by the setgid gid
+ - SOA could have the wrong TTL leading to double
+ records on ANY queries ("Jonas Daugaard" <jonas@cube.dk>)
+ - compression could suddenly be off Jonas Daugaard" <jonas@cube.dk>
+ - added --mysql-table (Ian Newlands)
+ - ranges work again (in allow-axfr-ips) (florus both)
+ - pipebackend now has pipe-timeout feature (Steve Bromwich)
+ - killed backends should respawn again (Steve Bromwich)
+ - backtrace feature under Linux
+ - corrupt packet error during axfr with secondary should not take
+ down pdns (Mike+Simon)
+ - >256 bytes compressed packet offsets did not function (Mike+Simon)
+
+
+changes since 2.6:
+ - repaired packetcache
+
+Changes since 2.5.1:
+ - removed 'unknown' packets from PacketCache
+ - improved packet accounting so counters match up better
+ - created ability to run with cache-ttl=0 and query-cache-ttl=0
+ and negquery-cache-ttl=0
+ - fixed silly bug with SOA cache with escaped dots
+ - performance increases
+ - @ hack in NS records for additional processing
+ - only-soa feature
+ - fixed very bad latency calculation error
+ - now start out with an ANY query to catch CNAMEs and possibly first-level-NS
+ - added 'cricket' to init.d script
+ - made cache quicker
+ - zone2sql now again can read Verisign generated COM/NET/ORG zones
+ $TTL in the middle of a record
+ - fixed bug with \ escaping in records that were cached
+
+Changes since 2.5:
+ - added RFC optional negative caching
+ - small speedup in non-packet-cached queries
+ - fixed huge memory leak in query cache
+ - added cache counts
+
+Changes since 2.4:
+enhance - packetcache is now case-insensitive
+ but does give correct case answers
+enhance - packetcache is now way more memory efficient
+ reengineered dnspacket
+ just stores a string
+bug - packetcache could change the 'rd' bit of queries
+bug - resolver would waste heaps of fd's
+bug - resolver would not log tcp allocation error
+bug - resolver would try to bind to priviliged ports
+bug - AXFR from masters had case sensitivity issues
+enhance - further improved some AXFR error wording
+ (all AXFR errors now contain the word AXFR)
+feature - flags can now also be specified as 'off' to turn them off, instead
+ of only as 'no'
+enhance - packetcache is now less lock-happy and a lot more complicated
+feature - database queries with no or one response are now also cached
+ in the packet cache
+enhance - log-dns-details
+ turn off for more performance
+
+Changes since 2.3:
+ - improved logging in DNS recursing proxy
+ - fixed crasher bug in compressed label parser
+ - added query-logging flag
+ - added ability to change some runtime flags
+ - added unified gmysql/gpgsql2 driver
+ - packetcache now also caches recursive queries
+ live in separate namespace
+ - added 'peak queries/second'
+ - more graceful death in case of master/slave communicator
+ database lack
+
+Changes since 2.2:
+ - improved error messages in master/slave communicator
+ - added slave-cycle-interval setting
+ - fixed SIGPIPE errors in communicator
+ - added additional check for SOA in ANY query (DENIC)
+ - pdns_control purge was broken badly
+ - master/slave communicator could get confused by delayed answers
+ from slow masters when operating as a slave.
+
+Changes since 2.1:
+ - wildcard CNAMEs!
+ - tcpreceiver sometimes would fall over a recursing packet that was
+ too short or malformed :-( (signal6)
+ - tcpreceived could wait far too long for response from remote
+ recursor
+ - cache-purge purged too much (Simon Kirby)
+ - cache-purge can now purge suffixes (Mike Benoit)
+ - some exceptions may not have been caught (tcp receiver connection
+ thread, dnsproxy)
+ - EOF on talking to TCP recursing backend would cause signal 6
+ - added soa-serial-offset to placate DENIC (again)
+
+Changes since 2.0.1:
+ - added --transactions to zone2sql
+ - there is now an option for wildcard fancy urls
+ - --lazy-recursion
+bug - configuration files aren't overwritten by the rpm
+bug - embarrassing bug in tcp recursion proxy (byteorder related)
+bug - tcp proxy neglected to honor port setting
+ - added 'pdns_control purge'
+ - improved Oracle backend documentation and support
+
+Changes since 2.0:
+ - fixed PDNS ignoring logging-facility in commandline, thanks to
+ Karl from WebMachine
+ - added --slave to zone2sql
+ - improved @ escaping in SOA hostmaster
+
+Changes since 2.0rc2:
+ - fixed zone2sql hang
+ - fixed pointer arithmetic problem in packetparser
+
+Changes since 2.0rc1:
+ - (WIN32) added a NTLog urgency to the logging class to avoid spamming the NT log.
+ - (WIN32) ported zone2sql and added it to the installation.
+ - (WIN32) ditched the Utility::Signal class.
+ - fixed chroot
+ - fixed setuid/setgid
+ - fixed >256 MX prios Jeff Crowe
+ - fixed ipv6 recursor forwarding (handy ipv6 enabler too!)
+ - fixed bogus notification reception code
+ - fixed AXFR code bug for 'many packets' format with no question in later
+ packets
+
+Changes since 1.99.12:
+ - now lowercase $ORIGIN too for postgresql
+ - strip trailing dot on $ORIGIN
+ - relative paths in named.conf include statements now work as in bind (Jeff Miller)
+ - relative paths in zone $include statements now work as in bind (Jeff Miller)
+ - fixed nasty crasher bug in mysqlbackend with . zone serving
+
+ - (WIN32) now reads the pdns.conf file if available.
+ - (WIN32) when running as a regular console app you can now shut it down using ctrl+c etc.
+ - (WIN32) installer now creates a default pdns.conf if none available.
+ - (WIN32) bug fixed where uninstaller wouldn't remove all files that had to be removed.
+ - (WIN32) dll's are now installed locally (in the same dir as the pdns executable).
+ - (WIN32) pdns_control is now added to the distribution.
+ - (WIN32) pdns responds to pdns_control commands correctly.
+ - (WIN32) added experimental master/slave support to the ODBC backend.
+ - (WIN32) fixed a bug in the database structure of the example zone.
+ - (WIN32) inserted a new (smaller) example zone.
+ - (WIN32) lots of small cleanups and fixes.
+
+Changes since 1.99.11:
+ - start of w2k merge
+ - zone2sql now understands $INCLUDE
+ - added --soa-minimum-ttl for DENIC compliance
+ - fixed bug in init.d scripts when virtual hosting
+ - added limit on number of simultaneous TCP connections
+ - added db2 backend
+ - case sensitivity issues fixed
+ - zone2sql now lowercases postgresql
+ - pdns_control now puts local socket in /tmp
+
+
+Changes since 1.99.10:
+ - now understand postfix ttl multipliers in zones outside of SOA
+ - no longer get confused by whitespace only lines after regular lines
+ - getRemote() method added for open source backend development kit
+
+Changes since 1.99.9:
+features:
+ - log-failed-updates
+ - facility logging
+ - work on master
+ now drills a hole for AXFR
+ - can now launch without ipv4
+ - also-notify support in backend
+ - added TCPv6, which works too
+ - more bsd-like default directories for freebsd
+ - zone2sql now groks 'domains' table
+
+bugs:
+ - fixed wildcard 'no data' error bug
+ - only not cache rd packets if doing recursion
+ - if a backend falls over, properly launch a new one
+ - ipv6 now actually works :-)
+
+
+
+Changes since 1.99.8:
+features:
+ - added IPv6 parsing for slave AXFR
+ - added IPv6 listener
+ - made AXFR pull reject out of zone data
+ - supermaster
+ - recursor can also live on another port now
+ - improved slave transferring semantics (scales better)
+
+bugs:
+ - pdns sometimes sent a duplicate answer when operating with a
+ recursing backend
+ - don't send out servfail on out of bailiwick CNAME traversal
+ - made zone2sql/bindparser resilient for ^Z
+ - pgsqlbackend no longer prints out connect string
+ - pgsqlbackend depended on wrong .so in debian unstable link (thanks Wojas)
+ - fix respawn of database connection in case of fatal error
+
+internal:
+ - changed SOA generation infrastructure
+ - improved internal backend API
+ - bindbackend passes regression test
+
+
+Changes since 1.99.7:
+ - simplified bindbackend, potentially resolving crashes observed
+ - fixed SOA data
+ - fixed SOA chopping for finding recursion
+ - added NAPTR
+ - documented all records encoded
+ - duplicate delete call in magical SOA id calculation
+ - servfail on question for unknown domain
+ - allow-axfr-ips now also does netmasks
+ - disabled rapid additional spawning of new backends on launch
+ - slight delay between spawning of processes to prevent overload in backends (mysql)
+
+ - added slave support
+ - added recursion
+ + acl
+ no longer caching recursive queries
+
+ - fixed potential tcp and AXFR segmentation fault
+
+Changes since 1.99.6:
+features:
+ - improved error reporting when parsing named.confs
+ (better line number counting)
+ - added --no-config
+ - added --bare to zone2sql
+ - added --gpgsql to zone2sql
+ - documented zone2sql
+
+bugs:
+ - many more named.confs can now be parsed - we now allow _ in
+ filenames
+ - freebsd version now stops/starts as it should
+ - wildcards were off by default
+ - --oracle did not function in zone2sql
+
+Changes since 1.99.5:
+features:
+ - added --webserver-print-arguments (defaults to no)
+ - added gpgsqlbackend
+ - fixed bind example zones
+bugs:
+ - fixed webserver listing of log messages
+ - fixed bad tcp question counting
+ - fixed bad tcp answer counter name
+ - fixed packetcache to detect clock skew
+ - improved flex error message
+ - accept : as part of filenames
+
+Changes since 1.99.4:
+bugs:
+ - zone2sql no longer crashes on named.confs with less than 100 domains
+ - in case of huffman encoding error, print offending character
+ - fixed memory leaks big enough to drive a truck through
+ - removed yet more fd leaks in guardian
+ - made pipebackend less chatty
+ - daemon now closes filedescriptors 0, 1 & 2
+
+performance:
+ - improved TCP dns code
+ now only creates backend connection for AXFR
+ has timeouts
+
+features:
+ - made it possible to disable checks on ctime in bindbackend
+ - added --list-modules
+
+Changes since 1.99.3:
+bugs:
+ - make sure zone compression is ON by default (heisenbug)
+ - fixed lack of exception catching in tcpreceiver
+ - made sure mysqlbackend closes its database connection
+ - learned bindparser about ip addresses which are not filenames
+ - fix truncation bug (don't truncate stuff in the cache)
+
+features:
+ - learned zone2sql about $GENERATE
+ - added --on-error-resume-next to zone2sql
+ - grok '@' in RHS of zonestatements
+ - catch dns updates & dns notifies, send out NOTIMP
+ - give zone2sql a default ttl
+
+performance:
+ - don't search for fancy records on ANY if not wanted
+
+Changes since 1.99.2:
+ - made bindparser case insensitive
+ - fixed AXFR rcodes for disallowed or unauth zones
+ - fixed fd leak when relaunching a child
+ - fixed zone2sql lack of fclose()
+ - make --help accept a prefix parameter
+ - added --zone-name to zone2sql
+ - added --disable-axfr (untested!)
+ - added --alow-axfr-ips
+ - rewrote zonefile parser
+ - enabled direct zoneparsing by pdns
+ 9500 zones in 3.5 seconds
+ - fixed zonetransfers bugs (we died on axfr connection reset by peer)
+ - implemented rfc-breaking axfr dump speedup
+ - fixed webserver crash
+
+Changes since 1.99.1:
+
+ - fixed uid/gid confusal
+ - fixed module backend restarting code
+ - bummed off 3 syscalls
+ - removed lot of unnecessary gettimeofday calls
+ - fixed buffer overrun in local socket binding
+ - do not parse configuration when outputting configuration
+ (when reinstalling)
+
+
+
+1.4.1
+ - added a webserver
+ - integrated safe_ahudns functionality
+ - improved ahudns.init.d, added to default install
+ - made socketdir configurable
+ - Fixed smtpredir 'black hole' forwarding behaviour in case of
+ unknown recipients
+ - Properly report temporary errors now as 4xx
+ - ANY queries now include MBOXFW data
+ - NS records now have precedence over wildcard records
+ - some more logging behind DLOG() so it only appears in
+ verbose-logging builds
+
+Changes since 1.1:
+
+ - Resolved memory leak in TCP server
+ - We did not reset the AA bit on a NS referral
+ - distribution tar did not include documentation directory
+ - improved database recycling in case of database server failure and
+ restoration
+
+
--- /dev/null
+Read http://doc.powerdns.com/compiling-powerdns.html
+
+./configure ; make; ./installer should do the trick
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+AM_CXXFLAGS=-D_GNU_SOURCE -DSYSCONFDIR=\"@sysconfdir@\" -DBINDIR=\"@bindir@\" -DLOCALSTATEDIR=\"@localstatedir@\" -Ibackends/bind
+AM_CPPFLAGS=-Ibackends/bind
+
+EXTRA_DIST = codedocs/Makefile codedocs/doxygen.conf sample docs/Makefile \
+docs/gslb-operations.sgml docs/powerdns-case.sgml docs/powerdns-install.sgml \
+docs/powerdns-overview.sgml docs/powerdns-technical.sgml extra/Makefile \
+extra/null.c pdns.spec release-scripts/ debian/changelog debian/conffiles \
+debian/control debian/postinst debian/postrm debian/preinst \
+debian/prerm debian/rules installer \
+pathconfig.redhat pathconfig pathconfig.bsd pathconfig.debian docs/pdns.sgml \
+LICENSE choosepaths mtasker.cc COPYING
+
+bin_SCRIPTS = pdns
+sysconf_DATA = pdns.conf-dist smtpredir.conf-dist
+
+bin_PROGRAMS = pdns_server pdns_control binpatch # syncres # resolver syncres # smtpredir
+
+
+pdns_server_SOURCES=dnspacket.cc nameserver.cc tcpreceiver.hh \
+qtype.cc logger.cc arguments.cc packethandler.cc tcpreceiver.cc \
+packetcache.cc statbag.cc ahuexception.hh arguments.hh distributor.hh \
+dns.hh dnsbackend.hh dnsbackend.cc dnspacket.hh dynmessenger.hh lock.hh logger.hh \
+nameserver.hh packetcache.hh packethandler.hh qtype.hh statbag.hh \
+ueberbackend.hh pdns.conf-dist ws.hh ws.cc webserver.cc webserver.hh \
+session.cc session.hh misc.cc misc.hh receiver.cc ueberbackend.cc \
+dynlistener.cc dynlistener.hh dynhandler.cc dynhandler.hh \
+resolver.hh resolver.cc communicator.cc communicator.hh dnsproxy.cc \
+dnsproxy.hh randombackend.cc unix_utility.cc common_startup.cc \
+utility.hh iputils.hh common_startup.hh \
+backends/bind/bindbackend.cc backends/bind/zoneparser2.cc \
+backends/bind/bindparser.cc backends/bind/bindlexer.c \
+backends/bind/huffman.cc
+
+#
+pdns_server_LDFLAGS=-rdynamic @LIBDL@ extra/*.o `cat extra/ld` -ldl
+pdns_server_INCLUDES=
+
+
+#resolver_SOURCES=resolver.cc resolver.hh misc.cc unix_utility.cc qtype.cc \
+#logger.cc statbag.cc dnspacket.cc arguments.cc tres.cc
+
+#syncres_SOURCES=syncres.cc resolver.hh misc.cc unix_utility.cc qtype.cc \
+#logger.cc statbag.cc dnspacket.cc arguments.cc lwres.cc recns.cc lwres.hh \
+#mtasker.hh
+
+pdns_control_SOURCES=dynloader.cc dynmessenger.cc arguments.cc logger.cc statbag.cc misc.cc unix_utility.cc
+pdns_control_INCLUDES=path.hh
+pdns_control_LDFLAGS=
+
+binpatch_SOURCES=binpatch.cc
+
+SUBDIRS= codedocs backends extra .
+
+deb: ../ahudns_1.1-1_i386.deb
+
+../ahudns_1.1-1_i386.deb:
+ ./debian/rules binary-arch
--- /dev/null
+# Makefile.in generated automatically by automake 1.5 from Makefile.am.
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AMTAR = @AMTAR@
+AS = @AS@
+AWK = @AWK@
+CC = @CC@
+CXX = @CXX@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EXEEXT = @EXEEXT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LEX = @LEX@
+LIBDL = @LIBDL@
+LIBRESOLV = @LIBRESOLV@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+am__include = @am__include@
+am__quote = @am__quote@
+install_sh = @install_sh@
+
+AM_CXXFLAGS = -D_GNU_SOURCE -DSYSCONFDIR=\"@sysconfdir@\" -DBINDIR=\"@bindir@\" -DLOCALSTATEDIR=\"@localstatedir@\" -Ibackends/bind
+AM_CPPFLAGS = -Ibackends/bind
+
+EXTRA_DIST = codedocs/Makefile codedocs/doxygen.conf sample docs/Makefile \
+docs/gslb-operations.sgml docs/powerdns-case.sgml docs/powerdns-install.sgml \
+docs/powerdns-overview.sgml docs/powerdns-technical.sgml extra/Makefile \
+extra/null.c pdns.spec release-scripts/ debian/changelog debian/conffiles \
+debian/control debian/postinst debian/postrm debian/preinst \
+debian/prerm debian/rules installer \
+pathconfig.redhat pathconfig pathconfig.bsd pathconfig.debian docs/pdns.sgml \
+LICENSE choosepaths mtasker.cc COPYING
+
+
+bin_SCRIPTS = pdns
+sysconf_DATA = pdns.conf-dist smtpredir.conf-dist
+
+bin_PROGRAMS = pdns_server pdns_control binpatch # syncres # resolver syncres # smtpredir
+
+pdns_server_SOURCES = dnspacket.cc nameserver.cc tcpreceiver.hh \
+qtype.cc logger.cc arguments.cc packethandler.cc tcpreceiver.cc \
+packetcache.cc statbag.cc ahuexception.hh arguments.hh distributor.hh \
+dns.hh dnsbackend.hh dnsbackend.cc dnspacket.hh dynmessenger.hh lock.hh logger.hh \
+nameserver.hh packetcache.hh packethandler.hh qtype.hh statbag.hh \
+ueberbackend.hh pdns.conf-dist ws.hh ws.cc webserver.cc webserver.hh \
+session.cc session.hh misc.cc misc.hh receiver.cc ueberbackend.cc \
+dynlistener.cc dynlistener.hh dynhandler.cc dynhandler.hh \
+resolver.hh resolver.cc communicator.cc communicator.hh dnsproxy.cc \
+dnsproxy.hh randombackend.cc unix_utility.cc common_startup.cc \
+utility.hh iputils.hh common_startup.hh \
+backends/bind/bindbackend.cc backends/bind/zoneparser2.cc \
+backends/bind/bindparser.cc backends/bind/bindlexer.c \
+backends/bind/huffman.cc
+
+
+#
+pdns_server_LDFLAGS = -rdynamic @LIBDL@ extra/*.o `cat extra/ld` -ldl
+pdns_server_INCLUDES =
+
+
+#resolver_SOURCES=resolver.cc resolver.hh misc.cc unix_utility.cc qtype.cc \
+#logger.cc statbag.cc dnspacket.cc arguments.cc tres.cc
+
+#syncres_SOURCES=syncres.cc resolver.hh misc.cc unix_utility.cc qtype.cc \
+#logger.cc statbag.cc dnspacket.cc arguments.cc lwres.cc recns.cc lwres.hh \
+#mtasker.hh
+pdns_control_SOURCES = dynloader.cc dynmessenger.cc arguments.cc logger.cc statbag.cc misc.cc unix_utility.cc
+pdns_control_INCLUDES = path.hh
+pdns_control_LDFLAGS =
+
+binpatch_SOURCES = binpatch.cc
+
+SUBDIRS = codedocs backends extra .
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = pdns.conf-dist buildroot.sh showvar pdns mkbindist
+bin_PROGRAMS = pdns_server$(EXEEXT) pdns_control$(EXEEXT) \
+ binpatch$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+
+am_binpatch_OBJECTS = binpatch.$(OBJEXT)
+binpatch_OBJECTS = $(am_binpatch_OBJECTS)
+binpatch_LDADD = $(LDADD)
+binpatch_DEPENDENCIES =
+binpatch_LDFLAGS =
+am_pdns_control_OBJECTS = dynloader.$(OBJEXT) dynmessenger.$(OBJEXT) \
+ arguments.$(OBJEXT) logger.$(OBJEXT) statbag.$(OBJEXT) \
+ misc.$(OBJEXT) unix_utility.$(OBJEXT)
+pdns_control_OBJECTS = $(am_pdns_control_OBJECTS)
+pdns_control_LDADD = $(LDADD)
+pdns_control_DEPENDENCIES =
+am_pdns_server_OBJECTS = dnspacket.$(OBJEXT) nameserver.$(OBJEXT) \
+ qtype.$(OBJEXT) logger.$(OBJEXT) arguments.$(OBJEXT) \
+ packethandler.$(OBJEXT) tcpreceiver.$(OBJEXT) \
+ packetcache.$(OBJEXT) statbag.$(OBJEXT) dnsbackend.$(OBJEXT) \
+ ws.$(OBJEXT) webserver.$(OBJEXT) session.$(OBJEXT) \
+ misc.$(OBJEXT) receiver.$(OBJEXT) ueberbackend.$(OBJEXT) \
+ dynlistener.$(OBJEXT) dynhandler.$(OBJEXT) resolver.$(OBJEXT) \
+ communicator.$(OBJEXT) dnsproxy.$(OBJEXT) \
+ randombackend.$(OBJEXT) unix_utility.$(OBJEXT) \
+ common_startup.$(OBJEXT) bindbackend.$(OBJEXT) \
+ zoneparser2.$(OBJEXT) bindparser.$(OBJEXT) bindlexer.$(OBJEXT) \
+ huffman.$(OBJEXT)
+pdns_server_OBJECTS = $(am_pdns_server_OBJECTS)
+pdns_server_LDADD = $(LDADD)
+pdns_server_DEPENDENCIES =
+SCRIPTS = $(bin_SCRIPTS)
+
+
+DEFS = @DEFS@
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/arguments.Po $(DEPDIR)/bindbackend.Po \
+@AMDEP_TRUE@ $(DEPDIR)/bindlexer.Po $(DEPDIR)/bindparser.Po \
+@AMDEP_TRUE@ $(DEPDIR)/binpatch.Po $(DEPDIR)/common_startup.Po \
+@AMDEP_TRUE@ $(DEPDIR)/communicator.Po $(DEPDIR)/dnsbackend.Po \
+@AMDEP_TRUE@ $(DEPDIR)/dnspacket.Po $(DEPDIR)/dnsproxy.Po \
+@AMDEP_TRUE@ $(DEPDIR)/dynhandler.Po $(DEPDIR)/dynlistener.Po \
+@AMDEP_TRUE@ $(DEPDIR)/dynloader.Po $(DEPDIR)/dynmessenger.Po \
+@AMDEP_TRUE@ $(DEPDIR)/huffman.Po $(DEPDIR)/logger.Po \
+@AMDEP_TRUE@ $(DEPDIR)/misc.Po $(DEPDIR)/nameserver.Po \
+@AMDEP_TRUE@ $(DEPDIR)/packetcache.Po $(DEPDIR)/packethandler.Po \
+@AMDEP_TRUE@ $(DEPDIR)/qtype.Po $(DEPDIR)/randombackend.Po \
+@AMDEP_TRUE@ $(DEPDIR)/receiver.Po $(DEPDIR)/resolver.Po \
+@AMDEP_TRUE@ $(DEPDIR)/session.Po $(DEPDIR)/statbag.Po \
+@AMDEP_TRUE@ $(DEPDIR)/tcpreceiver.Po $(DEPDIR)/ueberbackend.Po \
+@AMDEP_TRUE@ $(DEPDIR)/unix_utility.Po $(DEPDIR)/webserver.Po \
+@AMDEP_TRUE@ $(DEPDIR)/ws.Po $(DEPDIR)/zoneparser2.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+ $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CXXFLAGS = @CXXFLAGS@
+DIST_SOURCES = $(binpatch_SOURCES) $(pdns_control_SOURCES) \
+ $(pdns_server_SOURCES)
+DATA = $(sysconf_DATA)
+
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
+ uninstall-info-recursive all-recursive install-data-recursive \
+ install-exec-recursive installdirs-recursive install-recursive \
+ uninstall-recursive check-recursive installcheck-recursive
+DIST_COMMON = README ./stamp-h.in COPYING ChangeLog INSTALL Makefile.am \
+ Makefile.in TODO acconfig.h aclocal.m4 buildroot.sh.in \
+ config.guess config.h.in config.sub configure configure.in \
+ depcomp install-sh ltmain.sh missing mkbindist.in mkinstalldirs \
+ pdns.conf-dist.in pdns.in showvar.in ylwrap
+DIST_SUBDIRS = $(SUBDIRS)
+SOURCES = $(binpatch_SOURCES) $(pdns_control_SOURCES) $(pdns_server_SOURCES)
+
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .o .obj
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && \
+ CONFIG_HEADERS= CONFIG_LINKS= \
+ CONFIG_FILES=$@ $(SHELL) ./config.status
+
+$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+$(ACLOCAL_M4): configure.in
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h stamp-hT
+ @echo timestamp > stamp-hT 2> /dev/null
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h \
+ $(SHELL) ./config.status
+ @mv stamp-hT stamp-h
+$(srcdir)/config.h.in: $(srcdir)/./stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/./stamp-h.in; \
+ $(MAKE) $(srcdir)/./stamp-h.in; \
+ else :; fi
+$(srcdir)/./stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/acconfig.h
+ @rm -f $(srcdir)/./stamp-h.in $(srcdir)/./stamp-h.inT
+ @echo timestamp > $(srcdir)/./stamp-h.inT 2> /dev/null
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @mv $(srcdir)/./stamp-h.inT $(srcdir)/./stamp-h.in
+
+distclean-hdr:
+ -rm -f config.h
+pdns.conf-dist: $(top_builddir)/config.status pdns.conf-dist.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+buildroot.sh: $(top_builddir)/config.status buildroot.sh.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+showvar: $(top_builddir)/config.status showvar.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+pdns: $(top_builddir)/config.status pdns.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+mkbindist: $(top_builddir)/config.status mkbindist.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+binpatch$(EXEEXT): $(binpatch_OBJECTS) $(binpatch_DEPENDENCIES)
+ @rm -f binpatch$(EXEEXT)
+ $(CXXLINK) $(binpatch_LDFLAGS) $(binpatch_OBJECTS) $(binpatch_LDADD) $(LIBS)
+pdns_control$(EXEEXT): $(pdns_control_OBJECTS) $(pdns_control_DEPENDENCIES)
+ @rm -f pdns_control$(EXEEXT)
+ $(CXXLINK) $(pdns_control_LDFLAGS) $(pdns_control_OBJECTS) $(pdns_control_LDADD) $(LIBS)
+bindbackend.$(OBJEXT): backends/bind/bindbackend.cc
+zoneparser2.$(OBJEXT): backends/bind/zoneparser2.cc
+bindparser.$(OBJEXT): backends/bind/bindparser.cc
+bindlexer.$(OBJEXT): backends/bind/bindlexer.c
+huffman.$(OBJEXT): backends/bind/huffman.cc
+pdns_server$(EXEEXT): $(pdns_server_OBJECTS) $(pdns_server_DEPENDENCIES)
+ @rm -f pdns_server$(EXEEXT)
+ $(CXXLINK) $(pdns_server_LDFLAGS) $(pdns_server_OBJECTS) $(pdns_server_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f="`echo $$p|sed '$(transform)'`"; \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/$$f; \
+ elif test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/$$f; \
+ else :; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f="`echo $$p|sed '$(transform)'`"; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/arguments.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/bindbackend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/bindlexer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/bindparser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/binpatch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/common_startup.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/communicator.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dnsbackend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dnspacket.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dnsproxy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dynhandler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dynlistener.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dynloader.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dynmessenger.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/huffman.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/logger.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/misc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/nameserver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/packetcache.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/packethandler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/qtype.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/randombackend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/receiver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/resolver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/session.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/statbag.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/tcpreceiver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ueberbackend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/unix_utility.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/webserver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ws.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/zoneparser2.Po@am__quote@
+
+distclean-depend:
+ -rm -rf $(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `cygpath -w $<`
+
+.c.lo:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LTCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$<
+
+bindlexer.o: backends/bind/bindlexer.c
+@AMDEP_TRUE@ source='backends/bind/bindlexer.c' object='bindlexer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindlexer.Po' tmpdepfile='$(DEPDIR)/bindlexer.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bindlexer.o `test -f backends/bind/bindlexer.c || echo '$(srcdir)/'`backends/bind/bindlexer.c
+
+bindlexer.obj: backends/bind/bindlexer.c
+@AMDEP_TRUE@ source='backends/bind/bindlexer.c' object='bindlexer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindlexer.Po' tmpdepfile='$(DEPDIR)/bindlexer.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bindlexer.obj `cygpath -w backends/bind/bindlexer.c`
+
+bindlexer.lo: backends/bind/bindlexer.c
+@AMDEP_TRUE@ source='backends/bind/bindlexer.c' object='bindlexer.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindlexer.Plo' tmpdepfile='$(DEPDIR)/bindlexer.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bindlexer.lo `test -f backends/bind/bindlexer.c || echo '$(srcdir)/'`backends/bind/bindlexer.c
+CCDEPMODE = @CCDEPMODE@
+
+.cc.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXXCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$<
+
+.cc.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXXCOMPILE) -c -o $@ `cygpath -w $<`
+
+.cc.lo:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LTCXXCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$<
+
+bindbackend.o: backends/bind/bindbackend.cc
+@AMDEP_TRUE@ source='backends/bind/bindbackend.cc' object='bindbackend.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindbackend.Po' tmpdepfile='$(DEPDIR)/bindbackend.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bindbackend.o `test -f backends/bind/bindbackend.cc || echo '$(srcdir)/'`backends/bind/bindbackend.cc
+
+bindbackend.obj: backends/bind/bindbackend.cc
+@AMDEP_TRUE@ source='backends/bind/bindbackend.cc' object='bindbackend.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindbackend.Po' tmpdepfile='$(DEPDIR)/bindbackend.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bindbackend.obj `cygpath -w backends/bind/bindbackend.cc`
+
+bindbackend.lo: backends/bind/bindbackend.cc
+@AMDEP_TRUE@ source='backends/bind/bindbackend.cc' object='bindbackend.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindbackend.Plo' tmpdepfile='$(DEPDIR)/bindbackend.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bindbackend.lo `test -f backends/bind/bindbackend.cc || echo '$(srcdir)/'`backends/bind/bindbackend.cc
+
+zoneparser2.o: backends/bind/zoneparser2.cc
+@AMDEP_TRUE@ source='backends/bind/zoneparser2.cc' object='zoneparser2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/zoneparser2.Po' tmpdepfile='$(DEPDIR)/zoneparser2.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoneparser2.o `test -f backends/bind/zoneparser2.cc || echo '$(srcdir)/'`backends/bind/zoneparser2.cc
+
+zoneparser2.obj: backends/bind/zoneparser2.cc
+@AMDEP_TRUE@ source='backends/bind/zoneparser2.cc' object='zoneparser2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/zoneparser2.Po' tmpdepfile='$(DEPDIR)/zoneparser2.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoneparser2.obj `cygpath -w backends/bind/zoneparser2.cc`
+
+zoneparser2.lo: backends/bind/zoneparser2.cc
+@AMDEP_TRUE@ source='backends/bind/zoneparser2.cc' object='zoneparser2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/zoneparser2.Plo' tmpdepfile='$(DEPDIR)/zoneparser2.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoneparser2.lo `test -f backends/bind/zoneparser2.cc || echo '$(srcdir)/'`backends/bind/zoneparser2.cc
+
+bindparser.o: backends/bind/bindparser.cc
+@AMDEP_TRUE@ source='backends/bind/bindparser.cc' object='bindparser.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindparser.Po' tmpdepfile='$(DEPDIR)/bindparser.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bindparser.o `test -f backends/bind/bindparser.cc || echo '$(srcdir)/'`backends/bind/bindparser.cc
+
+bindparser.obj: backends/bind/bindparser.cc
+@AMDEP_TRUE@ source='backends/bind/bindparser.cc' object='bindparser.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindparser.Po' tmpdepfile='$(DEPDIR)/bindparser.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bindparser.obj `cygpath -w backends/bind/bindparser.cc`
+
+bindparser.lo: backends/bind/bindparser.cc
+@AMDEP_TRUE@ source='backends/bind/bindparser.cc' object='bindparser.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/bindparser.Plo' tmpdepfile='$(DEPDIR)/bindparser.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bindparser.lo `test -f backends/bind/bindparser.cc || echo '$(srcdir)/'`backends/bind/bindparser.cc
+
+huffman.o: backends/bind/huffman.cc
+@AMDEP_TRUE@ source='backends/bind/huffman.cc' object='huffman.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/huffman.Po' tmpdepfile='$(DEPDIR)/huffman.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o huffman.o `test -f backends/bind/huffman.cc || echo '$(srcdir)/'`backends/bind/huffman.cc
+
+huffman.obj: backends/bind/huffman.cc
+@AMDEP_TRUE@ source='backends/bind/huffman.cc' object='huffman.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/huffman.Po' tmpdepfile='$(DEPDIR)/huffman.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o huffman.obj `cygpath -w backends/bind/huffman.cc`
+
+huffman.lo: backends/bind/huffman.cc
+@AMDEP_TRUE@ source='backends/bind/huffman.cc' object='huffman.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/huffman.Plo' tmpdepfile='$(DEPDIR)/huffman.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o huffman.lo `test -f backends/bind/huffman.cc || echo '$(srcdir)/'`backends/bind/huffman.cc
+CXXDEPMODE = @CXXDEPMODE@
+uninstall-info-am:
+install-sysconfDATA: $(sysconf_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(sysconfdir)
+ @list='$(sysconf_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(sysconfdir)/$$f"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(sysconfdir)/$$f; \
+ done
+
+uninstall-sysconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sysconf_DATA)'; for p in $$list; do \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " rm -f $(DESTDIR)$(sysconfdir)/$$f"; \
+ rm -f $(DESTDIR)$(sysconfdir)/$$f; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+ || etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP)
+
+GTAGS:
+ here=`CDPATH=: && cd $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = .
+# Avoid unsightly `./'.
+distdir = $(PACKAGE)-$(VERSION)
+
+GZIP_ENV = --best
+
+distdir: $(DISTFILES)
+ -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
+ mkdir $(distdir)
+ $(mkinstalldirs) $(distdir)/. $(distdir)/codedocs $(distdir)/debian $(distdir)/docs $(distdir)/extra
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ $(mkinstalldirs) "$(distdir)/$$dir"; \
+ fi; \
+ if test -d $$d/$$file; then \
+ cp -pR $$d/$$file $(distdir) \
+ || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" \
+ distdir=../$(distdir)/$$subdir \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -chmod -R a+w $(distdir) > /dev/null 2>&1; rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ chmod a-w $(distdir)
+ dc_install_base=`CDPATH=: && cd $(distdir)/=inst && pwd` \
+ && cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && (test `find $$dc_install_base -type f -print | wc -l` -le 1 \
+ || (echo "Error: files left after uninstall" 1>&2; \
+ exit 1) ) \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && $(MAKE) $(AM_MAKEFLAGS) distclean \
+ && rm -f $(distdir).tar.gz \
+ && (test `find . -type f -print | wc -l` -eq 0 \
+ || (echo "Error: files left after distclean" 1>&2; \
+ exit 1) )
+ -chmod -R a+w $(distdir) > /dev/null 2>&1; rm -rf $(distdir)
+ @echo "$(distdir).tar.gz is ready for distribution" | \
+ sed 'h;s/./=/g;p;x;p;x'
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(bindir) $(DESTDIR)$(sysconfdir)
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+dist-all: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
+distclean: distclean-recursive
+ -rm -f config.status config.cache config.log
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS \
+ install-sysconfDATA
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-info-am uninstall-sysconfDATA
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
+ clean-binPROGRAMS clean-generic clean-libtool clean-recursive \
+ dist dist-all distcheck distclean distclean-compile \
+ distclean-depend distclean-generic distclean-hdr \
+ distclean-libtool distclean-recursive distclean-tags distdir \
+ dvi dvi-am dvi-recursive info info-am info-recursive install \
+ install-am install-binPROGRAMS install-binSCRIPTS install-data \
+ install-data-am install-data-recursive install-exec \
+ install-exec-am install-exec-recursive install-info \
+ install-info-am install-info-recursive install-man \
+ install-recursive install-strip install-sysconfDATA \
+ installcheck installcheck-am installdirs installdirs-am \
+ installdirs-recursive maintainer-clean maintainer-clean-generic \
+ maintainer-clean-recursive mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
+ tags tags-recursive uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-binSCRIPTS uninstall-info-am \
+ uninstall-info-recursive uninstall-recursive \
+ uninstall-sysconfDATA
+
+
+deb: ../ahudns_1.1-1_i386.deb
+
+../ahudns_1.1-1_i386.deb:
+ ./debian/rules binary-arch
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+See http://pdns.powerdns.com and especially
+http://pdns.powerdns.com/doc & http://pdns.powerdns.com/doc/pdns.pdf
+
+For those not reading documentation, and installing from the .tar.gz:
+
+ $ ./choosepaths
+ or
+ $ editor pathconfig
+
+ and then, as root
+
+ # ./installer
+
+If you installed the RPM or the .deb, you can skip the above.
+
+If this went ok:
+
+# /etc/init.d/pdns monitor
+
+Now add "bind-example-zones" to pds.conf, and query your nameserver:
+
+$ host www.example.com 127.0.0.1
+www.example.com A 1.2.3.4
+
+and NOW read the documentation!
\ No newline at end of file
--- /dev/null
+
+ betere compressie (. NS records passen er niet in!)
+
+ zone includes absolute/relative paths
+
+ learn bindbackend to reload the configuration
+ 'rediscover' method?
+
+done pdns_control notify interface
+ pdns_control mass-notify
+ notify fucking everybody of fucking everything
+
+ pdns_control rediscover
+
+ make guardian perform pings over the controlsocket, 'heartbeat'
+
+
+ Solaris build
+ Resurrect Windows build
+
+ autotuning number of backend threads
+
--- /dev/null
+/* Define when extra posix typedefs are needed (solaris2.6) */
+#undef NEED_POSIX_TYPEDEF
+#undef VERBOSELOG
--- /dev/null
+# aclocal.m4 generated automatically by aclocal 1.5
+
+# Copyright 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 5
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# We require 2.13 because we rely on SHELL being computed by configure.
+AC_PREREQ([2.13])
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If MACRO-NAME is provided do IF-PROVIDED, else IF-NOT-PROVIDED.
+# The purpose of this macro is to provide the user with a means to
+# check macros which are provided without letting her know how the
+# information is coded.
+# If this macro is not defined by Autoconf, define it here.
+ifdef([AC_PROVIDE_IFELSE],
+ [],
+ [define([AC_PROVIDE_IFELSE],
+ [ifdef([AC_PROVIDE_$1],
+ [$2], [$3])])])
+
+
+# AM_INIT_AUTOMAKE(PACKAGE,VERSION, [NO-DEFINE])
+# ----------------------------------------------
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`CDPATH=:; cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run \"make distclean\" there first])
+fi
+
+# Define the identity of the package.
+PACKAGE=$1
+AC_SUBST(PACKAGE)dnl
+VERSION=$2
+AC_SUBST(VERSION)dnl
+ifelse([$3],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])
+
+# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
+# the ones we care about.
+ifdef([m4_pattern_allow],
+ [m4_pattern_allow([^AM_[A-Z]+FLAGS])])dnl
+
+# Autoconf 2.50 always computes EXEEXT. However we need to be
+# compatible with 2.13, for now. So we always define EXEEXT, but we
+# don't compute it.
+AC_SUBST(EXEEXT)
+# Similar for OBJEXT -- only we only use OBJEXT if the user actually
+# requests that it be used. This is a bit dumb.
+: ${OBJEXT=o}
+AC_SUBST(OBJEXT)
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal)
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake)
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_PROVIDE_IFELSE([AC_PROG_][CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_][CC],
+ defn([AC_PROG_][CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_][CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_][CXX],
+ defn([AC_PROG_][CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+
+# serial 2
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ am_backtick='`'
+ AC_MSG_WARN([${am_backtick}missing' script is too old or missing])
+fi
+])
+
+# AM_AUX_DIR_EXPAND
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND], [
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`CDPATH=:; cd $ac_aux_dir && pwd`
+])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# serial 4 -*- Autoconf -*-
+
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ---------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX" or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc']
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ echo '#include "conftest.h"' > conftest.c
+ echo 'int i;' > conftest.h
+ echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=conftest.c object=conftest.o \
+ depfile=conftest.Po tmpdepfile=conftest.TPo \
+ $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
+ grep conftest.h conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+$1DEPMODE="depmode=$am_cv_$1_dependencies_compiler_type"
+AC_SUBST([$1DEPMODE])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[rm -f .deps 2>/dev/null
+mkdir .deps 2>/dev/null
+if test -d .deps; then
+ DEPDIR=.deps
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ DEPDIR=_deps
+fi
+rmdir .deps 2>/dev/null
+AC_SUBST(DEPDIR)
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking Speeds up one-time builds
+ --enable-dependency-tracking Do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+pushdef([subst], defn([AC_SUBST]))
+subst(AMDEPBACKSLASH)
+popdef([subst])
+])
+
+# Generate code to set up dependency tracking.
+# This macro should only be invoked once -- use via AC_REQUIRE.
+# Usage:
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],[
+AC_OUTPUT_COMMANDS([
+test x"$AMDEP_TRUE" != x"" ||
+for mf in $CONFIG_FILES; do
+ case "$mf" in
+ Makefile) dirpart=.;;
+ */Makefile) dirpart=`echo "$mf" | sed -e 's|/[^/]*$||'`;;
+ *) continue;;
+ esac
+ grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`echo "$file" | sed -e 's|/[^/]*$||'`
+ $ac_aux_dir/mkinstalldirs "$dirpart/$fdir" > /dev/null 2>&1
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+], [AMDEP_TRUE="$AMDEP_TRUE"
+ac_aux_dir="$ac_aux_dir"])])
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+doit:
+ @echo done
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include='#'
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote='"'
+ _am_result=BSD
+ fi
+fi
+AC_SUBST(am__include)
+AC_SUBST(am__quote)
+AC_MSG_RESULT($_am_result)
+rm -f confinc confmf
+])
+
+# serial 3
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+#
+# FIXME: Once using 2.50, use this:
+# m4_match([$1], [^TRUE\|FALSE$], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_DEFUN([AM_CONDITIONAL],
+[ifelse([$1], [TRUE],
+ [errprint(__file__:__line__: [$0: invalid condition: $1
+])dnl
+m4exit(1)])dnl
+ifelse([$1], [FALSE],
+ [errprint(__file__:__line__: [$0: invalid condition: $1
+])dnl
+m4exit(1)])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+# serial 3
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. We must strip everything past the first ":",
+# and everything past the last "/".
+
+AC_PREREQ([2.12])
+
+AC_DEFUN([AM_CONFIG_HEADER],
+[ifdef([AC_FOREACH],dnl
+ [dnl init our file count if it isn't already
+ m4_ifndef([_AM_Config_Header_Index], m4_define([_AM_Config_Header_Index], [0]))
+ dnl prepare to store our destination file list for use in config.status
+ AC_FOREACH([_AM_File], [$1],
+ [m4_pushdef([_AM_Dest], m4_patsubst(_AM_File, [:.*]))
+ m4_define([_AM_Config_Header_Index], m4_incr(_AM_Config_Header_Index))
+ dnl and add it to the list of files AC keeps track of, along
+ dnl with our hook
+ AC_CONFIG_HEADERS(_AM_File,
+dnl COMMANDS, [, INIT-CMDS]
+[# update the timestamp
+echo timestamp >"AS_ESCAPE(_AM_DIRNAME(]_AM_Dest[))/stamp-h]_AM_Config_Header_Index["
+][$2]m4_ifval([$3], [, [$3]]))dnl AC_CONFIG_HEADERS
+ m4_popdef([_AM_Dest])])],dnl
+[AC_CONFIG_HEADER([$1])
+ AC_OUTPUT_COMMANDS(
+ ifelse(patsubst([$1], [[^ ]], []),
+ [],
+ [test -z "$CONFIG_HEADERS" || echo timestamp >dnl
+ patsubst([$1], [^\([^:]*/\)?.*], [\1])stamp-h]),dnl
+[am_indx=1
+for am_file in $1; do
+ case " \$CONFIG_HEADERS " in
+ *" \$am_file "*)
+ am_dir=\`echo \$am_file |sed 's%:.*%%;s%[^/]*\$%%'\`
+ if test -n "\$am_dir"; then
+ am_tmpdir=\`echo \$am_dir |sed 's%^\(/*\).*\$%\1%'\`
+ for am_subdir in \`echo \$am_dir |sed 's%/% %'\`; do
+ am_tmpdir=\$am_tmpdir\$am_subdir/
+ if test ! -d \$am_tmpdir; then
+ mkdir \$am_tmpdir
+ fi
+ done
+ fi
+ echo timestamp > "\$am_dir"stamp-h\$am_indx
+ ;;
+ esac
+ am_indx=\`expr \$am_indx + 1\`
+done])
+])]) # AM_CONFIG_HEADER
+
+# _AM_DIRNAME(PATH)
+# -----------------
+# Like AS_DIRNAME, only do it during macro expansion
+AC_DEFUN([_AM_DIRNAME],
+ [m4_if(m4_regexp([$1], [^.*[^/]//*[^/][^/]*/*$]), -1,
+ m4_if(m4_regexp([$1], [^//\([^/]\|$\)]), -1,
+ m4_if(m4_regexp([$1], [^/.*]), -1,
+ [.],
+ m4_patsubst([$1], [^\(/\).*], [\1])),
+ m4_patsubst([$1], [^\(//\)\([^/].*\|$\)], [\1])),
+ m4_patsubst([$1], [^\(.*[^/]\)//*[^/][^/]*/*$], [\1]))[]dnl
+]) # _AM_DIRNAME
+
+
+# AM_PROG_LEX
+# Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT
+AC_DEFUN([AM_PROG_LEX],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+AC_CHECK_PROGS(LEX, flex lex, [${am_missing_run}flex])
+AC_PROG_LEX
+AC_DECL_YYTEXT])
+
+# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
+
+# serial 46 AC_PROG_LIBTOOL
+
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])
+
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+_LT_AC_PROG_ECHO_BACKSLASH
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ AC_PATH_MAGIC
+ fi
+ ;;
+esac
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_SAVE
+ AC_LANG_C
+ AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_RESTORE])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one
+ AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+ [AC_TRY_LINK([],
+ [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);
+ DllMain (0, 0, 0);],
+ [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])])
+
+ case $host/$CC in
+ *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*)
+ # old mingw systems require "-dll" to link a DLL, while more recent ones
+ # require "-mdll"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mdll"
+ AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+ [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+ CFLAGS="$SAVE_CFLAGS" ;;
+ *-*-cygwin* | *-*-pw32*)
+ # cygwin systems need to pass --dll to the linker, and not link
+ # crt.o which will require a WinMain@16 definition.
+ lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+ esac
+ ;;
+ ])
+esac
+
+_LT_AC_LTCONFIG_HACK
+
+])
+
+# AC_LIBTOOL_HEADER_ASSERT
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT],
+[AC_CACHE_CHECK([whether $CC supports assert without backlinking],
+ [lt_cv_func_assert_works],
+ [case $host in
+ *-*-solaris*)
+ if test "$GCC" = yes && test "$with_gnu_ld" != yes; then
+ case `$CC --version 2>/dev/null` in
+ [[12]].*) lt_cv_func_assert_works=no ;;
+ *) lt_cv_func_assert_works=yes ;;
+ esac
+ fi
+ ;;
+ esac])
+
+if test "x$lt_cv_func_assert_works" = xyes; then
+ AC_CHECK_HEADERS(assert.h)
+fi
+])# AC_LIBTOOL_HEADER_ASSERT
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)
+])# _LT_AC_CHECK_DLFCN
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+solaris* | sysv5*)
+ symcode='[[BDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $host_os in
+mingw*)
+ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[[ABCDGISTW]]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ rm -f conftest*
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
+
+ cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+ sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
+ cat <<\EOF >> conftest.$ac_ext
+ {0, (lt_ptr) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ pipe_works=yes
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "$progname: failed program was:" >&AC_FD_CC
+ cat conftest.$ac_ext >&5
+ fi
+ rm -f conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+ global_symbol_to_c_name_address=
+else
+ global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
+ global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
+fi
+if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
+then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+# ---------------------------------
+AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR],
+[# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+ [AC_DIVERT_PUSH(NOTICE)])
+_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+ ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X[$]1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+ then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL [$]0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$CONFIG_SHELL [$]0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "[$]0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+ ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+AC_DIVERT_POP
+])# _LT_AC_PROG_ECHO_BACKSLASH
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}]
+EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_unknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_AC_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_AC_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+AC_DEFUN([_LT_AC_LTCONFIG_HACK],
+[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+need_locks="$enable_libtool_lock"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+if test x"$host" != x"$build"; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case $host_os in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+ ;;
+ *)
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="[$]2"
+
+AC_MSG_CHECKING([for objdir])
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+AC_MSG_RESULT($objdir)
+
+
+AC_ARG_WITH(pic,
+[ --with-pic try to use only PIC/non-PIC objects [default=use both]],
+pic_mode="$withval", pic_mode=default)
+test -z "$pic_mode" && pic_mode=default
+
+# We assume here that the value for lt_cv_prog_cc_pic will not be cached
+# in isolation, and that seeing it set (from the cache) indicates that
+# the associated values are set (in the cache) correctly too.
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+AC_CACHE_VAL(lt_cv_prog_cc_pic,
+[ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_shlib=
+ lt_cv_prog_cc_wl=
+ lt_cv_prog_cc_static=
+ lt_cv_prog_cc_no_builtin=
+ lt_cv_prog_cc_can_build_shared=$can_build_shared
+
+ if test "$GCC" = yes; then
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-static'
+
+ case $host_os in
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # not sure about C++ programs.
+ lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_cv_prog_cc_pic='-fno-common'
+ ;;
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_cv_prog_cc_pic=-Kconform_pic
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for PIC flags for the system compiler.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ lt_cv_prog_cc_wl='-Wl,'
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_cv_prog_cc_static='-Bstatic'
+ else
+ lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
+ lt_cv_prog_cc_pic='+Z'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+
+ newsos6)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ # All OSF/1 code is PIC.
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ lt_cv_prog_cc_pic='-Kpic'
+ lt_cv_prog_cc_static='-dn'
+ lt_cv_prog_cc_shlib='-belf'
+ ;;
+
+ solaris*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Wl,'
+ ;;
+
+ sunos4*)
+ lt_cv_prog_cc_pic='-PIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Qoption ld '
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ if test "x$host_vendor" = xsni; then
+ lt_cv_prog_cc_wl='-LD'
+ else
+ lt_cv_prog_cc_wl='-Wl,'
+ fi
+ ;;
+
+ uts4*)
+ lt_cv_prog_cc_pic='-pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_cv_prog_cc_pic='-Kconform_pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ fi
+ ;;
+
+ *)
+ lt_cv_prog_cc_can_build_shared=no
+ ;;
+ esac
+ fi
+])
+if test -z "$lt_cv_prog_cc_pic"; then
+ AC_MSG_RESULT([none])
+else
+ AC_MSG_RESULT([$lt_cv_prog_cc_pic])
+
+ # Check to make sure the pic_flag actually works.
+ AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works])
+ AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+ AC_TRY_COMPILE([], [], [dnl
+ case $host_os in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then
+ # they create non-PIC objects. So, if there were any warnings, we
+ # assume that PIC is not supported.
+ if test -s conftest.err; then
+ lt_cv_prog_cc_pic_works=no
+ else
+ lt_cv_prog_cc_pic_works=yes
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic_works=yes
+ ;;
+ esac
+ ], [dnl
+ lt_cv_prog_cc_pic_works=no
+ ])
+ CFLAGS="$save_CFLAGS"
+ ])
+
+ if test "X$lt_cv_prog_cc_pic_works" = Xno; then
+ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_can_build_shared=no
+ else
+ lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
+ fi
+
+ AC_MSG_RESULT([$lt_cv_prog_cc_pic_works])
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$lt_cv_prog_cc_shlib"; then
+ AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries])
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then :
+ else
+ AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure])
+ lt_cv_prog_cc_can_build_shared=no
+ fi
+fi
+
+AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works])
+AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl
+ lt_cv_prog_cc_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+ AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes])
+ LDFLAGS="$save_LDFLAGS"
+])
+
+# Belt *and* braces to stop my trousers falling down:
+test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
+AC_MSG_RESULT([$lt_cv_prog_cc_static_works])
+
+pic_flag="$lt_cv_prog_cc_pic"
+special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
+wl="$lt_cv_prog_cc_wl"
+link_static_flag="$lt_cv_prog_cc_static"
+no_builtin_flag="$lt_cv_prog_cc_no_builtin"
+can_build_shared="$lt_cv_prog_cc_can_build_shared"
+
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext])
+AC_CACHE_VAL([lt_cv_compiler_c_o], [
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ lt_cv_compiler_c_o=no
+ else
+ lt_cv_compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&AC_FD_CC
+ lt_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+])
+compiler_c_o=$lt_cv_compiler_c_o
+AC_MSG_RESULT([$compiler_c_o])
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ AC_MSG_CHECKING([if $compiler supports -c -o file.lo])
+ AC_CACHE_VAL([lt_cv_compiler_o_lo], [
+ lt_cv_compiler_o_lo=no
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ save_objext="$ac_objext"
+ ac_objext=lo
+ AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ lt_cv_compiler_o_lo=no
+ else
+ lt_cv_compiler_o_lo=yes
+ fi
+ ])
+ ac_objext="$save_objext"
+ CFLAGS="$save_CFLAGS"
+ ])
+ compiler_o_lo=$lt_cv_compiler_o_lo
+ AC_MSG_RESULT([$compiler_o_lo])
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$GCC" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions])
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
+ compiler_rtti_exceptions=no
+ AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ compiler_rtti_exceptions=no
+ else
+ compiler_rtti_exceptions=yes
+ fi
+ ])
+ CFLAGS="$save_CFLAGS"
+ AC_MSG_RESULT([$compiler_rtti_exceptions])
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+fi
+
+# See if the linker supports building shared libraries.
+AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries])
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+old_archive_from_expsyms_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_into_libs=no
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_all_deplibs=unknown
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced. Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+extract_expsyms_cmds=
+
+case $host_os in
+cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ # On AIX, the GNU linker is very broken
+ # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
+ sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
+ test -f $output_objdir/impgen.exe || (cd $output_objdir && \
+ if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
+ else $CC -o impgen impgen.c ; fi)~
+ $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
+
+ old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
+
+ # cygwin and mingw dlls have different entry points and sets of symbols
+ # to exclude.
+ # FIXME: what about values for MSVC?
+ dll_entry=__cygwin_dll_entry@12
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
+ case $host_os in
+ mingw*)
+ # mingw values
+ dll_entry=_DllMainCRTStartup@12
+ dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
+ ;;
+ esac
+
+ # mingw and cygwin differ, and it's simplest to just exclude the union
+ # of the two symbol sets.
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one (in ltdll.c)
+ if test "x$lt_cv_need_dllmain" = "xyes"; then
+ ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
+ ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
+ test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
+ else
+ ltdll_obj=
+ ltdll_cmds=
+ fi
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ # Be careful not to strip the DATA tag left be newer dlltools.
+ export_symbols_cmds="$ltdll_cmds"'
+ $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
+
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is.
+ # If DATA tags from a recent dlltool are present, honour them!
+ archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname-def;
+ else
+ echo EXPORTS > $output_objdir/$soname-def;
+ _lt_hint=1;
+ cat $export_symbols | while read symbol; do
+ set dummy \$symbol;
+ case \[$]# in
+ 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+ *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;;
+ esac;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done;
+ fi~
+ '"$ltdll_cmds"'
+ $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
+ $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
+ $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # dlltool doesn't understand --whole-archive et. al.
+ whole_archive_flag_spec=
+ ;;
+ *)
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ ;;
+ esac
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ hardcode_direct=yes
+ archive_cmds=''
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ esac
+
+ shared_flag='-shared'
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ shared_flag='${wl}-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall can do strange things, so it is better to
+ # generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
+ archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ else
+ hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='${wl}-berok'
+ # This is a bit strange, but is similar to how AIX traditionally builds
+ # it's shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ ;;
+
+ darwin* | rhapsody*)
+ case "$host_os" in
+ rhapsody* | darwin1.[[012]])
+ allow_undefined_flag='-undefined suppress'
+ ;;
+ *) # Darwin 1.3 on
+ allow_undefined_flag='-flat_namespace -undefined suppress'
+ ;;
+ esac
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes. Also zsh mangles
+ # `"' quotes if we put them in here... so don't!
+ archive_cmds='$nonopt $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+ # We need to add '_' to the symbols in $export_symbols first
+ #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ whole_archive_flag_spec='-all_load $convenience'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ case $host_os in
+ hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
+ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
+ esac
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_minus_L=yes # Not in the search PATH, but as the default
+ # location of the library.
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case "$host_os" in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+ #Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ ;;
+
+ solaris*)
+ # gcc --version < 3.0 without binutils cannot create self contained
+ # shared libraries reliably, requiring libgcc.a to resolve some of
+ # the object symbols generated in some cases. Libraries that use
+ # assert need libgcc.a to resolve __eprintf, for example. Linking
+ # a copy of libgcc.a into every shared library to guarantee resolving
+ # such symbols causes other problems: According to Tim Van Holder
+ # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
+ # (to the application) exception stack for one thing.
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ case `$CC --version 2>/dev/null` in
+ [[12]].*)
+ cat <<EOF 1>&2
+
+*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
+*** create self contained shared libraries on Solaris systems, without
+*** introducing a dependency on libgcc.a. Therefore, libtool is disabling
+*** -no-undefined support, which will at least allow you to build shared
+*** libraries. However, you may find that when you link such libraries
+*** into an application without using GCC, you have to manually add
+*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to
+*** upgrade to a newer version of GCC. Another option is to rebuild your
+*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
+
+EOF
+ no_undefined_flag=
+ ;;
+ esac
+ fi
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ if test "x$host_vendor" = xsno; then
+ archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ else
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv5*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec=
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4.2uw2*)
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ hardcode_runpath_var=yes
+ runpath_var=LD_RUN_PATH
+ ;;
+
+ sysv5uw7* | unixware7*)
+ no_undefined_flag='${wl}-z ${wl}text'
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+AC_MSG_RESULT([$ld_shlibs])
+test "$ld_shlibs" = no && can_build_shared=no
+
+# Check hardcoding attributes.
+AC_MSG_CHECKING([how to hardcode library paths into programs])
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$hardcode_shlibpath_var" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+AC_MSG_RESULT([$hardcode_action])
+
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+# PORTME Fill in your ld.so characteristics
+AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4* | aix5*)
+ version_type=linux
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can
+ # not hardcode correct soname into executable. Probably we can
+ # add versioning support to collect2, so additional links can
+ # be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}.so$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi4*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ export_dynamic_flag_spec=-rdynamic
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ need_version=no
+ need_lib_prefix=no
+ case $GCC,$host_os in
+ yes,cygwin*)
+ library_names_spec='$libname.dll.a'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
+ postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog .libs/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $rm \$dlpath'
+ ;;
+ yes,mingw*)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+ ;;
+ yes,pw32*)
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+ ;;
+ *)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes.
+ library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
+ soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ *)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *) version_type=irix ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+openbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case "$host_os" in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_version=no
+ need_lib_prefix=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+ soname_spec='$libname.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+AC_LIBTOOL_DLOPEN_SELF
+
+if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+ AC_CACHE_VAL([lt_cv_archive_cmds_need_lc],
+ [$rm conftest*
+ echo 'static int dummy;' > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile); then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_cv_prog_cc_wl
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi])
+ AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc])
+ ;;
+ esac
+fi
+need_lc=${lt_cv_archive_cmds_need_lc-yes}
+
+# The second clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+ :
+else
+ # If there is no Makefile yet, we rely on a make rule to execute
+ # `config.status --recheck' to rerun these tests and create the
+ # libtool script then.
+ test -f Makefile && make "$ltmain"
+fi
+
+if test -f "$ltmain"; then
+ trap "$rm \"${ofile}T\"; exit 1" 1 2 15
+ $rm -f "${ofile}T"
+
+ echo creating $ofile
+
+ # Now quote all the things that may contain metacharacters while being
+ # careful not to overquote the AC_SUBSTed values. We take copies of the
+ # variables and quote the copies for generation of the libtool script.
+ for var in echo old_CC old_CFLAGS \
+ AR AR_FLAGS CC LD LN_S NM SHELL \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
+ postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
+ old_striplib striplib file_magic_cmd export_symbols_cmds \
+ deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ global_symbol_to_c_name_address \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case $var in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ cat <<__EOF__ > "${ofile}T"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996-2000 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$need_lc
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# The default C compiler.
+CC=$lt_CC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_pic_flag
+pic_mode=$pic_mode
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$lt_compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+ case $host_os in
+ aix3*)
+ cat <<\EOF >> "${ofile}T"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2*)
+ cat <<'EOF' >> "${ofile}T"
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999-2000 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# /* O_BINARY isn't required (or even defined sometimes) under Unix */
+# #ifndef O_BINARY
+# #define O_BINARY 0
+# #endif
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (dll < 1)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+
+EOF
+ ;;
+ esac
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
+
+ mv -f "${ofile}T" "$ofile" || \
+ (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
+ chmod +x "$ofile"
+fi
+
+])# _LT_AC_LTCONFIG_HACK
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_LIBTOOL_PICMODE - implement the --with-pic flag
+# Usage: AC_LIBTOOL_PICMODE[(MODE)]
+# Where MODE is either `yes' or `no'. If omitted, it defaults to
+# `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)])
+
+
+# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="ifelse([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+])
+
+
+# AC_PATH_MAGIC - find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl
+AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | [[A-Za-z]]:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+# AC_PROG_LD_GNU -
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])
+
+# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag,
+[lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+])
+
+# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependant libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* | pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.[[012]])
+ lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ irix5* | nonstopux*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+openbsd*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+ else
+ lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv5uw[[78]]* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ esac
+ ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+])
+
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
+AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library and LTDLINCL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments. Note that LIBLTDL and LTDLINCL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
+# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
+# with '${top_builddir}/' and LTDLINCL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case $enable_ltdl_convenience in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ # For backwards non-gettext consistent compatibility...
+ INCLTDL="$LTDLINCL"
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library and LTDLINCL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments. Note that LIBLTDL and LTDLINCL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
+# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!). If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ LTDLINCL=
+ fi
+ # For backwards non-gettext consistent compatibility...
+ INCLTDL="$LTDLINCL"
+])
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD], [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM], [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef AHUEXCEPTION_HH
+#define AHUEXCEPTION_HH
+/* (C) 2002 POWERDNS.COM BV */
+
+#include<string>
+
+using namespace std;
+
+//! Generic Exception thrown
+class AhuException
+{
+public:
+ AhuException(){reason="Unspecified";};
+ AhuException(string r){reason=r;};
+
+ string reason; //! Print this to tell the user what went wrong
+};
+
+class TimeoutException : public AhuException
+{};
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include <fstream>
+#include <iostream>
+#include "logger.hh"
+#include "arguments.hh"
+#include "misc.hh"
+
+#define L theL("pdns")
+extern Logger &theL(const string &prefix);
+
+const ArgvMap::param_t::const_iterator ArgvMap::begin()
+{
+ return params.begin();
+}
+
+const ArgvMap::param_t::const_iterator ArgvMap::end()
+{
+ return params.end();
+}
+
+string & ArgvMap::set(const string &var)
+{
+ return params[var];
+}
+
+bool ArgvMap::mustDo(const string &var)
+{\r
+ return ((*this)[var]!="no") && ((*this)[var]!="off");
+}
+
+vector<string>ArgvMap::list()
+{
+ vector<string> ret;
+ for(map<string,string>::const_iterator i=params.begin();i!=params.end();++i)
+ ret.push_back(i->first);
+ return ret;
+}
+
+string ArgvMap::getHelp(const string &item)
+{
+ return helpmap[item];
+}
+
+string & ArgvMap::set(const string &var, const string &help)
+{
+ helpmap[var]=help;
+ d_typeMap[var]="Parameter";
+ return set(var);
+}
+
+void ArgvMap::setCmd(const string &var, const string &help)
+{
+ helpmap[var]=help;
+ d_typeMap[var]="Command";
+ set(var)="no";
+}
+
+string & ArgvMap::setSwitch(const string &var, const string &help)
+{
+ helpmap[var]=help;
+ d_typeMap[var]="Switch";
+ return set(var);
+}
+
+
+// FIXME XXX this is pretty ugly
+bool ArgvMap::contains(const string &var, const string &val)
+{
+ const string content(params[var]);
+
+ if(content==val) // easy as pie
+ return true;
+
+ string part;
+ for(string::const_iterator i=content.begin();
+ i!=content.end();
+ i++)
+ {
+ if((*i==' ' || *i==',' || *i=='\t' || (i+1)==content.end()) && !part.empty())
+ {
+ if(i+1==content.end())
+ part+=*i;
+
+ if(part==val)
+ return true;
+ part="";
+ }
+ else
+ part+=*i;
+
+ }
+ return false;
+}
+
+
+string ArgvMap::helpstring(string prefix)
+{
+ if(prefix=="no")
+ prefix="";
+
+ string help;
+
+ for(map<string,string>::const_iterator i=helpmap.begin();
+ i!=helpmap.end();
+ i++)
+ {
+ if(!prefix.empty() && i->first.find(prefix)) // only print items with prefix
+ continue;
+
+ help+=" --";
+ help+=i->first;
+
+ string type=d_typeMap[i->first];
+
+ if(type=="Parameter")
+ help+="=...";
+ else if(type=="Switch")
+ {
+ help+=" | --"+i->first+"=yes";
+ help+=" | --"+i->first+"=no";
+ }
+
+
+ help+="\n\t";
+ help+=i->second;
+ help+="\n";
+
+ }
+ return help;
+}
+
+string ArgvMap::configstring()
+{
+ string help;
+
+ help="# Autogenerated configuration file template\n";
+ for(map<string,string>::const_iterator i=helpmap.begin();
+ i!=helpmap.end();
+ i++)
+ {
+ if(d_typeMap[i->first]=="Command")
+ continue;
+
+ help+="#################################\n";
+ help+="# ";
+ help+=i->first;
+ help+="\t";
+ help+=i->second;
+ help+="\n#\n";
+ help+="# "+i->first+"="+params[i->first]+"\n\n";
+
+ }
+ return help;
+}
+
+
+const string & ArgvMap::operator[](const string &arg)
+{
+ if(!parmIsset(arg))
+ throw ArgException(string("Undefined but needed argument: '")+arg+"'");
+
+
+ return params[arg];
+}
+
+int ArgvMap::asNum(const string &arg)
+{
+ if(!parmIsset(arg))
+ throw ArgException(string("Undefined but needed argument: '")+arg+"'");
+
+ return atoi(params[arg].c_str());
+}
+
+double ArgvMap::asDouble(const string &arg)
+{
+ if(!parmIsset(arg))
+ throw ArgException(string("Undefined but needed argument: '")+arg+"'");
+
+ return atof(params[arg].c_str());
+}
+
+ArgvMap::ArgvMap()
+{
+
+}
+
+bool ArgvMap::parmIsset(const string &var)
+{
+ return (params.find(var)!=params.end());
+}
+
+void ArgvMap::parseOne(const string &arg, const string &parseOnly, bool lax)
+{
+ string var, val;
+ unsigned int pos;
+
+ if(!arg.find("--") &&(pos=arg.find("="))!=string::npos) // this is a --port=25 case
+ {
+ var=arg.substr(2,pos-2);
+ val=arg.substr(pos+1);
+ }
+ else if(!arg.find("--") && (arg.find("=")==string::npos)) // this is a --daemon case
+ {
+ var=arg.substr(2);
+ val="";
+ }
+ else if(arg[0]=='-')
+ {
+ var=arg.substr(1);
+ val="";
+ }
+ else { // command
+ d_cmds.push_back(arg);
+ }
+
+ if(var!="" && (parseOnly.empty() || var==parseOnly)) {
+ if(parmIsset(var))
+ params[var]=val;
+ else
+ if(!lax)
+ throw ArgException("Trying to set unexisting parameter '"+var+"'");
+ }
+}
+
+const vector<string>&ArgvMap::getCommands()
+{
+ return d_cmds;
+}
+
+void ArgvMap::parse(int &argc, char **argv, bool lax)
+{
+ for(int n=1;n<argc;n++) {
+ parseOne(argv[n],"",lax);
+ }
+}
+
+void ArgvMap::preParse(int &argc, char **argv, const string &arg)
+{
+ for(int n=1;n<argc;n++) {
+ string varval=argv[n];
+ if(!varval.find("--"+arg))
+ parseOne(argv[n]);
+ }
+}
+
+bool ArgvMap::preParseFile(const char *fname, const string &arg)
+{
+ ifstream f(fname);
+ if(!f)
+ return false;
+
+ string line;
+ string pline;
+ unsigned int pos;
+
+ while(getline(f,pline)) {
+ chomp(pline,"\t\r\n");
+ if(pline[pline.size()-1]=='\\') {
+ line+=pline.substr(0,pline.length()-1);
+ continue;
+ }
+ else
+ line+=pline;
+
+
+ // strip everything after a #
+ if((pos=line.find("#"))!=string::npos)
+ line=line.substr(0,pos);
+
+ // strip trailing spaces
+ chomp(line," ");
+
+ // strip leading spaces
+ if((pos=line.find_first_not_of(" \t\r\n"))!=string::npos)
+ line=line.substr(pos);
+
+ // gpgsql-basic-query=sdfsdfs dfsdfsdf sdfsdfsfd
+
+ parseOne(string("--")+line, arg);
+ line="";
+ }
+
+ return true;
+}
+
+
+bool ArgvMap::file(const char *fname, bool lax)
+{
+ ifstream f(fname);
+ if(!f) {
+ // L<<"Tried file '"<<fname<<"' for configuration"<<endl;
+ return false;
+ }
+ if(!lax)
+ L<<"Opened file '"<<fname<<"' for configuration"<<endl;
+
+ string line;
+ string pline;
+ unsigned int pos;
+ while(getline(f,pline)) {
+ chomp(pline,"\t\r\n");
+
+ if(pline[pline.size()-1]=='\\') {
+ line+=pline.substr(0,pline.length()-1);
+
+ continue;
+ }
+ else
+ line+=pline;
+
+ // strip everything after a #
+ if((pos=line.find("#"))!=string::npos)
+ line=line.substr(0,pos);
+
+ // strip trailing spaces
+ chomp(line," ");
+
+
+ // strip leading spaces
+ if((pos=line.find_first_not_of(" \t\r\n"))!=string::npos)
+ line=line.substr(pos);
+
+
+ parseOne(string("--")+line,"",lax);
+ line="";
+ }
+
+ return true;
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef ARGUMENTS_HH
+#define ARGUMENTS_HH
+
+#include <map>
+#include <string>
+#include <vector>
+#include "ahuexception.hh"
+
+using namespace std;
+
+typedef AhuException ArgException;
+
+/** This class helps parsing argc and argv into a map of parameters. We have 3 kinds of formats:
+
+
+ -w this leads to a key/value pair of "w"/void
+
+ --port=25 "port"/"25"
+
+ --daemon "daemon"/void
+
+ We do not support "--port 25" syntax.
+
+ It can also read from a file. This file can contain '#' to delimit comments.
+
+ Some sample code:
+
+ \code
+
+ ArgvMap R;
+
+ R.set("port")="25"; // use this to specify default parameters
+ R.file("./default.conf"); // parse configuration file
+
+ R.parse(argc, argv); // read the arguments from main()
+
+ cout<<"Will we be a deamon?: "<<R.isset("daemon")<<endl;
+ cout<<"Our port will be "<<R["port"]<<endl;
+
+ map<string,string>::const_iterator i;
+ cout<<"via iterator"<<endl;
+ for(i=R.begin();i!=R.end();i++)
+ cout<<i->first<<"="<<i->second<<endl;
+ \endcode
+*/
+
+
+
+class ArgvMap
+{
+public:
+ ArgvMap();
+ void parse(int &argc, char **argv, bool lax=false); //!< use this to parse from argc and argv
+ void laxParse(int &argc, char **argv) //!< use this to parse from argc and argv
+ {
+ parse(argc,argv,true);
+ }
+ void ArgvMap::preParse(int &argc, char **argv, const string &arg); //!< use this to preparse a single var
+ bool ArgvMap::preParseFile(const char *fname, const string &arg); //!< use this to preparse a single var in configuration
+
+ bool file(const char *fname, bool lax=false); //!< Parses a file with parameters
+ bool laxFile(const char *fname)
+ {
+ return file(fname,true);
+ }
+ typedef map<string,string> param_t; //!< use this if you need to know the content of the map
+ bool parmIsset(const string &var); //!< Checks if a parameter is set to *a* value
+ bool mustDo(const string &var); //!< if a switch is given, if we must do something (--help)
+ int asNum(const string &var); //!< return a variable value as a number
+ double asDouble(const string &var); //!< return a variable value as a number
+ string &set(const string &); //!< Gives a writable reference and allocates space for it
+ string &set(const string &, const string &); //!< Does the same but also allows to specify a help message
+ void setCmd(const string &, const string &); //!< Add a command flag
+ string &setSwitch(const string &, const string &); //!< Add a command flag
+ string helpstring(string prefix=""); //!< generates the --help
+ string configstring(); //!< generates the --mkconfig
+ bool contains(const string &var, const string &val);
+
+ vector<string>list();
+ string getHelp(const string &item);
+
+ const param_t::const_iterator begin(); //!< iterator semantics
+ const param_t::const_iterator end(); //!< iterator semantics
+ const string &operator[](const string &); //!< iterator semantics
+ const vector<string>&getCommands();
+private:
+ void parseOne(const string &unparsed, const string &parseOnly="", bool lax=false);
+ map<string,string> params;
+ map<string,string> helpmap;
+ map<string,string> d_typeMap;
+ vector<string> d_cmds;
+};
+
+extern ArgvMap &arg();
+
+#endif /* ARGUMENTS_HH */
--- /dev/null
+SUBDIRS=bind
--- /dev/null
+# Makefile.in generated automatically by automake 1.5 from Makefile.am.
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AMTAR = @AMTAR@
+AS = @AS@
+AWK = @AWK@
+CC = @CC@
+CXX = @CXX@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EXEEXT = @EXEEXT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LEX = @LEX@
+LIBDL = @LIBDL@
+LIBRESOLV = @LIBRESOLV@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+am__include = @am__include@
+am__quote = @am__quote@
+install_sh = @install_sh@
+
+SUBDIRS = bind
+subdir = backends
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
+ uninstall-info-recursive all-recursive install-data-recursive \
+ install-exec-recursive installdirs-recursive install-recursive \
+ uninstall-recursive check-recursive installcheck-recursive
+DIST_COMMON = Makefile.am Makefile.in
+DIST_SUBDIRS = $(SUBDIRS)
+all: all-recursive
+
+.SUFFIXES:
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign backends/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && \
+ CONFIG_HEADERS= CONFIG_LINKS= \
+ CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || etags $(ETAGS_ARGS) $$tags $$unique $(LISP)
+
+GTAGS:
+ here=`CDPATH=: && cd $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ $(mkinstalldirs) "$(distdir)/$$dir"; \
+ fi; \
+ if test -d $$d/$$file; then \
+ cp -pR $$d/$$file $(distdir) \
+ || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" \
+ distdir=../$(distdir)/$$subdir \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+
+distclean-am: clean-am distclean-generic distclean-libtool \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
+ clean-generic clean-libtool clean-recursive distclean \
+ distclean-generic distclean-libtool distclean-recursive \
+ distclean-tags distdir dvi dvi-am dvi-recursive info info-am \
+ info-recursive install install-am install-data install-data-am \
+ install-data-recursive install-exec install-exec-am \
+ install-exec-recursive install-info install-info-am \
+ install-info-recursive install-man install-recursive \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am installdirs-recursive maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive mostlyclean \
+ mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
+ tags tags-recursive uninstall uninstall-am uninstall-info-am \
+ uninstall-info-recursive uninstall-recursive
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+AM_CXXFLAGS=-D_GNU_SOURCE
+lib_LTLIBRARIES = libbindbackend.la
+
+libbindbackend_la_SOURCES=bindbackend.cc bindbackend.hh bindparser.yy \
+bindlexer.l zoneparser2.cc ../../misc.cc huffman.cc huffman.hh zoneparser.hh \
+bindparser.hh ../../unix_utility.cc
+
+bin_PROGRAMS = zone2sql
+
+zone2sql_SOURCES=bindparser.yy bindlexer.l zoneparser2.cc \
+../../arguments.cc ../../logger.cc zone2sql.cc ../../statbag.cc ../../misc.cc \
+../../unix_utility.cc
+
+zone2sql_LDFLAGS=
+
+LFLAGS = -s -i
+YFLAGS = -d --verbose --debug
--- /dev/null
+# Makefile.in generated automatically by automake 1.5 from Makefile.am.
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AMTAR = @AMTAR@
+AS = @AS@
+AWK = @AWK@
+CC = @CC@
+CXX = @CXX@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EXEEXT = @EXEEXT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LEX = @LEX@
+LIBDL = @LIBDL@
+LIBRESOLV = @LIBRESOLV@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+am__include = @am__include@
+am__quote = @am__quote@
+install_sh = @install_sh@
+
+AM_CXXFLAGS = -D_GNU_SOURCE
+lib_LTLIBRARIES = libbindbackend.la
+
+libbindbackend_la_SOURCES = bindbackend.cc bindbackend.hh bindparser.yy \
+bindlexer.l zoneparser2.cc ../../misc.cc huffman.cc huffman.hh zoneparser.hh \
+bindparser.hh ../../unix_utility.cc
+
+
+bin_PROGRAMS = zone2sql
+
+zone2sql_SOURCES = bindparser.yy bindlexer.l zoneparser2.cc \
+../../arguments.cc ../../logger.cc zone2sql.cc ../../statbag.cc ../../misc.cc \
+../../unix_utility.cc
+
+
+zone2sql_LDFLAGS =
+
+LFLAGS = -s -i
+YFLAGS = -d --verbose --debug
+subdir = backends/bind
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+libbindbackend_la_LDFLAGS =
+libbindbackend_la_LIBADD =
+am_libbindbackend_la_OBJECTS = bindbackend.lo bindparser.lo bindlexer.lo \
+ zoneparser2.lo misc.lo huffman.lo unix_utility.lo
+libbindbackend_la_OBJECTS = $(am_libbindbackend_la_OBJECTS)
+bin_PROGRAMS = zone2sql$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+
+am_zone2sql_OBJECTS = bindparser.$(OBJEXT) bindlexer.$(OBJEXT) \
+ zoneparser2.$(OBJEXT) arguments.$(OBJEXT) logger.$(OBJEXT) \
+ zone2sql.$(OBJEXT) statbag.$(OBJEXT) misc.$(OBJEXT) \
+ unix_utility.$(OBJEXT)
+zone2sql_OBJECTS = $(am_zone2sql_OBJECTS)
+zone2sql_LDADD = $(LDADD)
+zone2sql_DEPENDENCIES =
+
+DEFS = @DEFS@
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/arguments.Po $(DEPDIR)/bindbackend.Plo \
+@AMDEP_TRUE@ $(DEPDIR)/bindlexer.Plo $(DEPDIR)/bindlexer.Po \
+@AMDEP_TRUE@ $(DEPDIR)/bindparser.Plo $(DEPDIR)/bindparser.Po \
+@AMDEP_TRUE@ $(DEPDIR)/huffman.Plo $(DEPDIR)/logger.Po \
+@AMDEP_TRUE@ $(DEPDIR)/misc.Plo $(DEPDIR)/misc.Po \
+@AMDEP_TRUE@ $(DEPDIR)/statbag.Po $(DEPDIR)/unix_utility.Plo \
+@AMDEP_TRUE@ $(DEPDIR)/unix_utility.Po $(DEPDIR)/zone2sql.Po \
+@AMDEP_TRUE@ $(DEPDIR)/zoneparser2.Plo $(DEPDIR)/zoneparser2.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+ $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CXXFLAGS = @CXXFLAGS@
+LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+LTLEXCOMPILE = $(LIBTOOL) --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
+YLWRAP = $(top_srcdir)/ylwrap
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) --mode=compile $(YACC) $(YFLAGS) $(AM_YFLAGS)
+DIST_SOURCES = $(libbindbackend_la_SOURCES) $(zone2sql_SOURCES)
+DIST_COMMON = Makefile.am Makefile.in TODO bindlexer.c bindparser.cc \
+ bindparser.h ylwrap
+SOURCES = $(libbindbackend_la_SOURCES) $(zone2sql_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .l .lo .o .obj .yy
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign backends/bind/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && \
+ CONFIG_HEADERS= CONFIG_LINKS= \
+ CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+bindparser.h: bindparser.cc
+misc.lo: ../../misc.cc
+unix_utility.lo: ../../unix_utility.cc
+libbindbackend.la: $(libbindbackend_la_OBJECTS) $(libbindbackend_la_DEPENDENCIES)
+ $(CXXLINK) -rpath $(libdir) $(libbindbackend_la_LDFLAGS) $(libbindbackend_la_OBJECTS) $(libbindbackend_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+bindparser.h: bindparser.cc
+arguments.$(OBJEXT): ../../arguments.cc
+logger.$(OBJEXT): ../../logger.cc
+statbag.$(OBJEXT): ../../statbag.cc
+misc.$(OBJEXT): ../../misc.cc
+unix_utility.$(OBJEXT): ../../unix_utility.cc
+zone2sql$(EXEEXT): $(zone2sql_OBJECTS) $(zone2sql_DEPENDENCIES)
+ @rm -f zone2sql$(EXEEXT)
+ $(CXXLINK) $(zone2sql_LDFLAGS) $(zone2sql_OBJECTS) $(zone2sql_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/arguments.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/bindbackend.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/bindlexer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/bindlexer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/bindparser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/bindparser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/huffman.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/logger.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/misc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/misc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/statbag.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/unix_utility.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/unix_utility.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/zone2sql.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/zoneparser2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/zoneparser2.Po@am__quote@
+
+distclean-depend:
+ -rm -rf $(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `cygpath -w $<`
+
+.c.lo:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LTCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$<
+CCDEPMODE = @CCDEPMODE@
+
+.cc.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXXCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$<
+
+.cc.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXXCOMPILE) -c -o $@ `cygpath -w $<`
+
+.cc.lo:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LTCXXCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$<
+
+misc.o: ../../misc.cc
+@AMDEP_TRUE@ source='../../misc.cc' object='misc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/misc.Po' tmpdepfile='$(DEPDIR)/misc.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o misc.o `test -f ../../misc.cc || echo '$(srcdir)/'`../../misc.cc
+
+misc.obj: ../../misc.cc
+@AMDEP_TRUE@ source='../../misc.cc' object='misc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/misc.Po' tmpdepfile='$(DEPDIR)/misc.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o misc.obj `cygpath -w ../../misc.cc`
+
+misc.lo: ../../misc.cc
+@AMDEP_TRUE@ source='../../misc.cc' object='misc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/misc.Plo' tmpdepfile='$(DEPDIR)/misc.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o misc.lo `test -f ../../misc.cc || echo '$(srcdir)/'`../../misc.cc
+
+unix_utility.o: ../../unix_utility.cc
+@AMDEP_TRUE@ source='../../unix_utility.cc' object='unix_utility.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/unix_utility.Po' tmpdepfile='$(DEPDIR)/unix_utility.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix_utility.o `test -f ../../unix_utility.cc || echo '$(srcdir)/'`../../unix_utility.cc
+
+unix_utility.obj: ../../unix_utility.cc
+@AMDEP_TRUE@ source='../../unix_utility.cc' object='unix_utility.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/unix_utility.Po' tmpdepfile='$(DEPDIR)/unix_utility.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix_utility.obj `cygpath -w ../../unix_utility.cc`
+
+unix_utility.lo: ../../unix_utility.cc
+@AMDEP_TRUE@ source='../../unix_utility.cc' object='unix_utility.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/unix_utility.Plo' tmpdepfile='$(DEPDIR)/unix_utility.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix_utility.lo `test -f ../../unix_utility.cc || echo '$(srcdir)/'`../../unix_utility.cc
+
+arguments.o: ../../arguments.cc
+@AMDEP_TRUE@ source='../../arguments.cc' object='arguments.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/arguments.Po' tmpdepfile='$(DEPDIR)/arguments.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o arguments.o `test -f ../../arguments.cc || echo '$(srcdir)/'`../../arguments.cc
+
+arguments.obj: ../../arguments.cc
+@AMDEP_TRUE@ source='../../arguments.cc' object='arguments.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/arguments.Po' tmpdepfile='$(DEPDIR)/arguments.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o arguments.obj `cygpath -w ../../arguments.cc`
+
+arguments.lo: ../../arguments.cc
+@AMDEP_TRUE@ source='../../arguments.cc' object='arguments.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/arguments.Plo' tmpdepfile='$(DEPDIR)/arguments.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o arguments.lo `test -f ../../arguments.cc || echo '$(srcdir)/'`../../arguments.cc
+
+logger.o: ../../logger.cc
+@AMDEP_TRUE@ source='../../logger.cc' object='logger.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/logger.Po' tmpdepfile='$(DEPDIR)/logger.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logger.o `test -f ../../logger.cc || echo '$(srcdir)/'`../../logger.cc
+
+logger.obj: ../../logger.cc
+@AMDEP_TRUE@ source='../../logger.cc' object='logger.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/logger.Po' tmpdepfile='$(DEPDIR)/logger.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logger.obj `cygpath -w ../../logger.cc`
+
+logger.lo: ../../logger.cc
+@AMDEP_TRUE@ source='../../logger.cc' object='logger.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/logger.Plo' tmpdepfile='$(DEPDIR)/logger.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logger.lo `test -f ../../logger.cc || echo '$(srcdir)/'`../../logger.cc
+
+statbag.o: ../../statbag.cc
+@AMDEP_TRUE@ source='../../statbag.cc' object='statbag.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/statbag.Po' tmpdepfile='$(DEPDIR)/statbag.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o statbag.o `test -f ../../statbag.cc || echo '$(srcdir)/'`../../statbag.cc
+
+statbag.obj: ../../statbag.cc
+@AMDEP_TRUE@ source='../../statbag.cc' object='statbag.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/statbag.Po' tmpdepfile='$(DEPDIR)/statbag.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o statbag.obj `cygpath -w ../../statbag.cc`
+
+statbag.lo: ../../statbag.cc
+@AMDEP_TRUE@ source='../../statbag.cc' object='statbag.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/statbag.Plo' tmpdepfile='$(DEPDIR)/statbag.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o statbag.lo `test -f ../../statbag.cc || echo '$(srcdir)/'`../../statbag.cc
+CXXDEPMODE = @CXXDEPMODE@
+
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LEXLIB = @LEXLIB@
+
+.l.c:
+ $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE)
+
+.yy.cc:
+ $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h -- $(YACCCOMPILE)
+uninstall-info-am:
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || etags $(ETAGS_ARGS) $$tags $$unique $(LISP)
+
+GTAGS:
+ here=`CDPATH=: && cd $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ $(mkinstalldirs) "$(distdir)/$$dir"; \
+ fi; \
+ if test -d $$d/$$file; then \
+ cp -pR $$d/$$file $(distdir) \
+ || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir)
+
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "bindparser.hbindparser.h" || rm -f bindparser.h bindparser.h
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am \
+ uninstall-libLTLIBRARIES
+
+.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libLTLIBRARIES clean-libtool distclean \
+ distclean-compile distclean-depend distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am info \
+ info-am install install-am install-binPROGRAMS install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-libLTLIBRARIES install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-info-am uninstall-libLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Stuff not working yet in zone2sql/bindbackend:
+
+$TTL
+Symbol notations of SOA, with 1H standing for 3600 etc
+
+We can't handle filenames that are mentioned multiply in named.conf it
+appears
+
+Reading zones only 1 time per all threads and not every time
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: bindbackend.cc,v 1.1 2002/11/27 15:18:37 ahu Exp $
+#include <errno.h>
+#include <string>
+#include <map>
+#include <set>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace std;
+
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "bindbackend.hh"
+#include "dnspacket.hh"
+
+#include "zoneparser.hh"
+#include "bindparser.hh"
+#include "logger.hh"
+#include "arguments.hh"
+#include "huffman.hh"
+#include "qtype.hh"
+#include "misc.hh"
+
+using namespace std;
+
+
+cmap_t BindBackend::d_qnames;
+map<int,vector<vector<BBResourceRecord>* > > BindBackend::d_zone_id_map;
+set<string> BindBackend::s_contents;
+HuffmanCodec BindBackend::s_hc;
+
+map<unsigned int,BBDomainInfo> BindBackend::d_bbds;
+
+int BindBackend::s_first=1;
+
+BBDomainInfo::BBDomainInfo()
+{
+ d_loaded=false;
+ d_last_check=0;
+ d_checknow=false;
+ d_rwlock=new pthread_rwlock_t;
+ //cout<<"Generated a new bbdomaininfo: "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
+ pthread_rwlock_init(d_rwlock,0);
+}
+
+void BBDomainInfo::setCheckInterval(time_t seconds)
+{
+ d_checkinterval=seconds;
+}
+
+bool BBDomainInfo::current()
+{
+ if(d_checknow)
+ return false;
+
+ if(!d_checkinterval || (time(0)-d_lastcheck<d_checkinterval) || d_filename.empty())
+ return true;
+
+ return (getCtime()==d_ctime);
+}
+
+time_t BBDomainInfo::getCtime()
+{
+ struct stat buf;
+
+ if(d_filename.empty() || stat(d_filename.c_str(),&buf)<0)
+ return 0;
+ d_lastcheck=time(0);
+ return buf.st_ctime;
+}
+
+void BBDomainInfo::setCtime()
+{
+ struct stat buf;
+ if(stat(d_filename.c_str(),&buf)<0)
+ return;
+ d_ctime=buf.st_ctime;
+}
+
+
+void BindBackend::setFresh(u_int32_t domain_id)
+{
+ d_bbds[domain_id].d_last_check=time(0);
+}
+
+bool BindBackend::startTransaction(const string &qname, int id)
+{
+ d_of=new ofstream("/tmp/juh");
+ d_bbds[d_transaction_id=id].lock();
+ return true;
+}
+
+bool BindBackend::commitTransaction()
+{
+ delete d_of;
+ rename("/tmp/juh",d_bbds[d_transaction_id].d_filename.c_str());
+ queueReload(&d_bbds[d_transaction_id]);
+ d_bbds[d_transaction_id].unlock();
+ return true;
+}
+
+
+bool BindBackend::feedRecord(const DNSResourceRecord &r)
+{
+ if(r.qtype.getCode()!=QType::MX)
+ *d_of<<r.qname<<".\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<r.content<<endl;
+ else
+ *d_of<<r.qname<<".\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<r.ttl<<"\t"<<r.priority<<"\t"<<r.content<<endl;
+ return true;
+}
+
+void BindBackend::getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains)
+{
+ for(map<u_int32_t,BBDomainInfo>::const_iterator i=d_bbds.begin();i!=d_bbds.end();++i) {
+ if(i->second.d_master.empty())
+ continue;
+ DomainInfo sd;
+ sd.id=i->first;
+ sd.zone=i->second.d_name;
+ sd.master=i->second.d_master;
+ sd.last_check=i->second.d_last_check;
+ sd.backend=this;
+ sd.kind=DomainInfo::Slave;
+
+ SOAData soadata;
+ soadata.serial=0;
+ soadata.refresh=0;
+ getSOA(i->second.d_name,soadata);
+ sd.serial=soadata.serial;
+ if(sd.last_check+soadata.refresh<(unsigned int)time(0))
+ unfreshDomains->push_back(sd);
+ }
+}
+
+bool BindBackend::getDomainInfo(const string &domain, DomainInfo &di)
+{
+ for(map<u_int32_t,BBDomainInfo>::const_iterator i=d_bbds.begin();i!=d_bbds.end();++i) {
+ if(i->second.d_name==domain) {
+ di.id=i->first;
+ di.zone=domain;
+ di.master=i->second.d_master;
+ di.last_check=i->second.d_last_check;
+ di.backend=this;
+ di.kind=i->second.d_master.empty() ? DomainInfo::Master : DomainInfo::Slave;
+
+ return true;
+ }
+ }
+ return false;
+}
+
+
+static string canonic(string ret)
+{
+ string::iterator i;
+ for(i=ret.begin();
+ i!=ret.end();
+ ++i)
+ *i=tolower(*i);
+
+ if(*(i-1)=='.')
+ ret.resize(i-ret.begin()-1);
+ return ret;
+}
+
+
+void BindBackend::insert(int id, const string &qnameu, const string &qtype, const string &content, int ttl=300, int prio=25)
+{
+ static int s_count;
+ static unsigned int len;
+ static unsigned int ulen;
+ DLOG(
+ if(!((s_count++)%10000))
+ cerr<<"\r"<<s_count-1<<", "<<s_contents.size()<<" different contents, "<<d_qnames.size()<<" different qnames, "<<len/1000000<<"MB, saved: "<<
+ (ulen-len)/1000;
+ );
+ string compressed;
+ s_hc.encode(toLower(canonic(qnameu)),compressed);
+ // string(compressed).swap(compressed);
+ // cout<<"saved: "<<qnameu.size()-compressed.size()<<endl;
+
+ vector<BBResourceRecord>::const_iterator i;
+
+ if(d_qnames[compressed].empty()) { // NEW! NEW! NEW! in de top 40!
+ d_zone_id_map[id].push_back(&d_qnames[compressed]);
+ i=d_qnames[compressed].end();
+ }
+ else
+ for(i=d_qnames[compressed].begin();i!=d_qnames[compressed].end();++i)
+ if(((i)->qtype==QType::chartocode(qtype.c_str())))
+ if((*(i)->content==canonic(content)))
+ break;
+
+ // never saw this specific name/type/content triple before
+ if(i==d_qnames[compressed].end()) {
+ BBResourceRecord v=resourceMaker(id,qtype,canonic(content),ttl,prio);
+ v.qnameptr=&d_qnames.find(compressed)->first;
+ len+=compressed.size();
+ ulen+=qnameu.size();
+ d_qnames[compressed].push_back(v);
+
+ d_qnames[compressed].reserve(0);
+ // vector<BBResourceRecord>&tmp=d_qnames[compressed];
+ // vector<BBResourceRecord>(tmp).swap(tmp);
+ }
+ else {
+ s_count--;
+ }
+
+
+}
+
+
+
+BBResourceRecord BindBackend::resourceMaker(int id, const string &qtype, const string &content, int ttl, int prio)
+{
+ BBResourceRecord make;
+
+ make.domain_id=id;
+
+ make.qtype=QType::chartocode(qtype.c_str());
+
+ set<string>::const_iterator i=s_contents.find(content);
+ if(i==s_contents.end()) {
+ s_contents.insert(content);
+ i=s_contents.find(content);
+ }
+ make.content=&*i;
+ make.ttl=ttl;
+ make.priority=prio;
+ return make;
+}
+
+static BindBackend *us;
+static int domain_id;
+
+static void callback(const string &domain, const string &qtype, const string &content, int ttl, int prio)
+{
+ us->insert(domain_id,domain,qtype,content,ttl,prio);
+}
+
+
+
+BindBackend::BindBackend(const string &suffix)
+{
+ if(!s_first)
+ return;
+
+ setArgPrefix("bind"+suffix);
+
+ s_first=0;
+ if(!mustDo("enable-huffman"))
+ s_hc.passthrough(true);
+
+ if(mustDo("example-zones")) {
+ insert(0,"www.example.com","A","1.2.3.4");
+ insert(0,"example.com","SOA","ns1.example.com hostmaster.example.com");
+ insert(0,"example.com","NS","ns1.example.com",86400);
+ insert(0,"example.com","NS","ns2.example.com",86400);
+ insert(0,"example.com","MX","mail.example.com",3600,25);
+ insert(0,"example.com","MX","mail1.example.com",3600,25);
+ insert(0,"mail.example.com","A","4.3.2.1");
+ insert(0,"mail1.example.com","A","5.4.3.2");
+ insert(0,"ns1.example.com","A","4.3.2.1");
+ insert(0,"ns2.example.com","A","5.4.3.2");
+
+ for(int i=0;i<1000;i++)
+ insert(0,"host-"+itoa(i)+".example.com","A","2.3.4.5");
+
+ BBDomainInfo bbd;
+ bbd.d_name="example.com";
+ bbd.d_filename="";
+ bbd.d_id=0;
+ d_bbds[0]=bbd;
+
+ d_bbds[0].d_loaded=true;
+ }
+
+
+ if(!getArg("config").empty()) {
+ BindParser BP;
+ BP.parse(getArg("config"));
+
+ ZoneParser ZP;
+
+ vector<BindDomainInfo> domains=BP.getDomains();
+
+ us=this;
+ domain_id=1;
+ ZP.setDirectory(BP.getDirectory());
+ ZP.setCallback(&callback);
+ L<<Logger::Warning<<"Parsing "<<domains.size()<<" domain(s)"<<endl;
+
+ for(vector<BindDomainInfo>::const_iterator i=domains.begin();
+ i!=domains.end();
+ ++i)
+ {
+ BBDomainInfo bbd;
+ bbd.d_name=i->name;
+ bbd.d_filename=i->filename;
+ bbd.d_master=i->master;
+ bbd.d_id=domain_id;
+ bbd.setCtime();
+ bbd.setCheckInterval(getArgAsNum("check-interval"));
+
+ d_bbds[domain_id]=bbd;
+
+ ZP.parse(i->filename,i->name); // calls callback for us
+
+ vector<vector<BBResourceRecord> *>&tmp=d_zone_id_map[domain_id];
+ vector<vector<BBResourceRecord> *>(tmp).swap(tmp);
+ d_bbds[domain_id].d_loaded=true;
+
+ domain_id++;
+ }
+ L<<Logger::Warning<<"Done"<<endl;
+ L<<Logger::Info<<"Number of buckets: "<<d_qnames.bucket_count()<<", number of entries: "<<d_qnames.size()<< endl;
+ }
+}
+
+void BindBackend::rediscover()
+{
+
+}
+
+void BindBackend::queueReload(BBDomainInfo *bbd)
+{
+ // we reload *now* for the time being
+ //cout<<"unlock domain"<<endl;
+ bbd->unlock();
+ //cout<<"lock it again"<<endl;
+ bbd->lock();
+ //cout<<"locked, start nuking records"<<endl;
+ bbd->d_loaded=0; // block further access
+
+ // now nuke all records with our id
+ for(vector<vector<BBResourceRecord> *>::const_iterator i=d_zone_id_map[bbd->d_id].begin();
+ i!=d_zone_id_map[bbd->d_id].end();++i)
+ {
+ (*i)->clear();
+ }
+ // cout<<"Now clearing the list of records"<<endl;
+ // now zonk the list with all records for our id
+ d_zone_id_map[bbd->d_id].clear();
+ // now reload
+
+
+ ZoneParser ZP;
+ us=this;
+ domain_id=bbd->d_id;
+ ZP.setCallback(&callback);
+ ZP.parse(bbd->d_filename,bbd->d_name);
+ bbd->setCtime();
+ // and raise d_loaded again!
+ bbd->d_loaded=1;
+ bbd->d_checknow=0;
+ L<<Logger::Warning<<"Zone '"<<bbd->d_name<<"' ("<<bbd->d_filename<<") reloaded"<<endl;
+}
+
+void BindBackend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_p, int zoneId )
+{
+ d_handle=new BindBackend::handle;
+ DLOG(L<<"BindBackend constructing handle for search for "<<qtype.getName()<<" for "<<
+ qname<<endl);
+
+ d_handle->qname=qname;
+ d_handle->parent=this;
+ d_handle->qtype=qtype;
+ string compressed;
+ s_hc.encode(toLower(qname),compressed);
+ d_handle->d_records=d_qnames[compressed];
+ d_handle->d_bbd=0;
+ if(!d_handle->d_records.empty()) {
+ BBDomainInfo& bbd=d_bbds[d_handle->d_records.begin()->domain_id];
+ if(!bbd.tryRLock()) {
+ L<<Logger::Warning<<"Can't get read lock on zone '"<<bbd.d_name<<"'"<<endl;
+ delete d_handle;
+ throw AhuException("Temporarily unavailable due to a zone lock"); // fuck
+ }
+
+ if(!bbd.d_loaded) {
+ delete d_handle;
+ throw AhuException("Temporarily unavailable due to a zone lock"); // fuck
+ }
+
+ if(!bbd.current()) {
+ L<<Logger::Warning<<"Zone '"<<bbd.d_name<<"' ("<<bbd.d_filename<<") needs reloading"<<endl;
+ queueReload(&bbd);
+ }
+ d_handle->d_bbd=&bbd;
+ }
+ else {
+ DLOG(L<<"Query with no results"<<endl);
+ }
+ d_handle->d_iter=d_handle->d_records.begin();
+ d_handle->d_list=false;
+}
+
+BindBackend::handle::handle()
+{
+ d_bbd=0;
+ count=0;
+}
+
+bool BindBackend::get(DNSResourceRecord &r)
+{
+ if(!d_handle->get(r)) {
+ delete d_handle;
+ d_handle=0;
+ return false;
+ }
+ return true;
+}
+
+bool BindBackend::handle::get(DNSResourceRecord &r)
+{
+ if(d_list)
+ return get_list(r);
+ else
+ return get_normal(r);
+}
+
+bool BindBackend::handle::get_normal(DNSResourceRecord &r)
+{
+ DLOG(L << "BindBackend get() was called for "<<qtype.getName() << " record for "<<
+ qname<<"- "<<d_records.size()<<" available!"<<endl);
+
+
+ while(d_iter!=d_records.end() && !(qtype=="ANY" || (d_iter)->qtype==QType(qtype).getCode())) {
+ DLOG(L<<"Skipped "<<qname<<"/"<<QType(d_iter->qtype).getName()<<": '"<<*d_iter->content<<"'"<<endl);
+ d_iter++;
+ }
+ if(d_iter==d_records.end()) { // we've reached the end
+ if(d_bbd) {
+ d_bbd->unlock();
+ d_bbd=0;
+ }
+ return false;
+ }
+
+ DLOG(L << "BindBackend get() returning a rr with a "<<QType(d_iter->qtype).getCode()<<endl);
+
+ r.qname=qname; // fill this in
+
+ r.content=*(d_iter)->content;
+ r.domain_id=(d_iter)->domain_id;
+ r.qtype=(d_iter)->qtype;
+ r.ttl=(d_iter)->ttl;
+ r.priority=(d_iter)->priority;
+ d_iter++;
+
+ return true;
+}
+
+bool BindBackend::list(int id)
+{
+ d_handle=new BindBackend::handle;
+ DLOG(L<<"BindBackend constructing handle for list of "<<id<<endl);
+
+ d_handle->d_qname_iter=d_zone_id_map[id].begin();
+ d_handle->d_qname_end=d_zone_id_map[id].end(); // iter now points to a vector of pointers to vector<BBResourceRecords>
+ d_handle->d_riter=(*(d_handle->d_qname_iter))->begin();
+ d_handle->d_rend=(*(d_handle->d_qname_iter))->end();
+ // rend?
+ d_handle->parent=this;
+ d_handle->id=id;
+ d_handle->d_list=true;
+ return true;
+}
+
+// naam -> naamnummer
+// naamnummer -> vector<BBResourceRecords>, BBResourceRecord bevat ook een pointer naar
+
+bool BindBackend::handle::get_list(DNSResourceRecord &r)
+{
+ DLOG(L << "BindBackend get_list()"<<endl);
+
+ while(d_riter==d_rend) {
+ DLOG(L<<"Starting new record"<<endl);
+ d_qname_iter++;
+ if(d_qname_iter==d_qname_end) { // we've reached the end of recordsets for this id
+ DLOG(L<<"Really stop!"<<endl);
+ return false;
+ }
+ d_riter=(*(d_qname_iter))->begin();
+ d_rend=(*(d_qname_iter))->end();
+ }
+ // d_riter points to a pointer to BBResourceRecord
+
+ // r.qname=qname; // fill this in HOW?!
+
+ r.qname=parent->s_hc.decode(*d_riter->qnameptr);
+
+ r.content=*(d_riter)->content;
+ r.domain_id=(d_riter)->domain_id;
+ r.qtype=(d_riter)->qtype;
+ r.ttl=(d_riter)->ttl;
+ r.priority=(d_riter)->priority;
+ d_riter++;
+ return true;
+}
+
+class BindFactory : public BackendFactory
+{
+ public:
+ BindFactory() : BackendFactory("bind") {}
+
+ void declareArguments(const string &suffix="")
+ {
+ declare(suffix,"config","Location of named.conf","");
+ declare(suffix,"example-zones","Install example zones","no");
+ declare(suffix,"enable-huffman","Enable huffman compression","no");
+ declare(suffix,"check-interval","Interval for zonefile changes","0");
+ }
+
+ DNSBackend *make(const string &suffix="")
+ {
+ return new BindBackend(suffix);
+ }
+};
+
+
+//! Magic class that is activated when the dynamic library is loaded
+class Loader
+{
+public:
+ Loader()
+ {
+ BackendMakers().report(new BindFactory);
+ theL()<<Logger::Notice<<"[BindBackend] This is the bind backend version "VERSION" ("__DATE__", "__TIME__") reporting"<<endl;
+ }
+};
+static Loader loader;
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include <string>
+#include <map>
+#include <set>
+#include <pthread.h>
+#include <time.h>
+#include <fstream>
+
+#include "huffman.hh"
+
+#if __GNUC__ >= 3
+# include <ext/hash_map>
+using namespace __gnu_cxx;
+#else
+# include <hash_map>
+#endif
+
+
+using namespace std;
+
+class BBDomainInfo
+{
+public:
+ BBDomainInfo();
+
+#if 0
+ BBDomainInfo(const BBDomainInfo &orig) {
+ d_name=orig.d_name;
+ d_loaded=orig.d_loaded;
+ d_rwlock=orig.d_rwlock;
+ cout<<"Copied "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
+ }
+ BBDomainInfo &operator=(const BBDomainInfo &orig) {
+ d_loaded=orig.d_loaded;
+ d_rwlock=orig.d_rwlock;
+ cout<<"Assigned "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
+ return *this;
+ }
+#endif
+
+ void setCtime();
+
+ bool current();
+
+ bool d_loaded;
+ bool d_checknow;
+ time_t d_ctime;
+ string d_name;
+ string d_filename;
+ unsigned int d_id;
+ time_t d_last_check;
+ string d_master;
+
+ bool tryRLock()
+ {
+ // cout<<"[trylock!] "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
+ return pthread_rwlock_tryrdlock(d_rwlock)!=EBUSY;
+ }
+
+ void unlock()
+ {
+ // cout<<"[unlock] "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
+ pthread_rwlock_unlock(d_rwlock);
+ }
+
+ void lock()
+ {
+ //cout<<"[writelock!] "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
+
+ pthread_rwlock_wrlock(d_rwlock);
+ }
+
+ void setCheckInterval(time_t seconds);
+private:
+ time_t getCtime();
+ time_t d_checkinterval;
+ time_t d_lastcheck;
+ pthread_rwlock_t *d_rwlock;
+};
+
+
+
+class BBResourceRecord
+{
+public:
+ bool operator==(const BBResourceRecord &o) const
+ {
+ return (o.domain_id==domain_id && o.qtype==qtype && o.content==content &&
+ o.ttl==ttl && o.priority==priority);
+ }
+
+ const string *qnameptr; // 4
+ unsigned int domain_id; // 4
+ unsigned short int qtype; // 2
+ unsigned short int priority; // 2
+ const string *content; // 4
+ unsigned int ttl; // 4
+
+};
+
+struct compare_string
+{
+ bool operator()(const string& s1, const string& s2) const
+ {
+ return s1 == s2;
+ }
+};
+
+struct hash_string
+{
+ size_t operator()(const string& s) const
+ {
+ return __stl_hash_string(s.c_str());
+ }
+};
+
+typedef hash_map<string,vector<BBResourceRecord>, hash_string, compare_string> cmap_t;
+
+
+
+/** The BindBackend is a DNSBackend that can answer DNS related questions. It looks up data
+ in a Bind-style zone file */
+class BindBackend : public DNSBackend
+{
+public:
+ BindBackend(const string &suffix=""); //!< Makes our connection to the database. Calls exit(1) if it fails.
+ void getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains);
+ bool getDomainInfo(const string &domain, DomainInfo &di);
+ time_t getCtime(const string &fname);
+
+
+ void lookup(const QType &, const string &qdomain, DNSPacket *p=0, int zoneId=-1);
+ bool list(int id);
+ bool get(DNSResourceRecord &);
+
+ static DNSBackend *maker();
+ static set<string> s_contents;
+
+ void setFresh(u_int32_t domain_id);
+
+ bool startTransaction(const string &qname, int id);
+ // bool BindBackend::stopTransaction(const string &qname, int id);
+ bool feedRecord(const DNSResourceRecord &r);
+ bool commitTransaction();
+ void insert(int id, const string &qname, const string &qtype, const string &content, int ttl, int prio);
+ void rediscover();
+ static HuffmanCodec s_hc;
+private:
+ class handle
+ {
+ public:
+ bool get(DNSResourceRecord &);
+ ~handle() {
+ if(d_bbd)
+ d_bbd->unlock();
+ }
+ handle();
+
+ BindBackend *parent;
+
+ vector<BBResourceRecord>d_records;
+ vector<BBResourceRecord>::const_iterator d_iter;
+
+ vector<BBResourceRecord>::const_iterator d_riter;
+ vector<BBResourceRecord>::const_iterator d_rend;
+ vector<vector<BBResourceRecord> *>::const_iterator d_qname_iter;
+ vector<vector<BBResourceRecord> *>::const_iterator d_qname_end;
+
+ // static map<int,vector<vector<BBResourceRecord>* > > d_zone_id_map;
+ // vector<vector<BBResourceRecord>* > d_zone_id_map[id]
+ // iterator NAAR vector<BBResourceRecord>* d_zone_id_map[id].begin()
+
+ bool d_list;
+ int id;
+ BBDomainInfo* d_bbd;
+ string qname;
+ QType qtype;
+ private:
+ int count;
+
+ bool get_normal(DNSResourceRecord &);
+ bool get_list(DNSResourceRecord &);
+ };
+
+ static cmap_t d_qnames;
+ static map<int,vector<vector<BBResourceRecord>* > > d_zone_id_map;
+
+ static map<unsigned int, BBDomainInfo>d_bbds;
+ static int s_first;
+
+ int d_transaction_id;
+ ofstream *d_of;
+ handle *d_handle;
+ void queueReload(BBDomainInfo *bbd);
+ BBResourceRecord resourceMaker(int id, const string &qtype, const string &content, int ttl, int prio);
+};
--- /dev/null
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/ahu/tmp/cvs2svn/pdns/pdns/backends/bind/bindlexer.c,v 1.1 2002/11/27 15:18:38 ahu Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <errno.h>
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
+static yyconst short int yy_accept[99] =
+ { 0,
+ 20, 20, 2, 2, 7, 7, 18, 18, 30, 20,
+ 25, 24, 17, 20, 20, 23, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 21, 22, 2, 4, 3,
+ 29, 7, 29, 18, 19, 20, 25, 20, 0, 27,
+ 1, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 2, 3, 3, 5, 7, 0, 18, 20, 0,
+ 26, 12, 20, 20, 20, 20, 20, 20, 20, 20,
+ 0, 20, 10, 20, 20, 20, 20, 16, 9, 8,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 6, 13, 15, 11, 20, 14, 0
+
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 4, 5, 1, 1, 1, 1, 1,
+ 1, 6, 1, 1, 1, 1, 7, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 8, 1,
+ 1, 1, 1, 1, 9, 1, 10, 11, 12, 13,
+ 14, 1, 15, 1, 1, 16, 17, 18, 19, 20,
+ 1, 21, 22, 23, 24, 1, 1, 1, 25, 26,
+ 1, 1, 1, 1, 1, 1, 9, 1, 10, 11,
+
+ 12, 13, 14, 1, 15, 1, 1, 16, 17, 18,
+ 19, 20, 1, 21, 22, 23, 24, 1, 1, 1,
+ 25, 26, 27, 1, 28, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[29] =
+ { 0,
+ 1, 2, 3, 4, 1, 5, 1, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 6, 6
+ } ;
+
+static yyconst short int yy_base[111] =
+ { 0,
+ 0, 0, 26, 27, 32, 33, 114, 113, 116, 0,
+ 113, 221, 221, 40, 32, 221, 104, 98, 97, 93,
+ 91, 100, 88, 82, 87, 221, 221, 0, 221, 39,
+ 221, 45, 0, 0, 221, 0, 103, 67, 101, 221,
+ 0, 94, 87, 80, 84, 89, 79, 70, 68, 70,
+ 71, 0, 43, 45, 221, 52, 84, 0, 121, 84,
+ 221, 0, 74, 73, 68, 69, 59, 66, 68, 67,
+ 70, 67, 0, 52, 59, 61, 53, 0, 0, 221,
+ 43, 54, 46, 42, 44, 42, 47, 44, 35, 34,
+ 34, 0, 0, 0, 0, 6, 0, 221, 149, 155,
+
+ 161, 167, 172, 178, 184, 190, 196, 202, 208, 214
+ } ;
+
+static yyconst short int yy_def[111] =
+ { 0,
+ 98, 1, 99, 99, 100, 100, 101, 101, 98, 102,
+ 98, 98, 98, 103, 102, 98, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 98, 98, 104, 98, 105,
+ 98, 98, 106, 107, 98, 102, 98, 103, 108, 98,
+ 102, 109, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 104, 105, 105, 98, 98, 106, 107, 109, 110,
+ 98, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 98, 102, 102, 102, 102, 102, 102, 102, 102, 98,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 0, 98, 98,
+
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98
+ } ;
+
+static yyconst short int yy_nxt[250] =
+ { 0,
+ 10, 11, 12, 13, 14, 10, 15, 16, 17, 10,
+ 18, 10, 19, 10, 20, 21, 22, 10, 23, 10,
+ 10, 10, 24, 10, 10, 25, 26, 27, 29, 29,
+ 97, 30, 30, 32, 32, 33, 33, 41, 42, 32,
+ 32, 39, 40, 39, 54, 55, 56, 39, 98, 98,
+ 54, 55, 56, 56, 96, 95, 94, 93, 92, 56,
+ 91, 90, 89, 88, 87, 86, 39, 39, 39, 40,
+ 39, 85, 84, 83, 39, 82, 81, 80, 79, 78,
+ 77, 76, 75, 74, 73, 72, 61, 71, 70, 69,
+ 68, 67, 66, 39, 39, 60, 61, 60, 65, 64,
+
+ 63, 60, 62, 40, 37, 51, 50, 49, 48, 47,
+ 46, 45, 44, 43, 37, 98, 35, 35, 98, 98,
+ 60, 60, 60, 61, 60, 98, 98, 98, 60, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 60, 60, 28,
+ 28, 28, 28, 28, 28, 31, 31, 31, 31, 31,
+ 31, 34, 34, 34, 34, 34, 34, 36, 98, 98,
+ 98, 36, 38, 38, 38, 38, 38, 38, 52, 52,
+ 98, 52, 98, 52, 53, 53, 98, 53, 53, 53,
+ 57, 98, 98, 98, 57, 57, 58, 58, 58, 98,
+
+ 58, 58, 39, 39, 39, 39, 39, 39, 59, 59,
+ 59, 59, 59, 59, 60, 60, 60, 60, 60, 60,
+ 9, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98
+ } ;
+
+static yyconst short int yy_chk[250] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 4,
+ 96, 3, 4, 5, 6, 5, 6, 15, 15, 5,
+ 6, 14, 14, 14, 30, 30, 32, 14, 53, 53,
+ 54, 54, 32, 56, 91, 90, 89, 88, 87, 56,
+ 86, 85, 84, 83, 82, 81, 14, 14, 38, 38,
+ 38, 77, 76, 75, 38, 74, 72, 71, 70, 69,
+ 68, 67, 66, 65, 64, 63, 60, 57, 51, 50,
+ 49, 48, 47, 38, 38, 42, 42, 42, 46, 45,
+
+ 44, 42, 43, 39, 37, 25, 24, 23, 22, 21,
+ 20, 19, 18, 17, 11, 9, 8, 7, 0, 0,
+ 42, 42, 59, 59, 59, 0, 0, 0, 59, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 59, 59, 99,
+ 99, 99, 99, 99, 99, 100, 100, 100, 100, 100,
+ 100, 101, 101, 101, 101, 101, 101, 102, 0, 0,
+ 0, 102, 103, 103, 103, 103, 103, 103, 104, 104,
+ 0, 104, 0, 104, 105, 105, 0, 105, 105, 105,
+ 106, 0, 0, 0, 106, 106, 107, 107, 107, 0,
+
+ 107, 107, 108, 108, 108, 108, 108, 108, 109, 109,
+ 109, 109, 109, 109, 110, 110, 110, 110, 110, 110,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "bindlexer.l"
+#define INITIAL 0
+#line 2 "bindlexer.l"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define YYSTYPE char *
+
+#ifdef WIN32
+#include "bindparser.tab.hh"
+#define isatty _isatty
+int isatty( int fd )
+{
+ return _isatty( fd );
+}
+#else
+#include "bindparser.h"
+#endif // WIN32
+
+int linenumber;
+#define MAX_INCLUDE_DEPTH 10
+YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+int include_stack_ln[MAX_INCLUDE_DEPTH];
+char *include_stack_name[MAX_INCLUDE_DEPTH];
+char *current_filename;
+char *original_filename;
+int include_stack_ptr = 0;
+extern const char *bind_directory;
+
+#define comment 1
+
+#define incl 2
+
+#define quoted 3
+
+#define YY_STACK_USED 1
+#line 487 "lex.yy.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 36 "bindlexer.l"
+
+
+
+#line 653 "lex.yy.c"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 99 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 221 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 39 "bindlexer.l"
+BEGIN(comment);
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 40 "bindlexer.l"
+/* eat anything that's not a '*' */
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 41 "bindlexer.l"
+/* eat up '*'s not followed by '/'s */
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 42 "bindlexer.l"
+++linenumber;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 43 "bindlexer.l"
+BEGIN(INITIAL);
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 45 "bindlexer.l"
+BEGIN(incl);
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 46 "bindlexer.l"
+/* eat the whitespace */
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 47 "bindlexer.l"
+{ /* got the include file name */
+ char filename[1024];
+ if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
+ {
+ fprintf( stderr, "Includes nested too deeply" );
+ exit( 1 );
+ }
+
+ yytext[strlen(yytext)-2]=0;
+
+ include_stack[include_stack_ptr]=YY_CURRENT_BUFFER;
+ include_stack_name[include_stack_ptr]=current_filename=strdup(yytext+1);
+ include_stack_ln[include_stack_ptr++]=linenumber;
+ linenumber=1;
+ if(*(yytext+1)=='/')
+ strcpy(filename,yytext+1);
+ else {
+ strcpy(filename,bind_directory);
+ strcat(filename,"/");
+ strcat(filename,yytext+1);
+ }
+
+ if (*yytext &&!(yyin=fopen(filename,"r"))) {
+ fprintf( stderr, "Unable to open '%s': %s\n",filename,strerror(errno));
+ exit( 1 );
+ }
+
+ BEGIN(INITIAL);
+ yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
+
+ }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(comment):
+case YY_STATE_EOF(incl):
+case YY_STATE_EOF(quoted):
+#line 80 "bindlexer.l"
+{
+ if ( --include_stack_ptr < 0 )
+ {
+ yyterminate();
+ }
+
+ else
+ {
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(include_stack[include_stack_ptr]);
+ linenumber=include_stack_ln[include_stack_ptr];
+ free(include_stack_name[include_stack_ptr]);
+ if(include_stack_ptr)
+ current_filename=include_stack_name[include_stack_ptr-1];
+ else
+ current_filename=original_filename;
+ }
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 102 "bindlexer.l"
+return ZONETOK;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 104 "bindlexer.l"
+return FILETOK;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 105 "bindlexer.l"
+return OPTIONSTOK;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 106 "bindlexer.l"
+return ACLTOK;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 107 "bindlexer.l"
+return LOGGINGTOK;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 108 "bindlexer.l"
+return DIRECTORYTOK;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 109 "bindlexer.l"
+return MASTERTOK;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 110 "bindlexer.l"
+return TYPETOK;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 111 "bindlexer.l"
+yy_push_state(quoted);
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 112 "bindlexer.l"
+yylval=strdup(yytext); return QUOTEDWORD;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 113 "bindlexer.l"
+yy_pop_state();
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 114 "bindlexer.l"
+yylval=strdup(yytext);return WORD;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 115 "bindlexer.l"
+return OBRACE;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 116 "bindlexer.l"
+return EBRACE;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 117 "bindlexer.l"
+return SEMICOLON;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 118 "bindlexer.l"
+linenumber++;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 119 "bindlexer.l"
+;
+ YY_BREAK
+case 26:
+*yy_cp = yy_hold_char; /* undo effects of setting up yytext */
+yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 120 "bindlexer.l"
+;
+ YY_BREAK
+case 27:
+*yy_cp = yy_hold_char; /* undo effects of setting up yytext */
+yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 121 "bindlexer.l"
+;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 122 "bindlexer.l"
+{
+ fprintf(stderr,"Parsing '%s': unable to parse line %d at character '%s'\n",current_filename, linenumber, yytext);
+ exit(1); }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 125 "bindlexer.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+#line 943 "lex.yy.c"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 99 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 99 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 98);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 125 "bindlexer.l"
+
--- /dev/null
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define YYSTYPE char *
+
+#ifdef WIN32
+#include "bindparser.tab.hh"
+#define isatty _isatty
+int isatty( int fd )
+{
+ return _isatty( fd );
+}
+#else
+#include "bindparser.h"
+#endif // WIN32
+
+int linenumber;
+#define MAX_INCLUDE_DEPTH 10
+YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+int include_stack_ln[MAX_INCLUDE_DEPTH];
+char *include_stack_name[MAX_INCLUDE_DEPTH];
+char *current_filename;
+char *original_filename;
+int include_stack_ptr = 0;
+extern const char *bind_directory;
+
+%}
+
+%x comment
+%x incl
+%x quoted
+%option stack
+%%
+
+
+"/*" BEGIN(comment);
+<comment>[^*\n]* /* eat anything that's not a '*' */
+<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
+<comment>\n ++linenumber;
+<comment>"*"+"/" BEGIN(INITIAL);
+
+include BEGIN(incl);
+<incl>[ \t;]* /* eat the whitespace */
+<incl>\"[^ \t\n";]+\"; { /* got the include file name */
+ char filename[1024];
+ if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
+ {
+ fprintf( stderr, "Includes nested too deeply" );
+ exit( 1 );
+ }
+
+ yytext[strlen(yytext)-2]=0;
+
+ include_stack[include_stack_ptr]=YY_CURRENT_BUFFER;
+ include_stack_name[include_stack_ptr]=current_filename=strdup(yytext+1);
+ include_stack_ln[include_stack_ptr++]=linenumber;
+ linenumber=1;
+ if(*(yytext+1)=='/')
+ strcpy(filename,yytext+1);
+ else {
+ strcpy(filename,bind_directory);
+ strcat(filename,"/");
+ strcat(filename,yytext+1);
+ }
+
+ if (*yytext &&!(yyin=fopen(filename,"r"))) {
+ fprintf( stderr, "Unable to open '%s': %s\n",filename,strerror(errno));
+ exit( 1 );
+ }
+
+ BEGIN(INITIAL);
+ yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
+
+ }
+
+
+<<EOF>> {
+ if ( --include_stack_ptr < 0 )
+ {
+ yyterminate();
+ }
+
+ else
+ {
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(include_stack[include_stack_ptr]);
+ linenumber=include_stack_ln[include_stack_ptr];
+ free(include_stack_name[include_stack_ptr]);
+ if(include_stack_ptr)
+ current_filename=include_stack_name[include_stack_ptr-1];
+ else
+ current_filename=original_filename;
+ }
+ }
+
+
+
+
+zone return ZONETOK;
+
+file return FILETOK;
+options return OPTIONSTOK;
+acl return ACLTOK;
+logging return LOGGINGTOK;
+directory return DIRECTORYTOK;
+masters return MASTERTOK;
+type return TYPETOK;
+\" yy_push_state(quoted);
+<quoted>[^\"]* yylval=strdup(yytext); return QUOTEDWORD;
+<quoted>\" yy_pop_state();
+[^\" \t\n{};]* yylval=strdup(yytext);return WORD;
+\{ return OBRACE;
+\} return EBRACE;
+; return SEMICOLON;
+\n linenumber++;
+[ \t]* ;
+\/\/.*$ ;
+\#.*$ ;
+. {
+ fprintf(stderr,"Parsing '%s': unable to parse line %d at character '%s'\n",current_filename, linenumber, yytext);
+ exit(1); }
+%%
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/* A Bison parser, made from /home/ahu/programming/ahudns/backends/bind/bindparser.yy
+ by GNU bison 1.35. */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+# define WORD 257
+# define QUOTEDWORD 258
+# define OBRACE 259
+# define EBRACE 260
+# define SEMICOLON 261
+# define ZONETOK 262
+# define FILETOK 263
+# define OPTIONSTOK 264
+# define DIRECTORYTOK 265
+# define ACLTOK 266
+# define LOGGINGTOK 267
+# define CLASSTOK 268
+# define TYPETOK 269
+# define MASTERTOK 270
+
+#line 1 "bindparser.yy"
+\r
+\r
+#define DIRTY_HACK WORD\r
+#undef WORD\r
+\r
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+#include <utility>
+#include <errno.h>
+#include "misc.hh"
+#include "ahuexception.hh"
+using namespace std;
+#define YYDEBUG 1
+extern int yydebug;
+#include "bindparser.hh"
+\r
+#define WORD DIRTY_HACK \r
+
+#define YYSTYPE char *
+
+extern "C"
+{
+ int yyparse(void);
+ int yylex(void);
+ int yywrap()
+ {
+ return 1;
+ }
+
+}
+
+extern int yydebug;
+const char *bind_directory;
+extern int linenumber;
+static void yyerror(const char *str)
+{
+ extern char *current_filename;
+ throw AhuException("Error in bind configuration '"+string(current_filename)+"' on line "+itoa(linenumber)+": "+str);
+}
+
+extern FILE *yyin;
+static BindParser *parent;
+BindDomainInfo s_di;
+
+void BindParser::parse(const string &fname)
+{
+ yydebug=0;
+ yyin=fopen(fname.c_str(),"r");
+
+ if(!yyin)
+ throw AhuException("Unable to open '"+fname+"': "+strerror(errno));
+
+ linenumber=1;
+ parent=this;
+ extern char *current_filename;
+ extern char *original_filename;
+
+ current_filename=original_filename=(char*)fname.c_str();
+
+ yyparse();
+
+// cerr<<"Need to parse "<<d_zonedomains.size()<<" zone statements"<<endl;
+}
+
+void BindParser::setDirectory(const string &dir)
+{
+ d_dir=dir;
+ bind_directory=d_dir.c_str();
+}
+
+const string &BindParser::getDirectory()
+{
+ return d_dir;
+}
+
+const vector<BindDomainInfo>& BindParser::getDomains()
+{
+ return d_zonedomains;
+}
+
+void BindParser::setVerbose(bool verbose)
+{
+ d_verbose=verbose;
+}
+
+void BindParser::commit(BindDomainInfo DI)
+{
+ if(DI.filename[0]!='/')
+ DI.filename=d_dir+"/"+DI.filename;
+
+ if(d_verbose)
+ cerr<<"Domain "<<DI.name<<" lives in file '"<<DI.filename<<"'"<<endl;
+
+ d_zonedomains.push_back(DI);
+}
+
+#ifndef YYSTYPE
+# define YYSTYPE int
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+
+
+
+#define YYFINAL 73
+#define YYFLAG -32768
+#define YYNTBASE 17
+
+/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
+#define YYTRANSLATE(x) ((unsigned)(x) <= 270 ? yytranslate[x] : 41)
+
+/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
+static const char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16
+};
+
+#if YYDEBUG
+static const short yyprhs[] =
+{
+ 0, 0, 1, 5, 7, 9, 11, 13, 14, 18,
+ 20, 24, 29, 34, 39, 43, 47, 51, 52, 56,
+ 58, 59, 63, 65, 67, 70, 71, 74, 76, 78,
+ 80, 84, 88, 89, 93, 95, 97, 99, 101, 106,
+ 107, 111, 113, 116, 119, 121
+};
+static const short yyrhs[] =
+{
+ -1, 17, 18, 7, 0, 20, 0, 23, 0, 21,
+ 0, 22, 0, 0, 19, 20, 7, 0, 29, 0,
+ 8, 39, 32, 0, 8, 39, 3, 32, 0, 10,
+ 5, 27, 6, 0, 13, 5, 27, 6, 0, 12,
+ 39, 24, 0, 12, 40, 24, 0, 5, 25, 6,
+ 0, 0, 26, 7, 25, 0, 3, 0, 0, 22,
+ 7, 27, 0, 20, 0, 28, 0, 11, 39, 0,
+ 0, 29, 30, 0, 3, 0, 31, 0, 39, 0,
+ 5, 19, 6, 0, 5, 33, 6, 0, 0, 33,
+ 21, 7, 0, 20, 0, 37, 0, 38, 0, 34,
+ 0, 16, 5, 35, 6, 0, 0, 35, 36, 7,
+ 0, 3, 0, 9, 39, 0, 15, 3, 0, 4,
+ 0, 3, 0
+};
+
+#endif
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const short yyrline[] =
+{
+ 0, 107, 108, 112, 112, 112, 112, 115, 116, 120,
+ 124, 131, 141, 143, 147, 148, 151, 154, 155, 159,
+ 163, 164, 168, 168, 171, 178, 179, 183, 183, 183,
+ 185, 189, 193, 194, 198, 198, 198, 198, 201, 204,
+ 205, 209, 215, 223, 232, 239
+};
+#endif
+
+
+#if (YYDEBUG) || defined YYERROR_VERBOSE
+
+/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
+static const char *const yytname[] =
+{
+ "$", "error", "$undefined.", "WORD", "QUOTEDWORD", "OBRACE", "EBRACE",
+ "SEMICOLON", "ZONETOK", "FILETOK", "OPTIONSTOK", "DIRECTORYTOK",
+ "ACLTOK", "LOGGINGTOK", "CLASSTOK", "TYPETOK", "MASTERTOK",
+ "root_commands", "root_command", "commands", "command", "zone_command",
+ "options_command", "acl_command", "acl_block", "acls", "acl",
+ "options_commands", "options_directory_command", "terms", "term",
+ "block", "zone_block", "zone_commands", "zone_masters_command",
+ "masters", "master", "zone_file_command", "zone_type_command",
+ "quotedname", "filename", 0
+};
+#endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const short yyr1[] =
+{
+ 0, 17, 17, 18, 18, 18, 18, 19, 19, 20,
+ 21, 21, 22, 22, 23, 23, 24, 25, 25, 26,
+ 27, 27, 22, 22, 28, 29, 29, 30, 30, 30,
+ 31, 32, 33, 33, 21, 21, 21, 21, 34, 35,
+ 35, 36, 37, 38, 39, 40
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const short yyr2[] =
+{
+ 0, 0, 3, 1, 1, 1, 1, 0, 3, 1,
+ 3, 4, 4, 4, 3, 3, 3, 0, 3, 1,
+ 0, 3, 1, 1, 2, 0, 2, 1, 1, 1,
+ 3, 3, 0, 3, 1, 1, 1, 1, 4, 0,
+ 3, 1, 2, 2, 1, 1
+};
+
+/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+ doesn't specify something else to do. Zero means the default is an
+ error. */
+static const short yydefact[] =
+{
+ 1, 25, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 5, 6, 4, 23, 9, 37, 35, 36,
+ 44, 0, 42, 25, 24, 45, 0, 0, 25, 43,
+ 39, 2, 27, 7, 26, 28, 29, 0, 32, 10,
+ 22, 0, 0, 17, 14, 15, 0, 0, 25, 11,
+ 25, 25, 12, 19, 0, 0, 13, 41, 38, 0,
+ 30, 0, 31, 34, 0, 21, 16, 17, 40, 8,
+ 33, 18, 0, 0
+};
+
+static const short yydefgoto[] =
+{
+ 1, 10, 48, 40, 12, 41, 14, 44, 54, 55,
+ 42, 15, 16, 34, 35, 39, 50, 17, 47, 59,
+ 18, 19, 21, 27
+};
+
+static const short yypact[] =
+{
+ -32768, 2, 16, 16, 18, 16, 5, 27, 34, 33,
+ 32,-32768,-32768,-32768,-32768,-32768, 31,-32768,-32768,-32768,
+ -32768, 22,-32768, 20,-32768,-32768, 35, 35, 20,-32768,
+ -32768,-32768,-32768,-32768,-32768,-32768,-32768, 36,-32768,-32768,
+ -32768, 37, 39, 40,-32768,-32768, 42, 1, 44,-32768,
+ 13, 20,-32768,-32768, 45, 46,-32768,-32768,-32768, 47,
+ -32768, 48,-32768,-32768, 49,-32768,-32768, 40,-32768,-32768,
+ -32768,-32768, 52,-32768
+};
+
+static const short yypgoto[] =
+{
+ -32768,-32768,-32768, -1, -8, 56,-32768, 19, -9,-32768,
+ -27,-32768,-32768,-32768,-32768, 23,-32768,-32768,-32768,-32768,
+ -32768,-32768, 0,-32768
+};
+
+
+#define YYLAST 60
+
+
+static const short yytable[] =
+{
+ 11, 46, 72, 22, 57, 24, 26, 58, 25, 20,
+ 2, 3, 4, 5, 6, 7, 36, 8, 9, 62,
+ 20, 2, 3, 23, 65, 37, -20, 38, 8, 9,
+ 4, 5, 28, 7, 32, 20, 33, 29, 30, 31,
+ 43, 38, 64, 53, 51, 52, 45, 61, 56, 63,
+ 60, 66, 73, 67, 68, 69, 70, 13, 71, 0,
+ 49
+};
+
+static const short yycheck[] =
+{
+ 1, 28, 0, 3, 3, 5, 6, 6, 3, 4,
+ 8, 9, 10, 11, 12, 13, 16, 15, 16, 6,
+ 4, 8, 9, 5, 51, 3, 6, 5, 15, 16,
+ 10, 11, 5, 13, 3, 4, 5, 3, 5, 7,
+ 5, 5, 50, 3, 7, 6, 27, 48, 6, 50,
+ 6, 6, 0, 7, 7, 7, 7, 1, 67, -1,
+ 37
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/share/bison/bison.simple"
+
+/* Skeleton output parser for bison,
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* This is the parser code that is written into each bison parser when
+ the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+# if YYLSP_NEEDED
+ YYLTYPE yyls;
+# endif
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# if YYLSP_NEEDED
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAX)
+# else
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAX)
+# endif
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up"); \
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run).
+
+ When YYLLOC_DEFAULT is run, CURRENT is set the location of the
+ first token. By default, to implement support for ranges, extend
+ its range to the last symbol. */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#if YYPURE
+# if YYLSP_NEEDED
+# ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+# else
+# define YYLEX yylex (&yylval, &yylloc)
+# endif
+# else /* !YYLSP_NEEDED */
+# ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+# else
+# define YYLEX yylex (&yylval)
+# endif
+# endif /* !YYLSP_NEEDED */
+#else /* !YYPURE */
+# define YYLEX yylex ()
+#endif /* !YYPURE */
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+\f
+#ifdef YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+#endif
+\f
+#line 315 "/usr/share/bison/bison.simple"
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL
+# else
+# define YYPARSE_PARAM_ARG YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
+ variables are global, or local to YYPARSE. */
+
+#define YY_DECL_NON_LSP_VARIABLES \
+/* The lookahead symbol. */ \
+int yychar; \
+ \
+/* The semantic value of the lookahead symbol. */ \
+YYSTYPE yylval; \
+ \
+/* Number of parse errors so far. */ \
+int yynerrs;
+
+#if YYLSP_NEEDED
+# define YY_DECL_VARIABLES \
+YY_DECL_NON_LSP_VARIABLES \
+ \
+/* Location data for the lookahead symbol. */ \
+YYLTYPE yylloc;
+#else
+# define YY_DECL_VARIABLES \
+YY_DECL_NON_LSP_VARIABLES
+#endif
+
+
+/* If nonreentrant, generate the variables here. */
+
+#if !YYPURE
+YY_DECL_VARIABLES
+#endif /* !YYPURE */
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ /* If reentrant, generate the variables here. */
+#if YYPURE
+ YY_DECL_VARIABLES
+#endif /* !YYPURE */
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yychar1 = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+#if YYLSP_NEEDED
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+#endif
+
+#if YYLSP_NEEDED
+# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+# define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+#if YYLSP_NEEDED
+ YYLTYPE yyloc;
+#endif
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+#if YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. */
+# if YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+ yyls = yyls1;
+# else
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+# endif
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+# if YYLSP_NEEDED
+ YYSTACK_RELOCATE (yyls);
+# endif
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+#if YYLSP_NEEDED
+ yylsp = yyls + yysize - 1;
+#endif
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE (yychar);
+
+#if YYDEBUG
+ /* We have to keep this `#if YYDEBUG', since we use variables
+ which are defined only if `YYDEBUG' is set. */
+ if (yydebug)
+ {
+ YYFPRINTF (stderr, "Next token is %d (%s",
+ yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise
+ meaning of a token, for further debugging info. */
+# ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+# endif
+ YYFPRINTF (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %d (%s), ",
+ yychar, yytname[yychar1]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#if YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to the semantic value of
+ the lookahead token. This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+#if YYLSP_NEEDED
+ /* Similarly for the default location. Let the user run additional
+ commands if for instance locations are ranges. */
+ yyloc = yylsp[1-yylen];
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+#endif
+
+#if YYDEBUG
+ /* We have to keep this `#if YYDEBUG', since we use variables which
+ are defined only if `YYDEBUG' is set. */
+ if (yydebug)
+ {
+ int yyi;
+
+ YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+ YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+ switch (yyn) {
+
+case 10:
+#line 126 "bindparser.yy"
+{
+ s_di.name=yyvsp[-1];
+ parent->commit(s_di);
+ s_di.clear();
+ }
+ break;
+case 11:
+#line 133 "bindparser.yy"
+{
+ s_di.name=yyvsp[-2];
+ parent->commit(s_di);
+ s_di.clear();
+ }
+ break;
+case 24:
+#line 172 "bindparser.yy"
+{
+ parent->setDirectory(yyvsp[0]);
+ }
+ break;
+case 41:
+#line 210 "bindparser.yy"
+{
+ s_di.master=yyvsp[0];
+ }
+ break;
+case 42:
+#line 217 "bindparser.yy"
+{
+ // printf("Found a filename: '%s'\n",$2);
+ s_di.filename=yyvsp[0];
+ }
+ break;
+case 43:
+#line 225 "bindparser.yy"
+{
+ // printf("Found a filename: '%s'\n",$2);
+ // ztype=$2;
+ }
+ break;
+case 44:
+#line 234 "bindparser.yy"
+{
+ yyval=yyvsp[0];
+ }
+ break;
+}
+
+#line 705 "/usr/share/bison/bison.simple"
+
+\f
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#if YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+#if YYLSP_NEEDED
+ *++yylsp = yyloc;
+#endif
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ char *yymsg;
+ int yyx, yycount;
+
+ yycount = 0;
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ if (yycheck[yyx + yyn] == yyx)
+ yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+ yysize += yystrlen ("parse error, unexpected ") + 1;
+ yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
+
+ if (yycount < 5)
+ {
+ yycount = 0;
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *));
+ yyx++)
+ if (yycheck[yyx + yyn] == yyx)
+ {
+ const char *yyq = ! yycount ? ", expecting " : " or ";
+ yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yycount++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exhausted");
+ }
+ else
+#endif /* defined (YYERROR_VERBOSE) */
+ yyerror ("parse error");
+ }
+ goto yyerrlab1;
+
+
+/*--------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action |
+`--------------------------------------------------*/
+yyerrlab1:
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+ YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
+ yychar, yytname[yychar1]));
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+
+/*-------------------------------------------------------------------.
+| yyerrdefault -- current state does not do anything special for the |
+| error token. |
+`-------------------------------------------------------------------*/
+yyerrdefault:
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+
+ /* If its default is to accept any token, ok. Otherwise pop it. */
+ yyn = yydefact[yystate];
+ if (yyn)
+ goto yydefault;
+#endif
+
+
+/*---------------------------------------------------------------.
+| yyerrpop -- pop the current state because it cannot handle the |
+| error token |
+`---------------------------------------------------------------*/
+yyerrpop:
+ if (yyssp == yyss)
+ YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#if YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "Error: state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+
+/*--------------.
+| yyerrhandle. |
+`--------------*/
+yyerrhandle:
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+#if YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+/*---------------------------------------------.
+| yyoverflowab -- parser overflow comes here. |
+`---------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+#line 240 "bindparser.yy"
--- /dev/null
+#ifndef BISON_Y_TAB_H
+# define BISON_Y_TAB_H
+
+# ifndef YYSTYPE
+# define YYSTYPE int
+# define YYSTYPE_IS_TRIVIAL 1
+# endif
+# define WORD 257
+# define QUOTEDWORD 258
+# define OBRACE 259
+# define EBRACE 260
+# define SEMICOLON 261
+# define ZONETOK 262
+# define FILETOK 263
+# define OPTIONSTOK 264
+# define DIRECTORYTOK 265
+# define ACLTOK 266
+# define LOGGINGTOK 267
+# define CLASSTOK 268
+# define TYPETOK 269
+# define MASTERTOK 270
+
+
+extern YYSTYPE yylval;
+
+#endif /* not BISON_Y_TAB_H */
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef BINDPARSER_HH
+#define BINDPARSER_HH
+#include <string>
+#include <map>
+#include <vector>
+
+using namespace std;
+
+class BindDomainInfo
+{
+public:
+ void clear()
+ {
+ name=filename=master="";
+ }
+ string name;
+ string filename;
+ string master;
+};
+
+extern const char *bind_directory;
+class BindParser
+{
+ public:
+ BindParser() : d_dir("."), d_verbose(false) {bind_directory=d_dir.c_str();}
+ void parse(const string &fname);
+ void commit(BindDomainInfo DI);
+ void setDirectory(const string &dir);
+ const string &getDirectory();
+ const vector<BindDomainInfo>& getDomains();
+ void setVerbose(bool verbose);
+private:
+ string d_dir;
+ bool d_verbose;
+ typedef map<string,string> zonedomain_t;
+
+ vector<BindDomainInfo> d_zonedomains;
+};
+
+#endif /* BINDPARSER_HH */
--- /dev/null
+%{\r
+\r
+#define DIRTY_HACK WORD\r
+#undef WORD\r
+\r
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+#include <utility>
+#include <errno.h>
+#include "misc.hh"
+#include "ahuexception.hh"
+using namespace std;
+#define YYDEBUG 1
+extern int yydebug;
+#include "bindparser.hh"
+\r
+#define WORD DIRTY_HACK \r
+
+#define YYSTYPE char *
+
+extern "C"
+{
+ int yyparse(void);
+ int yylex(void);
+ int yywrap()
+ {
+ return 1;
+ }
+
+}
+
+extern int yydebug;
+const char *bind_directory;
+extern int linenumber;
+static void yyerror(const char *str)
+{
+ extern char *current_filename;
+ throw AhuException("Error in bind configuration '"+string(current_filename)+"' on line "+itoa(linenumber)+": "+str);
+}
+
+extern FILE *yyin;
+static BindParser *parent;
+BindDomainInfo s_di;
+
+void BindParser::parse(const string &fname)
+{
+ yydebug=0;
+ yyin=fopen(fname.c_str(),"r");
+
+ if(!yyin)
+ throw AhuException("Unable to open '"+fname+"': "+strerror(errno));
+
+ linenumber=1;
+ parent=this;
+ extern char *current_filename;
+ extern char *original_filename;
+
+ current_filename=original_filename=(char*)fname.c_str();
+
+ yyparse();
+
+// cerr<<"Need to parse "<<d_zonedomains.size()<<" zone statements"<<endl;
+}
+
+void BindParser::setDirectory(const string &dir)
+{
+ d_dir=dir;
+ bind_directory=d_dir.c_str();
+}
+
+const string &BindParser::getDirectory()
+{
+ return d_dir;
+}
+
+const vector<BindDomainInfo>& BindParser::getDomains()
+{
+ return d_zonedomains;
+}
+
+void BindParser::setVerbose(bool verbose)
+{
+ d_verbose=verbose;
+}
+
+void BindParser::commit(BindDomainInfo DI)
+{
+ if(DI.filename[0]!='/')
+ DI.filename=d_dir+"/"+DI.filename;
+
+ if(d_verbose)
+ cerr<<"Domain "<<DI.name<<" lives in file '"<<DI.filename<<"'"<<endl;
+
+ d_zonedomains.push_back(DI);
+}
+
+%}
+
+%token WORD QUOTEDWORD OBRACE EBRACE SEMICOLON ZONETOK FILETOK OPTIONSTOK
+%token DIRECTORYTOK ACLTOK LOGGINGTOK CLASSTOK TYPETOK MASTERTOK
+
+%%
+
+root_commands:
+ |
+ root_commands root_command SEMICOLON
+ ;
+
+root_command: command | acl_command | zone_command | options_command
+ ;
+
+commands:
+ |
+ commands command SEMICOLON
+ ;
+
+command:
+ terms
+ ;
+
+zone_command:
+ ZONETOK quotedname zone_block
+ {
+ s_di.name=$2;
+ parent->commit(s_di);
+ s_di.clear();
+ }
+ |
+ ZONETOK quotedname WORD zone_block
+ {
+ s_di.name=$2;
+ parent->commit(s_di);
+ s_di.clear();
+ }
+ ;
+
+
+options_command:
+ OPTIONSTOK OBRACE options_commands EBRACE
+ |
+ LOGGINGTOK OBRACE options_commands EBRACE
+ ;
+
+acl_command:
+ ACLTOK quotedname acl_block | ACLTOK filename acl_block
+ ;
+
+acl_block: OBRACE acls EBRACE
+ ;
+
+acls:
+ |
+ acl SEMICOLON acls
+ ;
+
+acl:
+ WORD
+ ;
+
+options_commands:
+ |
+ options_command SEMICOLON options_commands
+ ;
+
+options_command: command | options_directory_command
+ ;
+
+options_directory_command: DIRECTORYTOK quotedname
+ {
+ parent->setDirectory($2);
+ }
+ ;
+
+
+terms: /* empty */
+ |
+ terms term
+ ;
+
+term: WORD | block | quotedname
+ ;
+block:
+ OBRACE commands EBRACE
+ ;
+
+zone_block:
+ OBRACE zone_commands EBRACE
+ ;
+
+zone_commands:
+ |
+ zone_commands zone_command SEMICOLON
+ ;
+
+zone_command: command | zone_file_command | zone_type_command | zone_masters_command
+ ;
+
+zone_masters_command: MASTERTOK OBRACE masters EBRACE
+ ;
+
+masters: /* empty */
+ |
+ masters master SEMICOLON
+ ;
+
+master: WORD
+ {
+ s_di.master=$1;
+ }
+ ;
+
+zone_file_command:
+ FILETOK quotedname
+ {
+ // printf("Found a filename: '%s'\n",$2);
+ s_di.filename=$2;
+ }
+ ;
+
+zone_type_command:
+ TYPETOK WORD
+ {
+ // printf("Found a filename: '%s'\n",$2);
+ // ztype=$2;
+ }
+ ;
+
+
+quotedname:
+ QUOTEDWORD
+ {
+ $$=$1;
+ }
+ ;
+
+filename: WORD
+ ;
\ No newline at end of file
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include <string>
+#include "huffman.hh"
+#include <bitset>
+#include <map>
+#include <sstream>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+#include <utility>
+
+void HuffmanCodec::set(char c,const string &code)
+{
+ d_dict[c]=code;
+}
+
+HuffmanCodec::HuffmanCodec()
+{
+ d_dict.clear();
+ set('6',"0000");
+ set('5',"0001");
+ set(0,"0010");
+ set('3',"0011");
+ set('4',"0100");
+ set('s',"0101");
+ set('n',"011");
+ set('c',"100000");
+ set('u',"100001");
+ set('-',"1000100");
+ set('1',"1000101");
+ set('f',"1000110");
+ set('j',"10001110");
+ set('9',"1000111100");
+ set('*',"100011110100");
+ set('q',"100011110101");
+ set('7',"10001111011");
+ set('8',"100011111");
+ set('o',"10010");
+ set('t',"10011");
+ set('e',"1010");
+ set('a',"10110");
+ set('r',"10111");
+ set('d',"110000");
+ set('2',"1100010");
+ set('k',"1100011");
+ set('.',"110010");
+ set('v',"1100110");
+ set('w',"1100111");
+ set('i',"1101");
+ set('l',"111000");
+ set('p',"1110010");
+ set('b',"1110011");
+ set('z',"111010000");
+ set('y',"111010001");
+ set('x',"11101001");
+ set('h',"1110101");
+ set('m',"1110110");
+ set('g',"1110111");
+ set('0',"1111");
+
+ d_min=10000;
+ d_max=0;
+ d_rdict.resize(128);
+ for(map<char,string>::const_iterator i=d_dict.begin();i!=d_dict.end();++i) {
+ d_min=min(d_min,i->second.length());
+ d_max=max(d_max,i->second.length());
+
+ (d_rdict[i->second.length()])[i->second]=i->first;
+ }
+ d_last_compressed=d_last_out="";
+ d_passthrough=false;
+}
+
+void HuffmanCodec::passthrough(bool shoulddo)
+{
+ d_passthrough=shoulddo;
+}
+
+
+// Bitify input: 1001101110101001000101
+//Decode got offered: '1001101110101001'
+
+
+void HuffmanCodec::decode(const string &compressed, string &out)
+{
+ if(d_passthrough) {
+ out=compressed;
+ return;
+ }
+ if(compressed==d_last_compressed) {
+ out=d_last_out;
+ return;
+ }
+ string full;
+
+ out="";
+ unbitify(compressed, full);
+ // cout<<"Decode got offered: '"<<full<<"'"<<endl;
+
+ unsigned int pos=0;
+ size_t cleft=full.length();
+ size_t mlen;
+ out.reserve(full.length()/5);
+ while(cleft) {
+ map<string,char>::const_iterator i;
+
+ for(mlen=d_min;mlen<=cleft && mlen<=d_max;++mlen) {
+ if(d_rdict[mlen].empty())
+ continue;
+
+ i=d_rdict[mlen].find(full.substr(pos,mlen));
+
+ if(i!=d_rdict[mlen].end()) { // match
+ if(!i->second) {
+ d_last_compressed=compressed;
+ d_last_out=out;
+ return;
+ }
+
+ out.append(1,i->second);
+
+ pos+=mlen;
+ cleft-=mlen;
+ break;
+ }
+ }
+ }
+ if(cleft)
+ throw AhuException("Unable to parse huffman symbol "+full.substr(pos));
+ d_last_compressed=compressed;
+ d_last_out=out;
+}
+
+void HuffmanCodec::encode(const string &in, string &out)
+{
+ if(d_passthrough) {
+ out=in;
+ return;
+ }
+ string full;
+ for(string::const_iterator i=in.begin();i!=in.end();++i) {
+ map<char,string>::const_iterator j=d_dict.find(tolower(*i));
+ if(j==d_dict.end()) {
+ string c;
+ char cc=tolower(*i);
+ c.append(1,cc);
+ throw AhuException("Trying to huffman encode an unknown symbol '"+c+"'");
+ }
+ full.append(j->second);
+ }
+ full.append(d_dict[0]);
+ bitify(full,out);
+ // cout<<"full: "<<full<<endl;
+}
+
+void HuffmanCodec::bitify(const string &full, string &out)
+{
+ unsigned char bitpos=0;
+ unsigned char curbyte=0;
+ // cout<<"Bitify input: "<<full<<endl;
+ for(string::const_iterator i=full.begin();i!=full.end();++i) {
+ curbyte|= (*i=='1')<<(7-bitpos);
+ if(bitpos++==7) {
+ out.append(1,curbyte);
+ bitpos=0;
+ curbyte=0;
+ }
+ }
+ out.append(1,curbyte);
+}
+
+void HuffmanCodec::unbitify(const string &in, string &full)
+{
+ bitset<8> byte;
+ ostringstream os;
+ full.reserve(in.length()*8);
+ for(string::const_iterator i=in.begin();i!=in.end();++i) {
+ byte=*i;
+ os<<byte;
+ }
+ full.append(os.str());
+}
+
+#if 0
+int main(int argc, char **argv)
+{
+ string in(argv[1]);
+ string compressed;
+
+ try {
+ HuffmanCodec hc;
+ // hc.initDictionary(dict);
+ // cout<<"in: "<<in.length()<<endl;
+ hc.encode(in,compressed);
+ // cout<<"compressed: "<<compressed.length()<<endl;
+ // cout<<"Compressed: '"<<compressed<<"'"<<endl;
+
+ string out;
+ hc.decode(compressed,out);
+
+ cout<<"'"<<out<<"'"<<endl;
+ }
+ catch(AhuException &ae) {
+ cerr<<"Fatal error: "<<ae.reason<<endl;
+ }
+}
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PDNS_HUFFMAN
+#define PDNS_HUFFMAN
+#include <string>
+#include <bitset>
+#include <map>
+#include <sstream>
+#include <vector>
+#include "../../ahuexception.hh"
+
+using namespace std;
+
+class HuffmanCodec
+{
+public:
+ HuffmanCodec();
+ void encode(const string &in, string &out);
+ void decode(const string &compressed, string &out);
+ void passthrough(bool);
+ string decode(const string &in) {
+ string tmp;
+ decode(in,tmp);
+ return tmp;
+ }
+private:
+ void bitify(const string &full, string &out);
+ void unbitify(const string &in, string &full);
+ void set(char c,const string &code);
+ map<char,string> d_dict;
+ vector<map<string,char> >d_rdict;
+ size_t d_min, d_max;
+ string d_last_compressed;
+ string d_last_out;
+ bool d_passthrough;
+};
+#endif /* PDNS_HUFFMAN */
--- /dev/null
+#! /bin/sh
+# ylwrap - wrapper for lex/yacc invocations.
+# Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Usage:
+# ylwrap INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
+# * INPUT is the input file
+# * OUTPUT is file PROG generates
+# * DESIRED is file we actually want
+# * PROGRAM is program to run
+# * ARGS are passed to PROG
+# Any number of OUTPUT,DESIRED pairs may be used.
+
+# The input.
+input="$1"
+shift
+case "$input" in
+ [\\/]* | ?:[\\/]*)
+ # Absolute path; do nothing.
+ ;;
+ *)
+ # Relative path. Make it absolute.
+ input="`pwd`/$input"
+ ;;
+esac
+
+# The directory holding the input.
+input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'`
+# Quote $INPUT_DIR so we can use it in a regexp.
+# FIXME: really we should care about more than `.' and `\'.
+input_rx=`echo "$input_dir" | sed -e 's,\\\\,\\\\\\\\,g' -e 's,\\.,\\\\.,g'`
+
+echo "got $input_rx"
+
+pairlist=
+while test "$#" -ne 0; do
+ if test "$1" = "--"; then
+ shift
+ break
+ fi
+ pairlist="$pairlist $1"
+ shift
+done
+
+# The program to run.
+prog="$1"
+shift
+# Make any relative path in $prog absolute.
+case "$prog" in
+ [\\/]* | ?:[\\/]*) ;;
+ *[\\/]*) prog="`pwd`/$prog" ;;
+esac
+
+# FIXME: add hostname here for parallel makes that run commands on
+# other machines. But that might take us over the 14-char limit.
+dirname=ylwrap$$
+trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15
+mkdir $dirname || exit 1
+
+cd $dirname
+
+$prog ${1+"$@"} "$input"
+status=$?
+
+if test $status -eq 0; then
+ set X $pairlist
+ shift
+ first=yes
+ # Since DOS filename conventions don't allow two dots,
+ # the DOS version of Bison writes out y_tab.c instead of y.tab.c
+ # and y_tab.h instead of y.tab.h. Test to see if this is the case.
+ y_tab_nodot="no"
+ if test -f y_tab.c || test -f y_tab.h; then
+ y_tab_nodot="yes"
+ fi
+
+ while test "$#" -ne 0; do
+ from="$1"
+ # Handle y_tab.c and y_tab.h output by DOS
+ if test $y_tab_nodot = "yes"; then
+ if test $from = "y.tab.c"; then
+ from="y_tab.c"
+ else
+ if test $from = "y.tab.h"; then
+ from="y_tab.h"
+ fi
+ fi
+ fi
+ if test -f "$from"; then
+ # If $2 is an absolute path name, then just use that,
+ # otherwise prepend `../'.
+ case "$2" in
+ [\\/]* | ?:[\\/]*) target="$2";;
+ *) target="../$2";;
+ esac
+
+ # Edit out `#line' or `#' directives. We don't want the
+ # resulting debug information to point at an absolute srcdir;
+ # it is better for it to just mention the .y file with no
+ # path.
+ sed -e "/^#/ s,$input_rx,," "$from" > "$target" || status=$?
+ else
+ # A missing file is only an error for the first file. This
+ # is a blatant hack to let us support using "yacc -d". If -d
+ # is not specified, we don't want an error when the header
+ # file is "missing".
+ if test $first = yes; then
+ status=1
+ fi
+ fi
+ shift
+ shift
+ first=no
+ done
+else
+ status=$?
+fi
+
+# Remove the directory.
+cd ..
+rm -rf $dirname
+
+exit $status
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/* accepts a named.conf as parameter and outputs heaps of sql */
+
+// $Id: zone2sql.cc,v 1.1 2002/11/27 15:18:39 ahu Exp $
+#ifdef WIN32
+# pragma warning ( disable: 4786 )
+# include <unistd.h>
+#endif // WIN32
+
+#include <string>
+#include <map>
+
+#include <iostream>
+#include <stdio.h>
+
+using namespace std;
+
+#include "dns.hh"
+#include "arguments.hh"
+#include "zoneparser.hh"
+#include "bindparser.hh"
+#include "statbag.hh"
+#include "misc.hh"
+
+StatBag S;
+
+string sqlstr(const string &str)
+{
+ if(str.find("\'")!=string::npos)
+ throw 0;
+
+ string ret="\'";
+ ret+=str;
+ ret+="\'";
+ return ret;
+}
+
+static int dirty_hack_num;
+
+enum dbmode_t {MYSQL=0,ORACLE=1,BARE=2,POSTGRES=3};
+dbmode_t mode;
+bool g_intransaction;
+
+static int num_records;
+static string lastsoa_qname;
+static void callback(const string &domain, const string &qtype, const string &content, int ttl, int prio)
+{
+ static int lastsoa_domain_id=-1;
+
+ num_records++;
+
+ if(qtype=="SOA") {
+ if(dirty_hack_num==lastsoa_domain_id && lastsoa_qname!=domain) {
+ dirty_hack_num++;
+ cerr<<"Second SOA in zone, raised domain_id"<<endl;
+ if(mode==POSTGRES || mode==ORACLE) {
+ if(g_intransaction && arg().mustDo("transactions")) {
+ cout<<"COMMIT WORK;"<<endl;
+ }
+ if(arg().mustDo("transactions")) {
+ if(mode==POSTGRES)
+ cout<<"BEGIN TRANSACTION;"<<endl;
+ g_intransaction=1;
+ }
+
+ if(mode==POSTGRES) {
+ cout<<"insert into domains (name,type) values ("<<sqlstr(domain)<<",'NATIVE');"<<endl;
+ }
+ else if(mode==ORACLE) {
+ cout<<"insert into domains (id,name,type) values (domains_id_sequence.nextval,"<<toLower(sqlstr(domain))<<",'NATIVE');"<<endl;
+ }
+ }
+ }
+ lastsoa_qname=domain;
+ }
+
+ lastsoa_domain_id=dirty_hack_num;
+
+ if(mode==MYSQL) {
+ cout<<"insert into records (domain_id, name,type,content,ttl,prio) values ("<< dirty_hack_num<<", "<<
+ sqlstr(ZoneParser::canonic(domain))<<", "<<
+ sqlstr(qtype)<<", "<<
+ sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<<");\n";
+ }
+ if(mode==POSTGRES) {
+ cout<<"insert into records (domain_id, name,type,content,ttl,prio) select id ,"<<
+ sqlstr(toLower(ZoneParser::canonic(domain)))<<", "<<
+ sqlstr(qtype)<<", "<<
+ sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<<
+ " from domains where name="<<toLower(sqlstr(lastsoa_qname))<<";\n";
+ }
+ else if(mode==ORACLE) {
+ cout<<"insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,"<<
+ sqlstr(toLower(ZoneParser::canonic(domain)))<<", "<<
+ sqlstr(qtype)<<", "<<
+ sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<<
+ " from Domains where name="<<toLower(sqlstr(lastsoa_qname))<<";\n";
+ }
+ else if(mode==BARE) {
+ cout<< dirty_hack_num<<"\t"<<
+ sqlstr(ZoneParser::canonic(domain))<<"\t"<<
+ sqlstr(qtype)<<"\t"<<sqlstr(ZoneParser::canonic(content))<<"\t"<<prio<<"\t"<<ttl<<"\n";
+ }
+
+}
+
+
+/* 2 modes of operation, either --named or --zone (the latter needs $ORIGIN)
+ 2 further modes: --mysql or --oracle
+ and a parameter: --start-id
+*/
+
+ArgvMap &arg()
+{
+ static ArgvMap theArg;
+ return theArg;
+}
+
+
+int main(int argc, char **argv)
+{
+ try {
+#if __GNUC__ >= 3
+ ios_base::sync_with_stdio(false);
+#endif
+
+ arg().setSwitch("mysql","Output in format suitable for mysqlbackend")="yes";
+ arg().setCmd("gpgsql","Output in format suitable for default gpgsqlbackend");
+ arg().setCmd("gmysql","Output in format suitable for default gmysqlbackend");
+ arg().setCmd("oracle","Output in format suitable for the oraclebackend");
+ arg().setCmd("bare","Output in a bare format, suitable for further parsing");
+ arg().setSwitch("verbose","Verbose comments on operation")="no";
+ arg().setSwitch("slave","Keep BIND slaves as slaves")="no";
+ arg().setSwitch("transactions","If target SQL supports it, use transactions")="no";
+ arg().setSwitch("on-error-resume-next","Continue after errors")="no";
+ arg().set("start-id","Value of first domain-id")="0";
+ arg().set("zone","Zonefile with $ORIGIN to parse")="";
+ arg().set("zone-name","Specify an $ORIGIN in case it is not present")="";
+ arg().set("named-conf","Bind 8 named.conf to parse")="";
+
+ arg().setCmd("help","Provide a helpful message");
+
+ S.declare("logmessages");
+
+ string namedfile="";
+ string zonefile="";
+
+ arg().parse(argc, argv);
+
+ if(argc<2 || arg().mustDo("help")) {
+ cerr<<"syntax:"<<endl<<endl;
+ cerr<<arg().helpstring()<<endl;
+ exit(1);
+ }
+
+ if(arg().mustDo("mysql"))
+ mode=MYSQL;
+ if(arg().mustDo("gpgsql") || arg().mustDo("gmysql"))
+ mode=POSTGRES;
+ if(arg().mustDo("bare"))
+ mode=BARE;
+ if(arg().mustDo("oracle")) {
+ mode=ORACLE;
+ if(!arg().mustDo("transactions"))
+ cout<<"set autocommit on;"<<endl;
+ }
+
+
+ dirty_hack_num=arg().asNum("start-id");
+ namedfile=arg()["named-conf"];
+ zonefile=arg()["zone"];
+
+ int count=0;
+
+ if(zonefile.empty()) {
+ BindParser BP;
+ BP.setVerbose(arg().mustDo("verbose"));
+ BP.parse(namedfile.empty() ? "./named.conf" : namedfile);
+
+ ZoneParser ZP;
+
+ const vector<BindDomainInfo> &domains=BP.getDomains();
+
+ int numdomains=domains.size();
+ int tick=numdomains/100;
+ ZP.setDirectory(BP.getDirectory());
+ ZP.setCallback(&callback);
+
+ for(vector<BindDomainInfo>::const_iterator i=domains.begin();
+ i!=domains.end();
+ ++i)
+ {
+ try {
+ if(mode==POSTGRES || mode==ORACLE) {
+ if(g_intransaction && arg().mustDo("transactions")) {
+ cout<<"COMMIT WORK;"<<endl;
+ }
+ if(arg().mustDo("transactions")) {
+ if(mode==POSTGRES)
+ cout<<"BEGIN TRANSACTION;"<<endl;
+ g_intransaction=1;
+ }
+
+ if(mode==POSTGRES) {
+ if(arg().mustDo("slave")) {
+ if(i->master.empty())
+ cout<<"insert into domains (name,type) values ("<<sqlstr(i->name)<<",'NATIVE');"<<endl;
+ else
+ cout<<"insert into domains (name,type,master) values ("<<sqlstr(i->name)<<",'SLAVE'"<<", '"<<i->master<<"');"<<endl;
+ }
+ else
+ cout<<"insert into domains (name,type) values ("<<sqlstr(i->name)<<",'NATIVE');"<<endl;
+ }
+ else if(mode==ORACLE) {
+ cout<<"insert into domains (id,name,type) values (domains_id_sequence.nextval,"<<toLower(sqlstr(i->name))<<",'NATIVE');"<<endl;
+ }
+ lastsoa_qname=i->name;
+ }
+ ZP.parse(i->filename,i->name);
+ }
+ catch(AhuException &ae) {
+ if(!arg().mustDo("on-error-resume-next"))
+ throw;
+ else
+ cerr<<ae.reason<<endl;
+ }
+
+ dirty_hack_num++;
+ if(!tick || !((count++)%tick))
+ cerr<<"\r"<<count*100/numdomains<<"% done ("<<i->filename<<")\033\133\113";
+ }
+ cerr<<"\r100% done\033\133\113"<<endl;
+ }
+ else {
+ ZoneParser ZP;
+ ZP.setDirectory(".");
+ ZP.setCallback(&callback);
+ ZP.parse(zonefile,arg()["zone-name"]);
+ dirty_hack_num++;
+ }
+ cerr<<"Parsed "<<num_records<<" records"<<endl;
+
+ }
+ catch(AhuException &ae) {
+ cerr<<"Fatal error: "<<ae.reason<<endl;
+ return 0;
+ }
+
+ if((mode==POSTGRES || mode==ORACLE) && arg().mustDo("transactions") && g_intransaction)
+ cout<<"COMMIT WORK;"<<endl;
+ return 1;
+
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef ZONEPARSER_HH
+#define ZONEPARSER_HH
+#include <string>
+#include <map>
+#include <vector>
+#include <time.h>
+
+using namespace std;
+
+class ZoneParser
+{
+ public:
+ struct Record
+ {
+ string name;
+ string qtype;
+ string content;
+ int ttl;
+ int prio;
+ };
+ ZoneParser() : d_ttl(3600) {}
+ ~ZoneParser();
+ void parse(const string &fname,const string &origin);
+ void parse(const string &fname,const string &origin, vector<Record>&records);
+
+ typedef void callback_t(const string &domain, const string &qtype, const string &content, int ttl, int prio);
+ void setCallback(callback_t *callback);
+ callback_t *d_callback;
+ bool parseLine(const vector<string>&words, vector<Record> &);
+ bool eatLine(string line, vector<Record>&);
+ void setDirectory(const string &dir);
+ static string canonic(const string& dom);
+
+private:
+ unsigned int zoneNumber(const string &str);
+ string d_filename;
+ string d_dir;
+ unsigned int d_lineno;
+ void soaCanonic(string &content);
+ bool isNumber(const string &);
+ bool isType(const string &);
+ bool isClass(const string &);
+ string d_origin;
+ time_t d_ttl;
+ void cutOff(string &line, const string &delim);
+ void fillRec(const string &qname, const string &qtype, const string &content, int ttl, int prio, vector<Record>&rec);
+ string expandWord(const string &line, int value);
+};
+
+
+#endif /* BINDPARSER_HH */
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+\r
+#ifdef WIN32\r
+# pragma warning ( disable: 4786 )\r
+#endif // WIN32\r
+\r
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <utility>
+#include <ctype.h>
+#include <errno.h>
+#include <stack>\r
+#include "utility.hh"
+#include "misc.hh"
+#include "ahuexception.hh"
+#include <algorithm>
+using namespace std;
+
+#include "zoneparser.hh"
+
+extern const char *bind_directory;
+void ZoneParser::setDirectory(const string &dir)
+{
+ d_dir=dir;
+
+}
+
+void ZoneParser::parse(const string &fname, const string &origin)
+{
+ d_filename=fname.c_str();
+
+ FILE *zonein=fopen(fname.c_str(),"r");
+
+ if(!zonein)
+ throw AhuException("Unable to open zonefile '"+fname+"': "+stringerror());
+
+ d_origin=origin;
+
+ char line[2048];
+ d_lineno=0;
+ vector<Record> rec;
+ stack<FILE *>fds;
+ fds.push(zonein);
+ while(!fds.empty()) {
+ while(fgets(line,2047,fds.top())) {
+ d_lineno++;
+ if(strstr(line, "$INCLUDE ")==line) {
+ vector<string> parts;
+ stringtok(parts,line," \t\n");
+ if(parts.size()!=2)
+ throw AhuException("Invalid $INCLUDE statement in zonefile '"+fname+"'");
+
+ string filename=parts[1];
+ if(filename[0]!='/')
+ filename=d_dir+"/"+filename;
+
+
+ FILE *fp=fopen(filename.c_str(),"r");
+ if(!fp)
+ throw AhuException("Unable to open zonefile '"+filename+"' included from '"+fname+"': "+stringerror());
+ fds.push(fp);
+ continue;
+ }
+ if(eatLine(line,rec))
+ for(vector<Record>::const_iterator i=rec.begin();i!=rec.end();++i)
+ d_callback(i->name, i->qtype,i->content,i->ttl,i->prio);
+ }
+ fclose(fds.top());
+ fds.pop();
+ }
+}
+
+
+void ZoneParser::fillRec(const string &qname, const string &qtype, const string &content, int ttl, int prio, vector<Record>&recs)
+{
+ Record rec;
+ rec.name=qname;
+ rec.qtype=qtype;
+ rec.content=content;
+ rec.ttl=ttl;
+ rec.prio=prio;
+ recs.push_back(rec);
+
+}
+
+void ZoneParser::parse(const string &fname, const string &origin, vector<Record>&records)
+{
+ d_filename=fname.c_str();
+
+ FILE *zonein=fopen(fname.c_str(),"r");
+
+ if(!zonein)
+ throw AhuException("Unable to open zonefile '"+fname+"': "+stringerror());
+
+ d_origin=origin;
+
+ char line[2048];
+ d_lineno=0;
+ vector<Record> rec;
+ stack<FILE *>fds;
+ fds.push(zonein);
+ while(!fds.empty()) {
+ while(fgets(line,2047,fds.top())) {
+ d_lineno++;
+ if(strstr(line, "$INCLUDE ")==line) {
+ vector<string> parts;
+ stringtok(parts,line," \t\n");
+ if(parts.size()!=2)
+ throw AhuException("Invalid $INCLUDE statement in zonefile '"+fname+"'");
+
+
+ FILE *fp=fopen(parts[1].c_str(),"r");
+ if(!fp)
+ throw AhuException("Unable to open zonefile '"+parts[1]+"' included from '"+parts[1]+"': "+stringerror());
+ fds.push(fp);
+ continue;
+ }
+ if(eatLine(line,rec))
+ for(vector<Record>::const_iterator i=rec.begin();i!=rec.end();++i)
+ records.push_back(*i);
+ }
+ fclose(fds.top());
+ fds.pop();
+ }
+
+
+}
+
+void ZoneParser::cutOff(string &line, const string &delim)
+{
+ unsigned int pos=line.find_first_of(delim);
+ if(pos==string::npos)
+ return;
+ line=line.substr(0,pos);
+}
+
+bool ZoneParser::eatLine(string line, vector<Record> &rec)
+{
+
+ rec.clear();
+ static string tline;
+ static string lastfirstword;
+ chomp(line," \x1a\r\n");
+ cutOff(line,";");
+ unsigned int pos=string::npos;
+
+ if(tline.empty()) {
+ pos=line.find("(");
+ if(pos!=string::npos) { // this is a line that continues
+ tline=line.substr(0,pos);
+ return false;
+ }
+ else
+ tline=line; // complete & boring line
+ }
+ else { // continuation
+ pos=line.find(")");
+ if(pos==string::npos) { // middle part
+ tline.append(line);
+ return false;
+ }
+ else {
+ tline.append(line.substr(0,pos)); // end part, we have a complete line!
+ }
+ }
+
+ // full & unparenthesised line now in tline!
+ // cout<<"line: '"<<tline<<"'"<<endl;
+ if(tline.empty() || tline.find_first_not_of(" \t\n")==string::npos) {
+
+ tline="";
+ return false;
+ }
+
+ if(isspace(tline[0]))
+ tline=lastfirstword+"\t"+tline;
+
+ vector<string> parts;
+ stringtok(parts,tline," \t");
+ if(parts[0][0]!='$' && !isspace(parts[0][0]))
+ lastfirstword=parts[0];
+
+ // for_each(parts.begin(),parts.end(),print);
+ tline="";
+ return parseLine(parts,rec);
+}
+
+ZoneParser::~ZoneParser()
+{
+
+}
+
+void ZoneParser::setCallback(callback_t *callback)
+{
+ d_callback=callback;
+}
+
+bool ZoneParser::isNumber(const string &s)
+{
+ for(string::const_iterator i=s.begin();
+ i!=s.end();
+ ++i) {
+ if(i+1==s.end())
+ if(*i=='M' || *i=='D' || *i=='H' || *i=='W' || *i=='m' || *i=='d' || *i=='h' || *i=='w') // last character
+ continue;
+ if(!isdigit(*i))
+ return false;
+ }
+ return true;
+}
+
+bool ZoneParser::isType(const string &s)
+{
+ if(isNumber(s))
+ return false;
+
+ if(isClass(s))
+ return false;
+
+
+ return true;
+}
+
+bool ZoneParser::isClass(const string &s)
+{
+ return (s=="IN" || s=="CH" || s=="HS");
+}
+
+unsigned int ZoneParser::zoneNumber(const string &str)
+{
+ unsigned int val=atoi(str.c_str());
+ char lc=toupper(str[str.length()-1]);
+ if(!isdigit(lc))
+ switch(lc) {
+ case 'H':
+ val*=3600;
+ break;
+ case 'D':
+ val*=3600*24;
+ break;
+ case 'W':
+ val*=3600*24*7;
+ break;
+ case 'M':
+ val*=3600*24*7*4;
+ break;
+ case 'Y': // ? :-)
+ val*=3600*24*365;
+ break;
+ default:
+ throw AhuException("Unable to parse "+d_origin+" time specification '"+str+"'");
+ }
+ return val;
+
+}
+
+/** this parser handles 10 cases (sigh)
+ 1) qname TTL CLASS QTYPE *
+ 2) qname CLASS TTL QTYPE *
+ 3) qname CLASS QTYPE *
+ 4) qname TTL QTYPE *
+ 5) qname QTYPE *
+
+ And then everything again with a space first character, which implies 'same as last name'
+*/
+
+void ZoneParser::soaCanonic(string &content)
+{
+ vector<string>parts;
+ stringtok(parts,content," \t");
+ int pos=0;
+
+ // 'ns.naamserver.net. hostmaster.naamserver.net 2001102501 8H 2H 1W 1D'
+
+ string newcontent;
+ for(vector<string>::const_iterator i=parts.begin();i!=parts.end();++i,++pos) {
+ if(pos<3) {
+ if(pos)
+ newcontent.append(1,' ');
+ newcontent.append(*i);
+ }
+ else {
+ unsigned int val=zoneNumber(*i);
+
+ newcontent.append(1,' ');
+ newcontent.append(itoa(val));
+ }
+ }
+ content=newcontent;
+}
+
+string ZoneParser::expandWord(const string &line, int value)
+{
+ string newline;
+ bool escape=false;
+ for(string::const_iterator i=line.begin();i!=line.end();++i) {
+ if(*i=='\\')
+ escape=true;
+ else{
+ if(!escape && *i=='$') {
+ if(i+2<line.end() && *(i+1)=='{') { // shit
+ string::const_iterator k=(i+=2);
+ while(k++!=line.end() && *k!='}')
+ ;
+ if(k==line.end())
+ throw AhuException("Malformed $GENERATE statement");
+
+ string spec;
+
+ //copy(i,k,back_inserter(spec));\r
+ for ( string::const_iterator a = i; a != k; ++a )\r
+ spec += *a;\r
+\r
+ vector<string> partjes;
+ stringtok(partjes,spec,",");
+ if(partjes.empty())
+ throw AhuException("Malformed $GENERATE statement: '"+spec+"'");
+
+ value+=atoi(partjes[0].c_str());
+ int width=0;
+ char radix='d';
+ if(partjes.size()>=2)
+ width=atoi(partjes[1].c_str());
+ if(partjes.size()>=3)
+ radix=partjes[2][0];
+
+ char tmp[20];
+ string format;
+ format="%0";
+ format+=itoa(width);
+ format.append(1,radix);
+
+ snprintf(tmp,19,format.c_str(),value);
+
+ newline.append(tmp);
+ i=k;
+ }
+ else
+ newline.append(itoa(value));
+ }
+ else
+ newline.append(1,*i);
+ escape=false;
+ }
+ }
+ return newline;
+}
+
+string ZoneParser::canonic(const string& dom)
+{
+ if(dom[dom.size()-1]!='.')
+ return dom;
+
+ return dom.substr(0,dom.size()-1);
+
+}
+
+
+bool ZoneParser::parseLine(const vector<string>&words, vector<Record>&rec)
+{
+ int cpos=0;
+ if(!words.size())
+ return false;
+
+ if(words[0][0]=='$')
+ {
+ if(!Utility::strcasecmp(words[0].c_str(),"$ORIGIN") && words.size()>1) {
+ d_origin=canonic(words[1]);
+ }
+ else if(!Utility::strcasecmp(words[0].c_str(),"$TTL") && words.size()>1) {
+ d_ttl=zoneNumber(words[1]);
+ }
+ else if(!Utility::strcasecmp(words[0].c_str(),"$GENERATE") && words.size()>1) {
+ // $GENERATE 1-127 $ CNAME $.0
+ string range=words[1]; // 1-127 means 1...127 (including 127). 1-127/2 is 1..3..5..
+ vector<string>parts;
+ stringtok(parts,range,"-/");
+ if(parts.size()<2 || parts.size()>3)
+ throw AhuException("Malformed $GENERATE on line "+itoa(d_lineno)+" of "+d_filename);
+
+ int start, stop, step=1;
+ start=atoi(parts[0].c_str());
+ stop=atoi(parts[1].c_str());
+ if(parts.size()==3)
+ step=atoi(parts[2].c_str());
+ vector<string>newwords;
+
+ for(int i=start;i<stop;++i) {
+ newwords.clear();
+ for(unsigned int j=2;j<words.size();++j) {
+ newwords.push_back(expandWord(words[j],i));
+ }
+ parseLine(newwords, rec);
+ }
+ return true;
+ }
+ else {
+ throw AhuException("Unhandled command '"+words[0]+"' on line "+itoa(d_lineno)+" of "+d_filename);
+ }
+
+ return false;
+
+ }
+ if(words.size()<3)
+ {
+ if(words.size()==1 && words[0]==";")
+ return false;
+ cerr<<"Short line: "<<words.size()<<" words. Probably due to repeated record without domainname"<<endl;
+ cerr<<"'"<<words[0]<<"'"<<endl;
+ return false;
+ }
+
+ string qname=words[0];
+ string qclass="IN";
+ int ttl=d_ttl;
+ string qtype="NONE";
+ if(isNumber(words[1])) // 1 || 4
+ {
+ ttl=zoneNumber(words[1]);
+ if(isClass(words[2]))
+ {
+// cout<<1<<endl;
+ qclass=words[2];
+ qtype=words[3];
+ cpos=4;
+ // 1
+ }
+ else
+ {
+// cout<<4<<endl;
+
+ qtype=words[2];
+ cpos=3;
+ // 4
+ }
+ }
+ else /* 2 || 3 || 5 */
+ {
+ if(!isClass(words[1]))
+ {
+
+ qtype=words[1];
+ cpos=2;
+// cout<<5<<endl;
+ // 5
+ }
+ else // 2 || 3
+ {
+ qclass=words[1];
+ if(isNumber(words[2]))
+ {
+ ttl=zoneNumber(words[2]);
+ qtype=words[3];
+// cout<<2<<endl;
+ cpos=4;
+ // 2
+ }
+ else if(isType(words[2]))
+ {
+ qtype=words[2];
+// cout<<4<<endl;
+ cpos=3;
+ // 4
+ }
+ }
+
+ }
+ if(!cpos)
+ {
+ cerr<<"Funky parse case!"<<endl;
+ }
+
+ if(qname=="@")
+ qname=d_origin;
+ else
+ if(qname[qname.size()-1]!='.')
+ qname+="."+d_origin;
+
+
+// cerr<<qname<<", "<<qclass<<", "<<qtype<<", "<<ttl<<", rest from field "<<cpos<<endl;
+
+ int left=words.size()-cpos;
+ string content;
+
+ if(qtype=="MX" && left==2)
+ {
+ int prio=atoi(words[cpos++].c_str());
+ content=words[cpos];
+ if(content=="@")
+ content=d_origin;
+ else
+ if(content[content.size()-1]!='.')
+ content+="."+d_origin;
+
+ fillRec(qname, qtype, content, ttl, prio,rec);
+ return true;
+ }
+ else if(left)
+ {
+ content=words[cpos++];left--;
+
+ while(left--)
+ content+=" "+words[cpos++];
+
+ if(qtype=="MX" || qtype=="CNAME" || qtype=="NS") {
+ if(content=="@")
+ content=d_origin;
+ else
+ if(content[content.size()-1]!='.')
+ content+="."+d_origin;
+ }
+ if(qtype=="SOA")
+ soaCanonic(content);
+
+ fillRec(qname, qtype, content,ttl, 0, rec);
+ return true;
+ }
+ else
+ {
+ cerr<<"NO CONTENT!"<<endl;
+ }
+ return false;
+}
+
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include <iostream>
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <unistd.h>
+#include <errno.h>
+#include <climits>
+#include <string>
+#include <map>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include <sys/stat.h>
+
+
+using namespace std;
+
+static void imbue(char *pname, const char *search, const string &replace);
+static string stringerror();
+static off_t filesize(int fd);
+
+int main(int argc, char **argv)
+{
+ if(argc!=3) {
+ cerr<<"Syntax: binpatch binary configuration-directory"<<endl;
+ exit(0);
+ }
+
+ imbue(argv[1],"!@@SYSCONFDIR@@:",argv[2]);
+}
+
+static void imbue(char *pname, const char *search, const string &replace)
+{
+ int fd=open(pname, O_RDWR);
+ if(fd<0) {
+ cerr<<"Unable to open executable read/write for imbuing: "<<stringerror()<<endl;
+ exit(1);
+ }
+ int fs=filesize(fd);
+ void *ptr=mmap(0,fs,PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if(ptr==(caddr_t)-1) {
+ cerr<<"Unable to mmap executable read/write for imbuing: "<<stringerror()<<endl;
+ exit(1);
+ }
+
+ char *p=(char *)ptr;
+ char *end=p+fs;
+ for(;p<end;++p)
+ if(*p==*search && *(p+1)==*(search+1) && !memcmp(p,search,strlen(search)))
+ break;
+
+ if(p==end) {
+ cerr<<"Cannot find marker in binary, not imbueing"<<endl;
+ exit(1);
+ }
+ strcpy(p+strlen(search),replace.c_str());
+ munmap(ptr,filesize(fd));
+ close(fd);
+ cerr<<"Imbued configuration location '"<<replace<<"'"<<endl;
+ return;
+}
+
+static off_t filesize(int fd)
+{
+ struct stat buf;
+ fstat(fd, &buf);
+ return buf.st_size;
+}
+static string stringerror()
+{
+ return strerror(errno);
+}
--- /dev/null
+#!/bin/sh
+echo Please ignore this warning when you see it:
+echo warning: AC_TRY_RUN called without default to allow cross compiling
+echo
+
+
+aclocal
+autoheader
+automake --add-missing --foreign
+autoconf
+
--- /dev/null
+#!/bin/sh
+
+prefix=@prefix@
+
+echo building PowerDNS chroot in $prefix
+echo -n "Copying libraries: "
+cp $(./finddeps ahudns resolver dynloader /bin/sh) $prefix/lib
+echo done
+echo -n "Copying in /bin/sh: "
+cp /bin/sh $prefix/bin
+echo done
+
+preprefix=$(echo $prefix | sed s/$(basename $prefix)//)
+
+echo -n "Making tmp and pre-prefix in root: "
+mkdir -p $prefix/tmp $prefix/$preprefix
+echo "done"
+echo -n "Creating $prefix in $prefix: "
+cd $prefix/$preprefix
+ln -s .. $(basename $prefix)
+cd -
+echo done
+echo -n "Creating launch script: "
+echo \#\!/bin/sh > $prefix/launch
+echo cd $prefix >> $prefix/launch
+echo export ORACLE_HOME=$prefix/oracle >> $prefix/launch
+echo chroot . ./bin/ahudns >> $prefix/launch
+chmod +x $prefix/launch
+echo done
+
--- /dev/null
+#!/bin/sh
+IB="dialog --inputbox"
+MB="dialog --msgbox"
+YN="dialog --yesno"
+
+. ./pathconfig
+
+$MB "\nWelcome to the PowerDNS installation program!\n\nPlease select \
+locations for the different PowerDNS files." 11 60
+
+redo=1
+while [ "$redo" = "1" ]
+do
+echo $redo
+
+askPath()
+{
+ val=`eval echo \\$$2`
+ $IB "$1\n\n" 10 60 $val 2> ./dialog.tmp
+ if [ "$?" != "0" ] ; then exit ; fi
+ eval $2=`cat ./dialog.tmp`
+}
+
+askPath "Intended location of your init.d scripts" INITDPATH
+askPath "Intended location of your binaries" BINARYPATH
+askPath "Intended location of your configuration files" CONFIGPATH
+askPath "Intended location of the controlsocket directory" SOCKETPATH
+askPath "Intended location of the PowerDNS plugins directory" LIBRARYPATH
+askPath "Intended location of the PowerDNS documentation directory" DOCPATH
+
+$MB "\nPowerDNS can be configured to run as an\n\
+unprivileged user.\n\
+This is highly recommended. You should\n\
+now create a user and a group for PDNS\n\
+to run as and then press enter, \n\
+after which you will be asked for\n\
+the identity." 15 60
+
+askPath "Intended user id for PDNS to run as" PDNSUID
+askPath "Intended group id for PDNS to run as" PDNSGID
+
+$YN "Do you accept these values?\n\ninit.d: $INITDPATH\n\
+binaries: $BINARYPATH\n\
+configuration: $CONFIGPATH\n\
+sockets: $SOCKETPATH\n\
+plugins: $LIBRARYPATH\n\
+documentation: $DOCPATH\n\
+uid: $PDNSUID\n\
+gid: $PDNSGID\n" 15 60
+redo=$?
+echo $ready
+done
+
+mv pathconfig pathconfig.old 2> /dev/null > /dev/null
+
+(echo INITDPATH=$INITDPATH
+echo BINARYPATH=$BINARYPATH
+echo CONFIGPATH=$CONFIGPATH
+echo SOCKETPATH=$SOCKETPATH
+echo LIBRARYPATH=$LIBRARYPATH
+echo PDNSUID=$PDNSUID
+echo DOCPATH=$DOCPATH
+echo PDNSGID=$PDNSGID) > pathconfig
+
+$MB "\nDone recording your directory preferences." 7 70
+
+
--- /dev/null
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.5 from Makefile.am.
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+prefix = /opt/pdns
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/pdns
+pkglibdir = $(libdir)/pdns
+pkgincludedir = $(includedir)/pdns
+top_builddir = ..
+
+ACLOCAL = ${SHELL} /home/ahu/programming/ahudns/missing --run aclocal
+AUTOCONF = ${SHELL} /home/ahu/programming/ahudns/missing --run autoconf
+AUTOMAKE = ${SHELL} /home/ahu/programming/ahudns/missing --run automake
+AUTOHEADER = ${SHELL} /home/ahu/programming/ahudns/missing --run autoheader
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = s,x,x,
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = i686-pc-linux-gnu
+build_triplet = i686-pc-linux-gnu
+host_alias = i686-pc-linux-gnu
+host_triplet = i686-pc-linux-gnu
+target_alias = i686-pc-linux-gnu
+target_triplet = i686-pc-linux-gnu
+AMTAR = ${SHELL} /home/ahu/programming/ahudns/missing --run tar
+AS = @AS@
+AWK = mawk
+CC = gcc
+CXX = c++
+DEPDIR = .deps
+DLLTOOL = @DLLTOOL@
+ECHO = echo
+EXEEXT =
+INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
+LEX = flex
+LIBDL = -ldl
+LIBRESOLV = -lresolv
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LN_S = ln -s
+OBJDUMP = @OBJDUMP@
+OBJEXT = o
+PACKAGE = pdns
+RANLIB = ranlib
+STRIP = strip
+VERSION = 2.9
+YACC = bison -y
+am__include = include
+am__quote =
+install_sh = /home/ahu/programming/ahudns/install-sh
+subdir = codedocs
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+DIST_COMMON = Makefile.am Makefile.in
+all: all-am
+
+.SUFFIXES:
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign codedocs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && \
+ CONFIG_HEADERS= CONFIG_LINKS= \
+ CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ $(mkinstalldirs) "$(distdir)/$$dir"; \
+ fi; \
+ if test -d $$d/$$file; then \
+ cp -pR $$d/$$file $(distdir) \
+ || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+
+installdirs:
+
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+uninstall-am: uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool uninstall uninstall-am uninstall-info-am
+
+
+codedocs: .
+ doxygen doxygen.conf
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+codedocs: .
+ doxygen doxygen.conf
--- /dev/null
+# Makefile.in generated automatically by automake 1.5 from Makefile.am.
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AMTAR = @AMTAR@
+AS = @AS@
+AWK = @AWK@
+CC = @CC@
+CXX = @CXX@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EXEEXT = @EXEEXT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LEX = @LEX@
+LIBDL = @LIBDL@
+LIBRESOLV = @LIBRESOLV@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+am__include = @am__include@
+am__quote = @am__quote@
+install_sh = @install_sh@
+subdir = codedocs
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+DIST_COMMON = Makefile.am Makefile.in
+all: all-am
+
+.SUFFIXES:
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign codedocs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && \
+ CONFIG_HEADERS= CONFIG_LINKS= \
+ CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ $(mkinstalldirs) "$(distdir)/$$dir"; \
+ fi; \
+ if test -d $$d/$$file; then \
+ cp -pR $$d/$$file $(distdir) \
+ || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+
+installdirs:
+
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+uninstall-am: uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool uninstall uninstall-am uninstall-info-am
+
+
+codedocs: .
+ doxygen doxygen.conf
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+# Doxyfile 1.2.6
+
+# This file describes the settings to be used by doxygen for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = ahudns
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ./
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
+# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian,
+# Polish, Portuguese and Slovene.
+
+OUTPUT_LANGUAGE = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these class will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH =
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a class diagram (in Html and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off.
+
+CLASS_DIAGRAMS = YES
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower case letters. If set to YES upper case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# The ENABLE_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consist of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+FILE_PATTERNS = *.cc \
+ *.hh
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse.
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set YES to add extra items for group members
+# to the contents of the Html help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript and frames is required (for instance Netscape 4.0+
+# or Internet explorer 4.0+).
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimised for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = YES
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using a WORD or other.
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assigments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH = ../
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS = *.hh
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other
+# documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented header file showing
+# the documented files that directly or indirectly include this file
+
+INCLUDED_BY_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermedate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
+# The CGI_NAME tag should be the name of the CGI script that
+# starts the search engine (doxysearch) with the correct parameters.
+# A script with this name will be generated by doxygen.
+
+CGI_NAME = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the
+# cgi binaries are located. See the documentation of your http daemon for
+# details.
+
+CGI_URL =
+
+# The DOC_URL tag should be the absolute URL to the directory where the
+# documentation is located. If left blank the absolute path to the
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL =
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the
+# documentation is located. If left blank the directory on the local machine
+# will be used.
+
+DOC_ABSPATH =
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
+# is installed.
+
+BIN_ABSPATH = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to
+# documentation generated for other projects. This allows doxysearch to search
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS =
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "common_startup.hh"\r
+\r
+typedef Distributor<DNSPacket,DNSPacket,PacketHandler> DNSDistributor;\r
+\r
+\r
+ArgvMap theArg;\r
+StatBag S; //!< Statistics are gathered accross PDNS via the StatBag class S\r
+PacketCache PC; //!< This is the main PacketCache, shared accross all threads\r
+DNSProxy *DP;\r
+DynListener *dl;\r
+CommunicatorClass Communicator;\r
+UDPNameserver *N;\r
+int avg_latency;\r
+TCPNameserver *TN;\r
+\r
+ArgvMap &arg()\r
+{\r
+ return theArg;\r
+}\r
+\r
+\r
+void declareArguments()\r
+{\r
+ arg().set("local-port","The port on which we listen")="53";\r
+ arg().setSwitch("log-failed-updates","If PDNS should log failed update requests")="";\r
+ arg().setSwitch("log-dns-details","If PDNS should log failed update requests")="";\r
+ arg().set("urlredirector","Where we send hosts to that need to be url redirected")="127.0.0.1";\r
+ arg().set("smtpredirector","Our smtpredir MX host")="a.misconfigured.powerdns.smtp.server";\r
+ arg().set("local-address","Local IP address to which we bind")="0.0.0.0";\r
+ arg().set("local-ipv6","Local IP address to which we bind")="";\r
+ arg().set("max-queue-length","Maximum queuelength before considering situation lost")="5000";\r
+ arg().set("soa-serial-offset","Make sure that no SOA serial is less than this number")="0";\r
+ arg().set("only-soa","Make sure that no SOA serial is less than this number")="org";\r
+ arg().setCmd("help","Provide a helpful message");\r
+ arg().setCmd("config","Provide a helpful message");\r
+ arg().setCmd("list-modules","Lists all modules available");\r
+ arg().setCmd("no-config","Don't parse configuration file");\r
+ \r
+ arg().set("control-console","Debugging switch - don't use")="no"; // but I know you will!\r
+ arg().set("fancy-records","Process URL and MBOXFW records")="no";\r
+ arg().set("wildcard-url","Process URL and MBOXFW records")="no";\r
+ arg().set("wildcards","Honor wildcards in the database")="";\r
+ arg().set("loglevel","Amount of logging. Higher is more. Do not set below 3")="4";\r
+ arg().set("default-soa-name","name to insert in the SOA record if none set in the backend")="a.misconfigured.powerdns.server";\r
+ arg().set("distributor-threads","Default number of Distributor (backend) threads to start")="3";\r
+ arg().set("queue-limit","Maximum number of milliseconds to queue a query")="1500"; \r
+ arg().set("recursor","If recursion is desired, IP address of a recursing nameserver")="no"; \r
+ arg().set("lazy-recursion","Only recurse if question cannot be answered locally")="yes";\r
+ arg().set("allow-recursion","List of netmasks that are allowed to recurse")=""; \r
+ \r
+ arg().set("disable-tcp","Do not listen to TCP queries")="no";\r
+ arg().set("disable-axfr","Do not allow zone transfers")="no";\r
+ \r
+ arg().set("config-name","Name of this virtual configuration - will rename the binary image")="";\r
+\r
+ arg().set("load-modules","Load this module - supply absolute or relative path")="";\r
+ arg().set("launch","Which backends to launch and order to query them in")="";\r
+ arg().setSwitch("disable-axfr","Disable zonetransfers but do allow TCP queries")="no";\r
+ arg().set("allow-axfr-ips","If disabled, DO allow zonetransfers from these IP addresses")="";\r
+ arg().set("slave-cycle-interval","Reschedule failed SOA serial checks once every .. seconds")="60";\r
+ \r
+ arg().setSwitch("slave","Act as a slave")="no";\r
+ arg().setSwitch("master","Act as a master")="no";\r
+ arg().setSwitch("guardian","Run within a guardian process")="no";\r
+ arg().setSwitch("skip-cname","Do not perform CNAME indirection for each query")="no";\r
+ arg().setSwitch("strict-rfc-axfrs","Perform strictly rfc compliant axfrs (very slow)")="no";\r
+ \r
+ arg().setSwitch("webserver","Start a webserver for monitoring")="no"; \r
+ arg().setSwitch("webserver-print-arguments","If the webserver should print arguments")="no"; \r
+ arg().set("webserver-address","IP Address of webserver to listen on")="127.0.0.1";\r
+ arg().set("webserver-port","Port of webserver to listen on")="8081";\r
+ arg().set("webserver-password","Password required for accessing the webserver")="";\r
+\r
+ arg().set("receiver-threads","Number of receiver threads to launch")="1";\r
+ \r
+ arg().setSwitch("out-of-zone-additional-processing","Do out of zone additional processing")="no";\r
+ arg().setSwitch("query-logging","Hint backends that queries should be logged")="no";\r
+ \r
+ arg().set("cache-ttl","Seconds to store packets in the PacketCache")="20";\r
+ arg().set("recursive-cache-ttl","Seconds to store packets in the PacketCache")="10";\r
+ arg().set("negquery-cache-ttl","Seconds to store packets in the PacketCache")="60";\r
+ arg().set("query-cache-ttl","Seconds to store packets in the PacketCache")="20";\r
+ arg().set("soa-minimum-ttl","Default SOA mininum ttl")="3600";\r
+ arg().set("max-tcp-connections","Maximum number of TCP connections")="10";\r
+\r
+ arg().setSwitch( "use-logfile", "Use a log file" )= "no";\r
+ arg().set( "logfile", "Logfile to use" )= "pdns.log";\r
+\r
+}\r
+\r
+\r
+\r
+void declareStats(void)\r
+{\r
+ S.declare("udp-queries","Number of UDP queries received");\r
+ S.declare("udp-answers","Number of answers sent out over UDP");\r
+ S.declare("recursing-answers","Number of recursive answers sent out");\r
+ S.declare("recursing-questions","Number of questions sent to recursor");\r
+ S.declare("corrupt-packets","Number of corrupt packets received");\r
+\r
+ S.declare("tcp-queries","Number of TCP queries received");\r
+ S.declare("tcp-answers","Number of answers sent out over TCP");\r
+\r
+ S.declare("qsize-q","Number of questions waiting for database attention");\r
+\r
+ S.declare("deferred-cache-inserts","Amount of cache inserts that were deferred because of maintenance");\r
+ S.declare("deferred-cache-lookup","Amount of cache lookups that were deferred because of maintenance");\r
+\r
+ S.declare("query-cache-hit","Number of hits on the query cache");\r
+ S.declare("query-cache-miss","Number of misses on the query cache");\r
+\r
+\r
+ S.declare("servfail-packets","Number of times a server-failed packet was sent out");\r
+ S.declare("latency","Average number of microseconds needed to answer a question");\r
+ S.declare("timedout-packets","Number of packets which weren't answered within timeout set");\r
+\r
+ S.declareRing("queries","UDP Queries Received");\r
+ S.declareRing("nxdomain-queries","Queries for non-existent records within existent domains");\r
+ S.declareRing("noerror-queries","Queries for existing records, but for type we don't have");\r
+ S.declareRing("servfail-queries","Queries that could not be answered due to backend errors");\r
+ S.declareRing("unauth-queries","Queries for domains that we are not authoritative for");\r
+ S.declareRing("logmessages","Log Messages");\r
+ S.declareRing("remotes","Remote server IP addresses");\r
+ S.declareRing("remotes-unauth","Remote hosts querying domains for which we are not auth");\r
+ S.declareRing("remotes-corrupt","Remote hosts sending corrupt packets");\r
+\r
+}\r
+\r
+\r
+int isGuarded(char **argv)\r
+{\r
+ char *p=strstr(argv[0],"-instance");\r
+\r
+ return !!p;\r
+}\r
+\r
+\r
+void sendout(const DNSDistributor::AnswerData &AD)\r
+{\r
+ static int &numanswered=*S.getPointer("udp-answers");\r
+ if(!AD.A)\r
+ return;\r
+ \r
+ N->send(AD.A);\r
+ numanswered++;\r
+ int diff=AD.A->d_dt.udiff();\r
+ avg_latency=(int)(0.999*avg_latency+0.001*diff);\r
+\r
+ delete AD.A; \r
+\r
+\r
+}\r
+\r
+\r
+//! The qthread receives questions over the internet via the Nameserver class, and hands them to the Distributor for futher processing\r
+void *qthread(void *p)\r
+{\r
+ DNSDistributor *D=static_cast<DNSDistributor *>(p);\r
+\r
+ DNSPacket *P;\r
+\r
+ DNSPacket question;\r
+ DNSPacket cached;\r
+\r
+ int &numreceived=*S.getPointer("udp-queries");\r
+ int &numanswered=*S.getPointer("udp-answers");\r
+ numreceived=-1;\r
+ int diff;\r
+\r
+ for(;;) {\r
+ if(!((numreceived++)%50)) { // maintenance tasks\r
+ S.set("latency",(int)avg_latency);\r
+ int qcount, acount;\r
+ D->getQueueSizes(qcount, acount);\r
+ S.set("qsize-q",qcount);\r
+ }\r
+ \r
+ if(!(P=N->receive(&question))) { // receive a packet inline\r
+ continue; // packet was broken, try again\r
+ }\r
+\r
+\r
+ S.ringAccount("queries", P->qdomain+"/"+P->qtype.getName());\r
+ S.ringAccount("remotes",P->getRemote());\r
+\r
+ if(PC.get(P,&cached)) { // short circuit - does the PacketCache recognize this question?\r
+ cached.setRemote((struct sockaddr *)(P->remote),P->d_socklen); // inlined\r
+ cached.setSocket(P->getSocket()); // inlined\r
+ cached.spoofID(P->d.id); // inlined \r
+ cached.d.rd=P->d.rd; // copy in recursion desired bit \r
+ cached.commitD(); // commit d to the packet inlined\r
+\r
+ N->send(&cached); // answer it then inlined\r
+ diff=P->d_dt.udiff(); \r
+ avg_latency=(int)(0.999*avg_latency+0.001*diff); // 'EWMA'\r
+ \r
+ numanswered++;\r
+ continue;\r
+ }\r
+\r
+ D->question(P, &sendout); // otherwise, give to the distributor\r
+ }\r
+ return 0;\r
+}\r
+\r
+\r
+void mainthread()\r
+{\r
+ Utility::srandom(time(0));\r
+\r
+ int newgid=0; \r
+ if(!arg()["setgid"].empty()) \r
+ newgid=Utility::makeGidNumeric(arg()["setgid"]); \r
+ int newuid=0; \r
+ if(!arg()["setuid"].empty()) \r
+ newuid=Utility::makeUidNumeric(arg()["setuid"]); \r
+ if(!arg()["chroot"].empty()) { \r
+ if(chroot(arg()["chroot"].c_str())<0) {\r
+ L<<Logger::Error<<"Unable to chroot: "<<strerror(errno)<<", exiting"<<endl; \r
+ exit(1);\r
+ } \r
+ else\r
+ L<<Logger::Error<<"Chrooted to '"<<arg()["chroot"]<<"'"<<endl; \r
+ } \r
+ Utility::dropPrivs(newuid, newgid);\r
+\r
+ if(arg().mustDo("recursor")){\r
+ DP=new DNSProxy(arg()["recursor"]);\r
+ DP->onlyFrom(arg()["allow-recursion"]);\r
+ DP->go();\r
+ }\r
+ // NOW SAFE TO CREATE THREADS!\r
+ dl->go();\r
+\r
+\r
+\r
+\r
+ pthread_t qtid;\r
+ StatWebServer sws;\r
+\r
+ if(arg()["webserver"]!="no") \r
+ sws.go();\r
+ \r
+ if(arg().mustDo("slave") || arg().mustDo("master"))\r
+ Communicator.go(); \r
+\r
+ if(TN)\r
+ TN->go(); // tcp nameserver launch\r
+ \r
+ // fork(); (this worked :-))\r
+ for(int n=0;n<arg().asNum("receiver-threads");++n) {\r
+ DNSDistributor *D= new DNSDistributor(arg().asNum("distributor-threads")); // the big dispatcher!\r
+ pthread_create(&qtid,0,qthread,static_cast<void *>(D)); // receives packets\r
+ }\r
+\r
+ void *p;\r
+ pthread_join(qtid, &p);\r
+ \r
+ L<<Logger::Error<<"Mainthread exiting - should never happen"<<endl;\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+\r
+#ifndef COMMON_STARTUP_HH\r
+#define COMMON_STARTUP_HH\r
+\r
+\r
+#include "utility.hh"\r
+#include "arguments.hh"\r
+#include "communicator.hh"\r
+#include "distributor.hh"\r
+#include "dnspacket.hh"\r
+#include "dnsproxy.hh"\r
+#include "dynlistener.hh"\r
+#include "nameserver.hh"\r
+#include "statbag.hh"\r
+#include "tcpreceiver.hh"\r
+#include "webserver.hh"\r
+#include "ws.hh"\r
+\r
+extern ArgvMap theArg;\r
+extern StatBag S; //!< Statistics are gathered accross PDNS via the StatBag class S\r
+extern PacketCache PC; //!< This is the main PacketCache, shared accross all threads\r
+extern DNSProxy *DP;\r
+extern DynListener *dl;\r
+extern CommunicatorClass Communicator;\r
+extern UDPNameserver *N;\r
+extern int avg_latency;\r
+extern TCPNameserver *TN;\r
+\r
+\r
+extern ArgvMap & arg( void );\r
+extern void declareArguments();\r
+extern void declareStats();\r
+extern void mainthread();\r
+extern int isGuarded( char ** );\r
+\r
+#endif // COMMON_STARTUP_HH\r
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"
+#include <errno.h>
+#include "communicator.hh"
+#include <set>
+
+#include "dnsbackend.hh"
+#include "ueberbackend.hh"
+#include "packethandler.hh"
+#include "resolver.hh"
+#include "logger.hh"
+#include "dns.hh"
+#include "arguments.hh"
+#include "session.hh"
+
+
+void CommunicatorClass::addSuckRequest(const string &domain, const string &master)
+{
+ Lock l(&d_lock);
+
+ SuckRequest sr;
+ sr.domain = domain;
+ sr.master = master;
+
+ d_suckdomains.push(sr);
+
+ d_suck_sem.post();
+ d_any_sem.post();
+}
+
+
+void CommunicatorClass::suck(const string &domain,const string &remote)
+{
+ u_int32_t domain_id;
+ PacketHandler P;
+
+ DomainInfo di;
+ di.backend=0;
+
+ try {
+ Resolver resolver;
+ resolver.axfr(remote,domain.c_str());
+
+ UeberBackend *B=dynamic_cast<UeberBackend *>(P.getBackend());
+
+ if(!B->getDomainInfo(domain, di) || !di.backend) {
+ L<<Logger::Error<<"Can't determine backend for domain '"<<domain<<"'"<<endl;
+ return;
+ }
+ domain_id=di.id;
+ di.backend->startTransaction(domain, domain_id);
+
+ L<<Logger::Error<<"AXFR started for '"<<domain<<"', transaction started"<<endl;
+ Resolver::res_t recs;
+
+ while(resolver.axfrChunk(recs)) {
+ for(Resolver::res_t::iterator i=recs.begin();i!=recs.end();++i) {
+ if((i->qname.size()-toLower(i->qname).rfind(toLower(domain)))!=domain.size()) {
+ L<<Logger::Error<<"Remote "<<remote<<" sneaked in out-of-zone data '"<<i->qname<<"' during AXFR of zone '"<<domain<<"'"<<endl;
+ di.backend->abortTransaction();
+ return;
+ }
+ i->domain_id=domain_id;
+ di.backend->feedRecord(*i);
+ }
+ }
+ di.backend->commitTransaction();
+ di.backend->setFresh(domain_id);
+ L<<Logger::Error<<"AXFR done for '"<<domain<<"', zone committed"<<endl;
+ }
+ catch(ResolverException &re) {
+ L<<Logger::Error<<"Unable to AXFR zone '"+domain+"': "<<re.reason<<endl;
+ if(di.backend) {
+ L<<Logger::Error<<"Aborting possible open transaction for domain '"<<domain<<"' AXFR"<<endl;
+ di.backend->abortTransaction();
+ }
+ }
+}
+
+class FindNS
+{
+public:
+ vector<string>lookup(const string &name, DNSBackend *B)
+ {
+ vector<string>addresses;
+ struct hostent *h;
+ h=gethostbyname(name.c_str());
+
+ if(h) {
+ for(char **h_addr_list=h->h_addr_list;*h_addr_list;++h_addr_list) {
+ ostringstream os;
+ unsigned char *p=reinterpret_cast<unsigned char *>(*h_addr_list);
+ os<<(int)*p++<<".";
+ os<<(int)*p++<<".";
+ os<<(int)*p++<<".";
+ os<<(int)*p++;
+
+ addresses.push_back(os.str());
+ }
+ }
+
+ B->lookup(QType(QType::A),name);
+ DNSResourceRecord rr;
+ while(B->get(rr))
+ addresses.push_back(rr.content); // SOL if you have a CNAME for an NS
+
+ return addresses;
+ }
+}d_fns;
+
+void CommunicatorClass::queueNotifyDomain(const string &domain, DNSBackend *B)
+{
+ set<string> ips;
+
+ DNSResourceRecord rr;
+ set<string>nsset;
+
+ B->lookup(QType(QType::NS),domain);
+ while(B->get(rr))
+ nsset.insert(rr.content);
+
+ for(set<string>::const_iterator j=nsset.begin();j!=nsset.end();++j) {
+ vector<string>nsips=d_fns.lookup(*j, B);
+ for(vector<string>::const_iterator k=nsips.begin();k!=nsips.end();++k)
+ ips.insert(*k);
+ }
+
+ // make calls to d_nq.add(domain, ip);
+ for(set<string>::const_iterator j=ips.begin();j!=ips.end();++j)
+ d_nq.add(domain,*j);
+
+ set<string>alsoNotify;
+ B->alsoNotifies(domain, &alsoNotify);
+
+ for(set<string>::const_iterator j=alsoNotify.begin();j!=alsoNotify.end();++j)
+ d_nq.add(domain,*j);
+}
+
+bool CommunicatorClass::notifyDomain(const string &domain)
+{
+ DomainInfo di;
+ PacketHandler P;
+ if(!P.getBackend()->getDomainInfo(domain, di)) {
+ L<<Logger::Error<<"No such domain '"<<domain<<"' in our database"<<endl;
+ return false;
+ }
+ queueNotifyDomain(domain, P.getBackend());
+ // call backend and tell them we sent out the notification - even though that is premature
+ di.backend->setNotified(di.id,di.serial);
+
+ return true;
+}
+
+
+void CommunicatorClass::masterUpdateCheck(PacketHandler *P)
+{
+ if(!arg().mustDo("master"))
+ return;
+
+ UeberBackend *B=dynamic_cast<UeberBackend *>(P->getBackend());
+ vector<DomainInfo> cmdomains;
+ B->getUpdatedMasters(&cmdomains);
+
+ if(cmdomains.empty())
+ L<<Logger::Error<<"No master domains need notifications"<<endl;
+ else
+ L<<Logger::Error<<cmdomains.size()<<" domain"<<(cmdomains.size()>1 ? "s" : "")<<" for which we are master need"<<
+ (cmdomains.size()>1 ? "" : "s")<<
+ " notifications"<<endl;
+
+ // figure out A records of everybody needing notification
+ // do this via the FindNS class, d_fns
+
+
+ for(vector<DomainInfo>::const_iterator i=cmdomains.begin();i!=cmdomains.end();++i) {
+ queueNotifyDomain(i->zone,P->getBackend());
+ i->backend->setNotified(i->id,i->serial);
+ }
+
+
+
+ // call it a day
+ // day()
+
+}
+
+void CommunicatorClass::slaveRefresh(PacketHandler *P)
+{
+ UeberBackend *B=dynamic_cast<UeberBackend *>(P->getBackend());
+ vector<DomainInfo> sdomains;
+ B->getUnfreshSlaveInfos(&sdomains);
+
+ if(sdomains.empty())
+ {
+ L<<Logger::Error<<"All slave domains are fresh"<<endl;
+ return;
+ }
+ else
+ L<<Logger::Error<<sdomains.size()<<" slave domain"<<(sdomains.size()>1 ? "s" : "")<<" need"<<
+ (sdomains.size()>1 ? "" : "s")<<
+ " checking"<<endl;
+
+ for(vector<DomainInfo>::const_iterator i=sdomains.begin();i!=sdomains.end();++i) {
+ u_int32_t theirserial=0;
+ try {
+ Resolver resolver;
+ int res=resolver.getSoaSerial(i->master,i->zone, &theirserial);
+ if(res<=0) {
+ L<<Logger::Error<<"Unable to determine SOA serial for "<<i->zone<<" at "<<i->master<<endl;
+ continue;
+ }
+
+ if(theirserial<i->serial) {
+ L<<Logger::Error<<"Domain "<<i->zone<<" more recent than master, our serial "<<i->serial<<" > their serial "<<theirserial<<endl;
+ i->backend->setFresh(i->id);
+ }
+ else if(theirserial==i->serial) {
+ L<<Logger::Warning<<"Domain "<<i->zone<<" is fresh"<<endl;
+ i->backend->setFresh(i->id);
+ }
+ else {
+ L<<Logger::Error<<"Domain "<<i->zone<<" is stale, master serial "<<theirserial<<", our serial "<<i->serial<<endl;
+ addSuckRequest(i->zone,i->master);
+ }
+ }
+ catch(ResolverException &re) {
+ L<<Logger::Error<<"Trying to retrieve/refresh '"+i->zone+"': "+re.reason<<endl;
+ }
+ }
+}
+
+
+
+int CommunicatorClass::doNotifications()
+{
+ struct sockaddr_in from;
+ Utility::socklen_t fromlen=sizeof(from);
+ char buffer[1500];
+ int size;
+ static Resolver d_nresolver;
+ // receive incoming notifications on the nonblocking socket and take them off the list
+
+#ifndef WIN32
+ while((size=recvfrom(d_nsock,buffer,sizeof(buffer),0,(struct sockaddr *)&from,&fromlen))>0) {
+#else
+ while((size=recvfrom(d_nsock,buffer,sizeof(buffer),0,(struct sockaddr *)&from,&fromlen))>0) {
+#endif
+
+
+
+ DNSPacket p;
+
+ p.setRemote((struct sockaddr *)&from, fromlen);
+
+ if(p.parse(buffer,size)<0) {
+ L<<Logger::Warning<<"Unable to parse SOA notification answer from "<<p.getRemote()<<endl;
+ continue;
+ }
+
+ if(p.d.rcode)
+ L<<Logger::Warning<<"Received unsuccesful notification report for '"<<p.qdomain<<"' from "<<p.getRemote()<<", rcode: "<<p.d.rcode<<endl;
+ else if(d_nq.removeIf(p.getRemote(), p.d.id, p.qdomain))
+ L<<Logger::Warning<<"Received valid notify answer for '"<<p.qdomain<<"' from "<<p.getRemote()<<endl;
+ else
+ L<<Logger::Warning<<"Received spurious notify answer for '"<<p.qdomain<<"' from "<<p.getRemote()<<endl;
+ }
+
+ // send out possible new notifications
+ string domain, ip;
+ u_int16_t id;
+
+ bool purged;
+ while(d_nq.getOne(domain, ip, &id, purged)) {
+ if(!purged) {
+ d_nresolver.notify(d_nsock,domain,ip,id);
+ drillHole(domain,ip);
+ }
+ else
+ L<<Logger::Error<<Logger::NTLog<<"Notification for "<<domain<<" to "<<ip<<" failed after retries"<<endl;
+ }
+
+ return d_nq.earliest();
+}
+
+void CommunicatorClass::drillHole(const string &domain, const string &ip)
+{
+ Lock l(&d_holelock);
+ d_holes[make_pair(domain,ip)]=time(0);
+}
+
+bool CommunicatorClass::justNotified(const string &domain, const string &ip)
+{
+ Lock l(&d_holelock);
+ if(d_holes.find(make_pair(domain,ip))==d_holes.end()) // no hole
+ return false;
+
+ if(d_holes[make_pair(domain,ip)]>time(0)-900) // recent hole
+ return true;
+
+ // do we want to purge this? XXX FIXME
+ return false;
+}
+
+void CommunicatorClass::makeNotifySocket()
+{
+ if((d_nsock=socket(AF_INET, SOCK_DGRAM,0))<0)
+ throw AhuException(string("notification socket: ")+strerror(errno));
+
+ struct sockaddr_in sin;
+ memset((char *)&sin,0, sizeof(sin));
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ int n=0;
+ for(;n<10;n++) {
+ sin.sin_port = htons(10000+(Utility::random()%50000));
+
+ if(bind(d_nsock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ break;
+ }
+ if(n==10) {
+ Utility::closesocket(d_nsock);
+ d_nsock=-1;
+ throw AhuException(string("binding dnsproxy socket: ")+strerror(errno));
+ }
+ if( !Utility::setNonBlocking( d_nsock ))
+ throw AhuException(string("error getting or setting notify socket non-blocking: ")+strerror(errno));
+
+}
+
+void CommunicatorClass::notify(const string &domain, const string &ip)
+{
+ d_nq.add(domain,ip);
+
+ d_any_sem.post();
+}
+
+void CommunicatorClass::mainloop(void)
+{
+ try {
+#ifndef WIN32
+ signal(SIGPIPE,SIG_IGN);
+#endif // WIN32
+ L<<Logger::Error<<"Master/slave communicator launching"<<endl;
+ PacketHandler P;
+ d_tickinterval=arg().asNum("slave-cycle-interval");
+ makeNotifySocket();
+
+ int rc;
+ time_t next;
+
+ int tick;
+
+ for(;;) {
+ slaveRefresh(&P);
+ masterUpdateCheck(&P);
+
+ tick=min(doNotifications(),
+ d_tickinterval);
+
+ next=time(0)+tick;
+
+ while(time(0)<next) {
+ rc=d_any_sem.tryWait();
+
+ if(rc)
+ Utility::sleep(1);
+ else {
+ if(!d_suck_sem.tryWait()) {
+ SuckRequest sr;
+ {
+ Lock l(&d_lock);
+ sr=d_suckdomains.front();
+ d_suckdomains.pop();
+ }
+ suck(sr.domain,sr.master);
+ }
+ }
+ // this gets executed at least once every second
+ doNotifications();
+ }
+ }
+ }
+ catch(AhuException &ae) {
+ L<<Logger::Error<<"Communicator thread died because of error: "<<ae.reason<<endl;
+ sleep(1);
+ exit(0);
+ }
+ catch(exception &e) {
+ L<<Logger::Error<<"Communicator thread died because of STL error: "<<e.what()<<endl;
+ exit(0);
+ }
+ catch( ... )
+ {
+ L << Logger::Error << "Communicator caught unknown exception." << endl;
+ exit( 0 );
+ }
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PDNS_COMMUNICATOR_HH
+#define PDNS_COMMUNICATOR_HH
+
+#include <pthread.h>
+#include <string>
+#include <semaphore.h>
+#include <queue>
+#include <list>
+\r
+#ifndef WIN32\r
+# include <unistd.h>\r
+# include <fcntl.h>\r
+# include <netdb.h>\r
+#endif // WIN32\r
+\r
+#include "lock.hh"
+#include "packethandler.hh"
+
+using namespace std;
+
+struct SuckRequest
+{
+ string domain;
+ string master;
+};
+
+class NotificationQueue
+{
+public:
+ void add(const string &domain, const string &ip)
+ {
+ NotificationRequest nr;\r
+ nr.domain = domain;\r
+ nr.ip = ip;\r
+ nr.attempts = 0;\r
+ nr.id = Utility::random()%0xffff;\r
+ nr.next = time(0);\r
+
+ d_nqueue.push_back(nr);
+ }
+
+ bool removeIf(const string &remote, u_int16_t id, const string &domain)
+ {
+ for(d_nqueue_t::iterator i=d_nqueue.begin();i!=d_nqueue.end();++i) {
+ cout<<i->id<<" "<<id<<endl;
+ cout<<i->ip<<" "<<remote<<endl;
+ cout<<i->domain<<" "<<domain<<endl;
+
+ if(i->id==id && i->ip==remote && i->domain==domain) {
+ d_nqueue.erase(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool getOne(string &domain, string &ip, u_int16_t *id, bool &purged)
+ {
+ for(d_nqueue_t::iterator i=d_nqueue.begin();i!=d_nqueue.end();++i)
+ if(i->next <= time(0)) {
+ i->attempts++;
+ purged=false;
+ i->next=time(0)+1+(1<<i->attempts);
+ domain=i->domain;
+ ip=i->ip;
+ *id=i->id;
+ purged=false;
+ if(i->attempts>4) {
+ purged=true;
+ d_nqueue.erase(i);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ time_t earliest()
+ {
+ time_t early=1<<31-1; // y2038 problem lurking here :-)
+ for(d_nqueue_t::const_iterator i=d_nqueue.begin();i!=d_nqueue.end();++i)
+ early=min(early,i->next);
+ return early-time(0);
+ }
+
+private:
+ struct NotificationRequest
+ {
+ string domain;
+ string ip;
+ int attempts;
+ u_int16_t id;
+ time_t next;
+ };
+
+ typedef list<NotificationRequest>d_nqueue_t;
+ d_nqueue_t d_nqueue;
+
+};
+
+/** this class contains a thread that communicates with other nameserver and does housekeeping.
+ Initially, it is notified only of zones that need to be pulled in because they have been updated. */
+
+class CommunicatorClass
+{
+public:
+ CommunicatorClass()
+ {
+ pthread_mutex_init(&d_lock,0);
+ pthread_mutex_init(&d_holelock,0);
+// sem_init(&d_suck_sem,0,0);
+// sem_init(&d_any_sem,0,0);
+ d_tickinterval=60;
+ }
+ int doNotifications();
+ void go()
+ {
+ pthread_t tid;
+ pthread_create(&tid,0,&launchhelper,this);
+ }
+
+ void drillHole(const string &domain, const string &ip);
+ bool justNotified(const string &domain, const string &ip);
+ void addSuckRequest(const string &domain, const string &master);
+ void notify(const string &domain, const string &ip);
+ void mainloop();
+ static void *launchhelper(void *p)
+ {
+ static_cast<CommunicatorClass *>(p)->mainloop();
+ return 0;
+ }
+ bool notifyDomain(const string &domain);
+private:
+ void makeNotifySocket();
+ void queueNotifyDomain(const string &domain, DNSBackend *B);
+ int d_nsock;
+ map<pair<string,string>,time_t>d_holes;
+ pthread_mutex_t d_holelock;
+ void suck(const string &domain, const string &remote);
+ void slaveRefresh(PacketHandler *P);
+ void masterUpdateCheck(PacketHandler *P);
+ pthread_mutex_t d_lock;
+ queue<SuckRequest> d_suckdomains;
+ Semaphore d_suck_sem;
+ Semaphore d_any_sem;
+ int d_tickinterval;
+ NotificationQueue d_nq;
+};
+
+#endif
--- /dev/null
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-03-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int dummy(){}" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+ if test $? = 0 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ rm -f $dummy.c $dummy.o $dummy.rel ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mipseb-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >$dummy.s
+ .data
+\$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ eval $set_cc_for_build
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `./$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ 2-1307)
+ UNAME_MACHINE="alphaev68"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
+ if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+ rm -f $dummy.c $dummy
+ fi ;;
+ esac
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3D:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ x86:Interix*:3*)
+ echo i386-pc-interix3
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ rm -f $dummy.c
+ test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
+ ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0 ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit 0 ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ rm -f $dummy.c
+ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i*86:*:5:[78]*)
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ echo `uname -p`-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */
+
+/* Define if you have the strftime function. */
+#undef HAVE_STRFTIME
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define if the setvbuf function takes the buffering type as its second
+ argument and the buffer pointer as the third, as on System V
+ before release 3. */
+#undef SETVBUF_REVERSED
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm. */
+#undef TM_IN_SYS_TIME
+
+/* Define if lex declares yytext as a char * by default, not a char[]. */
+#undef YYTEXT_POINTER
+
+/* Define when extra posix typedefs are needed (solaris2.6) */
+#undef NEED_POSIX_TYPEDEF
+#undef VERBOSELOG
+
+/* Define if you have the gethostname function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define if you have the gettimeofday function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the mkdir function. */
+#undef HAVE_MKDIR
+
+/* Define if you have the mktime function. */
+#undef HAVE_MKTIME
+
+/* Define if you have the select function. */
+#undef HAVE_SELECT
+
+/* Define if you have the socket function. */
+#undef HAVE_SOCKET
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the dl library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define if you have the resolv library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-03-07'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit 0;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | c4x | clipper \
+ | d10v | d30v | dsp16xx \
+ | fr30 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | m32r | m68000 | m68k | m88k | mcore \
+ | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el | mips64vr4300 \
+ | mips64vr4300el | mips64vr5000 | mips64vr5000el \
+ | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
+ | mipsisa32 | mipsisa64 \
+ | mn10200 | mn10300 \
+ | ns16k | ns32k \
+ | openrisc | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armv*-* \
+ | avr-* \
+ | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c54x-* \
+ | clipper-* | cydra-* \
+ | d10v-* | d30v-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | m32r-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | mcore-* \
+ | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
+ | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
+ | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+ | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ mmix*)
+ basic_machine=mmix-knuth
+ os=-mmixware
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i686-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3d)
+ basic_machine=alpha-cray
+ os=-unicos
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ windows32)
+ basic_machine=i386-pc
+ os=-windows32-msvcrt
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh3 | sh4 | sh3eb | sh4eb)
+ basic_machine=sh-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto*)
+ os=-nto-qnx
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --disable-dependency-tracking Speeds up one-time builds
+ --enable-dependency-tracking Do not reject slow dependency extractors"
+ac_default_prefix=/opt/pdns
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+ ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+
+EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+ then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --with-pic try to use only PIC/non-PIC objects [default=use both]"
+ac_help="$ac_help
+ --with-stl-includes=PATH Specify location of STL headers"
+ac_help="$ac_help
+ --with-stl-libs=PATH Specify location of STL libs"
+ac_help="$ac_help
+ --enable-verbose-logging Do verbose logging"
+ac_help="$ac_help
+ --enable-static-binaries Build static binaries"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=receiver.cc
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:755: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:776: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:794: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`CDPATH=:; cd $ac_aux_dir && pwd`
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:832: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:885: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ am_backtick='`'
+ echo "configure: warning: ${am_backtick}missing' script is too old or missing" 1>&2
+fi
+
+for ac_prog in mawk gawk nawk awk
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:956: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AWK="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+ echo "$ac_t""$AWK" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AWK" && break
+done
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:986: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval="$enable_dependency_tracking"
+ :
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+
+rm -f .deps 2>/dev/null
+mkdir .deps 2>/dev/null
+if test -d .deps; then
+ DEPDIR=.deps
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ DEPDIR=_deps
+fi
+rmdir .deps 2>/dev/null
+
+
+# test to see if srcdir already configured
+if test "`CDPATH=:; cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run \"make distclean\" there first" 1>&2; exit 1; }
+fi
+
+# Define the identity of the package.
+PACKAGE=pdns
+VERSION=2.9
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
+# the ones we care about.
+
+# Autoconf 2.50 always computes EXEEXT. However we need to be
+# compatible with 2.13, for now. So we always define EXEEXT, but we
+# don't compute it.
+
+# Similar for OBJEXT -- only we only use OBJEXT if the user actually
+# requests that it be used. This is a bit dumb.
+: ${OBJEXT=o}
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+
+
+
+
+CXXFLAGS="-Wall -pthread -O2"
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1111: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1141: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1192: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1224: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1235 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1240: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1266: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1271: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1280: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1299: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+doit:
+ @echo done
+END
+# If we don't find an include directive, just comment out the code.
+echo $ac_n "checking for style of include used by $am_make""... $ac_c" 1>&6
+echo "configure:1338: checking for style of include used by $am_make" >&5
+am__include='#'
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote='"'
+ _am_result=BSD
+ fi
+fi
+
+
+echo "$ac_t""$_am_result" 1>&6
+rm -f confinc confmf
+
+
+depcc="$CC" am_compiler_list=
+
+echo $ac_n "checking dependency style of $depcc""... $ac_c" 1>&6
+echo "configure:1372: checking dependency style of $depcc" >&5
+if eval "test \"`echo '$''{'am_cv_CC_dependencies_compiler_type'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ echo '#include "conftest.h"' > conftest.c
+ echo 'int i;' > conftest.h
+ echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=conftest.c object=conftest.o \
+ depfile=conftest.Po tmpdepfile=conftest.TPo \
+ $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
+ grep conftest.h conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+
+echo "$ac_t""$am_cv_CC_dependencies_compiler_type" 1>&6
+CCDEPMODE="depmode=$am_cv_CC_dependencies_compiler_type"
+
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1443: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CXX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+ echo "$ac_t""$CXX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1475: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1486 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:1491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cxx_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cxx_cross=no
+ else
+ ac_cv_prog_cxx_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+ { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1517: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:1522: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.C <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1531: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gxx=yes
+else
+ ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:1550: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+ ac_cv_prog_cxx_g=yes
+else
+ ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+
+depcc="$CXX" am_compiler_list=
+
+echo $ac_n "checking dependency style of $depcc""... $ac_c" 1>&6
+echo "configure:1584: checking dependency style of $depcc" >&5
+if eval "test \"`echo '$''{'am_cv_CXX_dependencies_compiler_type'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ echo '#include "conftest.h"' > conftest.c
+ echo 'int i;' > conftest.h
+ echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=conftest.c object=conftest.o \
+ depfile=conftest.Po tmpdepfile=conftest.TPo \
+ $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
+ grep conftest.h conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+
+echo "$ac_t""$am_cv_CXX_dependencies_compiler_type" 1>&6
+CXXDEPMODE="depmode=$am_cv_CXX_dependencies_compiler_type"
+
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1655: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1686: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1701 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1707: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1718 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1724: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1735 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1741: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+
+for ac_prog in flex lex
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1771: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LEX" && break
+done
+test -n "$LEX" || LEX="${am_missing_run}flex"
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1804: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:1838: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1846 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:1857: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking lex output file root""... $ac_c" 1>&6
+echo "configure:1880: checking lex output file root" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # The minimal lex program is just a single line: %%. But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+echo '%%
+%%' | $LEX
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_root" 1>&6
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6
+echo "configure:1901: checking whether yytext is a pointer" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS="$LIBS"
+LIBS="$LIBS $LEXLIB"
+cat > conftest.$ac_ext <<EOF
+#line 1913 "configure"
+#include "confdefs.h"
+`cat $LEX_OUTPUT_ROOT.c`
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1920: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+ cat >> confdefs.h <<\EOF
+#define YYTEXT_POINTER 1
+EOF
+
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1953: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:2006: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:2044: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2049 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:2060: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:2077: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2082 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:2089: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:2186: checking for ld used by GCC" >&5
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:2216: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:2219: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:2254: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6
+echo "configure:2271: checking for $LD option to reload object files" >&5
+if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+
+echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:2283: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+
+NM="$lt_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:2321: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6
+echo "configure:2342: checking how to recognise dependant libraries" >&5
+if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* | pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.[012])
+ lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ irix5* | nonstopux*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+openbsd*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+ else
+ lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv5uw[78]* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+
+echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+echo "configure:2519: checking for object suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftest*
+echo 'int i = 1;' > conftest.$ac_ext
+if { (eval echo configure:2525: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_objext" 1>&6
+OBJEXT=$ac_cv_objext
+ac_objext=$ac_cv_objext
+
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:2545: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:2555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.$ac_ext | *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6
+echo "configure:2586: checking command to parse $NM output" >&5
+if eval "test \"`echo '$''{'lt_cv_sys_global_symbol_pipe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+solaris* | sysv5*)
+ symcode='[BDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $host_os in
+mingw*)
+ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ rm -f conftest*
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ if { (eval echo configure:2666: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { (eval echo configure:2669: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
+
+ cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
+ cat <<\EOF >> conftest.$ac_ext
+ {0, (lt_ptr) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo configure:2720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -f conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+ global_symbol_to_c_name_address=
+else
+ global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
+ global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
+fi
+if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
+then
+ echo "$ac_t""failed" 1>&6
+else
+ echo "$ac_t""ok" 1>&6
+fi
+
+for ac_hdr in dlfcn.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2769: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2774 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2779: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6
+echo "configure:2814: checking for ${ac_tool_prefix}file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ echo $ac_n "checking for file""... $ac_c" 1>&6
+echo "configure:2876: checking for file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2947: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2979: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3014: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+ echo "$ac_t""$STRIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_STRIP"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3046: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_STRIP="strip"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+ echo "$ac_t""$STRIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ STRIP=":"
+fi
+fi
+
+
+enable_dlopen=no
+enable_win32_dll=no
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 3095 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:3096: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:3117: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ cat > conftest.$ac_ext <<EOF
+#line 3130 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+need_locks="$enable_libtool_lock"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+if test x"$host" != x"$build"; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case $host_os in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+ ;;
+ *)
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for objdir""... $ac_c" 1>&6
+echo "configure:3257: checking for objdir" >&5
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t""$objdir" 1>&6
+
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+test -z "$pic_mode" && pic_mode=default
+
+# We assume here that the value for lt_cv_prog_cc_pic will not be cached
+# in isolation, and that seeing it set (from the cache) indicates that
+# the associated values are set (in the cache) correctly too.
+echo $ac_n "checking for $compiler option to produce PIC""... $ac_c" 1>&6
+echo "configure:3284: checking for $compiler option to produce PIC" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_cc_pic'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_shlib=
+ lt_cv_prog_cc_wl=
+ lt_cv_prog_cc_static=
+ lt_cv_prog_cc_no_builtin=
+ lt_cv_prog_cc_can_build_shared=$can_build_shared
+
+ if test "$GCC" = yes; then
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-static'
+
+ case $host_os in
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # not sure about C++ programs.
+ lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_cv_prog_cc_pic='-fno-common'
+ ;;
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_cv_prog_cc_pic=-Kconform_pic
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for PIC flags for the system compiler.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ lt_cv_prog_cc_wl='-Wl,'
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_cv_prog_cc_static='-Bstatic'
+ else
+ lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
+ lt_cv_prog_cc_pic='+Z'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+
+ newsos6)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ # All OSF/1 code is PIC.
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ lt_cv_prog_cc_pic='-Kpic'
+ lt_cv_prog_cc_static='-dn'
+ lt_cv_prog_cc_shlib='-belf'
+ ;;
+
+ solaris*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Wl,'
+ ;;
+
+ sunos4*)
+ lt_cv_prog_cc_pic='-PIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Qoption ld '
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ if test "x$host_vendor" = xsni; then
+ lt_cv_prog_cc_wl='-LD'
+ else
+ lt_cv_prog_cc_wl='-Wl,'
+ fi
+ ;;
+
+ uts4*)
+ lt_cv_prog_cc_pic='-pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_cv_prog_cc_pic='-Kconform_pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ fi
+ ;;
+
+ *)
+ lt_cv_prog_cc_can_build_shared=no
+ ;;
+ esac
+ fi
+
+fi
+
+if test -z "$lt_cv_prog_cc_pic"; then
+ echo "$ac_t""none" 1>&6
+else
+ echo "$ac_t""$lt_cv_prog_cc_pic" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $lt_cv_prog_cc_pic works""... $ac_c" 1>&6
+echo "configure:3436: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5
+ if eval "test \"`echo '$''{'lt_cv_prog_cc_pic_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+ cat > conftest.$ac_ext <<EOF
+#line 3443 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3450: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ case $host_os in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then
+ # they create non-PIC objects. So, if there were any warnings, we
+ # assume that PIC is not supported.
+ if test -s conftest.err; then
+ lt_cv_prog_cc_pic_works=no
+ else
+ lt_cv_prog_cc_pic_works=yes
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic_works=yes
+ ;;
+ esac
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_prog_cc_pic_works=no
+
+fi
+rm -f conftest*
+ CFLAGS="$save_CFLAGS"
+
+fi
+
+
+ if test "X$lt_cv_prog_cc_pic_works" = Xno; then
+ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_can_build_shared=no
+ else
+ lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
+ fi
+
+ echo "$ac_t""$lt_cv_prog_cc_pic_works" 1>&6
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$lt_cv_prog_cc_shlib"; then
+ echo "configure: warning: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]" >/dev/null; then :
+ else
+ echo "configure: warning: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ lt_cv_prog_cc_can_build_shared=no
+ fi
+fi
+
+echo $ac_n "checking if $compiler static flag $lt_cv_prog_cc_static works""... $ac_c" 1>&6
+echo "configure:3502: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_cc_static_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_prog_cc_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+ cat > conftest.$ac_ext <<EOF
+#line 3510 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3517: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_prog_cc_static_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+
+
+# Belt *and* braces to stop my trousers falling down:
+test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
+echo "$ac_t""$lt_cv_prog_cc_static_works" 1>&6
+
+pic_flag="$lt_cv_prog_cc_pic"
+special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
+wl="$lt_cv_prog_cc_wl"
+link_static_flag="$lt_cv_prog_cc_static"
+no_builtin_flag="$lt_cv_prog_cc_no_builtin"
+can_build_shared="$lt_cv_prog_cc_can_build_shared"
+
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.$ac_objext""... $ac_c" 1>&6
+echo "configure:3544: checking if $compiler supports -c -o file.$ac_objext" >&5
+if eval "test \"`echo '$''{'lt_cv_compiler_c_o'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval echo configure:3563: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ lt_cv_compiler_c_o=no
+ else
+ lt_cv_compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&5
+ lt_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+fi
+
+compiler_c_o=$lt_cv_compiler_c_o
+echo "$ac_t""$compiler_c_o" 1>&6
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ echo $ac_n "checking if $compiler supports -c -o file.lo""... $ac_c" 1>&6
+echo "configure:3592: checking if $compiler supports -c -o file.lo" >&5
+ if eval "test \"`echo '$''{'lt_cv_compiler_o_lo'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ lt_cv_compiler_o_lo=no
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ save_objext="$ac_objext"
+ ac_objext=lo
+ cat > conftest.$ac_ext <<EOF
+#line 3603 "configure"
+#include "confdefs.h"
+
+int main() {
+int some_variable = 0;
+; return 0; }
+EOF
+if { (eval echo configure:3610: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ lt_cv_compiler_o_lo=no
+ else
+ lt_cv_compiler_o_lo=yes
+ fi
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ ac_objext="$save_objext"
+ CFLAGS="$save_CFLAGS"
+
+fi
+
+ compiler_o_lo=$lt_cv_compiler_o_lo
+ echo "$ac_t""$compiler_o_lo" 1>&6
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo $ac_n "checking if we can lock with hard links""... $ac_c" 1>&6
+echo "configure:3641: checking if we can lock with hard links" >&5
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$ac_t""$hard_links" 1>&6
+ if test "$hard_links" = no; then
+ echo "configure: warning: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" 1>&2
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$GCC" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions""... $ac_c" 1>&6
+echo "configure:3660: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
+ compiler_rtti_exceptions=no
+ cat > conftest.$ac_ext <<EOF
+#line 3666 "configure"
+#include "confdefs.h"
+
+int main() {
+int some_variable = 0;
+; return 0; }
+EOF
+if { (eval echo configure:3673: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ compiler_rtti_exceptions=no
+ else
+ compiler_rtti_exceptions=yes
+ fi
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ CFLAGS="$save_CFLAGS"
+ echo "$ac_t""$compiler_rtti_exceptions" 1>&6
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+fi
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries""... $ac_c" 1>&6
+echo "configure:3700: checking whether the linker ($LD) supports shared libraries" >&5
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+old_archive_from_expsyms_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_into_libs=no
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_all_deplibs=unknown
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced. Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+extract_expsyms_cmds=
+
+case $host_os in
+cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ # On AIX, the GNU linker is very broken
+ # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
+ sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
+ test -f $output_objdir/impgen.exe || (cd $output_objdir && \
+ if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
+ else $CC -o impgen impgen.c ; fi)~
+ $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
+
+ old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
+
+ # cygwin and mingw dlls have different entry points and sets of symbols
+ # to exclude.
+ # FIXME: what about values for MSVC?
+ dll_entry=__cygwin_dll_entry@12
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
+ case $host_os in
+ mingw*)
+ # mingw values
+ dll_entry=_DllMainCRTStartup@12
+ dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
+ ;;
+ esac
+
+ # mingw and cygwin differ, and it's simplest to just exclude the union
+ # of the two symbol sets.
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one (in ltdll.c)
+ if test "x$lt_cv_need_dllmain" = "xyes"; then
+ ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
+ ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
+ test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
+ else
+ ltdll_obj=
+ ltdll_cmds=
+ fi
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ # Be careful not to strip the DATA tag left be newer dlltools.
+ export_symbols_cmds="$ltdll_cmds"'
+ $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
+
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is.
+ # If DATA tags from a recent dlltool are present, honour them!
+ archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname-def;
+ else
+ echo EXPORTS > $output_objdir/$soname-def;
+ _lt_hint=1;
+ cat $export_symbols | while read symbol; do
+ set dummy \$symbol;
+ case \$# in
+ 2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+ *) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;;
+ esac;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done;
+ fi~
+ '"$ltdll_cmds"'
+ $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
+ $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
+ $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # dlltool doesn't understand --whole-archive et. al.
+ whole_archive_flag_spec=
+ ;;
+ *)
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ ;;
+ esac
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ hardcode_direct=yes
+ archive_cmds=''
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ esac
+
+ shared_flag='-shared'
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ shared_flag='${wl}-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall can do strange things, so it is better to
+ # generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
+ archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ else
+ hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='${wl}-berok'
+ # This is a bit strange, but is similar to how AIX traditionally builds
+ # it's shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ ;;
+
+ darwin* | rhapsody*)
+ case "$host_os" in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag='-undefined suppress'
+ ;;
+ *) # Darwin 1.3 on
+ allow_undefined_flag='-flat_namespace -undefined suppress'
+ ;;
+ esac
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes. Also zsh mangles
+ # `"' quotes if we put them in here... so don't!
+ archive_cmds='$nonopt $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+ # We need to add '_' to the symbols in $export_symbols first
+ #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ whole_archive_flag_spec='-all_load $convenience'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ case $host_os in
+ hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
+ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
+ esac
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_minus_L=yes # Not in the search PATH, but as the default
+ # location of the library.
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+ #Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ ;;
+
+ solaris*)
+ # gcc --version < 3.0 without binutils cannot create self contained
+ # shared libraries reliably, requiring libgcc.a to resolve some of
+ # the object symbols generated in some cases. Libraries that use
+ # assert need libgcc.a to resolve __eprintf, for example. Linking
+ # a copy of libgcc.a into every shared library to guarantee resolving
+ # such symbols causes other problems: According to Tim Van Holder
+ # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
+ # (to the application) exception stack for one thing.
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ case `$CC --version 2>/dev/null` in
+ [12].*)
+ cat <<EOF 1>&2
+
+*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
+*** create self contained shared libraries on Solaris systems, without
+*** introducing a dependency on libgcc.a. Therefore, libtool is disabling
+*** -no-undefined support, which will at least allow you to build shared
+*** libraries. However, you may find that when you link such libraries
+*** into an application without using GCC, you have to manually add
+*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to
+*** upgrade to a newer version of GCC. Another option is to rebuild your
+*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
+
+EOF
+ no_undefined_flag=
+ ;;
+ esac
+ fi
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ if test "x$host_vendor" = xsno; then
+ archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ else
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv5*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec=
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4.2uw2*)
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ hardcode_runpath_var=yes
+ runpath_var=LD_RUN_PATH
+ ;;
+
+ sysv5uw7* | unixware7*)
+ no_undefined_flag='${wl}-z ${wl}text'
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+echo "$ac_t""$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs""... $ac_c" 1>&6
+echo "configure:4385: checking how to hardcode library paths into programs" >&5
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$hardcode_shlibpath_var" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$ac_t""$hardcode_action" 1>&6
+
+striplib=
+old_striplib=
+echo $ac_n "checking whether stripping libraries is possible""... $ac_c" 1>&6
+echo "configure:4413: checking whether stripping libraries is possible" >&5
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+# PORTME Fill in your ld.so characteristics
+echo $ac_n "checking dynamic linker characteristics""... $ac_c" 1>&6
+echo "configure:4427: checking dynamic linker characteristics" >&5
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4* | aix5*)
+ version_type=linux
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can
+ # not hardcode correct soname into executable. Probably we can
+ # add versioning support to collect2, so additional links can
+ # be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}.so$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi4*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ export_dynamic_flag_spec=-rdynamic
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ need_version=no
+ need_lib_prefix=no
+ case $GCC,$host_os in
+ yes,cygwin*)
+ library_names_spec='$libname.dll.a'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+ postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog .libs/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $rm \$dlpath'
+ ;;
+ yes,mingw*)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+ ;;
+ yes,pw32*)
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll'
+ ;;
+ *)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes.
+ library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
+ soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ *)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *) version_type=irix ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+openbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case "$host_os" in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_version=no
+ need_lib_prefix=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+ soname_spec='$libname.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t""$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo $ac_n "checking if libtool supports shared libraries""... $ac_c" 1>&6
+echo "configure:4828: checking if libtool supports shared libraries" >&5
+echo "$ac_t""$can_build_shared" 1>&6
+
+echo $ac_n "checking whether to build shared libraries""... $ac_c" 1>&6
+echo "configure:4832: checking whether to build shared libraries" >&5
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+esac
+echo "$ac_t""$enable_shared" 1>&6
+
+echo $ac_n "checking whether to build static libraries""... $ac_c" 1>&6
+echo "configure:4855: checking whether to build static libraries" >&5
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$ac_t""$enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ *)
+ echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "configure:4896: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4901 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4924: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "configure:4942: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4950 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo configure:4961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "configure:4980: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4985 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:5026: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5034 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:5045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen in -lsvld""... $ac_c" 1>&6
+echo "configure:5064: checking for dlopen in -lsvld" >&5
+ac_lib_var=`echo svld'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsvld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5072 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:5083: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "configure:5102: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5110 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo configure:5121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "configure:5177: checking whether a program can dlopen itself" >&5
+if eval "test \"`echo '$''{'lt_cv_dlopen_self'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+#line 5187 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}
+EOF
+ if { (eval echo configure:5248: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "configure:5271: checking whether a statically linked program can dlopen itself" >&5
+if eval "test \"`echo '$''{'lt_cv_dlopen_self_static'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+#line 5281 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}
+EOF
+ if { (eval echo configure:5342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ echo $ac_n "checking whether -lc should be explicitly linked in""... $ac_c" 1>&6
+echo "configure:5391: checking whether -lc should be explicitly linked in" >&5
+ if eval "test \"`echo '$''{'lt_cv_archive_cmds_need_lc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ $rm conftest*
+ echo 'static int dummy;' > conftest.$ac_ext
+
+ if { (eval echo configure:5398: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_cv_prog_cc_wl
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { (eval echo configure:5411: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\") 1>&5; (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+fi
+
+ echo "$ac_t""$lt_cv_archive_cmds_need_lc" 1>&6
+ ;;
+ esac
+fi
+need_lc=${lt_cv_archive_cmds_need_lc-yes}
+
+# The second clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+ :
+else
+ # If there is no Makefile yet, we rely on a make rule to execute
+ # `config.status --recheck' to rerun these tests and create the
+ # libtool script then.
+ test -f Makefile && make "$ltmain"
+fi
+
+if test -f "$ltmain"; then
+ trap "$rm \"${ofile}T\"; exit 1" 1 2 15
+ $rm -f "${ofile}T"
+
+ echo creating $ofile
+
+ # Now quote all the things that may contain metacharacters while being
+ # careful not to overquote the AC_SUBSTed values. We take copies of the
+ # variables and quote the copies for generation of the libtool script.
+ for var in echo old_CC old_CFLAGS \
+ AR AR_FLAGS CC LD LN_S NM SHELL \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
+ postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
+ old_striplib striplib file_magic_cmd export_symbols_cmds \
+ deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ global_symbol_to_c_name_address \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case $var in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ cat <<__EOF__ > "${ofile}T"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996-2000 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$need_lc
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# The default C compiler.
+CC=$lt_CC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_pic_flag
+pic_mode=$pic_mode
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$lt_compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+ case $host_os in
+ aix3*)
+ cat <<\EOF >> "${ofile}T"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2*)
+ cat <<'EOF' >> "${ofile}T"
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999-2000 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# /* O_BINARY isn't required (or even defined sometimes) under Unix */
+# #ifndef O_BINARY
+# #define O_BINARY 0
+# #endif
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (dll < 1)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+
+EOF
+ ;;
+ esac
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
+
+ mv -f "${ofile}T" "$ofile" || \
+ (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
+ chmod +x "$ofile"
+fi
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Prevent multiple expansion
+
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+
+
+#dnl Replace `main' with a function in -ldl:
+#AC_CHECK_LIB(dl, main)
+#dnl Replace `main' with a function in -lpthread:
+#AC_CHECK_LIB(pthread, main)
+
+#CPPFLAGS="$CPPFLAGS -I/usr/include/postgresql"
+#LDFLAGS="$LDFLAGS -L/usr/local/lib"
+
+echo $ac_n "checking for getopt_long in -lgnugetopt""... $ac_c" 1>&6
+echo "configure:6010: checking for getopt_long in -lgnugetopt" >&5
+ac_lib_var=`echo gnugetopt'_'getopt_long | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lgnugetopt $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6018 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getopt_long();
+
+int main() {
+getopt_long()
+; return 0; }
+EOF
+if { (eval echo configure:6032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lgnugetopt"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
+echo "configure:6054: checking how to run the C++ preprocessor" >&5
+if test -z "$CXXCPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+ CXXCPP="${CXX-g++} -E"
+ cat > conftest.$ac_ext <<EOF
+#line 6067 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6072: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CXXCPP=/lib/cpp
+fi
+rm -f conftest*
+ ac_cv_prog_CXXCPP="$CXXCPP"
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+fi
+fi
+CXXCPP="$ac_cv_prog_CXXCPP"
+echo "$ac_t""$CXXCPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:6097: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6102 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6110: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 6127 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 6145 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6166 "configure"
+#include "confdefs.h"
+#ifdef __cplusplus
+extern "C" void exit(int);
+#endif
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:6180: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in fcntl.h getopt.h limits.h strings.h sys/time.h syslog.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:6207: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6212 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6217: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:6245: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6250 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:6278: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6283 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:6292: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:6313: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6318 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:6326: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether setvbuf arguments are reversed""... $ac_c" 1>&6
+echo "configure:6348: checking whether setvbuf arguments are reversed" >&5
+if eval "test \"`echo '$''{'ac_cv_func_setvbuf_reversed'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6356 "configure"
+#include "confdefs.h"
+#ifdef __cplusplus
+extern "C" void exit(int);
+#endif
+#include <stdio.h>
+/* If setvbuf has the reversed format, exit 0. */
+main () {
+ /* This call has the arguments reversed.
+ A reversed system may check and see that the address of main
+ is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */
+ if (setvbuf(stdout, _IOLBF, (char *) main, BUFSIZ) != 0)
+ exit(1);
+ putc('\r', stdout);
+ exit(0); /* Non-reversed systems segv here. */
+}
+EOF
+if { (eval echo configure:6373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_setvbuf_reversed=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_setvbuf_reversed=no
+fi
+rm -fr conftest*
+fi
+
+rm -f core core.* *.core
+fi
+
+echo "$ac_t""$ac_cv_func_setvbuf_reversed" 1>&6
+if test $ac_cv_func_setvbuf_reversed = yes; then
+ cat >> confdefs.h <<\EOF
+#define SETVBUF_REVERSED 1
+EOF
+
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:6397: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6402 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:6419: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for strftime""... $ac_c" 1>&6
+echo "configure:6438: checking for strftime" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6443 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strftime(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strftime();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strftime) || defined (__stub___strftime)
+choke me
+#else
+strftime();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6469: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRFTIME 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+# strftime is in -lintl on SCO UNIX.
+echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
+echo "configure:6491: checking for strftime in -lintl" >&5
+ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6499 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strftime();
+
+int main() {
+strftime()
+; return 0; }
+EOF
+if { (eval echo configure:6513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRFTIME 1
+EOF
+
+LIBS="-lintl $LIBS"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+for ac_func in gethostname gettimeofday mkdir mktime select socket strerror
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:6542: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6547 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+# #
+# # Check if we have libresolv. XXX If we do not have libresolv then we
+# # cannot build the 'resolver'. Is it possible to remove that target
+# # conditionally?
+# #
+#
+# AC_CHECK_LIB(resolv, res_mkquery, RESOLV_LIBS="-l resolv")
+# AC_MSG_CHECKING("for resolver library")
+# if test -f /usr/lib/libresolv.so -o -f /lib/libresolv.o
+# then
+# AC_MSG_RESULT("yes")
+# LIBS="$LIBS -lresolv"
+# else
+# AC_MSG_RESULT("no")
+# fi
+
+#
+# Check for libresolv
+#
+
+my_save_LIBS="$LIBS"
+LIBS=""
+echo $ac_n "checking for res_mkquery in -lresolv""... $ac_c" 1>&6
+echo "configure:6623: checking for res_mkquery in -lresolv" >&5
+ac_lib_var=`echo resolv'_'res_mkquery | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lresolv $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6631 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char res_mkquery();
+
+int main() {
+res_mkquery()
+; return 0; }
+EOF
+if { (eval echo configure:6645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lresolv $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+LIBRESOLV=$LIBS
+LIBS="$my_save_LIBS"
+
+
+#
+# Check for libdl
+#
+
+my_save_LIBS="$LIBS"
+LIBS=""
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:6683: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6691 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:6705: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-ldl $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+LIBDL=$LIBS
+LIBS="$my_save_LIBS"
+
+
+
+#
+# The following code checks for the right pthreads library and linker
+# flags. It was taken from MySQL, so we should have the same platform
+# support as they have.
+#
+# XXX Dit is nog niet correct. Als dit matched dan moet de rest van de
+# XXX thread checks niet. Fixen als we solaris hebben.
+#
+
+#AC_MSG_CHECKING("for Solaris threads")
+#if test -f /usr/lib/libpthread.so -a -f /usr/lib/libthread.so
+#then
+# with_named_thread="-lpthread -lthread"
+# AC_MSG_RESULT("yes")
+#else
+# AC_MSG_RESULT("no")
+#fi
+
+# pthread_create is in standard libraries (As in BSDI 3.0)
+echo $ac_n "checking "for pthread_create in -libc"""... $ac_c" 1>&6
+echo "configure:6757: checking "for pthread_create in -libc"" >&5;
+cat > conftest.$ac_ext <<EOF
+#line 6759 "configure"
+#include "confdefs.h"
+#include <pthread.h>
+int main() {
+ (void) pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0);
+; return 0; }
+EOF
+if { (eval echo configure:6766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ with_posix_threads=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ with_posix_threads=no
+fi
+rm -f conftest*
+echo "$ac_t"""$with_posix_threads"" 1>&6
+if test "$with_posix_threads" = "no"
+then
+ echo $ac_n "checking "for pthread_create in -lpthread"""... $ac_c" 1>&6
+echo "configure:6780: checking "for pthread_create in -lpthread"" >&5;
+ ac_save_LIBS="$LIBS"
+ LIBS="$LIBS -lpthread"
+ cat > conftest.$ac_ext <<EOF
+#line 6784 "configure"
+#include "confdefs.h"
+#include <pthread.h>
+int main() {
+ (void) pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0);
+; return 0; }
+EOF
+if { (eval echo configure:6791: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ with_posix_threads=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ with_posix_threads=no
+fi
+rm -f conftest*
+ echo "$ac_t"""$with_posix_threads"" 1>&6
+ if test "$with_posix_threads" = "no"
+ then
+ LIBS=" $ac_save_LIBS -lpthreads"
+ echo $ac_n "checking "for pthread_create in -lpthreads"""... $ac_c" 1>&6
+echo "configure:6806: checking "for pthread_create in -lpthreads"" >&5;
+ cat > conftest.$ac_ext <<EOF
+#line 6808 "configure"
+#include "confdefs.h"
+#include <pthread.h>
+int main() {
+ pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0);
+; return 0; }
+EOF
+if { (eval echo configure:6815: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ with_posix_threads=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ with_posix_threads=no
+fi
+rm -f conftest*
+ echo "$ac_t"""$with_posix_threads"" 1>&6
+ if test "$with_posix_threads" = "no"
+ then
+ # This is for FreeBSD
+ LIBS="$ac_save_LIBS -pthread"
+ echo $ac_n "checking "for pthread_create in -pthread"""... $ac_c" 1>&6
+echo "configure:6831: checking "for pthread_create in -pthread"" >&5;
+ cat > conftest.$ac_ext <<EOF
+#line 6833 "configure"
+#include "confdefs.h"
+#include <pthread.h>
+int main() {
+ pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0);
+; return 0; }
+EOF
+if { (eval echo configure:6840: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ with_posix_threads=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ with_posix_threads=no
+fi
+rm -f conftest*
+ echo "$ac_t"""$with_posix_threads"" 1>&6
+ if test "$with_posix_threads" = "no"
+ then
+ with_mit_threads="yes"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ fi
+fi
+
+case "$host_os" in
+solaris2*) cat >> confdefs.h <<\EOF
+#define NEED_POSIX_TYPEDEF 1
+EOF
+
+ ;;
+*)
+ ;;
+esac
+
+ac_safe=`echo "sstream" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sstream""... $ac_c" 1>&6
+echo "configure:6872: checking for sstream" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6877 "configure"
+#include "confdefs.h"
+#include <sstream>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6882: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ dontneedstl=1
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test "$dontneedstl" != "1"
+then
+
+# Check whether --with-stl-includes or --without-stl-includes was given.
+if test "${with_stl_includes+set}" = set; then
+ withval="$with_stl_includes"
+ if test x"$withval" = x"no"; then
+ search_stl=0
+ else
+ #if test x"$withval" != x"yes"; then
+ if test -d "$withval"; then
+ STL_INCLUDES="-I$withval"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+
+fi
+
+
+
+# Check whether --with-stl-libs or --without-stl-libs was given.
+if test "${with_stl_libs+set}" = set; then
+ withval="$with_stl_libs"
+ if test x"$withval" = x"no"; then
+ search_stl=0
+ else
+ #if test x"$withval" != x"yes"; then
+ if test -d "$withval"; then
+ STL_LIBS="$LIBS -L$withval -lstlport_gcc"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+
+fi
+
+
+
+
+
+
+if test x"$search_stl" != x"0"; then
+ echo $ac_n "checking "location of sstream"""... $ac_c" 1>&6
+echo "configure:6948: checking "location of sstream"" >&5
+ if test x"$search_stl" != x"0"; then
+ if test -f "/usr/include/sstream"; then
+ echo "$ac_t"""found in /usr/include"" 1>&6
+ STL_LIBS="-lstlport_gcc"
+ STL_INCLUDES=""
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+
+ if test x"$search_stl" != x"0"; then
+ if test -f "/usr/include/stlport/sstream"; then
+ echo "$ac_t"""found in /usr/include/stlport"" 1>&6
+ STL_LIBS="-lstlport_gcc"
+ STL_INCLUDES="-I/usr/include/stlport"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+
+ if test x"$search_stl" != x"0"; then
+ if test -f "/usr/local/include/sstream"; then
+ echo "$ac_t"""found in /usr/local"" 1>&6
+ STL_LIBS="-L/usr/local/lib -lstlport_gcc"
+ STL_INCLUDES="-I/usr/local/include"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+
+ if test x"$search_stl" != x"0"; then
+ if test -f "/usr/local/include/stl/sstream"; then
+ echo "$ac_t"""found in /usr/local/include/stl"" 1>&6
+ STL_LIBS="-L/usr/local/lib -L/usr/local/lib/stl -lstlport_gcc"
+ STL_INCLUDES="-I/usr/local/include/stl"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+
+ if test x"$search_stl" != x"0"; then
+ if test -f "/home/ahu/download/STLport-4.0/stlport/sstream"; then
+ echo "$ac_t"""found in /home/ahu/download/STLport-4.0/stlport"" 1>&6
+ STL_LIBS="-L/home/ahu/download/STLport-4.0/lib/ -lstlport_gcc"
+ STL_INCLUDES="-I/home/ahu/download/STLport-4.0/stlport/"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+
+ if test x"$search_stl" != x"0"; then
+ if test -f "$HOME/STLport-4.0/stlport/sstream"; then
+ echo "$ac_t"""found in $HOME/STLport-4.0/stlport"" 1>&6
+ STL_LIBS="-L$HOME/STLport-4.0/lib/ -lstlport_gcc"
+ STL_INCLUDES="-I$HOME/STLport-4.0/stlport/"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+
+
+fi
+
+if test x"$has_stl" = x"1"; then
+ echo Found sstream include file, assuming working and compliant STL
+else
+ echo
+ echo Did not find sstream include file, this probably means that your STL is not
+ echo compliant - the default gcc libstdc++ isn\'t. Download STLport-4.0 from
+ echo http://www.stlport.org, or use --with-stl-includes and --with-stl-libs
+ echo to specify the location of your STL.
+ echo
+ exit 1
+fi
+
+CPPFLAGS="$CPPFLAGS $STL_INCLUDES"
+LIBS="$LIBS $STL_LIBS"
+fi
+
+echo $ac_n "checking whether we will be doing verbose logging""... $ac_c" 1>&6
+echo "configure:7029: checking whether we will be doing verbose logging" >&5
+# Check whether --enable-verbose-logging or --disable-verbose-logging was given.
+if test "${enable_verbose_logging+set}" = set; then
+ enableval="$enable_verbose_logging"
+ enable_verbose_logging=yes
+else
+ enable_verbose_logging=no
+fi
+
+
+if test $enable_verbose_logging = yes; then cat >> confdefs.h <<\EOF
+#define VERBOSELOG 1
+EOF
+
+fi
+echo "$ac_t""$enable_verbose_logging" 1>&6
+
+echo $ac_n "checking whether we should build static binaries""... $ac_c" 1>&6
+echo "configure:7047: checking whether we should build static binaries" >&5
+# Check whether --enable-static-binaries or --disable-static-binaries was given.
+if test "${enable_static_binaries+set}" = set; then
+ enableval="$enable_static_binaries"
+ enable_static_binaries=yes
+else
+ enable_static_binaries=no
+fi
+
+
+if test $enable_static_binaries = yes;
+then
+ LDFLAGS="-all-static $LD_FLAGS"
+fi
+echo "$ac_t""$enable_static_binaries" 1>&6
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile codedocs/Makefile backends/bind/Makefile \
+backends/Makefile \
+pdns.conf-dist buildroot.sh \
+showvar pdns mkbindist config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@EXEEXT@%$EXEEXT%g
+s%@OBJEXT@%$OBJEXT%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@AMTAR@%$AMTAR%g
+s%@install_sh@%$install_sh%g
+s%@INSTALL_STRIP_PROGRAM@%$INSTALL_STRIP_PROGRAM%g
+s%@AWK@%$AWK%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@AMDEP_TRUE@%$AMDEP_TRUE%g
+s%@AMDEP_FALSE@%$AMDEP_FALSE%g
+s%@AMDEPBACKSLASH@%$AMDEPBACKSLASH%g
+s%@DEPDIR@%$DEPDIR%g
+s%@CC@%$CC%g
+s%@am__include@%$am__include%g
+s%@am__quote@%$am__quote%g
+s%@CCDEPMODE@%$CCDEPMODE%g
+s%@CXX@%$CXX%g
+s%@CXXDEPMODE@%$CXXDEPMODE%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@CPP@%$CPP%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@LN_S@%$LN_S%g
+s%@ECHO@%$ECHO%g
+s%@RANLIB@%$RANLIB%g
+s%@STRIP@%$STRIP%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@CXXCPP@%$CXXCPP%g
+s%@LIBRESOLV@%$LIBRESOLV%g
+s%@LIBDL@%$LIBDL%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile codedocs/Makefile backends/bind/Makefile \
+backends/Makefile \
+pdns.conf-dist buildroot.sh \
+showvar pdns mkbindist"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+am_indx=1
+for am_file in config.h; do
+ case " \$CONFIG_HEADERS " in
+ *" \$am_file "*)
+ am_dir=\`echo \$am_file |sed 's%:.*%%;s%[^/]*\$%%'\`
+ if test -n "\$am_dir"; then
+ am_tmpdir=\`echo \$am_dir |sed 's%^\(/*\).*\$%\1%'\`
+ for am_subdir in \`echo \$am_dir |sed 's%/% %'\`; do
+ am_tmpdir=\$am_tmpdir\$am_subdir/
+ if test ! -d \$am_tmpdir; then
+ mkdir \$am_tmpdir
+ fi
+ done
+ fi
+ echo timestamp > "\$am_dir"stamp-h\$am_indx
+ ;;
+ esac
+ am_indx=\`expr \$am_indx + 1\`
+done
+AMDEP_TRUE="$AMDEP_TRUE"
+ac_aux_dir="$ac_aux_dir"
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+test x"$AMDEP_TRUE" != x"" ||
+for mf in $CONFIG_FILES; do
+ case "$mf" in
+ Makefile) dirpart=.;;
+ */Makefile) dirpart=`echo "$mf" | sed -e 's|/[^/]*$||'`;;
+ *) continue;;
+ esac
+ grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`echo "$file" | sed -e 's|/[^/]*$||'`
+ $ac_aux_dir/mkinstalldirs "$dirpart/$fdir" > /dev/null 2>&1
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
--- /dev/null
+dnl intro
+AC_INIT(receiver.cc)
+AC_CANONICAL_SYSTEM
+AM_INIT_AUTOMAKE(pdns, 2.9)
+AM_CONFIG_HEADER(config.h)
+CXXFLAGS="-Wall -pthread -O2"
+
+AC_PREFIX_DEFAULT(/opt/pdns)
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_YACC
+AM_PROG_LEX
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AM_PROG_LIBTOOL
+AC_LANG_CPLUSPLUS
+
+
+#dnl Replace `main' with a function in -ldl:
+#AC_CHECK_LIB(dl, main)
+#dnl Replace `main' with a function in -lpthread:
+#AC_CHECK_LIB(pthread, main)
+
+#CPPFLAGS="$CPPFLAGS -I/usr/include/postgresql"
+#LDFLAGS="$LDFLAGS -L/usr/local/lib"
+
+AC_CHECK_LIB(gnugetopt,getopt_long,LIBS="$LIBS -lgnugetopt")
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h getopt.h limits.h strings.h sys/time.h syslog.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl Checks for library functions.
+AC_FUNC_SETVBUF_REVERSED
+AC_TYPE_SIGNAL
+AC_FUNC_STRFTIME
+AC_CHECK_FUNCS(gethostname gettimeofday mkdir mktime select socket strerror)
+
+
+
+# #
+# # Check if we have libresolv. XXX If we do not have libresolv then we
+# # cannot build the 'resolver'. Is it possible to remove that target
+# # conditionally?
+# #
+#
+# AC_CHECK_LIB(resolv, res_mkquery, RESOLV_LIBS="-l resolv")
+# AC_MSG_CHECKING("for resolver library")
+# if test -f /usr/lib/libresolv.so -o -f /lib/libresolv.o
+# then
+# AC_MSG_RESULT("yes")
+# LIBS="$LIBS -lresolv"
+# else
+# AC_MSG_RESULT("no")
+# fi
+
+#
+# Check for libresolv
+#
+
+my_save_LIBS="$LIBS"
+LIBS=""
+AC_CHECK_LIB(resolv,res_mkquery)
+LIBRESOLV=$LIBS
+LIBS="$my_save_LIBS"
+AC_SUBST(LIBRESOLV)
+
+#
+# Check for libdl
+#
+
+my_save_LIBS="$LIBS"
+LIBS=""
+AC_CHECK_LIB(dl,dlopen)
+LIBDL=$LIBS
+LIBS="$my_save_LIBS"
+AC_SUBST(LIBDL)
+
+
+#
+# The following code checks for the right pthreads library and linker
+# flags. It was taken from MySQL, so we should have the same platform
+# support as they have.
+#
+# XXX Dit is nog niet correct. Als dit matched dan moet de rest van de
+# XXX thread checks niet. Fixen als we solaris hebben.
+#
+
+#AC_MSG_CHECKING("for Solaris threads")
+#if test -f /usr/lib/libpthread.so -a -f /usr/lib/libthread.so
+#then
+# with_named_thread="-lpthread -lthread"
+# AC_MSG_RESULT("yes")
+#else
+# AC_MSG_RESULT("no")
+#fi
+
+# pthread_create is in standard libraries (As in BSDI 3.0)
+AC_MSG_CHECKING("for pthread_create in -libc");
+AC_TRY_LINK(
+[#include <pthread.h>],
+[ (void) pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0); ],
+with_posix_threads=yes, with_posix_threads=no)
+AC_MSG_RESULT("$with_posix_threads")
+if test "$with_posix_threads" = "no"
+then
+ AC_MSG_CHECKING("for pthread_create in -lpthread");
+ ac_save_LIBS="$LIBS"
+ LIBS="$LIBS -lpthread"
+ AC_TRY_LINK(
+ [#include <pthread.h>],
+ [ (void) pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0); ],
+ with_posix_threads=yes, with_posix_threads=no)
+ AC_MSG_RESULT("$with_posix_threads")
+ if test "$with_posix_threads" = "no"
+ then
+ LIBS=" $ac_save_LIBS -lpthreads"
+ AC_MSG_CHECKING("for pthread_create in -lpthreads");
+ AC_TRY_LINK(
+ [#include <pthread.h>],
+ [ pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0); ],
+ with_posix_threads=yes, with_posix_threads=no)
+ AC_MSG_RESULT("$with_posix_threads")
+ if test "$with_posix_threads" = "no"
+ then
+ # This is for FreeBSD
+ LIBS="$ac_save_LIBS -pthread"
+ AC_MSG_CHECKING("for pthread_create in -pthread");
+ AC_TRY_LINK(
+ [#include <pthread.h>],
+ [ pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0); ],
+ with_posix_threads=yes, with_posix_threads=no)
+ AC_MSG_RESULT("$with_posix_threads")
+ if test "$with_posix_threads" = "no"
+ then
+ with_mit_threads="yes"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ fi
+fi
+
+case "$host_os" in
+solaris2*) AC_DEFINE(NEED_POSIX_TYPEDEF)
+ ;;
+*)
+ ;;
+esac
+
+AC_CHECK_HEADER(sstream,dontneedstl=1)
+
+if test "$dontneedstl" != "1"
+then
+
+AC_ARG_WITH(stl-includes, [ --with-stl-includes=PATH Specify location of STL headers],
+[ if test x"$withval" = x"no"; then
+ search_stl=0
+ else
+ #if test x"$withval" != x"yes"; then
+ if test -d "$withval"; then
+ STL_INCLUDES="-I$withval"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+])
+
+
+AC_ARG_WITH(stl-libs, [ --with-stl-libs=PATH Specify location of STL libs],
+[ if test x"$withval" = x"no"; then
+ search_stl=0
+ else
+ #if test x"$withval" != x"yes"; then
+ if test -d "$withval"; then
+ STL_LIBS="$LIBS -L$withval -lstlport_gcc"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+])
+
+AC_DEFUN(AC_CHECK_STL,
+[ if test x"$search_stl" != x"0"; then
+ if test -f "$1/$2"; then
+ AC_MSG_RESULT($5)
+ STL_LIBS="$3"
+ STL_INCLUDES="$4"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+])
+
+AC_DEFUN(AC_SEARCH_STL,
+[ AC_MSG_CHECKING("location of sstream")
+ AC_CHECK_STL(/usr/include, sstream, -lstlport_gcc,, "found in /usr/include")
+ AC_CHECK_STL(/usr/include/stlport, sstream, -lstlport_gcc, -I/usr/include/stlport, "found in /usr/include/stlport")
+ AC_CHECK_STL(/usr/local/include, sstream, -L/usr/local/lib -lstlport_gcc, -I/usr/local/include, "found in /usr/local")
+ AC_CHECK_STL(/usr/local/include/stl, sstream, -L/usr/local/lib -L/usr/local/lib/stl -lstlport_gcc, -I/usr/local/include/stl, "found in /usr/local/include/stl")
+ AC_CHECK_STL(/home/ahu/download/STLport-4.0/stlport, sstream,-L/home/ahu/download/STLport-4.0/lib/ -lstlport_gcc, -I/home/ahu/download/STLport-4.0/stlport/, "found in /home/ahu/download/STLport-4.0/stlport")
+ AC_CHECK_STL($HOME/STLport-4.0/stlport, sstream,-L$HOME/STLport-4.0/lib/ -lstlport_gcc, -I$HOME/STLport-4.0/stlport/, "found in $HOME/STLport-4.0/stlport")
+])
+
+if test x"$search_stl" != x"0"; then
+ AC_SEARCH_STL()
+fi
+
+if test x"$has_stl" = x"1"; then
+ echo Found sstream include file, assuming working and compliant STL
+else
+ echo
+ echo Did not find sstream include file, this probably means that your STL is not
+ echo compliant - the default gcc libstdc++ isn\'t. Download STLport-4.0 from
+ echo http://www.stlport.org, or use --with-stl-includes and --with-stl-libs
+ echo to specify the location of your STL.
+ echo
+ exit 1
+fi
+
+CPPFLAGS="$CPPFLAGS $STL_INCLUDES"
+LIBS="$LIBS $STL_LIBS"
+fi
+
+AC_MSG_CHECKING(whether we will be doing verbose logging)
+AC_ARG_ENABLE(verbose-logging,
+ [ --enable-verbose-logging Do verbose logging],enable_verbose_logging=yes ,enable_verbose_logging=no)
+
+if test $enable_verbose_logging = yes; then AC_DEFINE(VERBOSELOG, 1)
+fi
+AC_MSG_RESULT($enable_verbose_logging)
+
+AC_MSG_CHECKING(whether we should build static binaries)
+AC_ARG_ENABLE(static-binaries,
+ [ --enable-static-binaries Build static binaries],enable_static_binaries=yes ,enable_static_binaries=no)
+
+if test $enable_static_binaries = yes;
+then
+ LDFLAGS="-all-static $LD_FLAGS"
+fi
+AC_MSG_RESULT($enable_static_binaries)
+
+
+
+AC_OUTPUT(Makefile codedocs/Makefile backends/bind/Makefile \
+backends/Makefile \
+pdns.conf-dist buildroot.sh \
+showvar pdns mkbindist)
--- /dev/null
+pdns (1:2.8-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 3 Nov 2002 15:22:25 +0100
+
+
+pdns (1:2.7.1-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Fri, 1 Nov 2002 15:22:25 +0100
+
+pdns (1:2.7-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Wed, 28 Oct 2002 15:22:25 +0100
+
+pdns (1:2.6.1-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Wed, 16 Oct 2002 15:22:25 +0100
+
+pdns (1:2.6-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Fri, 14 Oct 2002 15:22:25 +0100
+
+pdns (1:2.5.1-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Fri, 4 Oct 2002 15:22:25 +0100
+
+pdns (1:2.5-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 26 Sep 2002 15:22:25 +0100
+
+pdns (1:2.4-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 16 Sep 2002 15:22:25 +0100
+
+pdns (1:2.3-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 16 Sep 2002 15:22:25 +0100
+
+pdns (1:2.2-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 11 Sep 2002 15:22:25 +0100
+
+pdns (1:2.1-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 2 Sep 2002 15:22:25 +0100
+
+pdns (1:2.0.1-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 2 Sep 2002 15:22:25 +0100
+
+pdns (1:2.0-2) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 12 Aug 2002 15:22:25 +0100
+
+pdns (1:2.0-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 12 Aug 2002 15:22:25 +0100
+
+pdns (2.0) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 30 Jul 2002 15:22:25 +0100
+
+pdns (2.0rc2) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 8 Jul 2002 15:22:25 +0100
+
+pdns (2.0rc1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 17 Jun 2002 15:22:25 +0100
+
+pdns (2.0rc1-SNAPSHOT-20020601-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Sat, 1 Jun 2002 15:22:25 +0100
+
+pdns (1.99.12-2) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Wed, 22 May 2002 15:22:25 +0100
+
+pdns (1.99.12-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 16 May 2002 15:22:25 +0100
+
+pdns (1.99.11-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Mon, 6 May 2002 15:22:25 +0100
+
+pdns (1.99.10-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Thu, 2 May 2002 15:22:25 +0100
+
+pdns (1.99.9-6) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Tue, 18 Apr 2002 15:22:25 +0100
+
+pdns (1.99.9-5) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Tue, 15 Apr 2002 14:22:25 +0100
+
+pdns (1.99.9-4) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Tue, 15 Apr 2002 14:22:25 +0100
+
+pdns (1.99.9-3) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Tue, 15 Apr 2002 14:22:25 +0100
+
+pdns (1.99.9-2) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Tue, 15 Apr 2002 14:22:25 +0100
+
+
+pdns (1.99.9-1) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Tue, 9 Apr 2002 14:22:25 +0100
+
+pdns (1.99.8-2) experimental; urgency=low
+
+ * upstream update
+
+ -- bert hubert <bert@powerdns.com> Tue, 9 Apr 2002 14:22:25 +0100
+
+pdns (1.99.8-1) experimental; urgency=low
+
+ * upstream update
+
+ -- bert hubert <bert@powerdns.com> Fri, 5 Apr 2002 16:38:25 +0100
+
+pdns (1.99.7-2) experimental; urgency=low
+
+ * upstream update
+
+ -- bert hubert <bert@powerdns.com> Fri, 29 Mar 2002 15:34:25 +0100
+
+pdns (1.99.7-1) experimental; urgency=low
+
+ * upstream update
+
+ -- bert hubert <bert@powerdns.com> Fri, 29 Mar 2002 20:34:25 +0100
+
+pdns (1.99.6-8) experimental; urgency=low
+
+ * forgot pdns backend
+
+ -- bert hubert <bert@powerdns.com> Wed, 27 Mar 2002 20:34:25 +0100
+
+pdns (1.99.6-7) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Wed, 27 Mar 2002 17:34:25 +0100
+
+pdns (1.99.6-6) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Wed, 27 Mar 2002 16:34:25 +0100
+
+pdns (1.99.6-5) experimental; urgency=low
+
+ * upstream
+
+ -- bert hubert <bert@powerdns.com> Wed, 27 Mar 2002 12:34:25 +0100
+
+pdns (1.99.6-4) experimental; urgency=low
+
+ * added documentation
+
+ -- bert hubert <bert@powerdns.com> Wed, 27 Mar 2002 12:34:25 +0100
+
+pdns (1.99.6-3) experimental; urgency=low
+
+ * add gpgsql backend
+
+ -- bert hubert <bert@powerdns.com> Tue, 26 Mar 2002 16:34:25 +0100
+
+pdns (1.99.6-2) experimental; urgency=low
+
+ * better preinst
+
+ -- bert hubert <bert@powerdns.com> Mon, 25 Mar 2002 23:17:25 +0100
+
+pdns (1.99.6-1) experimental; urgency=low
+
+ * Upstream update
+
+ -- bert hubert <bert@powerdns.com> Mon, 25 Mar 2002 23:17:25 +0100
+
+pdns (1.99.5-7) experimental; urgency=low
+
+ * Upstream update
+
+ -- bert hubert <bert@powerdns.com> Mon, 25 Mar 2002 15:25:25 +0100
+
+pdns (1.99.5-6) experimental; urgency=low
+
+ * Upstream update
+
+ -- bert hubert <bert@powerdns.com> Mon, 25 Mar 2002 15:25:25 +0100
+
+pdns (1.99.5-5) experimental; urgency=low
+
+ * Speedups in TCP code, now with timeouts
+
+ -- bert hubert <bert@powerdns.com> Sun, 24 Mar 2002 21:53:55 +0100
+
+pdns (1.99.5-4) experimental; urgency=low
+
+ * fixed large memory leaks in TCP listener & AXFR code
+
+ -- bert hubert <bert@powerdns.com> Thu, 22 Mar 2002 20:49:55 +0100
+
+pdns (1.99.5-3) experimental; urgency=low
+
+ * wrong compiler chosen for backend :-(
+
+ -- bert hubert <bert@powerdns.com> Thu, 22 Mar 2002 20:49:55 +0100
+
+pdns (1.99.5-2) experimental; urgency=low
+
+ * wrong compiler chosen for backend :-(
+
+ -- bert hubert <bert@powerdns.com> Thu, 22 Mar 2002 20:49:55 +0100
+
+pdns (1.99.5-1) experimental; urgency=low
+
+ * zone2sql fixed
+
+ -- bert hubert <bert@powerdns.com> Thu, 22 Mar 2002 20:49:55 +0100
+
+pdns (1.99.4-4) experimental; urgency=low
+
+ * upstream released
+
+ -- bert hubert <bert@powerdns.com> Thu, 22 Mar 2002 20:49:55 +0100
+
+pdns (1.99.4-3) experimental; urgency=low
+
+ * Small upstream update
+
+ -- bert hubert <bert@powerdns.com> Thu, 22 Mar 2002 16:04:55 +0100
+
+pdns (1.99.4-2) experimental; urgency=low
+
+ * Small upstream update
+
+ -- bert hubert <bert@powerdns.com> Thu, 22 Mar 2002 13:24:55 +0100
+
+pdns (1.99.4-1) experimental; urgency=low
+
+ * Small upstream update
+
+ -- bert hubert <bert@powerdns.com> Thu, 21 Mar 2002 13:24:55 +0100
+
+pdns (1.99.3-4) experimental; urgency=low
+
+ * Small upstream update
+
+ -- bert hubert <bert@powerdns.com> Wed, 20 Mar 2002 14:17:55 +0100
+
+pdns (1.99.3-4) experimental; urgency=low
+
+ * Did not include the libraries
+
+ -- bert hubert <bert@powerdns.com> Wed, 20 Mar 2002 14:17:55 +0100
+
+pdns (1.99.3-3) experimental; urgency=low
+
+ * Accidentally compiled with gcc 3
+
+ -- bert hubert <bert@powerdns.com> Wed, 20 Mar 2002 14:03:55 +0100
+
+pdns (1.99.3-2) experimental; urgency=low
+
+ * init.d script should be a configuration file
+
+ -- bert hubert <bert@powerdns.com> Wed, 20 Mar 2002 13:20:55 +0100
+
+pdns (1.99.3-1) experimental; urgency=low
+
+ * new upstream version
+
+ -- bert hubert <bert@powerdns.com> Wed, 20 Mar 2002 13:14:55 +0100
+
+pdns (1.99.2-4) experimental; urgency=low
+
+ * make install script add pdns user
+
+ -- bert hubert <bert@powerdns.com> Wed, 15 Mar 2002 23:53:55 +0100
+
+pdns (1.99.2-3) experimental; urgency=low
+
+ * zone2sql fixes
+
+ -- bert hubert <bert@powerdns.com> Wed, 15 Mar 2002 18:24:55 +0100
+
+pdns (1.99.2-2) experimental; urgency=low
+
+ * First release by ahu
+
+ -- bert hubert <bert@powerdns.com> Wed, 14 Mar 2002 01:24:55 +0100
+
+pdns (1.99.2-1) experimental; urgency=low
+
+ * First release
+ * Remove bashism from pdns.in
+ * Handle already existing LD_LIBRARY_PATH in the installer (otherwise
+ fakeroot will break)
+ * Add force-reload to pdns.in
+ * Add download location to LICENSE so we don't need a seperate copyright
+ file
+
+ -- Wichert Akkerman <wichert@deephackmode.org> Wed, 13 Mar 2002 23:57:55 +0100
--- /dev/null
+/etc/powerdns/pdns.conf
+/etc/init.d/pdns
--- /dev/null
+Source: pdns
+Section: net
+Priority: extra
+Build-Depends: libmysqlclient10-dev
+Maintainer: PowerTeam <debian@powerdns.com>
+Bugs: mailto:debian@powerdns.com
+Origin: powerdns
+Build-Depends: file, flex, bison, docbook-utils, openjade, jade
+
+Package: pdns
+Architecture: i386
+Depends: ${shlibs:Depends}
+Description: extremely powerful and versatile nameserver
+ PowerDNS is a versatile nameserver which supports a large number
+ of different backends ranging from simple zonefiles to relational
+ databases and load balancing/failover algorithms.
+
--- /dev/null
+#!/bin/sh
+
+set -e
+
+if [ "$1" != "configure" ] ; then
+ exit 0
+fi
+
+update-rc.d pdns defaults > /dev/null
+
+if [ -n "$2" ] ; then
+ /etc/init.d/pdns restart
+else
+ /etc/init.d/pdns start
+fi
+
+exit 0
+
--- /dev/null
+#!/bin/sh
+
+set -e
+
+if [ "$1" = "purge" ] ; then
+ update-rc.d pdns remove > /dev/null
+ userdel pdns
+fi
+
+# TODO: check if we need to remove files from /var/run
+
+exit 0
+
--- /dev/null
+#!/bin/sh
+
+id pdns > /dev/null 2> /dev/null
+if [ $? = 1 ]
+then
+ adduser --no-create-home --group --system pdns
+fi
--- /dev/null
+#!/bin/sh
+
+set -e
+
+if [ "$1" = "remove" ] ; then
+ /etc/init.d/pdns stop
+fi
+
+exit 0
+
--- /dev/null
+#!/usr/bin/make -f
+
+clean:
+ rm -rf debian/tmp docs/html docs/pdns
+ rm -f debian/files debian/substvars
+ -make distclean
+
+build:
+ CXXFLAGS="-g -O2 -D_GNU_SOURCE" ./configure \
+ --prefix=/usr \
+ --mandir='$${prefix}'/share/man \
+ --libexecdir='$${prefix}'/lib \
+ --sysconfdir=/etc
+
+ set -e ; cd docs ; db2html -o html pdns.sgml
+
+binary: binary-arch binary-indep
+
+binary-indep:
+ @echo No binary-independent packages
+
+binary-arch:
+ test `id -u` = 0
+ rm -rf debian/tmp
+ install -d -m 755 -o root -g root debian/tmp
+ chmod g-s debian/tmp
+ make DESTDIR=$(shell pwd)/debian/tmp install
+
+ install -d -m 755 -o root -g root debian/tmp/usr/share/doc/pdns/html
+ cp -p docs/html/* debian/tmp/usr/share/doc/pdns/html/
+
+ chmod -R g-w debian/tmp
+
+ rm -f debian/tmp/etc/*
+ install -d -m 755 -o root -g root debian/tmp/etc/powerdns
+ install -p -m 644 -o root -g root debian/pdns.conf \
+ debian/tmp/etc/powerdns/
+
+ -strip --strip-unneeded --remove-section=.comment \
+ --remove-section=.note \
+ debian/tmp/usr/sbin/* debian/tmp/usr/bin/*
+
+ install -d -m 755 -o root -g root debian/tmp/etc/init.d
+ install -p -m 755 -o root -g root debian/init.d \
+ debian/tmp/etc/init.d/pdns
+
+ install -d -m 755 -o root -g root debian/tmp/usr/share/doc/pdns
+ install -p -m 644 -o root -g root debian/changelog \
+ debian/tmp/usr/share/doc/pdns/changelog.Debian
+ gzip -9f debian/tmp/usr/share/doc/pdns/[^h]*
+ install -p -m 644 -o root -g root debian/copyright \
+ debian/tmp/usr/share/doc/pdns/
+ install -p -m 644 -o root -g root README \
+ debian/tmp/usr/share/doc/pdns/README
+
+ install -d -m 755 -o root -g root debian/tmp/DEBIAN
+ install -p -m 644 -o root -g root debian/conffiles debian/tmp/DEBIAN/
+ install -p -m 755 -o root -g root debian/preinst debian/tmp/DEBIAN/
+ install -p -m 755 -o root -g root debian/postinst debian/tmp/DEBIAN/
+ install -p -m 755 -o root -g root debian/postrm debian/tmp/DEBIAN/
+ install -p -m 755 -o root -g root debian/prerm debian/tmp/DEBIAN/
+
+ dpkg-shlibdeps debian/tmp/usr/sbin/* debian/tmp/usr/bin/[^p]*
+ dpkg-gencontrol -isp
+ dpkg --build debian/tmp ..
+
+
+.PHONY: clean build binary binary-arch binary-indep
+
--- /dev/null
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. This file always lives in the current directory.
+ # Also, the AIX compiler puts `$object:' at the start of each line;
+ # $object doesn't have directory information.
+ stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ outname="$stripped.o"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 AIX compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+
+ tmpdepfile1="$object.d"
+ tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'`
+ if test "$libtool" = yes; then
+ "$@" -Wc,-MD
+ else
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile1"; then
+ tmpdepfile="$tmpdepfile1"
+ else
+ tmpdepfile="$tmpdepfile2"
+ fi
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a space and a tab in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ test -z "$dashmflag" && dashmflag=-M
+ ( IFS=" "
+ case " $* " in
+ *" --mode=compile "*) # this is libtool, let us make it quiet
+ for arg
+ do # cycle over the arguments
+ case "$arg" in
+ "--mode=compile")
+ # insert --quiet before "--mode=compile"
+ set fnord "$@" --quiet
+ shift # fnord
+ ;;
+ esac
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # "$arg"
+ done
+ ;;
+ esac
+ "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ ) &
+ proc=$!
+ "$@"
+ stat=$?
+ wait "$proc"
+ if test "$stat" != 0; then exit $stat; fi
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ # X makedepend
+ (
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in no)
+ set ""; shift
+ cleared=yes
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift;;
+ -*)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ ) &
+ proc=$!
+ "$@"
+ stat=$?
+ wait "$proc"
+ if test "$stat" != 0; then exit $stat; fi
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tail +3 "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ ( IFS=" "
+ case " $* " in
+ *" --mode=compile "*)
+ for arg
+ do # cycle over the arguments
+ case $arg in
+ "--mode=compile")
+ # insert --quiet before "--mode=compile"
+ set fnord "$@" --quiet
+ shift # fnord
+ ;;
+ esac
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # "$arg"
+ done
+ ;;
+ esac
+ "$@" -E |
+ sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ ) &
+ proc=$!
+ "$@"
+ stat=$?
+ wait "$proc"
+ if test "$stat" != 0; then exit $stat; fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ ( IFS=" "
+ case " $* " in
+ *" --mode=compile "*)
+ for arg
+ do # cycle over the arguments
+ case $arg in
+ "--mode=compile")
+ # insert --quiet before "--mode=compile"
+ set fnord "$@" --quiet
+ shift # fnord
+ ;;
+ esac
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # "$arg"
+ done
+ ;;
+ esac
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ ) &
+ proc=$!
+ "$@"
+ stat=$?
+ wait "$proc"
+ if test "$stat" != 0; then exit $stat; fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+\r
+#ifndef DISTRIBUTOR_HH\r
+#define DISTRIBUTOR_HH\r
+\r
+\r
+#include <string>
+#include <deque>
+#include <queue>
+#include <vector>
+#include <pthread.h>
+#include <semaphore.h>\r
+\r
+#ifndef WIN32
+# include <unistd.h>\r
+#endif // WIN32\r
+
+#include "logger.hh"
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "ahuexception.hh"
+
+
+/** the Distributor template class enables you to multithread slow question/answer
+ processes.
+
+ Generally, you will run 2 threads. One that inserts questions and one that handles
+ the answers.
+*/
+
+
+template<class Answer, class Question, class Backend> class Distributor
+{
+public:
+ Distributor(int n=10); //!< Create a new Distributor with \param n threads
+ struct AnswerData
+ {
+ Answer *A;
+ time_t created;
+ };
+ int question(Question *, void (*)(const AnswerData &)=0); //!< Submit a question to the Distributor
+ Answer *answer(void); //!< Wait for any answer from the Distributor
+ Answer *wait(Question *); //!< wait for an answer to a specific question
+ int timeoutWait(int id, Answer *, int); //!< wait for a specific answer, with timeout
+ static void* makeThread(void *); //!< helper function to create our n threads
+ void getQueueSizes(int &questions, int &answers); //!< Returns length of question queue
+
+
+ //! This function can run in a separate thread to output statistics on the queues
+ static void* doStats(void *p)
+ {
+ Distributor *us=static_cast<Distributor *>(p);
+ for(;;)
+ {
+ sleep(1);
+ int qcount, acount;
+
+ us->numquestions.getvalue( &qcount );\r
+ us->numanswers.getvalue( &acount );\r
+
+ L <<"queued questions: "<<qcount<<", pending answers: "<<acount<<endl;
+ }
+ }
+
+ int getNumBusy()
+ {
+ return d_num_threads-d_idle_threads;
+ }
+
+
+
+
+ struct QuestionData
+ {
+ Question *Q;
+ time_t created;
+ void (*callback)(const AnswerData &);
+ int id;
+ };
+
+
+ typedef pair<QuestionData, AnswerData> tuple_t;
+
+private:
+ queue<QuestionData> questions;
+ pthread_mutex_t q_lock;
+
+
+ deque<tuple_t> answers;
+ pthread_mutex_t a_lock;
+
+ Semaphore numquestions;
+ Semaphore numanswers;
+
+ pthread_mutex_t to_mut;
+ pthread_cond_t to_cond;
+
+ int nextid;
+ time_t d_last_started;
+ int d_num_threads;
+ int d_idle_threads;
+ Backend *b;
+};
+
+
+//template<class Answer, class Question, class Backend>::nextid;
+
+template<class Answer, class Question, class Backend>Distributor<Answer,Question,Backend>::Distributor(int n)
+{
+ b=0;
+ d_idle_threads=0;
+ d_last_started=time(0);
+// sem_init(&numquestions,0,0);
+ pthread_mutex_init(&q_lock,0);
+
+// sem_init(&numanswers,0,0);
+ pthread_mutex_init(&a_lock,0);
+
+ pthread_mutex_init(&to_mut,0);
+ pthread_cond_init(&to_cond,0);
+
+ pthread_t tid;
+
+ d_num_threads=n;
+
+ L<<Logger::Warning<<"About to create "<<n<<" backend threads"<<endl;
+
+ for(int i=0;i<n;i++) {
+ pthread_create(&tid,0,&makeThread,static_cast<void *>(this));
+ Utility::usleep(50000); // we've overloaded mysql in the past :-)
+ }
+
+ L<<"Done launching threads, ready to distribute questions"<<endl;
+}
+
+// start of a new thread
+template<class Answer, class Question, class Backend>void *Distributor<Answer,Question,Backend>::makeThread(void *p)
+{
+ try {
+ Backend *b=new Backend(); // this will answer our questions
+ Distributor *us=static_cast<Distributor *>(p);
+ int qcount;
+
+ // this is so gross
+#ifndef SMTPREDIR
+ int queuetimeout=arg().asNum("queue-limit");
+#endif
+ // ick ick ick!
+
+ for(;;) {
+ us->d_idle_threads++;
+\r
+ us->numquestions.getValue( &qcount );
+
+ us->numquestions.wait();\r
+
+ us->d_idle_threads--;
+ pthread_mutex_lock(&us->q_lock);
+
+ QuestionData QD=us->questions.front();
+
+ Question *q=QD.Q;
+
+ us->questions.pop();
+
+ pthread_mutex_unlock(&us->q_lock);
+ Answer *a;
+
+
+#ifndef SMTPREDIR
+ if(queuetimeout && q->d_dt.udiff()>queuetimeout*1000) {
+ delete q;
+ S.inc("timedout-packets");
+ continue;
+ }
+#endif
+ // this is the only point where we interact with the backend (synchronous)
+ try {
+ a=b->question(q); // a can be NULL!
+ delete q;
+ }
+ catch(const AhuException &e) {
+ L<<Logger::Error<<"Backend error: "<<e.reason<<endl;
+ delete b;
+ return 0;
+ }
+ catch(...) {
+ L<<Logger::Error<<Logger::NTLog<<"Caught unknown exception in Distributor thread "<<(unsigned long)pthread_self()<<endl;
+ delete b;
+ return 0;
+ }
+
+ AnswerData AD;
+ AD.A=a;
+ AD.created=time(0);
+ tuple_t tuple(QD,AD);
+
+ if(QD.callback) {
+ QD.callback(AD);
+ }
+ else {
+ pthread_mutex_lock(&us->a_lock);
+
+ us->answers.push_back(tuple);
+ pthread_mutex_unlock(&us->a_lock);
+
+ // L<<"We have an answer to send! Trying to get to to_mut lock"<<endl;
+ pthread_mutex_lock(&us->to_mut);
+ // L<<"Yes, we got the lock, we can transmit! First we post"<<endl;
+ us->numanswers.post();
+ // L<<"And now we broadcast!"<<endl;
+ pthread_cond_broadcast(&us->to_cond); // for timeoutWait();
+ pthread_mutex_unlock(&us->to_mut);
+ }
+ }
+
+ delete b;
+ }
+ catch(const AhuException &AE) {
+ L<<Logger::Error<<Logger::NTLog<<"Distributor caught fatal exception: "<<AE.reason<<endl;
+ }
+ catch(...) {
+ L<<Logger::Error<<Logger::NTLog<<"Caught an unknown exception when creating backend, probably"<<endl;
+ }
+ return 0;
+}
+
+template<class Answer, class Question, class Backend>int Distributor<Answer,Question,Backend>::question(Question* q, void (*callback)(const AnswerData &))
+{
+ if(d_num_threads==1 && callback) { // short circuit
+ if(!b) {
+ L<<Logger::Error<<"Engaging bypass - now operating unthreaded"<<endl;
+ b=new Backend;
+ }
+ Answer *a;
+
+ a=b->question(q);
+
+ AnswerData AD;
+ AD.A=a;
+ AD.created=time(0);
+ callback(AD);
+ return 0;
+ }
+ else {
+ q=new Question(*q);
+ }
+
+ DLOG(L<<"Distributor has "<<Backend::numRunning()<<" threads available"<<endl);
+ if(Backend::numRunning()<d_num_threads && time(0)-d_last_started>5) { // add one
+ d_last_started=time(0);
+ L<<"Distributor misses a thread ("<<Backend::numRunning()<<"<"<<d_num_threads<<"), spawning new one"<<endl;
+ pthread_t tid;
+ pthread_create(&tid,0,&makeThread,static_cast<void *>(this));
+ }
+
+ pthread_mutex_lock(&q_lock);
+ QuestionData QD;
+ QD.Q=q;
+ QD.id=nextid++;
+ QD.callback=callback;
+ questions.push(QD);
+ pthread_mutex_unlock(&q_lock);
+\r
+ numquestions.post();
+\r
+ if(!(nextid%50)) {
+ int val;
+ numquestions.getValue( &val );
+ if(val>arg().asNum("max-queue-length")) {
+ L<<Logger::Error<<val<<" questions waiting for database attention. Limit is "<<arg().asNum("max-queue-length")<<", respawning"<<endl;
+ exit(1);
+ }
+ }\r
+
+ return QD.id;
+}
+
+template<class Answer, class Question,class Backend>Answer* Distributor<Answer,Question,Backend>::answer()
+{
+ numanswers.wait();
+ tuple_t tuple;
+
+ pthread_mutex_lock(&a_lock);
+ tuple=answers.front();
+ answers.pop_front();
+ pthread_mutex_unlock(&a_lock);
+ return tuple.second.A;
+}
+
+//! Wait synchronously for the answer of the question just asked. For this to work, no answer() functions must be called
+template<class Answer, class Question,class Backend>Answer* Distributor<Answer,Question,Backend>::wait(Question *q)
+{
+ for(;;)
+ {
+ numanswers.wait();
+ pthread_mutex_lock(&a_lock);
+
+ // search if the answer is there
+ tuple_t tuple=answers.front();
+ if(tuple.first==q)
+ {
+ answers.pop_front();
+ pthread_mutex_unlock(&a_lock);
+ return tuple.second.A;
+ }
+ // if not, loop again
+ pthread_mutex_unlock(&a_lock);
+ numanswers.post();
+ }
+ // FIXME: write this
+}
+
+template<class Answer, class Question,class Backend>void Distributor<Answer,Question,Backend>::getQueueSizes(int &questions, int &answers)
+{\r
+ numquestions.getValue( &questions );\r
+ numanswers.getValue( &answers );
+}
+
+//! Wait synchronously for the answer of the question just asked. For this to work, no answer() functions must be called
+template<class Answer, class Question,class Backend>int Distributor<Answer,Question,Backend>::timeoutWait(int id, Answer *a, int timeout)
+{
+ struct timeval now;
+ struct timespec then;
+
+ Utility::gettimeofday(&now,0);
+
+ then.tv_sec=now.tv_sec+timeout;
+ then.tv_nsec=150*1000000+now.tv_usec*1000; // 150ms
+
+ int rc;
+
+ // L<<"About to acquire to_mut - new broadcasts will then be corked"<<endl;
+ pthread_mutex_lock(&to_mut); // start the lock to prevent races
+
+ for(;;)
+ {
+ // L<<"Acquired the to_mut lock - checking to see if there are already answers"<<endl;
+
+ int val;
+ rc=numanswers.getvalue( &val); // are there answers?
+ // L<<"Now "<<val<<" answers according to the semaphore"<<endl;
+
+ if(val)
+ {
+ DLOG(L<<"There are some answers! Is the one we want among them?"<<endl);
+ DLOG(L<<"numanswers: "<<val<<", rc="<<rc<<", errno="<<errno<<endl);
+
+ pthread_mutex_lock(&a_lock);
+
+ DLOG(L<<"deque contains: "<<answers.size()<<endl);
+ // search if the answer is there
+
+ bool found=false;
+ int rc;
+
+ for(typename deque<tuple_t>::iterator tuple=answers.begin();
+ tuple!=answers.end();
+ tuple++)
+ {
+ if(!found && tuple->first.id==id)
+ {
+ numanswers.wait(); // remove from the semaphore
+ DLOG(L<<"found the answer tuple ("<<tuple->first.id<<") - may be empty answer"<<endl);
+
+ found=true;
+
+ if(!tuple->second.A)
+ rc=-1;
+ else
+ {
+ *a=*tuple->second.A;
+ rc=0;
+ }
+
+ answers.erase(tuple);
+ tuple=answers.begin(); // restart
+ if(tuple==answers.end())break;
+
+ }
+ else // an answer, but not the right one
+ {
+ if(time(0)-tuple->second.created>5) // delete after 5 seconds
+ {
+ L<<"Deleted unclaimed answer "<<tuple->first.id<<" due to age"<<endl;
+ answers.erase(tuple);
+ tuple=answers.begin(); // restart
+ if(tuple==answers.end())break;
+ numanswers.wait();
+ }
+ }
+ }
+ pthread_mutex_unlock(&a_lock);
+
+ if(!found)
+ L<<"Right answer was NOT found - we should now sleep and recheck whenever there are new answers"<<endl;
+ else
+ {
+ pthread_mutex_unlock(&to_mut);
+ return 0;
+ }
+ }
+ else
+ L<<"No answers!"<<endl;
+
+
+ DLOG(L<<"starting wait on condition, to see if there are new answers"<<endl);
+
+ // this first lets go of the to_mut lock, which will 'uncork' the pending pthread_cond_broadcasts
+ rc=pthread_cond_timedwait(&to_cond, &to_mut, &then);
+ // and then it atomically reacquires the lock
+
+ if(rc==ETIMEDOUT)
+ {
+ L<<Logger::Error<<"Timeout waiting for data"<<endl;
+ pthread_mutex_unlock(&to_mut);
+ return -ETIMEDOUT;
+ }
+ L<<"We received a broadcast that there is new data, checking"<<endl;
+
+ }
+
+ return -1; // timeout or whatever
+ // FIXME: write this
+}
+
+\r
+#endif // DISTRIBUTOR_HH\r
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: dns.hh,v 1.1 2002/11/27 15:18:31 ahu Exp $
+/* (C) 2002 POWERDNS.COM BV */
+#ifndef DNS_HH
+#define DNS_HH
+\r
+#include "utility.hh"
+#include "qtype.hh"
+#include <time.h>
+#include <sys/types.h>
+class DNSBackend;
+
+struct SOAData
+{
+ string qname;
+ string nameserver;
+ string hostmaster;
+ u_int32_t ttl;
+ u_int32_t serial;
+ u_int32_t refresh;
+ u_int32_t retry;
+ u_int32_t expire;
+ u_int32_t default_ttl;
+ int domain_id;
+ DNSBackend *db;
+};
+
+
+class RCode
+{
+public:
+ enum { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5 };
+};
+
+class Opcode
+{
+public:
+ enum { Query=0, IQuery=1, Status=2, Notify=4, Update=5 };
+};
+
+
+//! This class represents a resource record
+class DNSResourceRecord
+{
+public:
+ DNSResourceRecord() : d_place(ANSWER){};
+ ~DNSResourceRecord(){};
+
+ string serialize() const;
+ int unSerialize(const string &str);
+
+ // data
+
+ QType qtype; //!< qtype of this record, ie A, CNAME, MX etc
+ string qname; //!< the name of this record, for example: www.powerdns.com
+ string content; //!< what this record points to. Example: 10.1.2.3
+ u_int16_t priority; //!< For qtype's that support a priority or preference. Currently only MX
+ u_int32_t ttl; //!< Time To Live of this record
+ int domain_id; //!< If a backend implements this, the domain_id of the zone this record is in
+ time_t last_modified; //!< For autocalculating SOA serial numbers - the backend needs to fill this in
+ enum Place {QUESTION=0, ANSWER=1, AUTHORITY=2, ADDITIONAL=3}; //!< Type describing the positioning of a DNSResourceRecord within, say, a DNSPacket
+ Place d_place; //!< This specifies where a record goes within the packet
+
+private:
+ string escape(const string &str) const;
+};
+
+#define L theL()
+extern time_t s_starttime;
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include "dnsbackend.hh"
+#include "arguments.hh"
+#include "ueberbackend.hh"
+#include "logger.hh"
+
+#include <sys/types.h>
+#include "dnspacket.hh"
+
+string DNSResourceRecord::serialize() const
+{
+ ostringstream ostr;
+ ostr<<escape(qname)<<"|"<<qtype.getName()<<"|"<<escape(content)<<"|"<<ttl<<"|"<<priority<<"|"<<domain_id
+ <<"|"<<last_modified;
+ return ostr.str();
+}
+
+string DNSResourceRecord::escape(const string &name) const
+{
+ string a;
+
+ for(string::const_iterator i=name.begin();i!=name.end();++i)
+ if(*i=='|' || *i=='\\'){
+ a+='\\';
+ a+=*i;
+ }
+ else
+ a+=*i;
+
+ return a;
+}
+
+int DNSResourceRecord::unSerialize(const string &source)
+{
+ // qname|qtype|content|ttl|priority|domain_id|last_modified;
+ string chunk;
+ unsigned int m=0;
+ for(int n=0;n<7;++n) {
+ chunk="";
+ for(;m<source.size();++m) {
+ if(source[m]=='\\' && m+1<source.size())
+ chunk.append(1,source[++m]);
+ else if(source[m]=='|') {
+ ++m;
+ break;
+ }
+ else
+ chunk.append(1,source[m]);
+ }
+ switch(n) {
+ case 0:
+ qname=chunk;
+ break;
+ case 1:
+ qtype=chunk;
+ break;
+ case 2:
+ content=chunk;
+ break;
+ case 3:
+ ttl=atoi(chunk.c_str());
+ break;
+ case 4:
+ priority=atoi(chunk.c_str());
+ break;
+ case 5:
+ domain_id=atoi(chunk.c_str());
+ break;
+ case 6:
+ last_modified=atoi(chunk.c_str());
+ break;
+ }
+ }
+ return m;
+}
+
+string DNSBackend::getRemote(DNSPacket *p)
+{
+ return p->getRemote();
+}
+
+bool DNSBackend::getRemote(DNSPacket *p, struct sockaddr *sa, Utility::socklen_t *len)
+{
+ if(p->d_socklen<*len)
+ return false;
+ *len=p->d_socklen;
+ memcpy(sa,&p->remote,*len);
+ return true;
+}
+
+
+
+void DNSBackend::setArgPrefix(const string &prefix)
+{
+ d_prefix=prefix;
+}
+
+bool DNSBackend::mustDo(const string &key)
+{
+ return arg().mustDo(d_prefix+"-"+key);
+}
+
+const string &DNSBackend::getArg(const string &key)
+{
+ return arg()[d_prefix+"-"+key];
+}
+
+int DNSBackend::getArgAsNum(const string &key)
+{
+ return arg().asNum(d_prefix+"-"+key);
+}
+
+void BackendFactory::declare(const string &suffix, const string ¶m, const string &help, const string &value)
+{
+ string fullname=d_name+"-"+suffix+param;
+ arg().set(fullname,help)=value;
+}
+
+const string &BackendFactory::getName() const
+{
+ return d_name;
+}
+
+BackendMakerClass &BackendMakers()
+{
+ static BackendMakerClass bmc;
+ return bmc;
+}
+
+void BackendMakerClass::report(BackendFactory *bf)
+{
+ d_repository[bf->getName()]=bf;
+}
+
+
+vector<string> BackendMakerClass::getModules()
+{
+ load_all();
+ vector<string> ret;
+ // copy(d_repository.begin(), d_repository.end(),back_inserter(ret));
+ for(d_repository_t::const_iterator i=d_repository.begin();i!=d_repository.end();++i)
+ ret.push_back(i->first);
+ return ret;
+}
+
+void BackendMakerClass::load_all()
+{\r
+ // TODO: Implement this?\r
+#ifndef WIN32
+ DIR *dir=opendir(arg()["module-dir"].c_str());
+ if(!dir) {
+ L<<Logger::Error<<"Unable to open module directory '"<<arg()["module-dir"]<<"'"<<endl;
+ return;
+ }
+ struct dirent *entry;
+ while((entry=readdir(dir))) {
+ if(!strncmp(entry->d_name,"lib",3) &&
+ entry->d_name[strlen(entry->d_name)-1]=='o' &&
+ entry->d_name[strlen(entry->d_name)-2]=='s' &&
+ entry->d_name[strlen(entry->d_name)-3]=='.')
+ load(entry->d_name);
+ }
+ closedir(dir);\r
+#endif // WIN32
+}
+
+void BackendMakerClass::load(const string &module)
+{
+ int res;
+
+ if(module.find(".")==string::npos)
+ res=UeberBackend::loadmodule(arg()["module-dir"]+"/lib"+module+"backend.so");
+ else if(module[0]=='/' || (module[0]=='.' && module[1]=='/') || (module[0]=='.' && module[1]=='.')) // absolute or current path
+ res=UeberBackend::loadmodule(module);
+ else
+ res=UeberBackend::loadmodule(arg()["module-dir"]+"/"+module);
+
+ if(res==false) {
+ L<<Logger::Error<<"Unable to load module "<<module<<endl;
+ exit(1);
+ }
+}
+
+void BackendMakerClass::launch(const string &instr)
+{
+ // if(instr.empty())
+ // throw ArgException("Not launching any backends - nameserver won't function");
+
+ vector<string> parts;
+ stringtok(parts,instr,", ");
+
+ for(vector<string>::const_iterator i=parts.begin();i!=parts.end();++i) {
+ const string &part=*i;
+
+ string module, name;
+ vector<string>pparts;
+ stringtok(pparts,part,": ");
+ module=pparts[0];
+ if(pparts.size()>1)
+ name=pparts[1]+"-";
+
+ if(d_repository.find(module)==d_repository.end()) {
+ // this is *so* userfriendly
+ load(module);
+ if(d_repository.find(module)==d_repository.end())
+ throw ArgException("Trying to launch unknown backend '"+module+"'");
+ }
+
+ d_repository[module]->declareArguments(name);
+ d_instances.push_back(make_pair(module,name));
+ }
+}
+
+int BackendMakerClass::numLauncheable()
+{
+ return d_instances.size();
+}
+
+vector<DNSBackend *>BackendMakerClass::all()
+{
+ vector<DNSBackend *>ret;
+ if(d_instances.empty())
+ throw AhuException("No database backends configured for launch, unable to function");
+
+ try {
+ for(vector<pair<string,string> >::const_iterator i=d_instances.begin();i!=d_instances.end();++i) {
+ DNSBackend *made=d_repository[i->first]->make(i->second);
+ if(!made)
+ throw AhuException("Unable to launch backend '"+i->first+"'");
+
+ ret.push_back(made);
+ }
+ }
+ catch(...) {
+ // and cleanup
+ for(vector<DNSBackend *>::const_iterator i=ret.begin();i!=ret.end();++i)
+ delete *i;
+ throw;
+ }
+
+ return ret;
+}
+
+bool DNSBackend::getSOA(const string &domain, SOAData &sd)
+{
+ this->lookup(QType(QType::SOA),domain,0);
+
+ DNSResourceRecord rr;
+
+ int hits=0;
+
+ while(this->get(rr)) {
+ hits++;
+ DNSPacket::fillSOAData(rr.content, sd);
+ sd.domain_id=rr.domain_id;
+ sd.ttl=rr.ttl;
+ }
+
+ if(!hits)
+ return false;
+
+ if(sd.nameserver.empty())
+ sd.nameserver=arg()["default-soa-name"];
+
+ if(sd.hostmaster.empty())
+ sd.hostmaster="hostmaster."+domain;
+
+ if(!sd.serial) { // magic time!
+ DLOG(L<<Logger::Warning<<"Doing soa serialnumber autocalculation for "<<rr.qname<<endl);
+
+ // we do this by listing the domain and taking the maximum last modified timestamp
+
+ DNSResourceRecord i;
+ time_t newest=0;
+
+ if(!(this->list(sd.domain_id)))
+ throw AhuException("Backend error trying to determine magic serial number of zone '"+domain+"'");
+
+ while(this->get(i)) {
+ if(i.last_modified>newest)
+ newest=i.last_modified;
+ }
+
+ sd.serial=newest;
+ DLOG(L<<"autocalculated soa serialnumber for "<<rr.qname<<" is "<<newest<<endl);
+
+ }
+ sd.db=this;
+ return true;
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: dnsbackend.hh,v 1.1 2002/11/27 15:18:32 ahu Exp $
+/* (C) 2002 POWERDNS.COM BV */
+
+#ifndef DNSBACKEND_HH
+#define DNSBACKEND_HH
+
+class DNSPacket;\r
+\r
+#include "utility.hh"
+#include <string>
+#include <vector>
+#include <map>
+#include <sys/types.h>
+#include <set>\r
+\r
+#ifndef WIN32\r
+# include <sys/socket.h>\r
+# include <dirent.h>\r
+#endif // WIN32\r
+
+#include "qtype.hh"
+#include "dns.hh"
+using namespace std;
+
+/** This virtual base class defines the interface for backends for the ahudns. To create a backend,
+ inherit from this class and implement functions for all virtual methods.
+*/
+
+class DNSBackend;
+struct DomainInfo
+{
+ u_int32_t id;
+ string zone;
+ string master;
+ u_int32_t serial;
+ u_int32_t notified_serial;
+ time_t last_check;
+ enum {Master,Slave,Native} kind;
+ DNSBackend *backend;
+};
+
+class DNSPacket;
+class DNSBackend
+{
+public:
+ virtual void lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
+ virtual bool get(DNSResourceRecord &)=0;
+ virtual bool list(int domain_id)=0;
+
+ virtual ~DNSBackend(){};
+
+ static void reconfigure(const string &);
+
+ virtual bool getSOA(const string &name, SOAData &soadata);
+
+ virtual bool isMaster(const string &name, const string &ip)
+ {
+ return false;
+ }
+
+ virtual bool startTransaction(const string &qname, int id=-1)
+ {
+ return false;
+ }
+
+ virtual bool commitTransaction()
+ {
+ return false;
+ }
+
+ virtual bool abortTransaction()
+ {
+ return false;
+ }
+
+ virtual void reload()
+ {
+ }
+
+ virtual void rediscover()
+ {
+ }
+
+ virtual bool feedRecord(const DNSResourceRecord &rr)
+ {
+ return false; // no problem!
+ }
+ virtual bool getDomainInfo(const string &domain, DomainInfo &di)
+ {
+ return false;
+ }
+ virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains)
+ {
+ }
+
+ virtual void alsoNotifies(const string &domain, set<string> *ips)
+ {
+ }
+ virtual void getUpdatedMasters(vector<DomainInfo>* domains)
+ {
+ }
+ virtual DNSBackend *getBackendAndID(const string &qdomain, u_int32_t *id)
+ {
+ return 0;
+ }
+ virtual void setFresh(u_int32_t domain_id)
+ {
+
+ }
+ virtual void setNotified(u_int32_t id, u_int32_t serial)
+ {
+ }
+
+ void setArgPrefix(const string &prefix);
+ virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
+ {
+ return false;
+ }
+ virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account)
+ {
+ return false;
+ }
+
+protected:
+ bool mustDo(const string &key);
+ const string &getArg(const string &key);
+ int getArgAsNum(const string &key);
+ string getRemote(DNSPacket *p);
+ bool getRemote(DNSPacket *p, struct sockaddr *in, Utility::socklen_t *len);
+
+private:
+ string d_prefix;
+};
+
+class BackendFactory
+{
+public:
+ BackendFactory(const string &name) : d_name(name) {}
+ virtual ~BackendFactory(){}
+ virtual DNSBackend *make(const string &suffix)=0;
+ virtual void declareArguments(const string &suffix=""){}
+ const string &getName() const;
+
+protected:
+ void declare(const string &suffix, const string ¶m, const string &explanation, const string &value);
+
+private:
+ const string d_name;
+};
+
+class BackendMakerClass
+{
+public:
+ void report(BackendFactory *bf);
+ void launch(const string &instr);
+ vector<DNSBackend *>all();
+ void load(const string &module);
+ int numLauncheable();
+ vector<string> getModules();
+
+private:
+ void load_all();
+ typedef map<string,BackendFactory *>d_repository_t;
+ d_repository_t d_repository;
+ vector<pair<string,string> >d_instances;
+};
+
+extern BackendMakerClass &BackendMakers();
+
+class BackendException
+{};
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: dnspacket.cc,v 1.1 2002/11/27 15:18:31 ahu Exp $
+#include "utility.hh"
+#include <cstdio>
+
+#include <cstdlib>
+#include <sys/types.h>
+
+#include <iostream>
+
+#include <string>
+#include <errno.h>
+
+#include <algorithm>
+
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "ahuexception.hh"
+#include "dnspacket.hh"
+#include "logger.hh"
+#include "arguments.hh"
+
+
+DNSPacket::DNSPacket()
+{
+ d_wrapped=false;
+ d_compress=true;
+}
+
+
+string DNSPacket::getString()
+{
+ return stringbuffer;
+}
+
+
+string DNSPacket::getRemote() const
+{
+ return sockAddrToString((struct sockaddr_in *)remote, d_socklen);
+}
+
+
+
+// Make s lowercase:
+void lowercase(string& s) {
+ for(unsigned int i = 0; i < s.length(); i++)
+ s[i] = tolower(s[i]);
+}
+
+void DNSPacket::trim()
+{
+ rrs.clear();
+ qdomain=""; // .clear();
+ string(stringbuffer).swap(stringbuffer); // kudos Scott
+}
+
+DNSPacket::DNSPacket(const DNSPacket &orig)
+{
+ DLOG(L<<"DNSPacket copy constructor called!"<<endl);
+ d_socket=orig.d_socket;
+ memcpy(remote, orig.remote, sizeof(remote));
+ len=orig.len;
+ d_qlen=orig.d_qlen;
+ d_dt=orig.d_dt;
+ d_socklen=orig.d_socklen;
+ d_compress=orig.d_compress;
+ qtype=orig.qtype;
+ qclass=orig.qclass;
+ qdomain=orig.qdomain;
+
+ rrs=orig.rrs;
+
+ d_wrapped=orig.d_wrapped;
+
+ stringbuffer=orig.stringbuffer;
+ d=orig.d;
+
+}
+
+int DNSPacket::expand(const char *begin, const char *end, string &expanded, int depth)
+{
+ if(depth>10)
+ throw AhuException("Looping label when parsing a packet");
+
+ unsigned int n;
+ const char *p=begin;
+
+ while((n=*(unsigned char *)p++)) {
+ char tmp[256];
+ if((n & 0xc0) == 0xc0 ) {
+ unsigned int labelOffset=(n&~0xc0)*256+ (int)*(unsigned char *)p;
+ expand(stringbuffer.c_str()+labelOffset,end,expanded,depth++);
+ return 1+p-begin;
+ }
+
+ if(p+n>=end) { // this is a bogus packet, references beyond the end of the buffer
+ throw AhuException("Label claims to be longer than packet");
+ }
+ strncpy(tmp,p,n);
+
+ if(*(p+n)) { // add a ., except at the end
+ tmp[n]='.';
+ tmp[n+1]=0;
+ }
+ else
+ tmp[n]=0;
+
+ expanded+=tmp;
+
+ p+=n;
+ }
+
+ // lowercase(qdomain); (why was this?)
+
+ return p-begin;
+
+}
+
+/** copies the question into our class
+ * and returns offset of question type & class. Returns -1 in case of an error
+ */
+int DNSPacket::getq()
+{
+ const char *orig=stringbuffer.c_str()+12;
+ const char *end=orig+(stringbuffer.length()-12);
+ qdomain="";
+ try {
+ return expand(orig,end,qdomain);
+ }
+ catch(AhuException &ae) {
+ L<<Logger::Error<<"On retrieving question of packet, encountered error: "<<ae.reason<<endl;
+ }
+ return -1;
+}
+
+/*
+ 1 1 1 1 1 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ID |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | QDCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ANCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | NSCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ARCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+*/
+
+void DNSPacket::setRcode(int v)
+{
+ d.rcode=v;
+}
+
+void DNSPacket::setAnswer(bool b)
+{
+ if(b) {
+ stringbuffer.assign(12,(char)0);
+ memset((void *)&d,0,sizeof(d));
+
+ d.qr=b;
+ }
+}
+
+void DNSPacket::setA(bool b)
+{
+ d.aa=b;
+}
+
+void DNSPacket::setID(u_int16_t id)
+{
+ d.id=id;
+}
+
+void DNSPacket::setRA(bool b)
+{
+ d.ra=b;
+}
+
+void DNSPacket::setRD(bool b)
+{
+ d.rd=b;
+}
+
+
+void DNSPacket::setOpcode(u_int16_t opcode)
+{
+ d.opcode=opcode;
+}
+
+const char *DNSPacket::getRaw(void)
+{
+ return stringbuffer.data();
+}
+
+void DNSPacket::setRaw(char *mesg, int length)
+{
+ stringbuffer.assign(mesg,length);
+}
+
+void DNSPacket::addARecord(const DNSResourceRecord &rr)
+{
+ DLOG(L<<"Adding an A record to the packet!"<<endl);
+ addARecord(rr.qname, htonl(inet_addr(rr.content.c_str())), rr.ttl, rr.d_place);
+}
+
+void DNSPacket::addRecord(const DNSResourceRecord &rr)
+{
+ if(d_compress)
+ for(vector<DNSResourceRecord>::const_iterator i=rrs.begin();i!=rrs.end();++i)
+ if(rr.qname==i->qname && rr.qtype==i->qtype && rr.content==i->content)
+ return;
+
+ rrs.push_back(rr);
+}
+
+void DNSPacket::addARecord(const string &name, u_int32_t ip, u_int32_t ttl, DNSResourceRecord::Place place)
+{
+ string piece1;
+ toqname(name, &piece1);
+
+ char p[14];
+
+ p[0]=0;
+ p[1]=1; // A
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=4; // length of data
+
+ p[10]=(ip>>24)&0xff;
+ p[11]=(ip>>16)&0xff;
+ p[12]=(ip>>8)&0xff;
+ p[13]=ip&0xff;
+
+ stringbuffer.append(piece1);
+ stringbuffer.append(p,14);
+
+ if(place==DNSResourceRecord::ADDITIONAL)
+ d.arcount++;
+ else
+ d.ancount++;
+}
+
+void DNSPacket::addAAAARecord(const DNSResourceRecord &rr)
+{
+ DLOG(L<<"Adding an AAAA record to the packet!"<<endl);
+ unsigned char addr[16];
+
+ if( Utility::inet_pton( AF_INET6, rr.content.c_str(), static_cast< void * >( addr )))
+ addAAAARecord(rr.qname, addr, rr.ttl);
+ else
+ L<<Logger::Error<<"Unable to convert IPv6 TEXT '"<<rr.content<<"' into binary for record '"<<rr.qname<<"': "
+ <<endl;
+}
+
+
+
+void DNSPacket::addAAAARecord(const string &name, unsigned char addr[16], u_int32_t ttl)
+{
+ string piece1;
+ toqname(name.c_str(),&piece1);
+
+ char p[26];
+
+ p[0]=0;
+ p[1]=28; // AAAA
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=16; // length of data
+
+ for(int n=0;n<16;n++)
+ p[10+n]=addr[n];
+
+ stringbuffer.append(piece1);
+ stringbuffer.append(p,26);
+
+ d.ancount++;
+}
+
+
+void DNSPacket::addMXRecord(const DNSResourceRecord &rr)
+{
+ addMXRecord(rr.qname, rr.content, rr.priority, rr.ttl);
+}
+
+void DNSPacket::addMXRecord(const string &domain, const string &mx, int priority, u_int32_t ttl)
+{
+ string piece1;
+
+ toqname(domain,&piece1);
+
+ char piece2[12];
+
+ piece2[0]=0;
+
+ piece2[1]=15; // MX
+ piece2[2]=0;
+ piece2[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(piece2+4);
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ piece2[8]=0;
+ piece2[9]=0; // need to fill this in
+
+ // start of payload for which we need to specify the length in 8 & 9
+
+ piece2[10]=(priority>>8)&0xff;
+ piece2[11]=priority&0xff;
+
+ string piece3;
+ toqname(mx,&piece3);
+ // end of payload
+
+ piece2[9]=piece3.length()+2; // fill in length
+
+ stringbuffer+=piece1;
+ stringbuffer.append(piece2,12);
+ stringbuffer+=piece3;
+
+ d.ancount++;
+}
+
+string &DNSPacket::attodot(string &str)
+{
+ if(str.find_first_of("@")==string::npos)
+ return str;
+
+ for (unsigned int i = 0; i < str.length(); i++)
+ {
+ if (str[i] == '@') {
+ str[i] = '.';
+ break;
+ } else if (str[i] == '.') {
+ str.insert(i++, "\\");
+ }
+ }
+
+ return str;
+}
+
+void DNSPacket::fillSOAData(const string &content, SOAData &data)
+{
+ // content consists of fields separated by spaces:
+ // nameservername hostmaster serial-number [refresh [retry [expire [ minimum] ] ] ]
+
+ // fill out data with some plausible defaults:
+ // 10800 3600 604800 3600
+ data.serial=0;
+ data.refresh=10800;
+ data.retry=3600;
+ data.expire=604800;
+ data.default_ttl=arg().asNum("soa-minimum-ttl");
+
+ vector<string>parts;
+ stringtok(parts,content);
+ int pleft=parts.size();
+
+ // cout<<"'"<<content<<"'"<<endl;
+
+ if(pleft)
+ data.nameserver=parts[0];
+
+ if(pleft>1)
+ data.hostmaster=attodot(parts[1]); // ahu@ds9a.nl -> ahu.ds9a.nl, piet.puk@ds9a.nl -> piet\.puk.ds9a.nl
+
+ if(pleft>2)
+ data.serial=atoi(parts[2].c_str());
+
+ if(pleft>3)
+ data.refresh=atoi(parts[3].c_str());
+
+ if(pleft>4)
+ data.retry=atoi(parts[4].c_str());
+
+
+ if(pleft>5)
+ data.expire=atoi(parts[5].c_str());
+
+ if(pleft>6)
+ data.default_ttl=atoi(parts[6].c_str());
+
+}
+
+
+string DNSPacket::serializeSOAData(const SOAData &d)
+{
+ ostringstream o;
+
+ // nameservername hostmaster serial-number [refresh [retry [expire [ minimum] ] ] ]
+
+ o<<d.nameserver<<" "<< d.hostmaster <<" "<< d.serial <<" "<< d.refresh << " "<< d.retry << " "<< d.expire << " "<< d.default_ttl;
+
+ return o.str();
+
+}
+
+ /* the hostmaster is encoded as two parts - the bit UNTIL the first unescaped '.'
+ is encoded as a TXT string, the rest as a domain
+
+ we might encounter escaped dots in the first part though: bert\.hubert.powerdns.com for example should be
+ 11bert.hubert7powerdns3com0 */
+
+/* Very ugly btw, this needs to be better */
+const string DNSPacket::makeSoaHostmasterPiece(const string &hostmaster)
+{
+ string ret;
+ string first;
+ string::size_type i;
+
+ for(i=0;i<hostmaster.length();++i) {
+ if(hostmaster[i]=='.') {
+ break;
+ }
+ if(hostmaster[i]=='\\' && i+1<hostmaster.length()) {
+ ++i;
+ first.append(1,hostmaster[i]);
+ continue;
+ }
+ first.append(1,hostmaster[i]);
+ }
+
+ ret.resize(1);
+ ret[0]=first.length();
+ ret+=first;
+
+ string second;
+ if(i+1<hostmaster.length())
+ toqname(hostmaster.substr(i+1),&second);
+ else {
+ second.resize(1);
+ second[0]=0;
+ }
+
+ return ret+second;
+}
+
+void DNSPacket::addSOARecord(const DNSResourceRecord &rr)
+{
+ addSOARecord(rr.qname, rr.content, rr.ttl, rr.d_place);
+}
+
+void DNSPacket::addSOARecord(const string &domain, const string & content, u_int32_t ttl,DNSResourceRecord::Place place)
+{
+ SOAData soadata;
+ fillSOAData(content, soadata);
+
+ string piece1;
+ toqname(domain, &piece1);
+
+ char p[10];
+
+ p[0]=0;
+ p[1]=6; // SOA
+ p[2]=0;
+ p[3]=1; // IN
+
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+ cout<<"adding ttl: "<<ttl<<endl;
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=0; // need to fill this in (length)
+
+ string piece3;
+ toqname(soadata.nameserver,&piece3, false);
+
+ string piece4=makeSoaHostmasterPiece(soadata.hostmaster);
+
+ char piece5[20];
+
+ u_int32_t *i_p=(u_int32_t *)piece5;
+
+ u_int32_t soaoffset;
+ if(soadata.serial && (soaoffset=arg().asNum("soa-serial-offset")))
+ if(soadata.serial<soaoffset)
+ soadata.serial+=soaoffset; // thank you DENIC
+
+ *i_p++=htonl(soadata.serial ? soadata.serial : time(0));
+ *i_p++=htonl(soadata.refresh);
+ *i_p++=htonl(soadata.retry);
+ *i_p++=htonl(soadata.expire);
+ *i_p++=htonl(soadata.default_ttl);
+
+
+ p[9]=piece3.length()+piece4.length()+20;
+
+ stringbuffer+=piece1;
+ stringbuffer.append(p,10);
+ stringbuffer+=piece3;
+ stringbuffer+=piece4;
+ stringbuffer.append(piece5,20);
+ if(place==DNSResourceRecord::ANSWER)
+ d.ancount++;
+ else
+ d.nscount++;
+}
+
+
+
+
+void DNSPacket::addCNAMERecord(const DNSResourceRecord &rr)
+{
+ addCNAMERecord(rr.qname, rr.content, rr.ttl);
+}
+
+void DNSPacket::addCNAMERecord(const string &domain, const string &alias, u_int32_t ttl)
+{
+ string piece1;
+
+ //xtoqname(domain.c_str(),&piece1);
+ toqname(domain.c_str(),&piece1);
+ char p[10];
+
+ p[0]=0;
+ p[1]=5; // CNAME
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=0; // need to fill this in
+
+ string piece3;
+ //xtoqname(alias,&piece3);
+ toqname(alias,&piece3);
+
+ p[9]=piece3.length();
+
+ stringbuffer+=piece1;
+ stringbuffer.append(p,10);
+ stringbuffer+=piece3;
+
+ d.ancount++;
+}
+
+
+void DNSPacket::addRPRecord(const DNSResourceRecord &rr)
+{
+ addRPRecord(rr.qname, rr.content, rr.ttl);
+}
+
+void DNSPacket::addRPRecord(const string &domain, const string &content, u_int32_t ttl)
+{
+ string piece1;
+
+ //xtoqname(domain.c_str(),&piece1);
+ toqname(domain.c_str(),&piece1);
+ char p[10];
+
+ p[0]=0;
+ p[1]=17; // RP
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=0; // need to fill this in
+
+ // content contains: mailbox-name more-info-domain (Separated by a space)
+ unsigned int pos;
+ if((pos=content.find(" "))==string::npos)
+ {
+ L<<Logger::Warning<<"RP record for domain '"<<domain<<"' has malformed content field"<<endl;
+ return;
+ }
+
+ string mboxname=content.substr(0,pos);
+ string moreinfo=content.substr(pos+1);
+
+ string piece3;
+ //xtoqname(mboxname,&piece3);
+ toqname(mboxname,&piece3);
+
+ string piece4;
+ //xtoqname(moreinfo,&piece4);
+ toqname(moreinfo,&piece4);
+
+ p[9]=(piece3.length()+piece4.length())%256;
+ p[10]=(piece3.length()+piece4.length())/256;
+
+ stringbuffer+=piece1;
+ stringbuffer.append(p,10);
+ stringbuffer+=piece3;
+ stringbuffer+=piece4;
+
+ // done
+ d.ancount++;
+}
+
+
+
+
+void DNSPacket::addNAPTRRecord(const DNSResourceRecord &rr)
+{
+ addNAPTRRecord(rr.qname, rr.content, rr.ttl);
+}
+
+
+
+void DNSPacket::addNAPTRRecord(const string &domain, const string &content, u_int32_t ttl)
+{
+ string piece1;
+
+ //xtoqname(domain.c_str(),&piece1);
+ toqname(domain.c_str(),&piece1);
+ char p[10];
+
+ p[0]=0;
+ p[1]=QType::NAPTR;
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=0; // need to fill this in
+
+ // content contains: 100 100 "s" "http+I2R" "" _http._tcp.foo.com.
+
+ vector<string> parts;
+ stringtok(parts,content);
+ if(parts.size()<2)
+ return;
+
+ int order=atoi(parts[0].c_str());
+ int pref=atoi(parts[1].c_str());
+
+ vector<string::const_iterator>poss;
+ string::const_iterator i;
+ for(i=content.begin();i!=content.end();++i)
+ if(*i=='"')
+ poss.push_back(i);
+
+ if(poss.size()!=6)
+ return;
+
+ string flags, services, regex;
+ insert_iterator<string> flagsi(flags, flags.begin());
+ copy(poss[0]+1,poss[1],flagsi);
+ insert_iterator<string> servicesi(services, services.begin());
+ copy(poss[2]+1,poss[3],servicesi);
+ insert_iterator<string> regexi(regex, regex.begin());
+ copy(poss[4]+1,poss[5],regexi);
+
+ for(i=poss[5]+1;i<content.end() && isspace(*i);++i); // skip spaces
+ string replacement;
+ insert_iterator<string> replacementi(replacement,replacement.begin());
+ copy(i,content.end(),replacementi);
+
+/*
+ The packet format for the NAPTR record is:
+
+ 1 1 1 1 1 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ORDER |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | PREFERENCE |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ / FLAGS /
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ / SERVICES /
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ / REGEXP /
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ / REPLACEMENT /
+ / /
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ (jeez)
+*/
+
+
+ string piece3;
+ piece3.resize(4);
+
+ piece3[0]=(order>>8)&0xff;
+ piece3[1]=(order)&0xff;
+
+ piece3[2]=(pref>>8)&0xff;
+ piece3[3]=(pref)&0xff;
+
+ piece3.append(1,flags.length());
+ piece3.append(flags);
+ piece3.append(1,services.length());
+ piece3.append(services);
+ piece3.append(1,regex.length());
+ piece3.append(regex);
+
+ string piece4;
+ toqname(replacement,&piece4);
+
+ p[9]=(piece3.length()+piece4.length())%256;
+ p[10]=(piece3.length()+piece4.length())/256;
+
+ stringbuffer+=piece1;
+ stringbuffer.append(p,10);
+ stringbuffer+=piece3;
+ stringbuffer+=piece4;
+
+ // done
+ d.ancount++;
+}
+
+void DNSPacket::addPTRRecord(const DNSResourceRecord &rr)
+{
+ addPTRRecord(rr.qname, rr.content, rr.ttl);
+}
+
+void DNSPacket::addPTRRecord(const string &domain, const string &alias, u_int32_t ttl)
+{
+ string piece1;
+
+ //xtoqname(domain,&piece1);
+ toqname(domain,&piece1);
+ char p[10];
+
+ p[0]=0;
+ p[1]=12; // PTR
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=0; // need to fill this in
+
+
+ string piece3;
+ //xtoqname(alias,&piece3);
+ toqname(alias,&piece3);
+
+ p[9]=piece3.length();
+
+ stringbuffer+=piece1;
+ stringbuffer.append(p,10);
+ stringbuffer+=piece3;
+
+ d.ancount++;
+}
+
+
+
+void DNSPacket::addTXTRecord(const DNSResourceRecord& rr)
+{
+ addTXTRecord(rr.qname, rr.content, rr.ttl);
+}
+
+void DNSPacket::addTXTRecord(string domain, string txt, u_int32_t ttl)
+{
+ string piece1;
+ //xtoqname(domain, &piece1);
+ toqname(domain, &piece1);
+ char p[10];
+
+ p[0]=0;
+ p[1]=16; // TXT
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=0; // need to fill this in
+
+ string piece3;
+ piece3.reserve(txt.length()+1);
+ piece3.append(1,txt.length());
+ piece3.append(txt);
+
+ p[8]=0;
+ p[9]=piece3.length();
+
+ stringbuffer+=piece1;
+ stringbuffer.append(p,10);
+ stringbuffer+=piece3;
+
+ d.ancount++;
+}
+
+void DNSPacket::addHINFORecord(const DNSResourceRecord& rr)
+{
+ addHINFORecord(rr.qname, rr.content, rr.ttl);
+}
+
+/** First word of content is the CPU */
+void DNSPacket::addHINFORecord(string domain, string content, u_int32_t ttl)
+{
+ string piece1;
+ toqname(domain, &piece1);
+ char p[10];
+
+ p[0]=0;
+ p[1]=13; // HINFO
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=0; // need to fill this in
+
+ unsigned int offset=content.find(" ");
+ string cpu, host;
+ if(offset==string::npos) {
+ cpu=content;
+ } else {
+ cpu=content.substr(0,offset);
+ host=content.substr(offset);
+ }
+
+
+ string piece3;
+ piece3.reserve(cpu.length()+1);
+ piece3.append(1,cpu.length());
+ piece3.append(cpu);
+
+ string piece4;
+ piece4.reserve(host.length()+1);
+ piece4.append(1,host.length());
+ piece4.append(host);
+
+
+ p[8]=0;
+ p[9]=piece3.length()+piece4.length();
+
+ stringbuffer+=piece1;
+ stringbuffer.append(p,10);
+ stringbuffer+=piece3;
+ stringbuffer+=piece4;
+
+ d.ancount++;
+}
+
+
+
+void DNSPacket::addNSRecord(const DNSResourceRecord &rr)
+{
+ addNSRecord(rr.qname, rr.content, rr.ttl, rr.d_place);
+}
+
+void DNSPacket::addNSRecord(string domain, string server, u_int32_t ttl, DNSResourceRecord::Place place)
+{
+ string piece1;
+ toqname(domain, &piece1);
+
+ char p[10];
+
+ p[0]=0;
+ p[1]=2; // NS
+ p[2]=0;
+ p[3]=1; // IN
+
+ u_int32_t *ttlp=(u_int32_t *)(p+4);
+
+ *ttlp=htonl(ttl); // 4, 5, 6, 7
+
+ p[8]=0;
+ p[9]=0; // need to fill this in
+
+ string piece3;
+ string::size_type pos=server.find('@'); // chop off @
+ if(pos!=string::npos)
+ server.resize(pos);
+
+ toqname(server,&piece3);
+
+ p[9]=piece3.length();;
+
+ stringbuffer.append(piece1);
+ stringbuffer.append(p,10);
+ stringbuffer.append(piece3);
+
+ if(place==DNSResourceRecord::AUTHORITY)
+ d.nscount++;
+ else
+ d.ancount++;
+
+}
+
+
+static int rrcomp(const DNSResourceRecord &A, const DNSResourceRecord &B)
+{
+ if(A.d_place<B.d_place)
+ return 1;
+
+ return 0;
+}
+
+/** You can call this function to find out if there are any records that need additional processing.
+ This holds for MX records and CNAME records, where information about the content may need further resolving. */
+bool DNSPacket::needAP()
+{
+ // if speed ever becomes an issue, this function might be implemented in the addRecord() method, which would set a flag
+ // whenever a record that needs additional processing is added
+
+ for(vector<DNSResourceRecord>::const_iterator i=rrs.begin();
+ i!=rrs.end();
+ ++i)
+ {
+ if(i->d_place!=DNSResourceRecord::ADDITIONAL &&
+ ( (i->qtype.getCode()==QType::NS && i->content.find('@')==string::npos) || // NS records with @ in them are processed
+ i->qtype.getCode()==QType::MX ))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+vector<DNSResourceRecord> DNSPacket::getAPRecords()
+{
+ vector<DNSResourceRecord> arrs;
+
+ for(vector<DNSResourceRecord>::const_iterator i=rrs.begin();
+ i!=rrs.end();
+ ++i)
+ {
+ if(i->d_place!=DNSResourceRecord::ADDITIONAL &&
+ (i->qtype.getCode()==15 ||
+ i->qtype.getCode()==2 )) // CNAME or MX or NS
+ {
+ arrs.push_back(*i);
+ }
+ }
+
+ return arrs;
+
+}
+
+void DNSPacket::setCompress(bool compress)
+{
+ d_compress=compress;
+ stringbuffer.reserve(65000);
+ rrs.reserve(200);
+}
+
+/** Must be called before attempting to access getData(). This function stuffs all resource
+ * records found in rrs into the data buffer. It also frees resource records queued for us.
+ */
+void DNSPacket::wrapup(void)
+{
+ if(d_wrapped) {
+ return;
+ }
+
+ // do embedded-additional processing decapsulation
+ DNSResourceRecord rr;
+ vector<DNSResourceRecord>::iterator pos;
+
+ vector<DNSResourceRecord> additional;
+ for(pos=rrs.begin();pos<rrs.end();++pos) {
+ if(pos->qtype.getCode()==QType::NS) {
+ vector<string>pieces;
+ stringtok(pieces,pos->content,"@");
+
+ if(pieces.size()>1) { // INSTANT ADDITIONAL PROCESSING!
+ rr.qname=pieces[0];
+ rr.qtype=QType::A;
+ rr.ttl=pos->ttl;
+ rr.content=pieces[1];
+ rr.d_place=DNSResourceRecord::ADDITIONAL;
+ additional.push_back(rr);
+ }
+ }
+ }
+ int ipos=rrs.size();
+ rrs.resize(rrs.size()+additional.size());
+ copy(additional.begin(), additional.end(), rrs.begin()+ipos);
+
+ // we now need to order rrs so that the different sections come at the right place
+ // we want a stable sort, based on the d_place field
+
+ stable_sort(rrs.begin(),rrs.end(),rrcomp);
+
+ d_wrapped=true;
+
+
+ for(pos=rrs.begin();pos<rrs.end();++pos) {
+ rr=*pos;
+ DLOG(L<<"Added to data, RR: " << rr.qname);
+ DLOG(L<<"(" << rr.qtype.getName() << ")" << " " << (int) rr.d_place<< endl);
+
+ switch(rr.qtype.getCode()) {
+ case 1: // A
+ addARecord(rr);
+ break;
+ case 2: // NS
+ addNSRecord(rr);
+ break;
+
+ case 5: // CNAME
+ addCNAMERecord(rr);
+ break;
+
+ case 6: // SOA
+ addSOARecord(rr);
+ break;
+
+ case 12: // PTR
+ addPTRRecord(rr);
+ break;
+
+ case 13: // HINFO
+ addHINFORecord(rr);
+ break;
+
+ case 15: // MX
+ addMXRecord(rr);
+ break;
+
+ case 16: // TXT
+ addTXTRecord(rr);
+ break;
+
+ case 17: // RP
+ addRPRecord(rr);
+ break;
+
+
+ case 28: // AAAA
+ addAAAARecord(rr);
+ break;
+
+ case QType::NAPTR:
+ addNAPTRRecord(rr);
+ break;
+
+ case 258: // CURL
+ case 256: // URL
+ addARecord(rr.qname,htonl(inet_addr(arg()["urlredirector"].c_str())),rr.ttl,DNSResourceRecord::ANSWER);
+ break;
+
+ case 257: // MBOXFW
+ unsigned int pos;
+ pos=rr.qname.find("@");
+ DLOG(L<<Logger::Warning<<"Adding rr.qname: '"<<rr.qname<<"'"<<endl);
+ if(pos!=string::npos)
+ {
+ string substr=rr.qname.substr(pos+1);
+
+ addMXRecord(substr,arg()["smtpredirector"],25,rr.ttl);
+ }
+ break;
+
+ default:
+ L<<Logger::Warning<<"Unable to insert a record of type "<<rr.qtype.getName()<<" for '"<<rr.qname<<"'"<<endl;
+ }
+ }
+ d.ancount=htons(d.ancount);
+ d.qdcount=htons(d.qdcount);
+ d.nscount=htons(d.nscount);
+ d.arcount=htons(d.arcount);
+
+ commitD();
+
+
+ len=stringbuffer.length();
+}
+
+
+/** Truncates a packet that has already been wrapup()-ed, possibly via a call to getData(). Do not call this function
+ before having done this - it will possibly break your packet, or crash your program.
+
+ This method sets the 'TC' bit in the stringbuffer, and caps the len attributed to new_length.
+*/
+
+void DNSPacket::truncate(int new_length)
+{
+ if(new_length>len || !d_wrapped)
+ return;
+
+ DLOG(L<<Logger::Warning<<"Truncating a packet to "<<inet_ntoa( reinterpret_cast< sockaddr_in * >( remote )->sin_addr )<<endl);
+
+ len=new_length;
+ stringbuffer[2]|=2; // set TC
+}
+
+string DNSPacket::compress(const string &qd)
+{
+ // input www.casema.net, output 3www6casema3net
+ // input www.casema.net., output 3www6casema3net
+ string qname = "";
+
+ // Convert the name to a qname
+
+ const char *p = qd.c_str();
+ const char *q = strchr(p, '.');
+
+ while (p <= (qd.c_str() + qd.length()))
+ {
+ int length = (q == NULL) ? strlen(p) : (q - p);
+ if (length == 0) {
+ break;
+ }
+ qname += (char) length;
+ qname.append(p, length);
+
+ if (q == NULL) {
+ break;
+ } else {
+ p = q + 1;
+ q = strchr(p, '.');
+ }
+ }
+
+ qname += (char) 0x00;
+ return qname;
+}
+
+void DNSPacket::setQuestion(int op, const string &qd, int qtype)
+{
+ memset(&d,0,sizeof(d));
+ d.id=Utility::random();
+ d.rd=d.tc=d.aa=false;
+ d.qr=false;
+ d.qdcount=1; // is htons'ed later on
+ d.ancount=d.arcount=d.nscount=0;
+ d.opcode=op;
+
+ string label=compress(qd);
+ stringbuffer.assign((char *)&d,sizeof(d));
+ stringbuffer.append(label);
+ u_int16_t tmp=htons(qtype);
+ stringbuffer.append((char *)&tmp,2);
+ tmp=htons(1);
+ stringbuffer.append((char *)&tmp,2);
+}
+
+
+
+
+/** A DNS answer packets needs to include the original question. This function allows you to
+ paste in a question */
+
+void DNSPacket::pasteQ(const char *question, int length)
+{
+ stringbuffer.replace(12,length,question,length); // bytes 12 & onward need to become *question
+}
+
+vector<DNSResourceRecord> DNSPacket::getAnswers()
+{
+ vector<DNSResourceRecord> rrs;
+ if(!(d.ancount|d.arcount|d.nscount))
+ return rrs;
+
+ const char *answerp=stringbuffer.c_str()+d_qlen+12;
+ const char *end=stringbuffer.c_str()+len;
+
+ int numanswers=ntohs(d.ancount) + ntohs(d.nscount) + ntohs(d.arcount);
+ int length;
+ int pos=0;
+ while(numanswers--) {
+ string name;
+ int offset=0;
+ offset=expand(answerp,end,name);
+
+ DNSResourceRecord rr;
+ rr.qname=name;
+ rr.qtype=ntohs(*((short int *)(answerp+offset)));
+ rr.ttl=ntohl(*(u_int32_t*)(answerp+offset+4)); // 4, 5, 6, 7
+ rr.content="";
+ length=ntohs(*(u_int16_t*)(answerp+offset+8));
+
+ const char *datapos=answerp+offset+10;
+ string part;
+ offset=0;
+
+ ostringstream o;
+ int ip;
+
+ switch(rr.qtype.getCode()) {
+
+ case QType::SOA:
+ part=""; offset+=expand(datapos+offset,end,part); rr.content=part; // mname
+ part=""; offset+=expand(datapos+offset,end,part); rr.content+=" "+part; // hostmaster
+
+ rr.content+=" ";rr.content+=itoa(ntohl(*(unsigned int *)(datapos+offset)));
+ rr.content+=" ";rr.content+=itoa(ntohl(*(unsigned int *)(datapos+offset+4)));
+ rr.content+=" ";rr.content+=itoa(ntohl(*(unsigned int *)(datapos+offset+8)));
+ rr.content+=" ";rr.content+=itoa(ntohl(*(unsigned int *)(datapos+offset+12)));
+ rr.content+=" ";rr.content+=itoa(ntohl(*(unsigned int *)(datapos+offset+16)));
+
+ break;
+
+ case QType::A:
+ ip = ntohl(*((int *)datapos));
+
+ o.clear();
+ o<<((ip>>24)&0xff)<<".";
+ o<<((ip>>16)&0xff)<<".";
+ o<<((ip>>8)&0xff)<<".";
+ o<<((ip>>0)&0xff);
+
+ rr.content=o.str();
+ break;
+
+ case QType::MX:
+ rr.priority=(datapos[0] << 8) + datapos[1];
+ expand(datapos+2,end,rr.content);
+
+ break;
+
+ case QType::CNAME:
+ case QType::NS:
+ case QType::PTR:
+ expand(datapos+offset,end,rr.content);
+ break;
+
+ case QType::AAAA:
+ if(length!=16)
+ throw AhuException("Wrong length AAAA record returned from remote");
+ char tmp[128];
+
+ if(!Utility::inet_ntop(AF_INET6, datapos, tmp, sizeof(tmp)-1))
+ throw AhuException("Unable to translate record of type AAAA in resolver");
+
+ rr.content=tmp;
+ break;
+
+ default:
+ throw AhuException("Unknown type number "+itoa(rr.qtype.getCode())+" for: '"+rr.qname+"'");
+ }
+ if(pos<ntohs(d.ancount))
+ rr.d_place=DNSResourceRecord::ANSWER;
+ else if(pos<ntohs(d.ancount)+ntohs(d.nscount))
+ rr.d_place=DNSResourceRecord::AUTHORITY;
+ else
+ rr.d_place=DNSResourceRecord::ADDITIONAL;
+
+ rrs.push_back(rr);
+ pos++;
+ // cout<<"Added '"<<rr.qname<<"' '"<<rr.content<<"' "<<rr.qtype.getName()<<endl;
+ // cout<<"Advancing "<<length<<" bytes"<<endl;
+ answerp=datapos+length;
+ }
+ return rrs;
+
+}
+
+/** convenience function for creating a reply packet from a question packet. Do not forget to delete it after use! */
+DNSPacket *DNSPacket::replyPacket() const
+{
+ DNSPacket *r=new DNSPacket;
+ r->setSocket(d_socket);
+
+
+ r->setRemote((struct sockaddr *)remote, d_socklen);
+ r->setAnswer(true); // this implies the allocation of the header
+ r->setA(true); // and we are authoritative
+ r->setRA(0); // no recursion available
+ r->setRD(d.rd); // if you wanted to recurse, answer will say you wanted it (we don't do it)
+ r->setID(d.id);
+ r->setOpcode(d.opcode);
+
+ // reserve some space
+ r->stringbuffer.reserve(d_qlen+12);
+ // copy the question in
+ r->pasteQ(stringbuffer.c_str()+12,d_qlen);
+ r->d.qdcount=1;
+
+ r->d_dt=d_dt;
+
+ return r;
+}
+
+int DNSPacket::findlabel(string &label)
+{
+ const char *data = stringbuffer.data();
+ const char *p = data + 12;
+
+ // Look in the question section
+
+ for (unsigned int i = 0; i < d.qdcount; i++) {
+ while (*p != 0x00) {
+ // Skip compressed labels
+ if ((*p & 0xC0) == 0xC0) {
+ p += 1;
+ break;
+ }
+ else {
+ if (strcmp(p, label.data()) == 0)
+ return (p - data);
+ p += (*p + 1);
+ }
+ }
+
+ // Skip the tailing zero
+ p++;
+
+ // Skip the header
+ p += 4;
+ }
+
+ //
+ // Look in the answer sections
+ //
+
+ for (unsigned int i = 0; i < d.ancount + d.nscount + d.arcount; i++) {
+ while (*p != 0x00) {
+ // Skip compressed labels - means the end
+ if ((*p & 0xC0) == 0xC0)
+ {
+ p += 1;
+ break;
+ }
+ else
+ {
+ if (strcmp(p, label.data()) == 0)
+ {
+ return (p - data);
+ }
+
+ p += (*p + 1);
+ }
+ }
+
+ // Skip the trailing zero or other half of the ptr
+
+ p++;
+
+ // Skip the header and data
+
+ short int dataLength = ntohs(*(short int*) (p + 8));
+ short int type = ntohs(*(short int*) (p));
+
+ p += 10;
+
+ // Check for NS, CNAME, PTR and MX records
+
+ if (type == QType::NS || type == QType::CNAME || type == QType::PTR || type == QType::MX) {
+ // For MX records, skip the preference field
+ if (type == QType::MX){
+ p += 2;
+ }
+
+ while (*p != 0x00) {
+ //
+ // Skip compressed labels
+ //
+
+ if ((*p & 0xC0) == 0xC0) {
+ p += 1;
+ break;
+ }
+ else {
+
+ if (strcmp(p, label.data()) == 0) {
+ return (p - data);
+ }
+
+ p += (*p + 1);
+ }
+ }
+
+ // Skip the trailing zero or the last byte of a compresed label
+ p++;
+ }
+ else {
+ p += dataLength;
+ }
+ }
+
+ return -1;
+}
+
+int DNSPacket::toqname(const char *name, string &qname, bool comp)
+{
+ qname = compress(name);
+
+ if (d_compress && comp) {
+ // Now find a previous declared label. We work through the complete
+ // name from left to right like this:
+ // ns1.norad.org
+ // norad.org
+ // org
+
+ int i = 0;
+
+ while (qname[i] != 0x00) {
+ // Get a portion of the name
+
+ string s = qname.substr(i);
+
+ // Did we see this before?
+ int offset = findlabel(s);
+
+ if ( offset != -1) {
+
+ qname[i + 0] = (char) (((offset | 0xC000) & 0x0000FF00) >> 8);
+ qname[i + 1] = (char) ((offset | 0xC000) & 0x000000FF);
+ qname = qname.substr(0, i + 2); // XX setlength() ?
+ // qname now consists of unique prefix+known suffix (on location 'offset')
+ break;
+ }
+ // Move to the next label
+ i += (qname[i] + 1); // doesn't quite handle very long labels
+ }
+ }
+
+ return qname.length();
+}
+
+int DNSPacket::toqname(const string &name, string &qname, bool compress)
+{
+ return toqname(name.c_str(), qname, compress);
+}
+
+int DNSPacket::toqname(const string &name, string *qname, bool compress)
+{
+ return toqname(name.c_str(), *qname, compress);
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: dnspacket.hh,v 1.1 2002/11/27 15:18:32 ahu Exp $
+#ifndef DNSPACKET_HH
+#define DNSPACKET_HH
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <sys/types.h>\r
+\r
+#ifndef WIN32
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <unistd.h>\r
+#include <arpa/inet.h>\r
+\r
+#endif // WIN32
+
+#include <iostream>
+#include <string>
+
+#include <vector>
+#include "qtype.hh"
+#include "dns.hh"
+#include "misc.hh"
+#include "utility.hh"
+#include "logger.hh"
+#include "ahuexception.hh"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+
+
+#ifdef NEED_POSIX_TYPEDEF
+typedef unsigned short int u_int16_t;
+#endif
+
+class DNSBackend;
+
+//! This class represents DNS packets, either received or to be sent.
+class DNSPacket
+{
+public:
+ DNSPacket();
+ DNSPacket(const DNSPacket &orig);
+
+ int expand(const char *begin, const char *end, string &expanded, int depth=0);
+ inline int parse(const char *mesg, int len); //!< parse a raw UDP or TCP packet and suck the data inward
+ string getString();
+
+ //! the raw DNS header
+ struct dnsheader
+ {
+ unsigned int id:16; //!< id of this query/response
+#if BYTE_ORDER == BIG_ENDIAN
+ unsigned int qr:1; //!< 1 if this is a query, 0 if response
+ unsigned int opcode:4; //!< the opcode
+ unsigned int aa:1; //!< packet contains authoritative data
+ unsigned int tc:1; //!< packet is truncated
+ unsigned int rd:1; //!< this packets wants us to recurse
+ unsigned int ra:1; //!< ??
+ unsigned int unused:1; //!<
+ unsigned int ad:1; //!< authentic data
+ unsigned int cd:1; //!< checking disabled by resolver
+ unsigned int rcode:4; //!< ??
+#else
+ unsigned int rd:1; //!< this packets wants us to recurse
+ unsigned int tc:1; //!< packet is truncated
+ unsigned int aa:1; //!< packet contains authoritative data
+ unsigned int opcode:4; //!< the opcode
+ unsigned int qr:1; //!< 1 if this is a query, 0 if response
+
+ ///////////
+
+ unsigned int rcode:4; //!< ??
+ unsigned int cd:1; //!< checking disabled by resolver
+ unsigned int ad:1; //!< authentic data
+ unsigned int unused:1; //!<
+ unsigned int ra:1; //!< ??
+#endif
+ ////////////////
+
+ unsigned int qdcount:16; //!< number of questions
+ unsigned int ancount:16; //!< number of answers
+ unsigned int nscount:16; //!< number of authoritative nameservers included in answer
+ unsigned int arcount:16; //!< number of additional resource records
+ };
+
+ inline void setRemote(const struct sockaddr *a, Utility::socklen_t socklen);
+ string getRemote() const;
+ void setA(bool); //!< make this packet authoritative
+ void setRA(bool); //!< set the Recursion Available flag
+ void setRD(bool); //!< set the Recursion Desired flag
+ void setAnswer(bool); //!< Make this packet an answer
+ void setID(u_int16_t); //!< set the DNS id of this packet
+ void setOpcode(u_int16_t); //!< set the Opcode of this packet
+ void setRcode(int v); //!< set the Rcode of this packet
+
+
+ /** Add a DNSResourceRecord to this packet. A DNSPacket (as does a DNS Packet) has 4 kinds of resource records. Questions,
+ Answers, Authority and Additional. See RFC 1034 and 1035 for details. You can specify where a record needs to go in the
+ DNSResourceRecord d_place field */
+ void addRecord(const DNSResourceRecord &);
+
+
+ /** helper function for both DNSPacket and addSOARecord() - converts a line into a struct, for easier parsing */
+ static void fillSOAData(const string &content, SOAData &data);
+
+ /** for use by DNSPacket, converts a SOAData class to a ascii line again */
+ static string serializeSOAData(const SOAData &data);
+ void setQuestion(int op, const string &qdomain, int qtype);
+ vector<DNSResourceRecord> getAnswers();
+private:
+ string compress(const string &qd);
+ void addARecord(const string&, u_int32_t, u_int32_t ttl, DNSResourceRecord::Place place); //!< add an A record to the packet
+ void addARecord(const DNSResourceRecord &); //!< add an A record to the packet
+
+ void addAAAARecord(const string &, unsigned char addr[16], u_int32_t ttl); //!< add an A record to the packet
+ void addAAAARecord(const DNSResourceRecord &); //!< add an A record to the packet
+
+
+ void addMXRecord(const string &domain, const string &mx, int priority, u_int32_t ttl); //!< add an MX record to the packet
+ void addMXRecord(const DNSResourceRecord &); //!< add an MX record to the packet
+
+ void addCNAMERecord(const string &domain, const string &alias, u_int32_t ttl); //!< add a CNAME record to the packet
+ void addCNAMERecord(const DNSResourceRecord &); //!< add a CNAME record to the packet
+
+ void addRPRecord(const string &domain, const string &content, u_int32_t ttl); //!< add a RP record to the packet
+ void addRPRecord(const DNSResourceRecord &); //!< add a RP record to the packet
+
+ void addNAPTRRecord(const string &domain, const string &content, u_int32_t ttl); //!< add a RP record to the packet
+ void addNAPTRRecord(const DNSResourceRecord &); //!< add a RP record to the packet
+
+
+ void addPTRRecord(const string &domain, const string &alias, u_int32_t ttl); //!< add a PTR record to the packet
+ void addPTRRecord(const DNSResourceRecord &); //!< add a PTR record to the packet
+
+
+ /** Adds a SOA record to the packet. The SOA record is very special because we have a lot of default values,
+ that may be overridden by the contents of the database. Content can have a variety of content:
+
+ (nothing)
+ hostmaster
+ hostmaster serial-number
+ hostmaster serial-number [refresh [retry [expire [ minimum] ] ] ]
+
+ Suggested values are:
+
+ 10800 ;refresh every three hours
+ 300 ;retry every 5 min
+ 604800 ;expire after a week
+ 86400 ;default ttl
+
+ An empty field means that we supply hostmaster+@+domain name as hostmaster. An empty serial number is replaced by the
+ number of seconds since 1 jan 1970 (unix timestamp). The other values are substituted as indicated
+
+ */
+
+
+ void addSOARecord(const string &domain, const string &content, u_int32_t ttl, DNSResourceRecord::Place place);
+ void addSOARecord(const DNSResourceRecord &); //!< add a SOA record to the packet
+
+
+ void addTXTRecord(string domain, string, u_int32_t ttl); //!< add a TXT record to the packet
+ void addTXTRecord(const DNSResourceRecord &); //!< add a TXT record to the packet
+
+ void addHINFORecord(string domain, string, u_int32_t ttl); //!< add a HINFO record to the packet
+ void addHINFORecord(const DNSResourceRecord &); //!< add a HINFO record to the packet
+
+ void addNSRecord(string domain, string server, u_int32_t ttl, DNSResourceRecord::Place place); //!< add an NS record to the packet
+ void addNSRecord(const DNSResourceRecord &); //!< add an NS record to the packet
+
+ static string &attodot(string &str); //!< for when you need to insert an email address in the SOA
+
+public:
+
+ DTime d_dt; //!< the time this packet was created. replyPacket() copies this in for you, so d_dt becomes the time spent processing the question+answer
+ void pasteQ(const char *question, int length); //!< set the question of this packet, useful for crafting replies
+ void trim();
+ void wrapup(void);
+ inline const char *getData(void); //!< get binary representation of packet
+ void setRaw(char *mesg, int length);
+ const char *getRaw(void);
+ inline void spoofID(u_int16_t id); //!< change the ID of an existing packet. Useful for fixing up packets returned from the PacketCache
+ inline void spoofQuestion(const string &qd); //!< paste in the exact right case of the question. Useful for PacketCache
+ void truncate(int new_length); // has documentation in source
+
+ bool needAP(); //!< query this to find out if this packet needs additional processing
+ vector<DNSResourceRecord> getAPRecords(); //!< get a vector with DNSResourceRecords that need additional processing
+ void setCompress(bool compress);
+
+ DNSPacket *replyPacket() const; //!< convenience function that creates a virgin answer packet to this question
+ Utility::sock_t getSocket() const
+ {
+ return d_socket;
+ }
+ inline void setSocket(Utility::sock_t sock);
+ inline void commitD();
+ static bool isRD(const string &buffer)
+ {
+ return ((struct dnsheader *)buffer.c_str())->rd;
+ }
+
+ //////// DATA !
+
+ char remote[28];
+ Utility::socklen_t d_socklen; // 4
+ u_int16_t len; //!< length of the raw binary packet 2
+ u_int16_t qclass; //!< class of the question - should always be INternet 2
+ struct dnsheader d; //!< dnsheader at the start of the databuffer 12
+
+ QType qtype; //!< type of the question 8
+
+ string qdomain; //!< qname of the question 4
+
+
+private:
+ bool d_wrapped; // 1
+ bool d_compress; // 1
+ u_int16_t d_qlen; // length of the question (including class & type) in this packet 2
+
+ int d_socket; // 4
+ int findlabel(string &label);
+ int toqname(const char *name, string &qname, bool compress = true);
+ int toqname(const string &name, string &qname, bool compress = true);
+ int toqname(const string &name, string *qname, bool compress = true);
+ const string makeSoaHostmasterPiece(const string &hostmaster);
+
+ int domprint();
+ int getq();
+
+ // MORE DATA!
+
+ string stringbuffer; // this is where everything lives 4
+
+ vector<DNSResourceRecord> rrs; // 4
+};
+
+
+inline void DNSPacket::spoofQuestion(const string &qd)
+{
+ string label=compress(qd);
+ for(string::size_type i=0;i<label.size();++i)
+ stringbuffer[i+sizeof(d)]=label[i];
+ d_wrapped=true; // if we do this, don't later on wrapup
+}
+
+/** This function takes data from the network, possibly received with recvfrom, and parses
+ it into our class. Results of calling this function multiple times on one packet are
+ unknown. Returns -1 if the packet cannot be parsed.
+*/
+int DNSPacket::parse(const char *mesg, int length)
+{
+ stringbuffer.assign(mesg,length);
+ len=length;
+ if(length < 12) {
+ L << Logger::Warning << "Ignoring packet: too short from "
+ << getRemote() << endl;
+ return -1;
+ }
+
+ memcpy((void *)&d,(const void *)stringbuffer.c_str(),12);
+
+ int offset=0;
+ d_qlen=0;
+ if(ntohs(d.qdcount)) {
+ offset = getq(); // also sets this->qdomain!
+ if(offset < 0) {
+ // L << Logger::Warning << "Ignoring packet: invalid label in question from "
+ // << inet_ntoa(remote.sin_addr) << endl;
+ return -1;
+ }
+ d_qlen=offset+4; // this points to the start of any answers
+ }
+
+
+ const char *p=(stringbuffer.c_str()+12+offset);
+ const unsigned short int *i=(const unsigned short int *)p;
+ qtype=ntohs(*i++);
+ qclass=ntohs(*i);
+
+
+ return 0;
+}
+
+//! Use this to set where this packet was received from or should be sent to
+inline void DNSPacket::setRemote(const struct sockaddr *s, Utility::socklen_t socklen)
+{
+ if(socklen>(Utility::socklen_t)sizeof(remote))
+ throw AhuException("Address too long for storage: "+itoa(socklen));
+
+ memcpy((void *)remote,(void *)s,socklen);
+ d_socklen=socklen;
+}
+
+inline void DNSPacket::spoofID(u_int16_t id)
+{
+ stringbuffer[1]=(id>>8)&0xff;
+ stringbuffer[0]=id&0xff;
+ d.id=id;
+}
+
+inline void DNSPacket::setSocket(Utility::sock_t sock)
+{
+ d_socket=sock;
+}
+
+inline void DNSPacket::commitD()
+{
+ stringbuffer.replace(0,12,(char *)&d,12); // copy in d
+}
+
+inline const char *DNSPacket::getData(void)
+{
+ if(!d_wrapped)
+ wrapup();
+
+ return stringbuffer.data();
+}
+
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include "dnsproxy.hh"
+#include "ahuexception.hh"
+#include <sys/types.h>
+#include <errno.h>
+#include "dns.hh"
+#include "logger.hh"
+#include "statbag.hh"
+#include "packetcache.hh"
+
+extern StatBag S;
+extern PacketCache PC;
+
+DNSProxy::DNSProxy(const string &remote)
+{
+ ServiceTuple st;
+ st.port=53;
+ parseService(remote,st);
+
+ pthread_mutex_init(&d_lock,0);
+ d_resanswers=S.getPointer("recursing-answers");
+ d_resquestions=S.getPointer("recursing-questions");
+ d_udpanswers=S.getPointer("udp-answers");
+ if((d_sock=socket(AF_INET, SOCK_DGRAM,0))<0)
+ throw AhuException(string("socket: ")+strerror(errno));
+
+ struct sockaddr_in sin;
+ memset((char *)&sin, 0, sizeof(sin));
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ int n=0;
+ for(;n<10;n++) {
+ sin.sin_port = htons(10000+( Utility::random()%50000));
+
+ if(bind(d_sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ break;
+ }
+ if(n==10) {
+ Utility::closesocket(d_sock);
+ d_sock=-1;
+ throw AhuException(string("binding dnsproxy socket: ")+strerror(errno));
+ }
+
+ struct sockaddr_in toaddr;
+ struct in_addr inp;
+ Utility::inet_aton(st.host.c_str(),&inp);
+ toaddr.sin_addr.s_addr=inp.s_addr;
+
+ toaddr.sin_port=htons(st.port);
+ toaddr.sin_family=AF_INET;
+
+ if(connect(d_sock, (sockaddr *)&toaddr, sizeof(toaddr))<0)
+ throw AhuException("Unable to UDP connect to remote nameserver "+st.host+" ("+itoa(st.port)+"): "+stringerror());
+
+ d_xor=Utility::random()&0xffff;
+ L<<Logger::Error<<"DNS Proxy launched, local port "<<ntohs(sin.sin_port)<<", remote "<<st.host<<":"<<st.port<<endl;
+}
+
+void DNSProxy::go()
+{
+ pthread_t tid;
+ pthread_create(&tid,0,&launchhelper,this);
+}
+
+
+void DNSProxy::onlyFrom(const string &ips)
+{
+ vector<string>parts;
+ stringtok(parts,ips,", \t");
+ for(vector<string>::const_iterator i=parts.begin();
+ i!=parts.end();++i)
+ d_ng.addMask(*i);
+
+}
+
+/** returns false if p->remote is not allowed to recurse via us */
+bool DNSProxy::sendPacket(DNSPacket *p)
+{
+ if(!d_ng.empty() && !d_ng.match((struct sockaddr_in *)&p->remote))
+ return false;
+
+ int id;
+ {
+ Lock l(&d_lock);
+ id=getID_locked();
+
+ ConntrackEntry ce;
+ ce.id = p->d.id;
+ memcpy((void *)&ce.remote,(void *)&p->remote, p->d_socklen);
+ ce.addrlen = p->d_socklen;
+ ce.outsock = p->getSocket();
+ ce.created = time( NULL );
+
+ d_conntrack[id]=ce;
+ }
+ p->spoofID(id^d_xor);
+
+ char *buffer=const_cast<char *>(p->getRaw());
+ int len=p->len;
+ if(send(d_sock,buffer,len,0)<0) { // zoom
+ L<<Logger::Error<<"Unable to send a packet to our recursing backend: "<<stringerror()<<endl;
+ }
+ (*d_resquestions)++;
+ return true;
+
+}
+/** This finds us an unused or stale ID. Does not actually clean the contents */
+int DNSProxy::getID_locked()
+{
+ map_t::iterator i;
+ for(int n=0;;++n) {
+ i=d_conntrack.find(n);
+ if(i==d_conntrack.end()) {
+ return n;
+ }
+ else if(i->second.created<time(0)-60) {
+ if(i->second.created)
+ L<<Logger::Warning<<"Recursive query for remote "<<
+ sockAddrToString((struct sockaddr_in *)&i->second.remote, i->second.addrlen)<<" with internal id "<<n<<
+ " was not answered by backend within timeout, reusing id"<<endl;
+
+ return n;
+ }
+ }
+}
+
+void DNSProxy::mainloop(void)
+{
+ try {
+ char buffer[1500];
+ int len;
+
+ for(;;) {
+ len=recv(d_sock, buffer, sizeof(buffer),0); // answer from our backend
+ if(len<12) {
+ if(len<0)
+ L<<Logger::Error<<"Error receiving packet from recursor backend: "<<stringerror()<<endl;
+ else if(len==0)
+ L<<Logger::Error<<"Error receiving packet from recursor backend, EOF"<<endl;
+ else
+ L<<Logger::Error<<"Short packet from recursor backend, "<<len<<" bytes"<<endl;
+
+ continue;
+ }
+ (*d_resanswers)++;
+ (*d_udpanswers)++;
+ DNSPacket::dnsheader *d=reinterpret_cast<DNSPacket::dnsheader *>(buffer);
+ {
+ Lock l(&d_lock);
+ map_t::iterator i=d_conntrack.find(d->id^d_xor);
+ if(i==d_conntrack.end()) {
+ L<<Logger::Error<<"Discarding untracked packet from recursor backend with id "<<(d->id^d_xor)<<
+ ". Contrack table size="<<d_conntrack.size()<<endl;
+ continue;
+ }
+ else if(i->second.created==0) {
+ L<<Logger::Error<<"Received packet from recursor backend with id "<<(d->id^d_xor)<<" which is a duplicate"<<endl;
+ continue;
+ }
+ d->id=i->second.id;
+ sendto(i->second.outsock,buffer,len,0,(struct sockaddr*)&i->second.remote,i->second.addrlen);
+
+ DNSPacket p,q;
+ p.parse(buffer,len);
+ q.parse(buffer,len);
+
+ PC.insert(&q, &p);
+ i->second.created=0;
+ }
+ }
+ }
+ catch(AhuException &ae) {
+ L<<Logger::Error<<"Fatal error in DNS proxy: "<<ae.reason<<endl;
+ }
+ catch(exception &e) {
+ L<<Logger::Error<<"Communicator thread died because of STL error: "<<e.what()<<endl;
+ }
+ catch( ... )
+ {
+ L << Logger::Error << "Caught unknown exception." << endl;
+ }
+ L<<Logger::Error<<"Exiting because DNS proxy failed"<<endl;
+ exit(1);
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PDNS_DNSPROXY
+#define PDNS_DNSPROXY
+#include <pthread.h>
+#include <map>
+\r
+#ifndef WIN32\r
+# include <sys/socket.h>\r
+# include <netinet/in.h>\r
+# include <arpa/inet.h>\r
+#endif // WIN32\r
+\r
+#include "dnspacket.hh"
+#include "lock.hh"
+#include "iputils.hh"
+
+using namespace std;
+
+/**
+
+how will this work.
+
+This is a thread that just throws packets around. Should handle ~1000 packets/second.
+
+Consists of a thread receiving packets back from the backend and retransmitting them to the original client.
+
+Furthermore, it provides a member function that reports the packet to the connection tracker and actually sends it out.
+
+The sending happens from a source port that is determined by the constructor, but IS random. Furthermore, the ID is XOR-ed with a random value
+to make sure outside parties can't spoof us.
+
+To fix: how to remove the stale entries that will surely accumulate
+*/
+
+class DNSProxy
+{
+public:
+ DNSProxy(const string &ip); //!< creates socket
+ void go(); //!< launches the actual thread
+ void onlyFrom(const string &ips); //!< Only these netmasks are allowed to recurse via us
+ bool sendPacket(DNSPacket *p); //!< send out a packet and make a conntrack entry to we can send back the answer
+
+ void mainloop(); //!< this is the main loop that receives reply packets and sends them out again
+ static void *launchhelper(void *p)
+ {
+ static_cast<DNSProxy *>(p)->mainloop();
+ return 0;
+ }
+
+private:
+ NetmaskGroup d_ng;
+ int d_sock;
+ int* d_resanswers;
+ int* d_udpanswers;
+ int* d_resquestions;
+ pthread_mutex_t d_lock;
+ u_int32_t d_xor;
+ int getID_locked();
+ struct ConntrackEntry
+ {
+ u_int16_t id;
+ struct sockaddr_in6 remote;
+ socklen_t addrlen;
+ int outsock;
+ time_t created;
+ };
+
+ typedef map<int,ConntrackEntry> map_t;
+ map_t d_conntrack;
+};
+
+#endif
--- /dev/null
+# $Id: Makefile,v 1.1 2002/11/27 15:18:34 ahu Exp $
+
+all: pdns.txt pdns.pdf html/index.html html.tar.gz
+
+
+clean:
+ rm -rf *.dvi *.pdf *.tex *.toc *.aux *.txt *.ps *.bak *.tmp *~ *.log html
+
+html/index.html: pdns.sgml
+ db2html -o html $<
+
+html.tar.gz: html/index.html
+ tar czf html.tar.gz html/
+
+%.txt: %.sgml
+ docbook2txt $<
+
+%.pdf: %.sgml
+ docbook2pdf $<
+
+publish:
+ rsync --copy-links --delete -avrze ssh ./html pdns.txt pdns.pdf \
+ spoon.powerdns.com:/opt/websites/downloads.powerdns.com/www/documentation/
\ No newline at end of file
--- /dev/null
+<!doctype linuxdoc system>
+
+<article>
+
+<!-- Title information -->
+<title>The case for PowerDNS</title>
+<author>PowerDNS BV (bert hubert <bert@trilab.com>) &nl;
+Trilab BV</author>
+<date>v1.0 $Date: 2002/11/27 15:18:34 $</date>
+<abstract>
+This document describes what Global Server Load Balancing is, and how
+PowerDNS can be employed in a GSLB configuration
+</abstract>
+<toc>
+<sect>GSLB
+<p>
+GSLB, short for Global Server Load Balancing, isr the act of distributing
+server traffic to different locations. Although not necessary, this is
+almost always done using a smart nameserver.
+<sect1>Typical GSLB implementation
+<p>
+A user enters the name of a site ('www.thesite.com') in his or her browser.
+This causes the operating system, often Windows, to send out a request to
+the ISP of the user, asking for the IP address of www.thesite.com. If the
+nameserver of the ISP doesn't know this address, it asks the nameserver of
+thesite.com.
+<p>
+This nameserver then contains the GSLB smartness. Based on the IP Address of
+the nameserver of the ISP, it determines which of the 'www.thesite.com'
+servers is closest.
+
+A multitude of algoritms is in use for determining which server is closest.
+Some of them employ the Border Gateway Protocol, BGP, which is used for
+global internet routing. Some use 'ICMP Ping' measurements, some use
+modified DNS Queries. The simplest algorithm is to use IP Netmasks, which
+are an easy rule of thumb for determining who assigned an IP Address, which
+also gives it probable location.
+
+<sect>IP Netmasks and Location
+<p>
+IP Addresses are asigned by only a few entities worldwide, the foremost
+being ARIN, RIPE and APNIC, who respectively manage North- and South
+America, Europe and surrounding areas, and the Asian Pacific Region.
+
+This allows for coarse grained identification of location. While not very
+precise, it is very robust and guaranteed to work. It can be likened to a
+very good rule-of-thumb. Other methods employ complicated and fragile
+techniques for determining the 'internet distance' to a site.
+
+For example, ICMP Ping measurements are becoming less and less valid. The
+advent of Distributed Denial of Service attacks has lead many internet
+providers to block or limit these packets. The aforementioned BGP router
+protocol gives distance in 'AS Hops' which are no longer a valid measure of
+distance, as many Autonomous Subsystems now spread the globe.
+
+<sect1>IP Netmasks Configuration
+<p>
+PowerDNS comes preconfigured with a reasonable set of IP Rules. These may
+need some maintainance over time. It is adviseable to get a Subscription with
+PowerDNS so as to receive updates.
+
+These rules come in several levels. The lowest level is based on who
+assigned the IP Addresses, ARIN, RIPE or APNIC. The second level contains
+exceptions to these major rules. Change is expected especially in this
+second level.
+
+<sect>GSLB Concepts
+<p>
+A number of concepts are used in the PowerDNS GSLB configuration:
+
+<descrip>
+<tag>Netblock</tag>
+A netblock is a range of IP Addresses. A number of Netblocks together are
+grouped in a Region.
+<tag>Region</tag>
+A Region might be called 'ARIN' or 'Surfnet', and consists of a limited
+number of Netmasks.
+<tag>Target</tag>
+A Target describes a set of servers in a single location. Target names might
+be 'UUnet Amsterdam', 'Level3 Amsterdam' or 'Genuity'.
+<tag>Route</tag>
+A Route assigns a certain Region to a Target. A sample Route might be:
+Assign all ARIN IP Addresses to Genuity.
+<tag>Schema</tag>
+A set of Routes, Regions, Netblocks and Targets is called a Schema. Many
+different domains may be assigned to this Schema, which then only needs to
+be defined once.
+</descrip>
+
+<sect>DNS Configuration
+<p>
+In order to Load Balance a domain it must be pointed at the GSLB Schema.
+This is typically done using a DNS CNAME on the nameserver of the domain
+that needs to be balanced.
+
+In order for this to work, the Schema name must resolve to the IP Address of
+PowerDNS.
+</article>
+
--- /dev/null
+<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<Book>
+
+ <BookInfo>
+
+ <Title>PowerDNS manual</Title>
+ <AUTHOR>
+ <affiliation>
+ <orgname>PowerDNS BV</orgname>
+ <address>
+ <email>pdns@powerdns.com</email>
+ </address>
+
+ </affiliation>
+ </author>
+
+ <PubDate>v2.1 $Date: 2002/11/27 15:18:37 $</PubDate>
+
+ <Abstract>
+ <para>
+ <blockquote>
+ <LITERALLAYOUT>
+ It is a book about a Spanish guy called Manual. You should read it.
+ -- Dilbert
+ </LITERALLAYOUT>
+
+ </BLOCKQUOTE>
+ </para>
+ </Abstract>
+
+
+ </BookInfo>
+
+ <Chapter id="powerdns">
+ <Title>The PowerDNS dynamic nameserver</Title>
+
+ <Para>
+ The PowerDNS daemon is a versatile nameserver which supports a large number
+ of backends. These backends can either be <link linkend="bindbackend">plain zonefiles</link> or be
+ <link linkend="pipebackend">more dynamic</link> in nature.
+ </Para>
+
+ <Para>
+ Prime examples of backends include relational databases, but also
+ loadbalancing and failover algorithms.
+ </Para>
+ <para>
+ The company is called PowerDNS BV, the nameserver daemon is called PDNS.
+ </para>
+
+ <sect1 id="function-design"><title>Function & design of PDNS</title>
+ <para>
+ PDNS is an authoritative only nameserver. It will answer questions about domains it knows about,
+ but will not go out on the net to resolve queries about other domains. However, it can use a
+ <link linkend="recursion">recursing backend</link> to provide that functionality.
+ </para>
+ <para>
+ When PDNS answers a question, it comes out of the database, and can be trusted as being authoritative. There is
+ no way to pollute the cache or to confuse the daemon.
+ </para>
+ <para>
+ PDNS has been designed to serve both the needs of small installations by being easy to setup, as well as
+ for serving very large query volumes on large numbers of domains.
+ </para>
+ <para>
+ Another prime goal is <link linkend="security">security</link>. By the use of language features, the PDNS source code
+ is very small (in the order of 10.000 lines) which makes auditing easy. In the same way, library features have been used
+ to mitigate the risks of buffer overflows.
+ </para>
+ <para>
+ Finally, PDNS is able to give a lot of <link linkend="monitoring">statistics</link> on its operation which is both helpful in
+ determining the scalability of an installation as well as for spotting problems.
+ </para>
+ </sect1>
+ <sect1 id="about"><title>About this document</title>
+ <para>
+ If you are reading this document from disk, you may want to check <ulink url="http://doc.powerdns.com">http://doc.powerdns.com</ulink>
+ for updates. The PDF version is available on <ulink url="http://doc.powerdns.com/pdf">http://doc.powerdns.com/pdf</ulink>, a text file is
+ on <ulink url="http://doc.powerdns.com/txt">http://doc.powerdns.com/txt/</ulink>.
+ </para>
+ <sect1 id="changelog">
+ <title>Release notes</title>
+ <para>
+ Before proceeding, it is advised to check the release notes for your PDNS version, as specified in the name of the distribution
+ file.
+ </para>
+ <sect2 id="changelog-2-8"><title>Version 2.8</title>
+ <para>
+ From this release onwards, we'll concentrate on stabilising for the 3.0 release. So if you have any must-have features,
+ let us know soonest. The 2.8 release fixes a bunch of small stability issues and add two new features. In the spirit of the move to
+ stability, this release has already been running 24 hours on our servers before release.
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ pipe backend gains the ability to restricts its invocation to a limited number of requests. This allows a very busy nameserver
+ to still serve packets from a slow perl backend.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ pipe backend now honors query-logging, which also documents which queries were blocked by the regex.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ pipe backend now has its own backend chapter.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ An incoming AXFR timeout at the wrong moment had the ability to crash the binary, forcing a reload. Thanks to our bug spotting
+ champions Mike Benoit and Simon Kirby of NetNation for reporting this.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-7"><title>Version 2.7 and 2.7.1</title>
+ <para>
+ This version fixes some very long standing issues and adds a few new features. If you are still running 2.6, upgrade yesterday. If you
+ were running 2.6.1, an upgrade is still strongly advised.
+ </para>
+ <para>
+ Features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ The controlsocket is now readable and writable by the 'setgid' user. This allows for non-root
+ access to PDNS which is nice for mrtg or cricket graphs.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ MySQL backend (the non-generic one) gains the ability to read from a different table using the
+ <command>mysql-table</command> setting.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ pipe backend now has a configurable timeout using the <command>pipe-timeout</command> setting. Thanks fo Steve Bromwich
+ for pointing out the need for this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Experimental backtraces. If PowerDNS crashes, it will log a lot of numbers and sometimes more to the syslog.
+ If you see these, please report them to us. Only available under Linux.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Bugs:
+ <itemizedlist>
+ <listitem>
+ <para>
+ 2.7 briefly broke the mysql backend, so don't use it if you use that. 2.7.1 fixes this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SOA records could sometimes have the wrong TTL. Thanks to Jonas Daugaard for reporting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ An ANY query might lead to duplicate SOA records being returned under exceptional circumstances.
+ Thanks to Jonas Daugaard for reporting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Underlying the above bug, packet compression could sometimes suddenly be turned off, leading to
+ overly large responses and non-removal of duplicate records.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <command>allow-axfr-ips</command> setting did not accept IP ranges (1.2.3.0/24) which the
+ documentation claimed it did (thanks to Florus Both of Ascio technologies for being sufficiently persistent in reporting this).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Killed backends were not being respawned, leading to suboptimal behaviour on intermittent database errors. Thanks to Steve Bromwich for
+ reporting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Corrupt packets during an incoming AXFR when acting as a slave would cause a PowerDNS reload instead of just failing that AXFR.
+ Thanks to Mike Benoit and Simon Kirby of NetNation for reporting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Label compression in incoming AXFR had problems with large offsets, causing the above mentioned errors. Thanks to Mike Benoit
+ and Simon Kirby of NetNation for reporting this.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ <sect2 id="changelog-2-6-1"><title>Version 2.6.1</title>
+ <para>
+ Quick fix release for a big cache problem.
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-6"><title>Version 2.6</title>
+ <para>
+ Performance release. A lot of work has been done to raise PDNS performance to staggering levels in order to take part
+ in benchmarketing efforts. Together with our as yet unnamed partner, PDNS has been benchmarked at 60.000 mostly cached queries/second
+ on off the shelf PC hardware. Uncached performance was 17.000 uncached DNS queries/second on the .ORG domain.
+ </para>
+ <para>
+ Performance has been increased by both making PDNS itself quicker but also by lowering the number of backend queries typically needed. Operators
+ will typically see PDNS taking less CPU and the backend seeing less load.
+ </para>
+ <para>
+ Furthermore, some real bugs were fixed. A couple of undocumented performance switches may appear in --help output but you are advised to stay
+ away from these.
+ </para>
+ <para>
+ Developers: this version needs the pdns-2.5.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
+ http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
+ </para>
+ <para>
+ Performance:
+ <itemizedlist>
+ <listitem>
+ <para>
+ A big error in latency calculations - cached packets were weighed 50 times less, leading to inflated latency reporting. Latency calculations
+ are now correct and way lower - often in the microseconds range.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ It is now possible to run with 0 second cache TTLs. This used to cause very frequent cache cleanups, leading
+ to performance degradation.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Many tiny performance improvements, removing duplicate cache key calculations, etc. The cache itself has also been reworked
+ to be more efficient.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ First 'CNAME' backend query replaced by an 'ANY' query, which most of the time returns the actual record,
+ preventing the need for a separate CNAME lookup, halving query load.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Much of the same for same-level-NS records on queries needing delegation.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Incidentally, the cache count would show 'unknown' packets, which was harmless but confusing. Thanks to Mike and Simon of
+ NetNation for reporting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SOA hostmaster with a . in the local-part would be cached wrongly, leading to a stray backslash
+ in case of multiple successively SOA queries. Thanks to Ascio Techologies for spotting this bug.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ zone2sql did not parse Verisign zonefiles correctly as these contained a $TTL statement in mid-record.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Sometimes packets would not be accounted, leading to 'udp-queries' and 'udp-answers' divergence.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ 'cricket' command added to init.d scripts that provides unadorned output for parsing by 'Cricket'.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-5-1"><title>Version 2.5.1</title>
+ <para>
+ <ulink url="http://www.tuxedo.org/~esr/jargon/html/entry/brown-paper-bag-bug.html">Brown paper bag</ulink> release fixing
+ a huge memory leak in the new Query Cache.
+ </para>
+ <para>
+ Developers: this version needs the new pdns-2.5.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
+ http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
+ </para>
+ <para>
+ And some small changes:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Added support for RFC2038 compliant negative-answer caching. This allows remotes to cache the fact that
+ a domain does not exist and will not exist for a while. Thanks to Chris Thompson for <ulink url="http://ops.ietf.org/lists/namedroppers/namedroppers.2002/msg01697.html">pointing out how tiny our minds are</ulink>. This feature may cause a noticeable reduction
+ in query load.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Small speedup to non-packet-cached queries, incidentally fixing the huge memory leak.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>pdns_control ccounts</command> command outputs statistics on what is in the cache, which is
+ useful to help optimize your caching strategy.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-5"><title>Version 2.5</title>
+ <para>
+ An important release which has seen quite a lot of trial and error testing. As a result, PDNS can now run with a huge cache
+ and concurrent invalidations. This is useful when running of a slower database or under high traffic load with a fast database.
+ </para>
+ <para>
+ Furthermore, the gpgsql2 backend has been validated for use and will soon supplant the gpgsql backend entirely. This also bodes
+ well for the gmysql backend which is the same code.
+ </para>
+ <para>
+ Also, a large amount of issues biting large scale slave operators were addressed. Most of these issues would only show up
+ after prolonged uptime.
+ </para>
+ <para>
+ New features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Query cache. The old Packet Cache only cached entire questions and their answers. This is very CPU efficient but
+ does not lead to maximum hitrate. Two packets both needing to resolve smtp.you.com internally would not benefit
+ from any caching. Furthermore, many different DNS queries lead to the same backend queries, like 'SOA for .COM?'.
+ </para>
+ <para>
+ PDNS now also caches backend queries, but only those having no answer (the majority) and those having one answer
+ (almost the rest).
+ </para>
+ <para>
+ In tests, these additional caches appear to halve the database backend load numerically and perhaps even more in terms
+ of CPU load. Often, queries with no answer are more expensive than those having one.
+ </para>
+ <para>
+ The default <command>ttl</command>s for the query-cache and negquery-cache are set to safe values (20 and 60 seconds
+ respectively), you should be seeing an improvement in behaviour without sacrificing a lot in terms of quick updates.
+ </para>
+ <para>
+ The webserver also displays the efficiency of the new Query Cache.
+ </para>
+ <para>
+ The old Packet Cache is still there (and useful) but see <xref linkend="performance"> for more details.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ There is now the ability to shut off some logging at a very early stage. High performance sites doing thousands of
+ queries/second may in fact spend most of their CPU time on attempting to write out logging, even though it is ignored
+ by syslog. The new flag <command>log-dns-details</command>, on by default, allows the operator to kill most
+ informative-only logging before it takes any cpu.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Flags which can be switched 'on' and 'off' can now also be set to 'off' instead of only to 'no' to turn them off.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Packet Cache is now case insensitive, leading to a higher hitrate because identical queries only differing in case
+ now both match. Care is taken to restore the proper case in the answer sent out.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Packet Cache stores packets more efficiently now, savings are estimated at 50%.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The Packet Cache is now asynchronous which means that PDNS continues to answer questions while the cache
+ is busy being purged or queried. Incidentally this will mean a cache miss where previously the question would
+ wait until the cache became available again.
+ </para>
+ <para>
+ The upshot of this is that operators can call <command>pdns_control purge</command> as often as desired without
+ fearing performance loss. Especially the full, non-specific, purge was speeded up tremendously.
+ </para>
+ <para>
+ This optimization is of little merit for small sites but is very important when running with a large packetcache, such
+ as when using recursion under high load.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ AXFR log messages now all contain the word 'AXFR' to ease grepping.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Linux static version now compiled with gcc 3.2 which is known to output better and faster code than the previously
+ used 3.0.4.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Packetcache would sometimes send packets back with slightly modified flags if these differed from the flags
+ of the cached copy.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Resolver code did bad things with filedescriptors leading to fd exhaustion after prolonged uptimes and many slave
+ SOA currency checks.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Resolver code failed to properly log some errors, leading to operator uncertainty regarding to AXFR problems with
+ remote masters.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ After prolonged uptime, slave code would try to use privileged ports for originating queries, leading to bad
+ replication efficiency.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Masters sending back answers in differing case from questions would lead to bogus
+ 'Master tried to sneak in out-of-zone data' errors and failing AXFRs.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-4"><title>Version 2.4</title>
+ <para>
+ Developers: this version is compatible with the pdns-2.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
+ http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
+ </para>
+ <para>
+ This version fixes some stability issues with malformed or malcrafted packets. An upgrade is advised. Furthermore, there are interesting new
+ features.
+ </para>
+ <para>
+ New features:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Recursive queries are now also cached, but in a separate namespace so non-recursive queries don't get recursed answers and
+ vice versa. This should mean way lower database load for sites running with the current default lazy-recursion. Up to now,
+ each and every recursive query would lead to a large amount of SQL queries.
+ </para>
+ <para>
+ To prevent the packetcache from becoming huge, a separate <command>recursive-cache-ttl</command> can be specified.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The ability to change parameters at runtime was added. Currently, only the new <command>query-logging</command> flag
+ can be changed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Added <command>query-logging</command> flag which hints a backend that it should output a textual representation of queries
+ it receives. Currently only gmysql and gpgsql2 honor this flag.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Gmysql backend can now also talk to PgSQL, leading to less code. Currently, the old postgresql driver ('gpgsql') is still the default,
+ the new driver is available as 'gpgsql2' and has the benefit that it does query logging. In the future, gpgsql2 will become the default
+ gpgsql driver.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ DNS recursing proxy is now more verbose in logging odd events which may be caused by buggy recursing backends.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Webserver now displays peak queries/second 1 minute average.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Failure to connect to database in master/slave communicator thread could lead to an unclean reload, fixed.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Documentation: added details for <command>strict-rfc-axfrs</command>. This feature can be used if very old clients need to be able
+ to do zone transfers with PDNS. Very slow.
+ </para>
+
+ </sect2>
+ <sect2 id="changelog-2-3"><title>Version 2.3</title>
+ <para>
+ Developers: this version is compatible with the pdns-2.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
+ http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
+ </para>
+ <para>
+ This release adds the Generic MySQL backend which allows full master/slave semantics with MySQL and InnoDB tables (or other tables that support
+ transactions). See <xref linkend="generic-mypgsql-backends">.
+ </para>
+ <para>
+ Other new features:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Improved error messages in master/slave communicator will help down track problems.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>slave-cycle-interval</command> setting added. Very large sites with thousands of slave domains may need to raise this value
+ above the default of 60. Every cycle, domains in undeterminate state are checked for their condition. Depending on the health of the masters,
+ this may entail many SOA queries or attempted AXFRs.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Bugs fixed:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 'pdns_control purge <userinput>domain</userinput>' and 'pdns_control purge <userinput>domain$</userinput>' were broken in version 2.2 and
+ did not in fact purge the cache. There is a slight risk that domain-specific purge commands could force a reload in previous version.
+ Thanks to Mike Benoit of NetNation for discovering this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Master/slave communicator thread got confused in case of delayed answers from slow masters. While not causing harm, this caused inefficient
+ behaviour when testing large amounts of slave domains because additional 'cycles' had to pass before all domains would have their status
+ ascertained.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Backends implementing special SOA semantics (currently only the undocumented 'pdns express backend', or homegrown backends) would
+ under some circumstances not answer the SOA record in case of an ANY query. This should put an end to the last DENIC problems. Thanks to
+ DENIC for helping us find the problem.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-2"><title>Version 2.2</title>
+ <para>
+ Developers: this version is compatible with the pdns-2.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
+ http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
+ </para>
+ <para>
+ Again a big release. PowerDNS is seeing some larger deployments in more demanding environments and these are helping shake out remaining issues,
+ especially with recursing backends.
+ </para>
+ <para>
+ The big news is that wildcard CNAMEs are now supported, an oft requested feature and nearly the only part in which PDNS differed from BIND in
+ authoritative capabilities.
+ </para>
+ <para>
+ If you were seeing signal 6 errors in PDNS causing reloads and intermittent service disruptions, please upgrade to this version.
+ </para>
+ <para>
+ For operators of PowerDNS Express trying to host .DE domains, the very special <command>soa-serial-offset</command> feature has been added
+ to placate the new DENIC requirement that the SOA serial be at least six digits. PowerDNS Express uses the SOA serial as an actual serial and
+ not to insert dates and hence often has single digit soa serial numbers, causing big problems with .DE redelegations.
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Malformed or shortened TCP recursion queries would cause a signal 6 and a reload. Same for EOF from the TCP recursing backend.
+ Thanks to Simon Kirby and Mike Benoit of NetNation for helping debug this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Timeouts on the TCP recursing backend were far too long, leading to possible exhaustion of TCP resolving threads.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>pdns_control purge domain</command> accidentally cleaned all packets with that name as a prefix. Thanks to Simon Kirby
+ for spotting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Improved exception error logging - in some circumstances PDNS would not properly log the cause of an exception, which hampered problem
+ resolution.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ New features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Wildcard CNAMEs now work as expected!
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>pdns_control purge</command> can now also purge based on suffix, allowing operators to
+ purge an entire domain from the packet cache instead of only specific records. See also <xref linkend="pdnscontrol">
+ Thanks to Mike Benoit for this suggestion.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>soa-serial-offset</command> for installations with small SOA serial numbers wishing to register .DE domains
+ with DENIC which demands six-figure SOA serial numbers. See also <xref linkend="all-settings">.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-1"><title>Version 2.1</title>
+ <para>
+ This is a somewhat bigger release due to pressing demands from customers. An upgrade is advised for installations using Recursion.
+ If you are using recursion, it is vital that you are aware of changes in semantics. Basically, local data will now override data in your
+ recursing backend under most circumstances. Old behaviour can be restored by turning <command>lazy-recursion</command> off.
+ </para>
+ <para>
+ Developers: this version has a new pdns-2.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
+ http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
+ </para>
+ <para>
+ <warning>
+ <para>
+ Most users will run a static version of PDNS which has no dependencies on external libraries. However, some may need to run the dynamic version.
+ This warning applies to these users.
+ </para>
+ <para>
+ To run the dynamic version of PDNS, which is needed for backend drivers which are only available in source form, gcc 3.0 is required.
+ RedHat 7.2 comes with gcc 3.0 as an optional component, RedHat 7.3 does not. However, the RedHat 7.2 Update gcc rpms install just fine
+ on RedHat 7.3. For Debian, we suggest running 'woody' and installing the g++-3.0 package. We expect to release a FreeBSD dynamic version
+ shortly.
+ </para>
+ </warning>
+ </para>
+
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ RPM releases sometimes overwrote previous configuration files. Thanks to Jorn Ekkelenkamp of Hubris/ISP Services for reporting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ TCP recursion sent out overly large responses due to a byteorder mistake, confusing some clients. Thanks to the capable engineers
+ of NetNation for bringing this to our attention.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ TCP recursion in combination with a recursing backend on a non-standard port did not work, leading to a
+ non-functioning TCP listener. Thanks to the capable engineers of NetNation for bringing this to our attention.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Unexpected behaviour:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Wildcard URL records where not implemented because they are a performance penalty. To turn these on, enable
+ <command>wildcard-url</command> in the configuration.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Unlike other nameservers, local data did not override the internet for recursing queries. This has mostly been brought into conformance
+ with user expectations. If a recursive question can be answered entirely from local data, it is. To restore old behaviour, disable
+ <command>lazy-recursion</command>. Also see <xref linkend="recursion">.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Oracle support has been tuned, leading to the first public release of the Oracle backend. Zone2sql now outputs better SQL
+ and the backend is now fully documented. Furthermore, the queries are compatible with the PowerDNS XML-RPC product, allowing
+ PowerDNS express to run off Oracle. See <xref linkend="oracle">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone2sql now accepts --transactions to wrap zones in a transaction for PostgreSQL and Oracle output. This is a major speedup and also
+ makes for better isolation of inserts. See <xref linkend="zone2sql">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>pdns_control</command> now has the ability to purge the PowerDNS cache or parts of it. This enables operators to
+ raise the TTL of the Packet Cache to huge values and only to invalidate the cache when changes are made. See also <xref linkend="performance"> and
+ <xref linkend="pdnscontrol">.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-0-1"><title>Version 2.0.1</title>
+ <para>
+ Maintenance release, fixing three small issues.
+ </para>
+ <para>
+ Developers: this version is compatible with 1.99.11 backends.
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ PowerDNS ignored the <command>logging-facility</command> setting unless it was specified on the commandline.
+ Thanks to Karl Obermayer from WebMachine Technologies for noticing this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone2sql neglected to preserve 'slaveness' of domains when converting to the slave capable PostgreSQL backend. Thanks
+ to Mike Benoit of NetNation for reporting this. Zone2sql now has a <command>--slave</command> option.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SOA Hostmaster addresses with dots in them before the @-sign were mis-encoded on the wire.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-0"><title>Version 2.0</title>
+ <para>
+ Two bugfixes, one stability/security related. No new features.
+ </para>
+ <para>
+ Developers: this version is compatible with 1.99.11 backends.
+ </para>
+ <para>
+ Bugfixes:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ zone2sql refused to work under some circumstances, taking 100% cpu and not functioning. Thanks to Andrew Clark and Mike Benoit
+ for reporting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Fixed a stability issue where malformed packets could force PDNS to reload. Present in all earlier 2.0 versions.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-0-rc2"><title>Version 2.0 Release Candidate 2</title>
+ <para>
+ Mostly bugfixes, no really new features.
+ </para>
+ <para>
+ Developers: this version is compatible with 1.99.11 backends.
+ </para>
+ <para>
+ Bugs fixed:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ chroot() works again - 2.0rc1 silently refused to chroot. Thanks to Hub Dohmen for noticing this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ setuid() and setgid() security features were silently not being performed in 2.0rc1. Thanks to Hub Dohmen for noticing this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ MX preferences over 255 now work as intended. Thanks to Jeff Crowe for noticing this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ IPv6 clients can now also benefit from the recursing backend feature. Thanks to Andy Furnell for proving beyond any doubt that this
+ did not work.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Extremely bogus code removed from DNS notification reception code - please test! Thanks to Jakub Jermar for working with us
+ in figuring out just how broken this was.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ AXFR code improved to handle more of the myriad different zonetransfer dialects available. Specifically, interoperability
+ with Bind 4 was improved, as well as Bind 8 in 'strict rfc conformance' mode. Thanks again for Jakub Jermar for running many tests for us.
+ If your transfers failed with 'Unknown type 14!!' or words to that effect, this was it.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Win32 version now has a zone2sql tool.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Win32 version now has support for specifying how urgent messages should be before they go to the NT event log.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Remaining issues:
+ <itemizedlist>
+ <listitem>
+ <para>
+ One persistent report of the default 'chroot=./' configuration not working.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ One report of disable-axfr and allow-axfr-ips not working as intended.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Support for relative paths in zones and in Bind configuration is not bug-for-bug compatible with bind yet.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-2-0-rc1"><title>Version 2.0 Release Candidate 1</title>
+ <para>
+ The MacOS X release! A very experimental OS X 10.2 build has been added. Furthermore, the Windows version is now in line with Unix with
+ respect to capabilities. The ODBC backend now has the code to function as both a master and a slave.
+ </para>
+ <para>
+ Developers: this version is compatible with 1.99.11 backends.
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Implemented native packet response parsing code, allowing Windows to perform AXFR and NS and SOA queries.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ This is the first version for which we have added support for Darwin 6.0, which is part of the forthcoming Mac OS X 10.2.
+ Please note that although this version is marked RC1, that we have not done extensive testing yet. Consider this a technology
+ preview.
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem><para>
+ The Darwin version has been developed on Mac OS X 10.2 (6C35). Other versions may or may not work.
+ </para></listitem>
+ <listitem><para>
+ Currently only the random, bind, mysql and pdns backends are included.
+ </para></listitem>
+
+ <listitem><para>
+ The menu based installer script does not work, you will have to edit pathconfig by hand as outlined in chapter 2.
+ </para></listitem>
+
+ <listitem><para>
+ On Mac OS X Client, PDNS will fail to start because a system service is already bound to port 53.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ This version is distributed as a compressed tar file. You should follow the generic UNIX installation instructions.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Zone2sql PostgreSQL mode neglected to lowercase $ORIGIN. Thanks to Maikel Verheijen of Ladot for spotting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone2sql PostgreSQL mode neglected to remove a trailing dot from $ORIGIN if present.
+ Thanks to Thanks to Maikel Verheijen of Ladot for spotting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zonefile parser was not compatible with bind when $INCLUDING non-absolute filenames. Thanks to Jeff Miller for working out
+ how this should work.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Bind configuration parser was not compatible with bind when including non-absolute filenames. Thanks to Jeff Miller for working out
+ how this should work.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Documentation incorrectly listed the Bind backend as 'slave capable'. This is not yet true, now labeled 'experimental'.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Windows changes. We are indebted to Dimitry Andric who educated us in the ways of distributing Windows software.
+ <itemizedlist>
+ <listitem>
+ <para>
+ <filename>pdns.conf</filename> is now read if available.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Console version responds to ^c now.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Default pdns.conf added to distribution
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Uninstaller missed several files, leaving remnants behind
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ DLLs are now installed locally, with the pdns executable.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ pdns_control is now also available on Windows
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ODBC backend can now act as master and slave. Experimental.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The example zone missed indexes and had other faults.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A runtime DLL that is present on most windows systems (but not all!) was missing.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-1-99-12"><title>Version 1.99.12 Prerelease</title>
+ <para>
+ The Windows release! See <xref linkend="windows">. Beware, windows support is still very fresh and untested. Feedback is very welcome.
+ </para>
+ <para>
+ Developers: this version is compatible with 1.99.11 backends.
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Windows 2000 codebase merge completed. This resulted in quite some changes on the Unix end of things, so this may impact reliability
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ODBC backend added for Windows. See <xref linkend="odbc">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ IBM DB2 Universal Database backend available for Linux. See <xref linkend="db2">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone2sql now understands $INCLUDE. Thanks to Amaze Internet for nagging about this
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The SOA Mininum TTL now has a configurable default (<command>soa-minimum-ttl</command>)value to placate the DENIC requirements.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Added a limit on the simultaneous numbers of TCP connections to accept (<command>max-tcp-connections</command>). Defaults to 10.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ When operating in virtual hosting mode (See <xref linkend="virtual">), the additional init.d scripts would not function correctly
+ and interface with other pdns instances.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ PDNS neglected to conserve case on answers. So a query for WwW.PoWeRdNs.CoM would get an answer listing the address of www.powerdns.com.
+ While this did not confuse resolvers, it is better to conserve case. This has semantical concequences for all backends, which the documentation
+ now spells out.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ PostgreSQL backend was case sensitive and returned only answers in case an exact match was found. The Generic PostgreSQL backend is now
+ officially all lower case and zone2sql in PostgreSQL mode enforces this.
+ Documentation has been been updated to reflect the case change. Thanks to Maikel Verheijen of Ladot for
+ spotting this!
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Documentation bug - postgresql create/index statements created a duplicate index. If you've previously copy pasted the commands and
+ not noticed the error, execute <command>CREATE INDEX rec_name_index ON records(name)</command> to remedy. Thanks to Jeff Miller for reporting
+ this. This also lead to depressingly slow 'ANY' lookups for those of you doing benchmarks.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ pdns_control (see <xref linkend="pdnscontrol">) now opens the local end of its socket in <filename>/tmp</filename> instead of next to the
+ remote socket (by default <filename>/var/run</filename>). This eases the way for allowing non-root access to pdns_control. When running chrooted
+ (see <xref linkend="security">), the local socket again moves back to <filename>/var/run</filename>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ pdns_control now has a 'version' command. See <xref linkend="pdnscontrol">.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+ <sect2 id="changelog-1-99-11"><title>Version 1.99.11 Prerelease</title>
+ <para>
+ This release is important because it is the first release which is accompanied by an Open Source Backend Development Kit, allowing external
+ developers to write backends for PDNS. Furthermore, a few bugs have been fixed:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Lines with only whitespace in zone files confused PDNS (thanks Henk Wevers)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ PDNS did not properly parse TTLs with symbolic sufixes in zone files, ie 2H instead of 7200 (thanks Henk Wevers)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-1-99-10"><title>Version 1.99.10 Prerelease</title>
+ <para>
+ IMPORTANT: there has been a tiny license change involving free public webbased dns hosting, check out the changes before deploying!
+ </para>
+ <para>
+ PDNS is now feature complete, or very nearly so. Besides adding features, a lot of 'fleshing out' work is done now. There is an important
+ performance bug fix which may have lead to disappointing benchmarks - so if you saw any of that, please try either this version or 1.99.8 which
+ also does not have the bug.
+ </para>
+ <para>
+ This version has been very stable for us on multiple hosts, as was 1.99.9.
+ </para>
+ <para>
+ PostgreSQL users should be aware that while 1.99.10 works with the schema as presented in earlier versions, advanced features
+ such as master or slave support will not work unless you create the new 'domains' table as well.
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Wildcard AAAA queries sometimes received an NXDOMAIN error where they should have gotten an empty NO ERROR. Thanks to Jeroen Massar
+ for spotting this on the .TK TLD!
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Do not disable the packetcache for 'recursion desired' packets unless a recursor was configured. Thanks to Greg Schueler for noticing this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A failing backend would not be reinstated. Thanks to 'Webspider' for discovering this problem with PostgreSQL connections that die after
+ prolonged inactivity.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Fixed loads of IPv6 transport problems. Thanks to Marco Davids and others for testing. Considered ready for production now.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <command>Zone2sql</command> printed a debugging statement on range $GENERATE commands. Thanks to Rene van Valkenburg for spotting this.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ PDNS can now act as a master, sending out notifications in case of changes and allowing slaves to AXFR. Big rewording of replication support,
+ domains are now either 'native', 'master' or 'slave'. See <xref linkend="replication"> for lots of details.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>Zone2sql</command> in PostgreSQL mode now populates the 'domains' table for easy master, slave or native replication support.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Ability to disable those annoying Windows DNS Dynamic Update messages from appearing in the log. See <function>log-failed-updates</function>
+ in <xref linkend="all-settings">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Ability to run on IPv6 transport only
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Logging can now happen under a 'facility' so all PDNS messages appear in their own file. See <xref linkend="syslog">.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Different OS releases of PDNS now get different install path defaults. Thanks to Mark Lastdrager for nagging about this and to Nero Imhard and
+ Frederique Rijsdijk for suggesting saner defaults.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Infrastructure for 'also-notify' statements added.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-1-99-9"><title>Version 1.99.9 Early Access Prerelease</title>
+ <para>
+ This is again a feature and an infrastructure release. We are nearly feature complete and will soon start
+ work on the backends to make sure that they are all master, slave and 'superslave' capable.
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ PDNS sometimes sent out duplicate replies for packets passed to the recursing backend. Mostly a problem on SMP systems. Thanks to Mike Benoit
+ for noticing this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Out-of-bailiwick CNAMES (ie, a CNAME to a domain not in PDNS) caused a 'ServFail' packet in 1.99.8, indicating failure, leading to hosts not
+ resolving. Thanks to Martin Gillstrom for noticing this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone2sql balked at zones editted under operating sytems terminating files with ^Z (Windows). Thanks Brian Willcott for reporting this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ PostgreSQL backend logged the password used to connect. Now only does so in case of failure to connect. Thanks to 'Webspider' for noticing this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Debian unstable distribution wrongly depended on home compiled PostgreSQL libraries. Thanks to Konrad Wojas for noticing this.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Features:
+ <itemizedlist>
+ <listitem>
+ <para>
+ When operating as a slave, AAAA records are now supported in the zone. They were already supported in master zones.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ IPv6 transport support - PDNS can now listen on an IPv6 socket using the <command>local-ipv6</command> setting.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Very silly randombackend added which appears in the documentation as a sample backend. See <xref linkend="backend-writers-guide">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ When transferring a slave zone from a master, out of zone data is now rejected. Malicious operators might try to insert bad records otherwise.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 'Supermaster' support for automatic provisioning from masters. See <xref linkend="supermaster">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Recursing backend can now live on a non-standard (!=53) port. See <xref linkend="recursion">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Slave zone retrieval is now queued instead of immediate, which scales better and is more resilient to temporary failures.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>max-queue-length</command> parameter. If this many packets are queued for database attention, consider the situation hopeless and
+ respawn.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Internal:
+ <itemizedlist>
+ <listitem>
+ <para>
+ SOA records are now 'special' and each backend can optionally generate them in special ways. PostgreSQL backend does so
+ when operating as a slave.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Writing backends is now a lot easier. See <xref linkend="backend-writers-guide">.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Added Bindbackend to internal regression tests, confirming that it is compliant.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2 id="changelog-1-99-8"><title>Version 1.99.8 Early Access Prerelease</title>
+ <para>
+ A lot of infrastructure work gearing up to 2.0. Some stability bugs fixed and a lot of new features.
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Bindbackend was overly complex and crashed on some systems on startup. Simplified launch code.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SOA fields were not always properly filled in, causing default values to go out on the wire
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Obscure bug triggered by malicious packets (we know who you are) in SOA finding code fixed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Magic serial number calculation contained a double free leading to instability.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Standards violation, questions for domains for which PDNS was unauthoritative now get a SERVFAIL answer.
+ Thanks to the IETF Namedroppers list for helping out with this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Slowly launching backends were being relaunched at a great rate when queries were coming in while launching backends.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ MySQL-on-unix-domain-socket on SMP systems was overwhelmed by the quick connection rate on launch, inserted a small 50ms delay.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Some SMP problems appear to be compiler related. Shifted to GCC 3.0.4 for Linux.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Ran ispell on documentation.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Feature enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Recursing backend. See <xref linkend="recursion">. Allows recursive and authoritative DNS on the same IP address.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="naptr">NAPTR support</link>, which is especially useful for the ENUM/E.164 community.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone transfers can now be allowed per <link linkend="allow-axfr-ips">netmask instead of only per IP address</link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Preliminary support for slave operation included. Only for the adventurous right now! See <xref linkend="slave">
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All record types now documented, see <xref linkend="types">.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <sect3><title>Known bugs</title>
+ <para>
+ Wildcard CNAMES do not work as they do with bind.
+ </para>
+ <para>
+ Recursion sometimes sends out duplicate packets (fixed in 1.99.9 snapshots)
+ </para>
+ <para>
+ Some stability issues which are caught by the guardian
+ </para>
+ </sect3>
+ <sect3><title>Missing features</title>
+ <para>
+ Features present in this document, but disabled or withheld from the current release:
+ <itemizedlist>
+ <listitem>
+ <para>
+ gmysqlbackend, oraclebackend
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </para>
+ </sect3>
+
+ </sect2>
+ <sect2 id="changelog-1-99-7"><title>Version 1.99.7 Early Access Prerelease</title>
+ <para>
+ Named.conf parsing got a lot of work and many more bind configurations can now be parsed. Furthermore, error reporting was improved.
+ Stability is looking good.
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Bind parser got confused by filenames with underscores and colons.
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ Bind parser got confused by spaces in quoted names
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ FreeBSD version now stops and starts when instructed to do so.
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ Wildcards were off by default, which violates standards. Now on by default.
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ --oracle was broken in zone2sql
+ </para
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Feature enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Line number counting goes on as it should when including files in named.conf
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Added --no-config to enable users to start the pdns daemon without parsing the configuration file.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ zone2sql now has --bare for unformatted output which can be used to generate insert statements for different database layouts
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ zone2sql now has --gpgsql, which is an alias for --mysql, to output in a format useful for the default Generic PgSQL backend
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ zone2sql is now documented.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <sect3><title>Known bugs</title>
+ <para>
+ Wildcard CNAMES do not work as they do with bind.
+ </para>
+ </sect3>
+ <sect3><title>Missing features</title>
+ <para>
+ Features present in this document, but disabled or withheld from the current release:
+ <itemizedlist>
+ <listitem>
+ <para>
+ gmysqlbackend, oraclebackend
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Some of these features will be present in newer releases.
+ </para>
+ </sect3>
+
+ </sect2>
+ <sect2><title>Version 1.99.6 Early Access Prerelease</title>
+ <para>
+ This version is now running on dns-eu1.powerdns.net and working very well for us. But please remain cautious before
+ deploying!
+ </para>
+ <para>
+ Bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Webserver neglected to show log messages
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ TCP question/answer miscounted multiple questions over one socket. Fixed misnaming of counter
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ Packetcache now detects clock skew and times out entries
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ named.conf parser now reports errors with line number and offending token
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Filenames in named.conf can now contain :
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Feature enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ The webserver now by default does not print out configuration statements, which might contain database backends. Use
+ <command>webserver-print-arguments</command> to restore the old behaviour.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Generic PostgreSQL backend is now included. Still rather beta.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <sect3><title>Known bugs</title>
+ <para>
+ FreeBSD version does not stop when requested to do so.
+ </para>
+ <para>
+ Wildcard CNAMES do not work as they do with bind.
+ </para>
+ </sect3>
+ <sect3><title>Missing features</title>
+ <para>
+
+ Features present in this document, but disabled or withheld from the current release:
+ <itemizedlist>
+ <listitem>
+ <para>
+ gmysqlbackend, oraclebackend
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Some of these features will be present in newer releases.
+ </para>
+ </sect3>
+
+ </sect2>
+ <sect2><title>Version 1.99.5 Early Access Prerelease</title>
+ <para>
+ The main focus of this release is stability and TCP improvements. This is the first release PowerDNS-the-company actually considers for running
+ on its production servers!
+ </para>
+ <para>
+ Major bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Zone2sql received a floating point division by zero error on named.confs with less than 100 domains.
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ Huffman encoder failed without specific error on illegal characters in a domain
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ Fixed huge memory leaks in TCP code.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Removed further file descriptor leaks in guardian respawning code
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Pipebackend was too chatty.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ pdns_server neglected to close fds 0, 1 & 2 when daemonizing
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Feature enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ bindbackend can be instructed not to check the ctime of a zone by specifying <command>bind-check-interval=0</command>,
+ which is also the new default.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>pdns_server --list-modules</command> lists all available modules.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Performance enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ TCP code now only creates a new database connection for AXFR.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ TCP connections timeout rather quickly now, leading to less load on the server.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <sect3><title>Known bugs</title>
+ <para>
+ FreeBSD version does not stop when requested to do so.
+ </para>
+ <para>
+ Wildcard CNAMES do not work as they do with bind.
+ </para>
+ </sect3>
+ <sect3><title>Missing features</title>
+ <para>
+
+ Features present in this document, but disabled or withheld from the current release:
+ <itemizedlist>
+ <listitem>
+ <para>
+ gmysqlbackend, oraclebackend, gpgsqlbackend
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Some of these features will be present in newer releases.
+ </para>
+ </sect3>
+
+ </sect2>
+ <sect2><title>Version 1.99.4 Early Access Prerelease</title>
+ <para>
+ A lot of new named.confs can now be parsed, zone2sql & bindbackend have gained features and stability.
+ </para>
+ <para>
+ Major bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Label compression was not always enabled, leading to large reply packets sometimes.
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ Database errors on TCP server lead to a nameserver reload by the guardian.
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ MySQL backend neglected to close its connection properly.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ BindParser miss parsed some IP addresses and netmasks.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Truncated answers were also truncated on the packetcache, leading to truncated TCP answers.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Feature enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Zone2sql and the bindbackend now understand the Bind $GENERATE{} syntax.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone2sql can optionally gloss over non-existing zones with <command>--on-error-resume-next</command>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone2sql and the bindbackend now properly expand @ also on the right hand side of records.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Zone2sql now sets a default TTL.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ DNS UPDATEs and NOTIFYs are now logged properly and sent the right responses.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Performance enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ 'Fancy records' are no longer queried for on ANY queries - this is a big speedup.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <sect3><title>Known bugs</title>
+ <para>
+ FreeBSD version does not stop when requested to do so.
+ </para>
+ <para>
+ Zone2sql refuses named.confs with less than 100 domains.
+ </para>
+ <para>
+ Wildcard CNAMES do not work as they do with bind.
+ </para>
+ </sect3>
+ <sect3><title>Missing features</title>
+ <para>
+
+ Features present in this document, but disabled or withheld from the current release:
+ <itemizedlist>
+ <listitem>
+ <para>
+ gmysqlbackend, oraclebackend, gpgsqlbackend
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Some of these features will be present in newer releases.
+ </para>
+ </sect3>
+
+ </sect2>
+
+ <sect2><title>Version 1.99.3 Early Access Prerelease</title>
+ <para>
+ The big news in this release is the BindBackend which is now capable of parsing many more named.conf Bind configurations.
+ Furthermore, PDNS has successfully parsed very large named.confs with large numbers of small domains, as well as small numbers of
+ large domains (TLD).
+ </para>
+ <para>
+ Zone transfers are now also much improved.
+ </para>
+ <para>
+ Major bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ zone2sql leaked file descriptors on each domain, used wrong Bison recursion leading to
+ parser stack overflows. This limited the amount of domains that could be parsed to 1024.
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ zone2sql can now read all known zonefiles, with the exception of those containing $GENERATE
+ </para
+ </listitem>
+ <listitem>
+ <para>
+ Guardian relaunching a child lost two file descriptors
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Don't die on a connection reset by peer during zone transfer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Webserver does not crash anymore on ringbuffer resize
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Feature enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ AXFR can now be disabled, and re-enabled per IP address
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ --help accepts a parameter, will then show only help items with that prefix.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ zone2sql now accepts a --zone-name parameter
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ BindBackend maturing - 9500 zones parsed in 3.5 seconds. No longer case sensitive.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Performance enhancements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Implemented RFC-breaking AXFR format (which is the industry standard). Zone transfers now zoom along
+ at wirespeed (many megabits/s).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <sect3><title>Known bugs</title>
+ <para>
+ FreeBSD version does not stop when requested to do so.
+ </para>
+ <para>
+ BindBackend cannot parse zones with $GENERATE statements.
+ </para>
+ </sect3>
+ <sect3><title>Missing features</title>
+ <para>
+
+ Features present in this document, but disabled or withheld from the current release:
+ <itemizedlist>
+ <listitem>
+ <para>
+ gmysqlbackend, oraclebackend, gpgsqlbackend
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Some of these features will be present in newer releases.
+ </para>
+ </sect3>
+
+ </sect2>
+
+ <sect2><title>Version 1.99.2 Early Access Prerelease</title>
+ <para>
+ Major bugs fixed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Database backend reload does not hang the daemon anymore
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Buffer overrun in local socket address initialisation may have caused binding problems
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ setuid changed the uid to the gid of the selected user
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ zone2sql doesn't coredump on invocation anymore. Fixed lots of small issues.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Don't parse configuration file when creating configuration file. This was a problem with reinstalling.
+ </para>
+ </listitem>
+ </itemizedlist>
+ Performance improvements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ removed a lot of unnecessary gettimeofday calls
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ removed needless select(2) call in case of listening on only one address
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ removed 3 useless syscalls in the fast path
+ </para>
+ </listitem>
+ </itemizedlist>
+ Having said that, more work may need to be done. Testing on a 486 saw packet rates in a simple setup
+ (question/wait/answer/question..) improve from 200 queries/second to over 400.
+ </para>
+ <para>
+ Usability improvements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Fixed error checking in init.d script (<command>show</command>, <command>mrtg</command>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Added 'uptime' to the mrtg output
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ removed further GNUisms from installer and init.d scripts for use on FreeBSD
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Debian package and apt repository, thanks to Wichert Akkerman.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ FreeBSD /usr/ports, thanks to Peter van Dijk (in progress).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
+ </para>
+ <para>
+ Stability may be an issue as well as performance. This version has a tendency to log a bit too much which slows
+ the nameserver down a lot.
+ </para>
+ <sect3><title>Known bugs</title>
+ <para>
+ Decreasing a ringbuffer on the website is a sure way to crash the daemon. Zone2sql, while improved, still
+ has problems with a zone in the following format:
+
+ <programlisting>
+name IN A 1.2.3.4
+ IN A 1.2.3.5
+ </programlisting>
+
+ To fix, add 'name' to the second line.
+ </para>
+ <para>
+ Zone2sql does not close filedescriptors.
+ <para>
+
+ <para>
+ FreeBSD version does not stop when requested via the init.d script.
+ <para>
+
+ </sect3>
+ <sect3><title>Missing features</title>
+ <para>
+ Features present in this document, but disabled or withheld from the current release:
+ <itemizedlist>
+ <listitem>
+ <para>
+ gmysqlbackend, oraclebackend, gpgsqlbackend
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ fully functioning bindbackend - will try to parse named.conf, but probably fail
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Some of these features will be present in newer releases.
+
+
+ </para>
+ </sect3>
+ </sect2>
+ <sect2><title>Version 1.99.1 Early Access Prerelease</title>
+ <para>
+ This is the first public release of what is going to become PDNS 2.0. As such, it is not of production quality.
+ Even PowerDNS-the-company does not run this yet.
+ </para>
+ <para>
+ Stability may be an issue as well as performance. This version has a tendency to log a bit too much which slows
+ the nameserver down a lot.
+ </para>
+ <sect3><title>Known bugs</title>
+ <para>
+ Decreasing a ringbuffer on the website is a sure way to crash the daemon. Zone2sql is very buggy.
+ </para>
+ </sect3>
+ <sect3><title>Missing features</title>
+ <para>
+ Features present in this document, but disabled or withheld from the current release:
+ <itemizedlist>
+ <listitem>
+ <para>
+ gmysqlbackend, oraclebackend, gpgsqlbackend
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ fully functioning bindbackend - will not parse configuration files
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Some of these features will be present in newer releases.
+
+
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+ <sect1 id="thanks-to"><title>Acknowledgements</title>
+ <para>
+ PowerDNS is grateful for the help of the following people or institutions:
+ <itemizedlist>
+ <listitem><para>Dave Aaldering</para></listitem>
+ <listitem><para>Wichert Akkerman</para></listitem>
+ <listitem><para>Antony Antony</para></listitem>
+ <listitem><para>Mike Benoit (NetNation Communication Inc.)</para></listitem>
+ <listitem><para>Peter van Dijk</para></listitem>
+ <listitem><para>Koos van den Hout</para></listitem>
+ <listitem><para>Andre Koopal</para></listitem>
+ <listitem><para>Eric Veldhuyzen</para></listitem>
+ <listitem><para>Paul Wouters</para></listitem>
+ <listitem><para>Thomas Wouters</para></listitem>
+ <listitem><para>IETF Namedroppers mailinglist</para></listitem>
+ </itemizedlist>
+ Thanks!
+ </para>
+ <para>
+ (these people don't share the blame for any errors or mistakes in powerdns - those are all ours)
+ </para>
+ </Chapter>
+
+<Chapter id="installing-on-unix">
+<Title>Installing on Unix</Title>
+
+<Para>
+After unpacking the PDNS distribution the files need to be moved to
+appropriate locations.
+</Para>
+
+<Para>
+PDNS can be installed in a variety of directories, which can easily be
+customised to local policy. Two ways are available - manual and via a menu.
+</Para>
+
+<Para>
+The menu is invoked by executing the './choosepaths' script and answering the
+questions. The manual way involves editing the 'pathconfig' file. The choice
+is up to you.
+</Para>
+
+<Para>
+After deciding paths, change to root and execute the 'installer' script.
+This will:
+ <itemizedlist>
+ <listitem>
+ <para>Configure the PowerDNS binary so it knows where the configuration directory is</para>
+ </listitem>
+ <listitem>
+ <para>If necessary, create the configuration directory</para>
+ </listitem>
+ <listitem>
+ <para>Write sample configuration file (not overwriting existing one)</para>
+ </listitem>
+ <listitem>
+ <para>Write a SysV-style init.d script in the configured directory</para>
+ </listitem>
+ <listitem>
+ <para>Move binaries and libraries to the configured places</para>
+ </listitem>
+ </itemizedlist>
+ </Para>
+
+ <sect1 id="problems">
+ <title>Possible problems at this point</title>
+ <para>
+ At this point some things may have gone wrong. Typical errors include:
+ <variablelist>
+ <varlistentry>
+ <term><errortype>error while loading shared libraries: libstdc++.so.x: cannot open shared object file: No such file or directory</errortype></term>
+ <listitem>
+ <para>
+ Errors looking like this indicate a mismatch between your PDNS distribution and your Unix operating system. Download the static PDNS
+ distribution for your operating system and try again. Please contact <email>pdns@powerdns.com</email> if this is impractical.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ </variablelist>
+ </para>
+ </sect1>
+
+<Sect1 id="testing">
+<Title>Testing your install</Title>
+ <para>
+ After installing, it is a good idea to test the basic functionality of the software before configuring database backends.
+ For this purpose, PowerDNS contains the 'bindbackend' which has a domain built in example.com, which is
+ officially reserved for testing.
+
+ To test, edit <filename>pdns.conf</filename> and add the following if not already present:
+
+ <screen>
+ launch=bind
+ bind-example-zones
+ </screen>
+
+ This configures powerdns to 'launch' the bindbackend, and enable the example zones. To fire up PDNS in testing mode, execute:
+ <command>/etc/init.d/pdns monitor</command>, where you may have to substitute the location of your SysV init.d location you
+ specified earlier.
+
+ In monitor mode, the pdns process runs in the foreground and is very verbose, which is perfect for testing your install.
+
+ If everything went all right, you can query the example.com domain like this:
+ <screen>
+ <command>host www.example.com 127.0.0.1</command>
+ </screen>
+ www.example.com should now have IP address 1.2.3.4. The <command>host</command> command can usually be found in the dnsutils
+ package of your operating system. Alternate command is: <command>dig www.example.com A @127.0.0.1</command> or even
+ <command>nslookup www.example.com 127.0.0.1</command>, although nslookup is not advised for DNS diagnostics.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ example.com SOA record
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ example.com NS record pointing to ns1.example.com
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ example.com NS record pointing to ns2.example.com
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ example.com MX record pointing to mail.example.com
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ example.com MX record pointing to mail1.example.com
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ mail.example.com A record pointing to 4.3.2.1
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ mail1.example.com A record pointing to 5.4.3.2
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ns1.example.com A record pointing to 4.3.2.1
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ns2.example.com A record pointing to 5.4.3.2
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ host-0 to host-9999.example.com A record pointing to 2.3.4.5
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ When satisfied that basic functionality is there, type <command>QUIT</command> to exit the monitor mode.
+ The adventurous may also type <command>SHOW *</command> to see some internal statistics.
+
+ In case of problems, you will want to read the following section.
+ </para>
+
+ <sect2>
+ <title>Typical errors</title>
+ <para>
+ At this point some things may have gone wrong. Typical errors include:
+ <variablelist>
+ <varlistentry>
+ <term><errortype>binding to UDP socket: Address already in use</errortype></term>
+ <listitem>
+ <para>
+ This means that another nameserver is listening on port 53 already. You can resolve this problem
+ by determining if it is safe to shutdown the nameserver already present, and doing so. If uncertain,
+ it is also possible to run PDNS on another port. To do so, add <command>local-port=5300</command> to
+ <filename>pdns.conf</filename>, and try again. This however implies that you can only test your nameserver
+ as clients expect the nameserver to live on port 53.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errortype>binding to UDP socket: Permission denied</errortype></term>
+ <listitem>
+ <para>
+ You must be superuser in order to be able to bind to port 53. If this is not a possibility,
+ it is also possible to run PDNS on another port. To do so, add <command>local-port=5300</command> to
+ <filename>pdns.conf</filename>, and try again. This however implies that you can only test your nameserver
+ as clients expect the nameserver to live on port 53.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errortype>Unable to launch, no backends configured for querying</errortype></term>
+ <listitem>
+ <para>
+ PDNS did not find the <command>launch=bind</command> instruction in pdns.conf.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </sect2>
+</Sect1>
+
+ <sect1 id="pdns-on-unix">
+ <Title>Running PDNS on unix</Title>
+
+ <Para>
+ PDNS is normally controlled via a SysV-style init.d script, often located in <filename>/etc/init.d</filename> or
+ <filename>/etc/rc.d/init.d</filename>. This script accepts the following commands:
+ <variablelist>
+ <varlistentry>
+ <term>monitor</term>
+ <listitem>
+ <para>
+ Monitor is a special way to view the daemon. It executes PDNS in the foreground with
+ a lot of logging turned on, which helps in determining startup problems.
+
+ Besides running in the foreground, the raw PDNS control socket is made available. All external
+ communication with the daemon is normally sent over this socket. While useful, the control console
+ is not an officially supported feature. Commands which work are: <command>QUIT</command>, <command>SHOW *</command>,
+ <command>SHOW varname</command>, <command>RPING</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>start</term>
+ <listitem>
+ <para>
+ Start PDNS in the background. Launches the daemon but makes no special effort to determine success,
+ as making database connections may take a while. Use <command>status</command> to query success. You
+ can safely run <command>start</command> many times, it will not start additional PDNS instances.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>restart</term>
+ <listitem>
+ <para>
+ Restarts PDNS if it was running, starts it otherwise.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>status</term>
+ <listitem>
+ <para>
+ Query PDNS for status. This can be used to figure out if a launch was successful.
+ The status found is prefixed by the PID of the main PDNS process.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>stop</term>
+ <listitem>
+ <para>
+ Requests that PDNS stop. Again, does not confirm success. Success can be ascertained with the <command>status</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>dump</term>
+ <listitem>
+ <para>
+ Dumps a lot of statistics of a running PDNS daemon. It is also possible to single out specific variable by using
+ the <command>show</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>show variable</term>
+ <listitem>
+ <para>
+ Show a single statistic, as present in the output of the <command>dump</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>mrtg</term>
+ <listitem>
+ <para>
+ See the performance monitoring <xref linkend="monitoring">.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </Para>
+
+ </sect1>
+</Chapter>
+
+<Chapter id="windows">
+ <Title>Installing on Microsoft Windows</Title>
+ <para>
+ <note>
+ <para>
+ PowerDNS support for Windows is, as of 1.99.12, very recent and therefore quite 'beta'. For reliability, we currently advise the use of
+ the Unix versions. Furthermore there is no support for master or slave operation in the ODBC backend, which is the only one provided currently.
+ This will be fixed soon.
+ </para>
+ </note>
+ </para>
+ <para>
+ As of 1.99.12, PowerDNS supports Windows natively. PDNS can act as an NT service and works with any ODBC drivers you may have.
+ </para>
+ <para>
+ To install PowerDNS for Windows you should check if your PC meets the following requirements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ A PC running Microsoft NT (with a recent servicepack and at least mdac 2.5), 2000 or XP.
+ </para>
+ </listitem>
+ <listitem>
+ <para>An ODBC source containing valid zone information (an example MS Access database is supplied in the form of <filename>powerdns.mdb</filename>).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ If your system meets these requirements, download the installer from <ulink url="http://www.powerdns.com/pdns/">http://www.powerdns.com/pdns/</ulink>.
+ After downloading the file begin the installation procedure by starting <filename>powerdns-VERSION.exe</filename>.
+
+ </para>
+
+ <para>
+ After installing the software you should create a valid ODBC source.
+ To do this you have open the ODBC sources dialog: <filename>Start->Settings->Control Panel->Administrative Tools->Data Sources (ODBC)</filename>.
+ </para>
+
+ <para>
+ We'll use the example zone database that is included in the installation to explain how to create a source.\r
+ </para>\r
+\r
+ <para>\r
+ When you are in the ODBC sources dialog you activate the <filename>System DSN</filename> tab. \r
+ <note><para>It is important to create a System DSN instead of an User DNS, otherwise the ODBC backend cannot function.</para></note>\r
+ </para>\r
+
+ <para>
+ Press <filename>Add...</filename>, then you have to select a driver.\r
+ </para>\r
+\r
+ <para>
+ Select <filename>Microsoft Access Driver (*.mdb)</filename>.
+ </para>
+
+ <para>
+ Use <filename>PowerDNS</filename> as the DSN name, you can leave the description empty.
+ </para>
+
+ <para>
+ Then press <filename>Select...</filename> to select the database (ie. <filename>C:\Program Files\PowerDNS\powerdns.mdb</filename>).
+ </para>
+
+ <para>
+ Press <function>Ok</function> and you should be done.
+ </para>
+ \r
+ <para>
+ For more information, see <xref linkend="odbc">.
+ </para>
+\r
+ <sect1 id="windows-configuration">\r
+ <title>Configuring PDNS on Microsoft Windows</title>\r
+\r
+ <para>\r
+ You can specify program parameters in the <filename>pdns.conf</filename> file\r
+ which should be located in pdns directory (ie. <filename>C:\Program Files\PowerDNS\</filename>).\r
+ </para>\r
+\r
+ <para>\r
+ To see a list of available parameters you can run <filename>pdns.exe --help</filename>.\r
+ </para>\r
+\r
+ <note>\r
+ <para>\r
+ A default configuration file has been supplied with the installation.\r
+ </para>\r
+ </note>\r
+\r
+ </sect1>\r
+
+ <sect1 id="running-on-windows">
+ <title>Running PDNS on Microsoft Windows</title>
+
+ <para>
+ If you installed pdns on Windows NT, 2000 or XP you can run pdns as a service.\r
+ </para>
+\r
+ <para>
+ This is how to do it:
+ Go to services (<filename>Start->Settings->Control Panel->Administrative Tools->Services</filename>) and locate <filename>PDNS</filename> (you should have registered the program as a NT service during the installation).
+ </para>
+
+ <para>
+ Double-click on <filename>PDNS</filename> and push the start button. You should now see a progress bar that gets to the end and see the status change to 'Started'.
+ </para>
+
+ <para>
+ This is the same as starting pdns like this:
+ <filename>pdns.exe --ntservice</filename>
+ </para>
+
+ <para>
+ If you haven't registered pdns as a service during the installation you can do so from the commandline by starting pdns like this:
+ <filename>pdns.exe --register-service</filename>
+ </para>
+
+ <para>
+ You can run pdns as a standard console program by using a command prompt or <filename>Start->Run...</filename>
+ This way you can specify command-line parameters (see the documentation for commandline options).
+ </para>
+
+ <para>
+ If you chose to add a PowerDNS menu to the start menu during the installation you can start pdns using the pdns shortcut in that menu.
+ </para>
+
+ </sect1>
+ </Chapter>
+
+ <Chapter id="configuring-db-connection">
+ <title>Configure database connectivity</title>
+ <para>
+ The default PDNS distribution comes with a simple MySQL backend built in, which we will now use for
+ demonstrating database connectivity. This backend is called 'mysql', and needs to be configured
+ in <filename>pdns.conf</filename>. Add the following lines, adjusted for your local setup:
+
+ <screen>
+ launch=mysql
+ mysql-host=127.0.0.1
+ mysql-user=root
+ mysql-dbname=pdnstest
+ </screen>
+
+ Remove any earlier <command>launch</command> statements. Also remove the <command>bind-example-zones</command>
+ statement as the <command>bind</command> module is no longer launched.
+ </para>
+ <para>
+ WARNING! Make sure that you can actually resolve the hostname of your database without accessing the database! It is advised to supply
+ an IP address here to prevent chicken/egg problems!
+ </para>
+ <para>
+ Now start PDNS using the monitor command:
+ <screen>
+ # /etc/init.d/pdns monitor
+ (...)
+ 15:31:30 PowerDNS 1.99.0 (Mar 12 2002, 15:00:28) starting up
+ 15:31:30 About to create 3 backend threads
+ 15:31:30 [MySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest'
+ 15:31:30 [MySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest'
+ 15:31:30 [MySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest'
+ </screen>
+
+ This is as to be expected - we did not yet add anything to MySQL for PDNS to read from. At this point you may also see
+ other errors which indicate that PDNS either could not find your MySQL server or was unable to connect to it. Fix these
+ before proceeding.
+ </para>
+ <para>
+ General MySQL knowledge is assumed in this chapter, please do not interpret these commands as DBA advice!
+ </para>
+ <sect1 id="configuring-mysql"><title>Configuring MySQL</title>
+ <para>
+ Connect to MySQL as a user with sufficient privileges and issue the following commands:
+ <screen>
+ # mysql
+ mysql> CREATE DATABASE pdnstest;
+ mysql> use pdnstest;
+
+ mysql> CREATE TABLE records (
+ id int(11) NOT NULL auto_increment,
+ domain_id int(11) default NULL,
+ name varchar(255) default NULL,
+ type varchar(6) default NULL,
+ content varchar(255) default NULL,
+ ttl int(11) default NULL,
+ prio int(11) default NULL,
+ change_date int(11) default NULL,
+ PRIMARY KEY (id),
+ KEY name_index(name),
+ KEY nametype_index(name,type),
+ KEY domainid_index(domain_id)
+ );
+ </screen>
+
+ Now we have a database and an empty table. PDNS should now be able to launch in monitor mode and display no errors:
+
+ <screen>
+ # /etc/init.d/pdns monitor
+ (...)
+ 15:31:30 PowerDNS 1.99.0 (Mar 12 2002, 15:00:28) starting up
+ 15:31:30 About to create 3 backend threads
+ 15:39:55 [MySQLbackend] MySQL connection succeeded
+ 15:39:55 [MySQLbackend] MySQL connection succeeded
+ 15:39:55 [MySQLbackend] MySQL connection succeeded
+ </screen>
+
+ A sample query sent to the database should now return quickly without data:
+ <screen>
+ $ host www.test.com 127.0.0.1
+ www.test.com A record currently not present at localhost
+ </screen>
+
+ And indeed, the control console now shows:
+ <screen>
+ Mar 12 15:41:12 We're not authoritative for 'www.test.com', sending unauth normal response
+ </screen>
+
+ Now we need to add some records to our database:
+ <screen>
+ # mysql pdnstest
+ mysql>
+ INSERT INTO records (domain_id, name, content, type,ttl,prio)
+ VALUES (1,'test.com','localhost ahu@ds9a.nl 1','SOA',86400,NULL);
+ INSERT INTO records (domain_id, name, content, type,ttl,prio)
+ VALUES (1,'test.com','dns-us1.powerdns.net','NS',86400,NULL);
+ INSERT INTO records (domain_id, name, content, type,ttl,prio)
+ VALUES (1,'test.com','dns-eu1.powerdns.net','NS',86400,NULL);
+ INSERT INTO records (domain_id, name, content, type,ttl,prio)
+ VALUES (1,'www.test.com','199.198.197.196','A',120,NULL);
+ INSERT INTO records (domain_id, name, content, type,ttl,prio)
+ VALUES (1,'mail.test.com','195.194.193.192','A',120,NULL);
+ INSERT INTO records (domain_id, name, content, type,ttl,prio)
+ VALUES (1,'localhost.test.com','127.0.0.1','A',120,NULL);
+ INSERT INTO records (domain_id, name, content, type,ttl,prio)
+ VALUES (1,'test.com','mail.test.com','MX',120,25);
+ </screen>
+
+ If we now requery our database, <command>www.test.com</command> should be present:
+ <screen>
+ $ host www.test.com 127.0.0.1
+ www.test.com A 199.198.197.196
+
+ $ host -v -t mx test.com 127.0.0.1
+ Address: 127.0.0.1
+ Aliases: localhost
+
+ Query about test.com for record types MX
+ Trying test.com ...
+ Query done, 1 answer, authoritative status: no error
+ test.com 120 IN MX 25 mail.test.com
+ Additional information:
+ mail.test.com 120 IN A 195.194.193.192
+ </screen>
+
+ To confirm what happened, issue the command <command>SHOW *</command> to the control console:
+ <screen>
+ % show *
+ corrupt-packets=0,latency=0,packetcache-hit=2,packetcache-miss=5,packetcache-size=0,
+ qsize-a=0,qsize-q=0,servfail-packets=0,tcp-answers=0,tcp-queries=0,
+ timedout-packets=0,udp-answers=7,udp-queries=7,
+ %
+ </screen>
+ The actual numbers will vary somewhat. Now enter <command>QUIT</command> and start PDNS as a regular daemon, and check launch status:
+
+ <screen>
+ # /etc/init.d/pdns start
+ pdns: started
+ # /etc/init.d/pdns status
+ pdns: 8239: Child running
+ # /etc/init.d/pdns dump
+ pdns: corrupt-packets=0,latency=0,packetcache-hit=0,packetcache-miss=0,
+ packetcache-size=0,qsize-a=0,qsize-q=0,servfail-packets=0,tcp-answers=0,
+ tcp-queries=0,timedout-packets=0,udp-answers=0,udp-queries=0,
+ </screen>
+
+ You now have a working database driven nameserver! To convert other zones already present, use the <command>zone2sql</command>
+ described in Appendix A.
+ </para>
+ <sect2><title>Common problems</title>
+ <para>
+ Most problems involve PDNS not being able to connect to the database.
+ <variablelist>
+ <varlistentry>
+ <term><errortype> Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)</errortype></term>
+ <listitem>
+ <para>
+ Your MySQL installation is probably defaulting to another location for its socket. Can be resolved
+ by figuring out this location (often <filename>/var/run/mysqld.sock</filename>), and specifying it
+ in the configuration file with the <command>mysql-socket</command> parameter.
+ </para>
+ <para>
+ Another solution is to not connect to the socket, but to 127.0.0.1, which can be achieved by specifying
+ <command>mysql-host=127.0.0.1</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errortype>Host 'x.y.z.w' is not allowed to connect to this MySQL server</errortype></term>
+ <listitem>
+ <para>
+ These errors are generic MySQL errors. Solve them by trying to connect to your MySQL database with the MySQL
+ console utility <command>mysql</command> with the parameters specified to PDNS. Consult the MySQL documentation.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+ </chapter>
+
+ <Chapter id="pipebackend-dynamic-resolution">
+ <title>Dynamic resolution using the PipeBackend</title>
+ <para>
+ Also included in the PDNS distribution is the PipeBackend. The PipeBackend is primarily meant for
+ allowing rapid development of new backends without tight integration with PowerDNS. It allows
+ end-users to write PDNS backends in any language. A perl sample is provided.
+
+ The PipeBackend is also very well suited for dynamic resolution of queries. Example applications include
+ DNS based loadbalancing, geo-direction, DNS based failover with low TTLs.
+ </para>
+ <sect1 id="pipe-and-bind"><title>Deploying the PipeBackend with the BindBackend</title>
+ <para>
+ Included with the PDNS distribution is the example.pl backend which has knowledge of the example.com zone, just like
+ the BindBackend. To install both, add the following to your <filename>pdns.conf</filename>:
+ <screen>
+ launch=pipe,bind
+ bind-example-zones
+ pipe-command=location/of/backend.pl
+ </screen>
+ Please adjust the <command>pipe-command</command> statement to the location of the unpacked PDNS distribution. If your backend is slow,
+ raise <command>pipe-timeout</command> from its default of 2000ms.
+
+ Now launch PDNS in monitor mode, and perform some queries. Note the difference with the earlier experiment where only the
+ BindBackend was loaded. The PipeBackend is launched first and thus gets queried first.
+
+ The sample backend.pl script knows about:
+ <itemizedlist>
+ <listitem>
+ <para>
+ webserver.example.com A records pointing to 1.2.3.4, 1.2.3.5, 1.2.3.6
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ www.example.com CNAME pointing to webserver.example.com
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ MBOXFW (mailbox forward) records pointing to powerdns@example.com.
+ See the smtpredir documentation for information about MBOXFW.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ For more information about how to write exciting backends with the PipeBackend, see Appendix A.
+ </para>
+ </sect1>
+ </chapter>
+
+ <Chapter id="monitoring">
+ <title>Logging & Monitoring PDNS performance</title>
+ <para>
+ In a production environment, you will want to be able to monitor PDNS performance. For this purpose, currently
+ two methods are available, the webserver and the init.d
+<command>dump</command>, <command>show</command> and
+ <command>mrtg</command>, commands. Furthermore, PDNS can perform a configurable amount of operational logging. This chapter
+ also explains how to configure syslog for best results.
+ </para>
+ <sect1 id="webserver"><title>Webserver</title>
+ <para>
+ To launch the internal webserver, add a <command>webserver</command> statement to the pdns.conf. This
+ will instruct the PDNS daemon to start a webserver on localhost at port 8081, without password protection.
+ Only local users (on the same host) will be able to access the webserver by default.
+
+ The webserver lists a lot of information about the PDNS process, including frequent queries, frequently failing queries,
+ lists of remote hosts sending queries, hosts sending corrupt queries etc. The webserver does not allow
+ remote management of the daemon.
+
+ The following nameserver related configuration items are available:
+ <variablelist>
+ <varlistentry>
+ <term>webserver</term>
+ <listitem>
+ <para>
+ If set to anything but 'no', a webserver is launched.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>webserver-address</term>
+ <listitem>
+ <para>
+ Address to bind the webserver to. Defaults to 127.0.0.1, which implies that only the local computer
+ is able to connect to the nameserver! To allow remote hosts to connect, change to 0.0.0.0 or the
+ physical IP address of your nameserver.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>webserver-password</term>
+ <listitem>
+ <para>
+ If set, viewers will have to enter this plaintext password in order to gain access to the statistics.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>webserver-port</term>
+ <listitem>
+ <para>
+ Port to bind the webserver to. Defaults to 8081.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </sect1>
+ <sect1 id="init-d-commands"><title>Via init.d commands</title>
+ <para>
+ As mentioned before, the init.d commands <command>dump</command>, <command>show</command> and
+ <command>mrtg</command> fetch data from a running PDNS process. Especially <command>mrtg</command> is powerful -
+ it outputs data in a format that is ready for processing by the MRTG graphing tool.
+ </para>
+ <para>
+ MRTG can make insightful graphics on the performance of your nameserver, enabling the operator to easily spot trends.
+ MRTG can be found on
+ <ulink url="http://people.ee.ethz.ch/~oetiker/webtools/mrtg/mrtg.html">
+ http://people.ee.ethz.ch/~oetiker/webtools/mrtg/mrtg.html
+ </ulink>
+ </para>
+ <para>
+ A sample mrtg.conf:
+ <screen>
+Interval: 5
+WorkDir: /var/www/mrtg
+WriteExpires: yes
+Options[_]: growright,nopercent
+XSize[_]: 600
+
+#---------------------------------------------------------------
+
+Target[udp-queries]: `/etc/init.d/pdns mrtg udp-queries udp-answers`
+Options[udp-queries]: growright,nopercent,perminute
+MaxBytes[udp-queries]: 600000
+AbsMax[udp-queries]: 600000
+Title[udp-queries]: Queries per minute
+PageTop[udp-queries]: <H2>Queries per minute</H2>
+WithPeak[udp-queries]: ymwd
+YLegend[udp-queries]: queries/minute
+ShortLegend[udp-queries]: q/m
+LegendI[udp-queries]: udp-questions
+LegendO[udp-queries]: udp-answers
+
+
+Target[perc-failed]: `/etc/init.d/pdns mrtg udp-queries udp-answers`
+Options[perc-failed]: growright,dorelpercent,perminute
+MaxBytes[perc-failed]: 600000
+AbsMax[perc-failed]: 600000
+Title[perc-failed]: Queries per minute, with percentage success
+PageTop[perc-failed]: <H2>Queries per minute, with percentage success</H2>
+WithPeak[perc-failed]: ymwd
+YLegend[perc-failed]: queries/minute
+ShortLegend[perc-failed]: q/m
+LegendI[perc-failed]: udp-questions
+LegendO[perc-failed]: udp-answers
+
+
+Target[packetcache-rate]: `/etc/init.d/pdns mrtg packetcache-hit udp-queries`
+Options[packetcache-rate]: growright,dorelpercent,perminute
+Title[packetcache-rate]: packetcache hitrate
+MaxBytes[packetcache-rate]: 600000
+AbsMax[packetcache-rate]: 600000
+PageTop[packetcache-rate]: <H2>packetcache hitrate</H2>
+WithPeak[packetcache-rate]: ymwd
+YLegend[packetcache-rate]: queries/minute
+ShortLegend[packetcache-rate]: q/m
+LegendO[packetcache-rate]: total
+LegendI[packetcache-rate]: hit
+
+Target[packetcache-missrate]: `/etc/init.d/pdns mrtg packetcache-miss udp-queries`
+Options[packetcache-missrate]: growright,dorelpercent,perminute
+Title[packetcache-missrate]: packetcache MISSrate
+MaxBytes[packetcache-missrate]: 600000
+AbsMax[packetcache-missrate]: 600000
+PageTop[packetcache-missrate]: <H2>packetcache MISSrate</H2>
+WithPeak[packetcache-missrate]: ymwd
+YLegend[packetcache-missrate]: queries/minute
+ShortLegend[packetcache-missrate]: q/m
+LegendO[packetcache-missrate]: total
+LegendI[packetcache-missrate]: MISS
+
+Target[latency]: `/etc/init.d/pdns mrtg latency`
+Options[latency]: growright,nopercent,gauge
+MaxBytes[latency]: 600000
+AbsMax[latency]: 600000
+Title[latency]: Query/answer latency
+PageTop[latency]: <H2>Query/answer latency</H2>
+WithPeak[latency]: ymwd
+YLegend[latency]: usec
+ShortLegend[latency]: usec
+LegendO[latency]: latency
+LegendI[latency]: latency
+
+Target[recursing]: `/etc/init.d/pdns mrtg recursing-questions recursing-answers`
+Options[recursing]: growright,nopercent,gauge
+MaxBytes[recursing]: 600000
+AbsMax[recursing]: 600000
+Title[recursing]: Recursive questions/answers
+PageTop[recursing]: <H2>Recursing questions/answers</H2>
+WithPeak[recursing]: ymwd
+YLegend[recursing]: queries/minute
+ShortLegend[recursing]: q/m
+LegendO[recursing]: recursing-questions
+LegendI[recursing]: recursing-answers
+
+ </screen>
+ </para>
+ <sect1 id="syslog"><title>Operational logging using syslog</title>
+ <para>(<command>logging-facility</command> is available from 1.99.10 and onwards)</para>
+ <para>
+ This chapter assumes familiarity with syslog, the unix logging device. PDNS logs messages with different levels. The more urgent the
+ message, the lower the 'priority'. By default, PDNS will only log messages with an urgency of 3 or lower, but this can be changed
+ using the <command>loglevel</command> setting in the configuration file. Setting it to 0 will eliminate all logging, 9 will log
+ everything.
+ </para>
+ <para>
+ By default, logging is performed under the 'DAEMON' facility which is shared with lots of other programs. If you regard nameserving
+ as important, you may want to have it under a dedicated facility so PDNS can log to its own files, and not clutter generic files.
+ </para>
+ <para>
+ For this purpose, syslog knows about 'local' facilities, numbered from LOCAL0 to LOCAL7. To move PDNS logging to LOCAL0, add
+ <command>logging-facility=0</command> to your configuration.
+ </para>
+ <para>
+ Furthermore, you may want to have separate files for the differing prioties - preventing lower priority messages from obscuring
+ important ones.
+ </para>
+ <para>
+ A sample syslog.conf might be:
+ <programlisting>
+local0.info -/var/log/pdns.info
+local0.warn -/var/log/pdns.warn
+local0.err /var/log/pdns.err
+ </programlisting>
+ </para>
+ <para>
+ Where local0.err would store the really important messages. For performance and diskspace reasons, it is advised
+ to audit your syslog.conf for statements also logging PDNS activities. Many syslog.confs have a '*.*' statement to
+ /var/log/syslog, which you may want to remove.
+ </para>
+ <para>
+ For performance reasons, be especially certain that no large amounts of synchronous logging take place. Under Linux, this
+ is indicated by filenames not starting with a '-' - indicating a synchronous log, which hurts performance.
+ </para>
+ </sect1>
+ </chapter>
+ <chapter id="security"><title>Security settings & considerations</title>
+ <sect1 id="settings"><title>Settings</title>
+ <para>PDNS has several options to easily allow it to run more securely. Most notable are the <command>chroot</command>,
+ <command>setuid</command> and <command>setgid</command> options which can be specified.</para>
+
+ <sect2><title>Running as a less privileged identity</title>
+ <para>
+ By specifying <command>setuid</command> and <command>setgid</command>, PDNS changes to this identity shortly after
+ binding to the privileged DNS ports. These options are highly recommended. It is suggested that a separate identity
+ is created for PDNS as the user 'nobody' is in fact quite powerful on most systems.
+ </para>
+
+ <para>
+ Both these parameters can be specified either numerically or as real names.
+ You should set these parameters immediately if they are not set!
+ </para>
+ <sect2><title>Jailing the process in a chroot</title>
+ <para>
+ The <command>chroot</command> option secures PDNS to its own directory so that even if it should become compromised and
+ under control of external influences, it will have a hard time affecting the rest of the system.
+ </para>
+ <para>
+ Even though this will hamper hackers a lot, chroot jails have been known to be broken.
+ </para>
+ <para>
+ When chrooting PDNS, take care that backends will be able to get to their files. Many databases need access to a UNIX
+ domain socket which should live within the chroot. It is often possible to hardlink such a socket into the chroot dir.
+ </para><para>
+ The default PDNS configuration is best chrooted to <filename>./</filename>, which boils down to the configured location
+ of the controlsocket.
+ </para><para>
+ This is achieved by adding the following to pdns.conf: <command>chroot=./</command>, and restarting PDNS.
+ </para>
+ </sect2>
+ </sect1>
+ <sect1 id="considerations"><title>Considerations</title>
+ <para>
+ In general, make sure that the PDNS process is unable to execute commands on your backend database.
+ Most database backends will only need SELECT privilege. Take care to not connect to your database as the 'root'
+ or 'sa' user, and configure the chosen user to have very slight privileges.
+ </para>
+ <para>
+ Databases empathic-ally do not need to run on the same machine that runs PDNS! In fact, in benchmarks
+ it has been discovered that having a separate database machine actually improves performance.
+ </para>
+ <para>
+ Separation will enhance your database security highly. Recommended.
+ </para>
+ </sect1>
+ </chapter>
+
+ <chapter id="virtual"><title>Virtual hosting</title>
+ <para>
+ It may be advantageous to run multiple separate PDNS installations on a single host, for example to make sure
+ that different customers cannot affect each others zones. PDNS fully supports running multiple instances on one host.
+ </para>
+ <para>
+ To generate additional PDNS instances, copy the init.d script <filename>pdns</filename> to <filename>pdns-name</filename>,
+ where <filename>name</filename> is the name of your virtual configuration. Must not contain a - as this will confuse the
+ script.
+ </para>
+ <para>
+ When you launch PDNS via this renamed script, it will seek configuration instructions not in <filename>pdns.conf</filename>
+ but in <filename>pdns-name.conf</filename>, allowing for separate specification of parameters.
+ </para>
+ <para>
+ Be aware however that the init.d <command>force-stop</command> will kill all PDNS instances!
+ </para>
+ </chapter>
+
+ <chapter id="performance"><title>Performance related settings</title>
+ <para>
+ Different backends will have different characteristics - some will want to have more parallel
+ instances than others. In general, if your backend is latency bound, like most relational databases are,
+ it pays to open more backends.
+ </para>
+ <para>
+ This is done with the <command>distributor-threads</command> setting. Of special importance is the choice between 1
+ or more backends. In case of only 1 thread, PDNS reverts to unthreaded operation which may be a lot faster, depending
+ on your operating system and architecture.
+ </para>
+ <para>
+ Another very important setting <command>cache-ttl</command>. PDNS caches entire packets it sends out so as to save the
+ time to query backends to assemble all data. The default setting of 10 seconds may be low for high traffic sites, a value of
+ 60 seconds rarely leads to problems.
+ </para>
+ <para>
+ Some PDNS operators set cache-ttl to many hours or even days, and use <command>pdns_control purge</command> to selectively
+ or globally notify PDNS of changes made in the backend. Also look at the Query Cache described in this chapter. It may
+ materially improve your performance.
+ </para>
+ <para>
+ To determine if PDNS is unable to keep up with packets, determine the value of the <command>qsize-q</command> variable.
+ This represents the number of packets waiting for database attention. During normal operations the queue should be small.
+ </para>
+ <para>
+ If it is known that backends will not contain CNAME records, the <command>skip-cname</command> setting can be used to prevent
+ the normally mandatory CNAME lookup that is needed at least once for each DNS query.
+ </para>
+
+ <para>
+ Much the same holds for the <command>wildcards</command> setting. On by default, each non-existent query will lead to a number of additional
+ wildcard queries. If it is known that the backends do not contain wildcard records, performance can be improved by adding <command>wildcards=no</command>
+ to <filename>pdns.conf</filename>.
+ </para>
+ <para>
+ Logging truly kills performance as answering a question from the cache is an order of magnitude less work than logging a
+ line about it. Busy sites will prefer to turn <command>log-dns-details</command> and <command>log-failed-updates</command>
+ off.
+ </para>
+ <sect1 id="packetcache"><title>Packet Cache</title>
+ <para>
+ PDNS by default uses the 'Packet Cache' to recognise identical questions and supply them with identical answers, without any further
+ processing. The default time to live is 10 seconds. It has been observed that the utility of the packet cache increases with the load on
+ your nameserver.
+ </para>
+ <para>
+ Not all backends may benefit from the packetcache. If your backend is memory based and does not lead to context switches, the packetcache
+ may actually hurt performance.
+ </para>
+ <para>
+ The size of the packetcache can be observed with <command>/etc/init.d/pdns show packetcache-size</command>
+ </para>
+ </sect1>
+ <sect1 id="querycache"><title>Query Cache</title>
+ <para>
+ Besides entire packets, PDNS can also cache individual backend queries. Each DNS query leads to a number of backend queries,
+ the most obvious additional backend query is the check for a possible CNAME. So, when a query comes in for the 'A' record for
+ 'www.powerdns.com', PDNS must first check for a CNAME for 'www.powerdns.com'.
+ </para>
+ <para>
+ The Query Cache caches these backend queries, many of which are quite repetitive. PDNS only caches queries with no answer,
+ or with exactly one. In the future this may be expanded but this lightweight solution is very simple and therefore fast.
+ </para>
+ <para>
+ Most gain is made from caching negative entries, ie, queries that have no answer. As these take little memory to store and
+ are typically not a real problem in terms of speed-of-propagation, the default TTL for negative queries is a rather high 60 seconds.
+ </para>
+ <para>
+ This only is a problem when first doing a query for a record, adding it, and immediately doing a query for that record again. It may
+ then take up to 60 seconds to appear. Changes to existing records however do not fall under the negative query ttl (
+ <command>negquery-cache-ttl</command>), but under the generic <command>query-ttl</command> which defaults to 20 seconds.
+ </para>
+ <para>
+ The default values should work fine for many sites. When tuning, keep in mind that the Query Cache mostly saves database access
+ but that the Packet Cache also saves a lot of CPU because 0 internal processing is done when answering a question from the
+ Packet Cache.
+ </para>
+ </sect1>
+ </chapter>
+ <chapter id="migration"><title>Migrating to PDNS</title>
+ <para>
+ Before migrating to PDNS a few things should be considered.
+ <variablelist>
+ <varlistentry>
+ <term>PDNS is not a recursing nameserver on its own</term>
+ <listitem>
+ <para>
+ If PDNS receives a question for which it is not authoritative, it can't go out on the net to figure out an answer. However,
+ because many installations are expected to be both authoritative and recursing, PDNS can use a separate recursing backend
+ to provide non-authoritative answers. See <xref linkend="recursion"> for more details.
+ </para>
+ </listitem></varlistentry>
+ <varlistentry>
+ <term>PDNS does not operate as a 'slave' server with all backends</term>
+ <listitem>
+ <para>
+ Only the PostgreSQL backend has, of version 1.99.9, the ability to act as a slave.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ To migrate, the <command>zone2sql</command> tool is provided.
+ </para>
+ <sect1 id="zone2sql"><title>Zone2sql</title>
+ <para>
+ Zone2sql parses Bind named.conf files and zonefiles and outputs SQL
+ on standard out, which can then be fed to your database.
+ </para>
+ <para>
+ Zone2sql understands the Bind master file extension '$GENERATE' and will also honour '$ORIGIN' and '$TTL'.
+ </para>
+ <para>
+ For backends supporting slave operation (currently only the PostgreSQL backend), there is also an option to keep slave zones as slaves,
+ and not convert them to native operation.
+ </para>
+ <para>
+ By default, zone2sql outputs code suitable for the mysqlbackend, but it can also generate SQL for the Generic PostgreSQL and Oracle backends.
+ The following commands are available:
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>--bare</term>
+ <listitem>
+ <para>
+ Output in a bare format, suitable for further parsing. The output is formatted as follows:
+ <screen>
+ domain_id<TAB>'qname'<TAB>'qtype'<TAB>'content'<TAB>prio<TAB>ttl
+ </screen>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--gmysql</term>
+ <listitem>
+ <para>
+ Output in format suitable for the default configuration of the Generic MySQL backend.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--gpgsql</term>
+ <listitem>
+ <para>
+ Output in format suitable for the default configuration of the Generic PostgreSQL backend.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--help</term>
+ <listitem>
+ <para>
+ List options.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--mysql</term>
+ <listitem>
+ <para>
+ Output in format suitable for the default configuration of the MySQL backend. Default.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--named-conf=...</term>
+ <listitem>
+ <para>
+ Parse this named.conf to find locations of zones.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--on-error-resume-next</term>
+ <listitem>
+ <para>
+ Ignore missing files during parsing. Dangerous.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--oracle</term>
+ <listitem>
+ <para>
+ Output in format suitable for the default configuration of the Generic Oracle backend.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--slave</term>
+ <listitem>
+ <para>
+ Maintain slave status of zones listed in named.conf as being slaves. The default behaviour is to convert all zones
+ to native operation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--startid</term>
+ <listitem>
+ <para>
+ Supply a value for the first domain_id generated. Defaults at 0.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--transactions</term>
+ <listitem>
+ <para>
+ For Oracle and PostgreSQL output, wrap each domain in a transaction for higher speed and integrity.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--verbose</term>
+ <listitem>
+ <para>
+ Be verbose during conversion.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--zone=...</term>
+ <listitem>
+ <para>
+ Parse only this zone file. Conflicts with <command>--named-conf</command> parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--zone-name=...</term>
+ <listitem>
+ <para>
+ When parsing a single zone without $ORIGIN statement, set this as the zone name.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect1>
+ </chapter>
+
+ <chapter id="recursion"><title>Recursion</title>
+
+ <para>(only available from 1.99.8 and onwards)</para>
+ <para>
+ PDNS is an authoritative nameserver. It answers questions with data from its backends. Besides handing out authoritative
+ answers, DNS also needs so called 'recursion', where a nameserver gets a question for which it has no authoritative answer available,
+ necessitating questions to other nameservers.
+ </para>
+ <para>
+ Although PDNS is an authoritative nameserver, a provision has been made to cater for installations that require both authoritative DNS
+ and recursion on one IP address.
+ </para>
+ <para>
+ By specifying the <command>recursor</command> option in the configuration file, questions requiring recursive treatment will be handed over
+ to the IP address specified. An example configuration might be <command>recursor=130.161.180.1</command>, which designates 130.161.180.1 as
+ the nameserver to handle recursive queries.
+ </para>
+ <para>
+ Any recursing nameserver is suitable but we highly advise the use of the DJBDNS dnscache (<ULINK URL="http://cr.yp.to/djbdns/dnscache.html" TYPE="alternate">http://cr.yp.to/djbdns/dnscache.html</ULINK>).
+ </para>
+ <para>
+ Take care not to point <command>recursor</command> to PDNS, which leads to a very tight packet loop!
+ </para>
+ <para>
+ By specifying <command>allow-recursion</command>, recursion can be restricted to netmasks specified. The default is to allow
+ recursion from everywhere. Example: <command>allow-recursion=192.168.0.0/24, 10.0.0.0/8, 1.2.3.4</command>.
+ </para>
+ <sect1 id="recursion-details"><title>Details</title>
+ <para>
+ Questions carry a number of flags. One of these is called 'Recursion Desired'. If PDNS is configured to allow recursion, AND such a flag
+ is seen, AND the IP address of the client is allowed to recurse via PDNS, then the packet is handed to the recursing backend.
+ </para>
+ <para>
+ If a Recursion Desired packet PDNS is configured to allow recursion, but not to the IP address of the client, resolution will proceed
+ as if the RD flag were unset and the answer will indicate that recursion was not available.
+ </para>
+ <para>
+ Recursive questions and answers are not stored in the Packet Cache as recursing backends are generally well equipped to cache questions
+ themselves.
+ </para>
+ <para>
+ It is also possible to use a resolver living on a different port. To do so, specify a recursor like this:
+ <command>recursor=130.161.180.1:5300</command>.
+ </para>
+ <para>
+ If the backend does not answer a question within a large amount of time, this is logged as 'Recursive query for remote 10.96.0.2 with internal id 0
+ was not answered by backend within timeout, reusing id'.
+ </para>
+ </sect1>
+ <sect1 id="lazy-recursion"><title>'Lazy recursion'</title>
+ <para>
+ PowerDNS is an authoritative nameserver. Up to version 2.1, a packet indication that recursion was desired, coming from a host from which
+ recursion was allowed, would be handed sight unseen to the recursing backend. This means that older installations do not have the ability to 'override'
+ the internet with local data. Recursive queries would not be answered from the database.
+ </para>
+ <para>
+ This behaviour sufficed for many users but some installations have a pressing need to override the internet, for example to support recursive
+ queries for fake domains like 'powerdns.office' or '.internal'.
+ </para>
+ <para>
+ As of version 2.1, PowerDNS has a feature called 'lazy recursion' where a packet will only be handed to the recursing backend if it cannot be answered
+ completely from the database. 'Completely' in this case means that the original question has an answer in the local database and any additional processing
+ can also succeed from the database.
+ </para>
+ <para>
+ So for example, if you have the 'your.office' domain and a query comes in for its MX record, you should locally have the 'your.office' MX record
+ as well as the IP address of (for example) 'smtp.your.office'.
+ </para>
+ <para>
+ If any of these conditions fail, your packet is handed to the recursor anyhow. So to benefit from lazy-recursion, be very sure that all
+ data needed is present locally!.
+ </para>
+ <para>
+ To restore pre-2.1 behaviour, specify <command>lazy-recursion=off</command>.
+ </para>
+ </sect1>
+ </chapter>
+ <chapter id="replication"><title>Master/Slave operation & replication</title>
+
+ <para>
+ PDNS offers full master and slave semantics for replicating domain information. Furthermore, PDNS can benefit from native
+ database replication.
+ </para>
+ <sect1 id="native-replication"><title>Native replication</title>
+ <para>
+ Native replication is the default, unless other operation is specifically configured. Native replication basically means that PDNS will
+ not send out DNS update notifications, nor will react to them. PDNS assumes that the backend is taking care of replication unaided.
+ </para>
+ <para>
+ MySQL replication has proven to be very robust and well suited, even over transatlantic connections between badly peering ISPs. Other PDNS
+ users employ Oracle replication which also works very well.
+ </para>
+ <para>
+ To use native replication, configure your backend storage to do the replication and do not configure PDNS to do so.
+ </para>
+ </sect1>
+ <sect1 id="slave"><title>Slave operation</title>
+ <para>
+ On launch, PDNS requests from all backends a list of domains which have not been checked recently for changes. This should happen every
+ '<command>refresh</command>' seconds, as specified in the SOA record. All domains that are unfresh are then checked for changes over at their
+ master. If the <link linkend="soa-type">SOA</link> serial number there is higher, the domain is retrieved and inserted into the database. In
+ any case, after the check the domain is declared 'fresh', and will only be checked again after '<command>refresh</command>' seconds have passed.
+ </para>
+ <para>
+ PDNS also reacts to notifies by immediately checking if the zone has updated and if so, retransfering it.
+ </para>
+ <para>
+ All backends which implement this feature must make sure that they can handle transactions so as to not leave the zone in a half updated state.
+ MySQL configured with either BerkeleyDB or InnoDB meets this requirement, as do PostgreSQL and Oracle. The Bindbackend implements transaction
+ semantics by renaming files if and only if they have been retrieved completely and parsed correctly.
+ </para>
+ <sect2 id=supermaster><title>Supermaster automatic provisioning of slaves</title>
+ <para>
+ PDNS can recognize so called 'supermasters'. A supermaster is a host which is master for domains and for which we are to be a slave. When
+ a master (re)loads a domain, it sends out a notification to its slaves. Normally, such a notification is only accepted if PDNS already
+ knows that it is a slave for a domain.
+ </para>
+ <para>
+ However, a notification from a supermaster carries more persuasion. When PDNS determines that a notification comes from a supermaster and it is
+ is bonafide, PDNS can provision the domain automatically, and configure itself as a slave for that zone.
+ </para>
+ <para>
+ To enable this feature, a backend needs to know about the IP address of the supermaster, and how PDNS will be listed in the set of
+ NS records remotely, and the 'account' name of your supermaster. There is no need to fill this out but it does help keep track of
+ where a domain comes from.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="master"><title>Master operation</title>
+ <para>
+ When operating as a master, PDNS sends out notifications of changes to slaves, which react to these notifications by querying PDNS to see
+ if the zone changed, and transferring its contents if it has. Notifications are a way to promptly propagate zone changes to slaves, as
+ described in RFC 1996.
+ </para>
+ <para>
+ Left open by RFC 1996 is who is to be notified - which is harder to figure out than it sounds. All slaves for this domain must receive a notification
+ but the nameserver only knows the names of the slaves - not the IP addresses, which is where the problem lies. The nameserver itself might
+ be authoritative for the name of its secondary, but not have the data available.
+ </para>
+ <para>
+ To resolve this issue, PDNS tries multiple tactics to figure out the IP addresses of the slaves, and notifies everybody. In contrived configurations
+ this may lead to duplicate notifications being sent out, which shouldn't hurt.
+ </para>
+ <para>
+ Some backends may be able to detect zone changes, others may chose to let the operator indicate which zones have changed and which haven't.
+ Consult the documentation for your backend to see how it processes changes in zones.
+ </para>
+ <para>
+ To help deal with slaves that may have missed notifications, or have failed to respond to them, several override commands are available via
+ the pdns_control tool (<xref linkend="pdnscontrol">):
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>pdns_control notify <command>domain</command></term>
+ <listitem>
+ <para>
+ This instructs PDNS to notify all IP addresses it considers to be slaves of this domain.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pdns_control notify-host <command>domain ip-address</command></term>
+ <listitem>
+ <para>
+ This is truly an override and sends a notification to an arbitrary IP address. Can be used in 'also-notify' situations
+ or when PDNS has trouble figuring out who to notify - which may happen in contrived configurations.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect1>
+ </chapter>
+ <chapter id="fancy-records"><title>Fancy records for seamless email and URL integration</title>
+
+ <para>
+ PDNS also supports so called 'fancy' records. A Fancy Record is actually not a DNS record, but it is translated into one. Currently,
+ two fancy records are implemented, but not very useful without additional unreleased software. For completeness, they are listed here.
+ The software will become available later on and is part of the Express and PowerMail suite of programs.
+ </para>
+ <para>
+ These records imply extra database lookups which has a performance impact. Therefore fancy records are only queried for if they are enabled
+ with the <command>fancy-records</command> command in <filename>pdns.conf</filename>.
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>MBOXFW</term>
+ <listitem>
+ <para>
+ This record denotes an email forward. A typical entry looks like this:
+ <screen>
+ support@yourdomain.com MBOXFW you@yourcompany.com
+ </screen>
+ When PDNS encounters a request for an MX record for yourdomain.com it will, if fancy records are enabled, also check for the existence
+ of an MBOXFW record ending on '@yourdomain.com', in which case it will hand out a record containing the configured
+ <command>smtpredirector</command>. This server should then also be able to access the PDNS database to figure out where mail to
+ support@yourdomain.com should go to.
+ </para>
+ </listitem>
+ <varlistentry>
+ <term>URL</term>
+ <listitem>
+ <para>
+ URL records work in much the same way, but for HTTP. A sample record:
+ <screen>
+ yourdomain.com URL http://somewhere.else.com/yourdomain
+ </screen>
+ A URL record is converted into an A record containing the IP address configured with the <command>urlredirector</command>
+ setting. On that IP address a webserver should live that knows how to redirect yourdomain.com to
+ http://somewhere.else.com/yourdomain.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </chapter>
+ <chapter id="all-settings"><title>Index of all settings</title>
+ <para>
+ All PDNS settings are listed here, excluding those that originate from backends, which are documented in the relevant chapters.
+ <variablelist>
+ <varlistentry>
+ <term><anchor id="allow-axfr-ips">allow-axfr-ips=...</term>
+ <listitem>
+ <para>When not allowing AXFR (disable-axfr), DO allow from these IP addresses or netmasks.
+ </para>
+ </listitem></varlistentry>
+ <varlistentry>
+ <term>allow-recursion=...</term>
+ <listitem>
+ <para>
+ By specifying <command>allow-recursion</command>, recursion can be restricted to netmasks specified. The default is to allow
+ recursion from everywhere. Example: <command>allow-recursion=192.168.0.0/24, 10.0.0.0/8, 1.2.3.4</command>.
+ </para>
+ </listitem></varlistentry>
+ <varlistentry><term>cache-ttl=...</term>
+ <listitem><para>
+ Seconds to store packets in the PacketCache. See <xref linkend="packetcache">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>chroot=...</term>
+ <listitem><para>
+ If set, chroot to this directory for more security. See <xref linkend="security">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>config-dir=...</term>
+ <listitem><para>
+ Location of configuration directory (pdns.conf)
+ </para></listitem></varlistentry>
+ <varlistentry><term>config-name=...</term>
+ <listitem><para>
+ Name of this virtual configuration - will rename the binary image. See <xref linkend="virtual">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>control-console=...</term>
+ <listitem><para>
+ Debugging switch - don't use.
+ </para></listitem></varlistentry>
+ <varlistentry><term>daemon=...</term>
+ <listitem><para>
+ Operate as a daemon
+ </para></listitem></varlistentry>
+ <varlistentry><term>default-soa-name=...</term>
+ <listitem><para>
+ name to insert in the SOA record if none set in the backend
+ </para></listitem></varlistentry>
+ <varlistentry><term>disable-axfr=...</term>
+ <listitem><para>
+ Do not allow zone transfers
+ </para></listitem></varlistentry>
+ <varlistentry><term>disable-tcp=...</term>
+ <listitem><para>
+ Do not listen to TCP queries. Breaks RFC compliance.
+ </para></listitem></varlistentry>
+ <varlistentry><term>distributor-threads=...</term>
+ <listitem><para>
+ Default number of Distributor (backend) threads to start. See <xref linkend="performance">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>fancy-records=...</term>
+ <listitem><para>
+ Process URL and MBOXFW records. See <xref linkend="fancy-records">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>guardian | --guardian=yes | --guardian=no</term>
+ <listitem><para>
+ Run within a guardian process. See <xref linkend="guardian">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>help</term>
+ <listitem><para>
+ Provide a helpful message
+ </para></listitem></varlistentry>
+ <varlistentry><term>launch=...</term>
+ <listitem><para>
+ Which backends to launch and order to query them in. See <xref linkend="modules">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>lazy-recursion=...</term>
+ <listitem><para>
+ On by default as of 2.1. Checks local data first before recursing. See <xref linkend="recursion">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>load-modules=...</term>
+ <listitem><para>
+ Load this module - supply absolute or relative path. See <xref linkend="modules">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>local-address=...</term>
+ <listitem><para>
+ Local IP address to which we bind. You can specify multiple addresses separated by commas or whitespace.
+ </para></listitem></varlistentry>
+ <varlistentry><term>local-port=...</term>
+ <listitem><para>
+ The port on which we listen. Only one port possible.
+ </para></listitem></varlistentry>
+ <varlistentry><term><anchor id="log-failed-updates">log-failed-updates=...</term>
+ <listitem><para>
+ If set to 'no', failed Windows Dynamic Updates will not be logged.
+ </para></listitem></varlistentry>
+ <varlistentry><term><anchor id="log-dns-details">log-dns-details=...</term>
+ <listitem><para>
+ If set to 'no', informative-only DNS details will not even be sent to syslog, improving performance. Available from 2.5
+ and onwards.
+ </para></listitem></varlistentry>
+ <varlistentry><term>logging-facility=...</term>
+ <listitem><para>
+ If set to a a digit, logging is performed under this LOCAL facility. See <xref linkend="syslog">. Available from 1.99.9 and onwards.
+ </para></listitem></varlistentry>
+ <varlistentry><term>loglevel=...</term>
+ <listitem><para>
+ Amount of logging. Higher is more. Do not set below 3
+ </para></listitem></varlistentry>
+ <varlistentry><term>max-queue-length=...</term>
+ <listitem><para>
+ If this many packets are waiting for database attention, consider the situation hopeless and respawn.
+ </para></listitem></varlistentry>
+ <varlistentry><term>module-dir=...</term>
+ <listitem><para>
+ Default directory for modules. See <xref linkend="modules">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>negquery-cache-ttl=...</term>
+ <listitem><para>
+ Seconds to store queries with no answer in the Query Cache. See <xref linkend="querycache">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>no-config</term>
+ <listitem><para>
+ Do not attempt to read the configuration file.
+ </para></listitem></varlistentry>
+ <varlistentry><term>out-of-zone-additional-processing | --out-of-zone-additional-processing=yes | --out-of-zone-additional-processing=no</term>
+ <listitem><para>
+ Do out of zone additional processing
+ </para></listitem></varlistentry>
+ <varlistentry><term>query-cache-ttl=...</term>
+ <listitem><para>
+ Seconds to store queries with an answer in the Query Cache. See <xref linkend="querycache">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>queue-limit=...</term>
+ <listitem><para>
+ Maximum number of miliseconds to queue a query. See <xref linkend="performance">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>query-logging | query-logging=yes | query-logging=no</term>
+ <listitem><para>
+ Hints to a backend that it should log a textual representation of queries it performs. Can be set at runtime.
+ </para></listitem></varlistentry>
+ <varlistentry><term>recursive-cache-ttl=...</term>
+ <listitem><para>
+ Seconds to store recursive packets in the PacketCache. See <xref linkend="packetcache">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>recursor=...</term>
+ <listitem><para>
+ If set, recursive queries will be handed to the recursor specified here. See <xref linkend="recursion">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>setgid=...</term>
+ <listitem><para>
+ If set, change group id to this gid for more security. See <xref linkend="security">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>setuid=...</term>
+ <listitem><para>
+ If set, change user id to this uid for more security. See <xref linkend="security">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>skip-cname | --skip-cname=yes | --skip-cname=no</term>
+ <listitem><para>
+ Do not perform CNAME indirection for each query. Has performance implications. See <xref linkend="security">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>slave-cycle-interval=60</term>
+ <listitem><para>
+ Schedule slave up-to-date checks of domains whose status is unknown every .. seconds. See <xref linkend="fancy-records">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>smtpredirector=...</term>
+ <listitem><para>
+ Our smtpredir MX host. See <xref linkend="fancy-records">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>soa-serial-offset=...</term>
+ <listitem><para>
+ If your database contains single-digit SOA serials and you need to host .DE domains, this setting can help
+ placate their 6-digit SOA serial requirements. Suggested value is to set this to 1000000 which adds 1000000 to all SOA Serials
+ under that offset.
+ </para></listitem></varlistentry>
+ <varlistentry><term>socket-dir=...</term>
+ <listitem><para>
+ Where the controlsocket will live. See <xref linkend="controlsocket">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>strict-rfc-axfrs | --strict-rfc-axfrs=yes | --strict-rfc-axfrs=no</term>
+ <listitem><para>
+ Perform strictly RFC conformant AXFRs, which are slow, but needed to placate some old client tools.
+ </para></listitem></varlistentry>
+ <varlistentry><term>urlredirector=...</term>
+ <listitem><para>
+ Where we send hosts to that need to be url redirected. See <xref linkend="fancy-records">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>webserver | --webserver=yes | --webserver=no</term>
+ <listitem><para>
+ Start a webserver for monitoring. See <xref linkend="monitoring">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>webserver-address=...</term>
+ <listitem><para>
+ IP Address of webserver to listen on. See <xref linkend="monitoring">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>webserver-password=...</term>
+ <listitem><para>
+ Password required for accessing the webserver. See <xref linkend="monitoring">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>webserver-port=...</term>
+ <listitem><para>
+ Port of webserver to listen on. See <xref linkend="monitoring">.
+ </para></listitem></varlistentry>
+ <varlistentry><term>wildcard-url=...</term>
+ <listitem><para>
+ Check for wildcard URL records.
+ </para></listitem></varlistentry>
+ <varlistentry><term>wildcards=...</term>
+ <listitem><para>
+ Honor wildcards in the database. On by default. Turning this off has performance implications, see <xref linkend="performance">.
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+ </chapter>
+ <chapter id="metrics"><title>Index of all internal metrics</title>
+ <para></para>
+ <sect1 id="counters-variables"><title>Counters & variables</title>
+ <para>
+ A number of counters and variables are set during PDNS operation. These can be queried with the init.d
+ <command>dump</command>, <command>show</command> and <command>mrtg</command> commands, or viewed with the
+ webserver.
+
+ <variablelist>
+ <varlistentry>
+ <term>corrupt-packets</term>
+ <listitem><para>Number of corrupt packets received</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>latency</term>
+ <listitem><para>Average number of microseconds a packet spends within PDNS</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>packetcache-hit</term>
+ <listitem><para>Number of packets which were answered out of the cache</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>packetcache-miss</term>
+ <listitem><para>Number of times a packet could not be answered out of the cache</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>packetcache-size</term>
+ <listitem><para>Amount of packets in the packetcache</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>qsize-a</term>
+ <listitem><para>Size of the queue before the transmitting socket.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>qsize-q</term>
+ <listitem><para>Number of packets waiting for database attention</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>servfail-packets</term>
+ <listitem><para>Amount of packets that could not be answered due to database problems</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>tcp-answers</term>
+ <listitem><para>Number of answers sent out over TCP</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>tcp-questions</term>
+ <listitem><para>Number of questions received over TCP</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>timedout-questions</term>
+ <listitem><para>Amount of packets that were dropped because they had to wait too long internally</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>udp-answers</term>
+ <listitem><para>Number of answers sent out over UDP</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>udp-questions</term>
+ <listitem><para>Number of questions received over UDP</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ <sect2><title>Ring buffers</title>
+ <para>
+ Besides counters, PDNS also maintains the ringbuffers. A ringbuffer records events, each new event gets a place
+ in the buffer until it is full. When full, earlier entries get overwritten, hence the name 'ring'.
+ </para>
+ <para>
+ By counting the entries in the buffer, statistics can be generated. These statistics can currently only be viewed
+ using the webserver and are in fact not even collected without the webserver running.
+ </para>
+ <para>
+ The following ringbuffers are available:
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>Log messages (logmessages)</term>
+ <listitem><para>All messages logged</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Queries for existing records but for a type we don't have (noerror-queries)</term>
+ <listitem><para>Queries for, say, the AAAA record of a domain, when only an A is available.
+ Queries are listed in the following format: name/type. So an AAA query for pdns.powerdns.com looks like
+ pdns.powerdns.com/AAAA.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Queries for non-existing records within existing domains(nxdomain-queries)</term>
+ <listitem><para>If PDNS knows it is authoritative over a domain, and it sees a question for a record in that domain
+ that does not exist, it is able to send out an authoritative 'no such domain' message. Indicates that hosts are
+ trying to connect to services really not in your zone.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>UDP queries received (udp-queries)</term>
+ <listitem><para>
+ All UDP queries seen.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Remote server IP addresses (remotes)</term>
+ <listitem><para>
+ Hosts querying PDNS. Be aware that UDP is anonymous - person A can send queries that appear to be coming from
+ person B.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Remotes sending corrupt packets (remote-corrupts)</term>
+ <listitem><para>
+ Hosts sending PDNS broken packets, possibly meant to disrupt service. Be aware that UDP is
+ anonymous - person A can send queries that appear to be coming from person B.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Remotes querying domains for which we are not auth (remote-unauth)</term>
+ <listitem><para>
+ It may happen that there are misconfigured hosts on the internet which are configured to
+ think that a PDNS installation is in fact a resolving nameserver. These hosts will not
+ get useful answers from PDNS. This buffer lists hosts sending queries for domains which
+ PDNS does not know about.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Queries that could not be answered due to backend errors (servfail-queries)</term>
+ <listitem><para>
+ For one reason or another, a backend may be unable to extract answers for a certain domain from
+ its storage. This may be due to a corrupt database or to inconsistent data. When this happens,
+ PDNS sends out a 'servfail' packet indicating that it was unable to answer the question. This buffer
+ shows which queries have been causing servfails.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Queries for domains that we are not authoritative for (unauth-queries)</term>
+ <listitem><para>
+ If a domain is delegated to a PDNS instance, but the backend is not made aware of this fact, questions come
+ in for which no answer is available, nor is the authority. Use this ringbuffer to spot such queries.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </chapter>
+
+ <chapter id="types"><title>Supported record types and their storage</title>
+ <para>
+ This chapter lists all record types PDNS supports, and how they are stored in backends. The list is mostly alphabetical but
+ some types are grouped.
+ <variablelist>
+ <varlistentry>
+ <term>A</term>
+ <listitem>
+ <para>
+ The A record contains an IP address. It is stored as a decimal dotted quad string,
+ for example: '213.244.168.210'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>AAAA</term>
+ <listitem>
+ <para>
+ The AAAA record contains an IPv6 address. It is stored as a decimal dotted quad string,
+ for example: '3ffe:8114:2000:bf0::1'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>CNAME</term>
+ <listitem>
+ <para>
+ The CNAME record specifies the canonical name of a record. It is stored plainly. Like all other records, it is not
+ terminated by a dot. A sample might be 'webserver-01.yourcompany.com'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>HINFO</term>
+ <listitem>
+ <para>
+ Hardware Info record, used to specify CPU and operating system. Stored with a single space separating these two,
+ example: 'i386 Linux'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>MX</term>
+ <listitem>
+ <para>
+ The MX record specifies a mail exchanger host for a domain. Each mail exchanger also has a priority or preference.
+ This should be specified in the separate field dedicated for that purpose, often called 'prio'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><anchor id="naptr">NAPTR</term>
+ <listitem>
+ <para>
+
+ Naming Authority Pointer, RFC 2915. Stored as follows:
+ <screen>
+ '100 50 "s" "z3950+I2L+I2C" "" _z3950._tcp.gatech.edu'.
+ </screen>
+ The fields are: order, preference, flags, service, regex,
+ replacement. Note that the replacement is not enclosed in quotes, and should not be. The replacement may be omitted, in which
+ case it is empty. See also RFC 2916 for how to use NAPTR for ENUM (E.164) purposes.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>NS</term>
+ <listitem>
+ <para>
+ Nameserver record. Specifies nameservers for a domain. Stored plainly: 'ns1.powerdns.com', as always without a terminating dot.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PTR</term>
+ <listitem>
+ <para>
+ Reverse pointer, used to specify the host name belonging to an IP or IPv6 address. Name is stored plainly: 'www.powerdns.com'.
+ As always, no terminating dot.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>RP</term>
+ <listitem>
+ <para>
+ Responsible Person record, as described in RFC 1183. Stored with a single space between the mailbox name and the more-information
+ pointer. Example 'peter.powerdns.com peter.people.powerdns.com', to indicate that peter@powerdns.com is responsible and that more
+ information about peter is available by querying the TXT record of peter.people.powerdns.com.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><anchor id="soa-type">SOA</term>
+ <listitem>
+ <para>
+ The Start of Authority record is one of the most complex available. It specifies a lot about a domain: the name
+ of the master nameserver ('the primary'), the hostmaster and a set of numbers indicating how the data in this domain
+ expires and how often it needs to be checked. Further more, it contains a serial number which should rise on each change
+ of the domain.
+ </para>
+ <para>
+ The stored format is:
+ <screen>
+ primary hostmaster serial refresh retry expire default_ttl
+ </screen>
+ Besides the primary and the hostmaster, all fields are numerical. PDNS has a set of default values:
+ <table>
+ <title>SOA fields</title>
+ <tgroup cols=2>
+ <tbody>
+ <row>
+ <entry>primary</entry><entry><command>default-soa-name</command> configuration option</entry>
+ </row>
+ <row>
+ <entry>hostmaster</entry><entry>hostmaster@domain-name</entry>
+ </row>
+ <row>
+ <entry>serial</entry><entry>0</entry>
+ </row>
+ <row>
+ <entry>refresh</entry><entry>10800 (3 hours)</entry>
+ </row>
+ <row>
+ <entry>retry</entry><entry>3600 (1 hour)</entry>
+ </row>
+ <row>
+ <entry>expire</entry><entry>604800 (1 week)</entry>
+ </row>
+ <row>
+ <entry>default_ttl</entry><entry>3600 (1 hour)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ The fields have complicated and sometimes controversial meanings. The 'serial' field is special. If left at 0, the default,
+ PDNS will perform an internal list of the domain to determine highest change_date field of all records within the zone, and use
+ that as the zone serial number. This means that the serial number is always raised when changes are made to the zone, as long
+ as the change_date field is being set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TXT</term>
+ <listitem>
+ <para>
+ The TXT field can be used to attach textual data to a domain. Text is stored plainly.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </chapter>
+ <chapter id="faq"><title>HOWTO & Frequently Asked Questions</title>
+ <para>
+ This chapter contains a number of FAQs and HOWTOs.
+ </para>
+ <sect1 id="pdns-devel-faq"><title>Backend developer HOWTO</title>
+ <para>
+ Writing backends without access to the full PDNS source means that you need to write code that can be loaded by PDNS at runtime.
+ This in turn means that you need to use the same compiler that we do. For linux, this is currently GCC 3.0.4, although any 3.0.x
+ compiler is probably fine. In tests, even 3.1 works.
+ </para>
+ <para>
+ For FreeBSD we use GCC 2.95.2.
+ </para>
+ <para>
+ Furthermore, your pdns_server executable must be dynamically linked. The default .rpm PDNS contains a static binary so you need to retrieve the
+ dynamic rpm or the dynamic tar.gz or the Debian unstable ('Woody') deb. FreeBSD dynamic releases are forthcoming.
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>Q: Will PDNS drivers work with other PDNS versions than they were compiled for?</term>
+ <listitem>
+ <para>
+ A: 'Probably'. We make no guarantees. Efforts have been made to keep the interface between the backend and PDNS as thin
+ as possible. For example, a backend compiled with the 1.99.11 backend development kit works with 1.99.10. But don't count on it.
+ We will notify when we think an incompatible API change has occured but you are best off recompiling your driver for each
+ new PDNS release.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: What is in that DNSPacket * pointer passed to lookup!</term>
+ <listitem>
+ <para>
+ A: For reasons outlined above, you should treat that pointer as opaque and only access it via the <function>getRemote()</function>
+ functions made available and documented above. The DNSPacket class changes a lot and this level of indirection allows for greater
+ changes to be made without changing the API to the backend coder.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: How is the PowerDNS Open Source Backend Development Kit licensed?</term>
+ <listitem>
+ <para>
+ A: MIT X11, a very liberal license permitting basically everything.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Can I release the backend I wrote?</term>
+ <listitem>
+ <para>
+ A: Please do! If you tell us about it we will list you on our page.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Can I sell backends I wrote?</term>
+ <listitem>
+ <para>
+ A: You can. Again, if you tell us about them we will list your backend on the site. You can keep the source of your backend
+ secret if you want, or you can share it with the world under any license of your chosing.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Will PowerDNS use my code in the PDNS distribution?</term>
+ <listitem>
+ <para>
+ A: If your license permits it and we like your backend, we sure will. If your license does not permit it but we like your
+ backend anyway we may contact you.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: My backend compiles but when I try to load it, it says 'undefined symbol: _Z13BackendMakersv'</term>
+ <listitem>
+ <para>
+ A: Your pdns_server binary is static and cannot load a backend driver at runtime. Get a dynamic version of pdns, or complain
+ to pdns@powerdns.com if one isn't available. To check what kind of binary you have, execute 'file $(which pdns_server)'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: My backend compiles but when I try to load it, it says 'undefined symbol: BackendMakers__Fv'</term>
+ <listitem>
+ <para>
+ A: You compiled with the wrong GCC. Use GCC 3.x for Linux, 2.95.x for FreeBSD. You may want to change g++ to g++-3.0 in the Makefile,
+ or change your path so that 3.x is used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: I downloaded a dynamic copy of pdns_server but it doesn't run, even without my backend</term>
+ <listitem>
+ <para>
+ A: Run 'ldd' on the pdns_server binary and figure out what libraries you are missing. Most likely you need to install gcc 3.0 libraries,
+ RedHat 7.1 and 7.2 have packages available, Debian installs these by default if you use the 'unstable deb' of PDNS.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: What I want can't be done from a backend - I need the whole PDNS source</term>
+ <listitem>
+ <para>
+ A: If you require the source, please contact us (pdns@powerdns.com). All commercial licensees receive the source,
+ for others we may grant exceptions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: What is this 'AhuException' I keep reading about?</term>
+ <listitem>
+ <para>
+ A: This name has historical reasons and has <ulink url="http://ds9a.nl">no significance</ulink>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: I need a backend but I can't write it, can you help?</term>
+ <listitem>
+ <para>
+ A: Yes, we also do custom development. Contact us at pdns@powerdns.com.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect1>
+ <sect1 id="powerdns-company-faq"><title>About PowerDNS.COM BV, 'the company'</title>
+ <para>
+ As of 25 November 2002, the PowerDNS nameserver and its modules are open source. This has led to a lot of questions on the future
+ of both PowerDNS, the company and the products. This FAQ attempts to address these questions.
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>Q: Is PowerDNS 2.9 really open source? What license?</term>
+ <listitem>
+ <para>
+ A: PowerDNS 2.9 is licensed under the GNU General Public License version two, the same license that covers the Linux kernel.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Is the open source version crippled?</term>
+ <listitem>
+ <para>
+ A: It is not. Not a single byte has been omitted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Is the nameserver abandoned?</term>
+ <listitem>
+ <para>
+ A: Far from it. In fact, we expect development to speed up now that we have joined the open source community.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Why is the nameserver now open source?</term>
+ <listitem>
+ <para>
+ A: In the current economic climate and also the way the Internet is built up right now, selling software is very hard. Most potential
+ customers had never before bought a piece of software for their UNIX internet setup. Even though we know (from the recent survey) that
+ nameserver operators love PowerDNS, their suggested price for it is in the $100 range.
+ </para>
+ <para>
+ For us, it makes far more sense to open source PowerDNS than to ask $100 for it. It is expected that open sourcing PowerDNS will lead
+ to far higher adoption rates. We hope that PowerDNS will soon be included in major Linux and UNIX distributions.
+ </para>
+ </listitem>
+ <varlistentry>
+ <term>Q: How does PowerDNS.COM BV expect to make money now that the nameserver is free?</term>
+ <listitem>
+ <para>
+ A: In fact, we don't expect to in the near future. We also don't have a lot of expenses, basically
+ some hosting and a few domain names.
+ </para>
+ <para>
+ However, we are available for consulting work, for example to help a large registrar or registry migrate to PowerDNS, or to help
+ integrate our software in existing provisioning systems.
+ </para>
+ <para>
+ Furthermore, non-GPL licenses are available for those needing to do closed source modifications, or for customers
+ uncomfortable with the GPL. This is much like what <ulink url="http://www.mysql.com/company/index.html">MySQL AB</ulink> is doing now.
+ </para>
+ <para>
+ In fact, their strategy is a lot like ours in general.
+ </para>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Can I buy support contracts for PowerDNS?</term>
+ <listitem>
+ <para>
+ Sure, to do so, please contact us at <email>sales@powerdns.com</email>
+ </para>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Will you accept patches? We've added a feature</term>
+ <listitem>
+ <para>
+ Probably - in general, it is best to discuss your intentions and needs on the <email>pdns-dev@mailman.powerdns.com</email> (<ulink url="http://mailman.powerdns.com/mailman/listinfo/pdns-dev">subscribe</ulink>)
+ mailinglist
+ before doing the work. We may have suggestions or guidelines on how you should implement the feature.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: PowerDNS doesn't work on my platform, will you port it?</term>
+ <term>Q: PowerDNS doesn't have feature I need, will you add it?</term>
+ <listitem>
+ <para>
+ Be sure to ask on the <email>pdns-dev@mailman.powerdns.com</email> (<ulink url="http://mailman.powerdns.com/mailman/listinfo/pdns-dev">subscribe</ulink>) mailinglist. You can even hire us to do work on PowerDNS
+ if plain asking is not persuasive enough. This might be the case if we don't currently have time for your feature, but you
+ need it quickly anyhow, and are not in a position to submit a patch implementing it.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q: Will <ulink url="http://express.powerdns.com">PowerDNS Express</ulink> be open sourced?
+ <ulink url="http://www.powerdns.com/powermail/">PowerMail?</ulink></term>
+ <listitem>
+ <para>
+ Perhaps, we're not yet sure. PowerMail most probably.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Q: We are a Linux/Unix vendor, can we include PowerDNS?
+ <listitem>
+ <para>
+ A: Please do. In fact, we'd be very happy to work with you to make this happen. Contact <email>ahu@ds9a.nl</email>
+ if you have specific upstream needs.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect1>
+ </chapter>
+ <Appendix id="backends-detail"><title>Backends in detail</title>
+ <para>
+ This appendix lists several of the available backends in more detail
+ </para>
+
+
+ <sect1 id="pipebackend"><title>PipeBackend</title>
+ <para>
+ <table>
+ <title>PipeBackend capabilities</title>
+ <tgroup cols=2>
+ <tbody>
+ <row><entry>Native</entry><entry>Yes</entry></row>
+ <row><entry>Master</entry><entry>No</entry></row>
+ <row><entry>Slave</entry><entry>No</entry></row>
+ <row><entry>Superslave</entry><entry>No</entry></row>
+ <row><entry>Autoserial</entry><entry>No</entry></row>
+ <row><entry>Case</entry><entry>Depends</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ The PipeBackend allows for easy dynamic resolution based on a 'Coprocess' which can be written in any
+ programming language that can read a question on standard input and answer on standard output.
+ </para>
+ <para>
+ To configure, the following settings are available:
+ <variablelist>
+ <varlistentry>
+ <term>pipe-command</term>
+ <listitem>
+ <para>
+ Command to launch as backend. Mandatory.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pipe-timeout</term>
+ <listitem>
+ <para>
+ Number of milliseconds to wait for an answer from the backend. If this time is ever exceeded, the backend
+ is declared dead and a new process is spawned. Available since 2.7.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pipe-regex</term>
+ <listitem>
+ <para>
+ If set, only questions matching this regular expression are even sent to the backend. This makes sure that
+ most of PowerDNS does not slow down if you you reploy a slow backend. A query for the A record of 'www.powerdns.com'
+ would be presented to the regex as 'www.powerdns.com;A'. A matching regex would be '^www.powerdns.com;.*$'.
+ </para>
+ <para>
+ To match only ANY and A queries for www.powerdns.com, use '^www.powerdns.com;(A|ANY)$'. Available since 2.8.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <sect2 id="pipebackend-protocol"><title>PipeBackend protocol</title>
+ <para>
+ Questions come in over a file descriptor, by default standard input. Answers
+ are sent out over another file descriptor, standard output by default.
+ </para>
+ <sect3>
+ <title>Handshake</title>
+ <para>
+ PowerDNS sends out 'HELO\t1', indicating that it wants to speak the
+ protocol as defined in this document, version 1.
+
+ A PowerDNS CoProcess must then send out a banner, prefixed by 'OK\t',
+ indicating it launched successfully. If it does not support the indicated
+ version, it should respond with FAIL, but not exit. Suggested behaviour is
+ to try and read a further line, and wait to be terminated.
+ </para></sect3>
+ <sect3><title>Questions</title>
+ <para>
+ Questions come in three forms and are prefixed by a tag indicating the kind:
+ <variablelist>
+ <varlistentry>
+ <term>Q</term>
+ <listitem>
+ <para>
+ Regular queries
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>AXFR</term>
+ <listitem>
+ <para>
+ List requests, which mean that an entire zone should be listed
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PING</term>
+ <listitem>
+ <para>
+ Check if the coprocess is functioning
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+The question format:
+<screen>
+type qname qclass qtype id ip-address
+</screen>
+
+Fields are tab separated, and terminated with a single \n.
+
+Type is the tag above, qname is the domain the question is about. qclass is
+always 'IN' currently, denoting an INternet question. qtype is the kind of
+information desired, the record type, like A, CNAME or AAAA. id can be
+specified to help your backend find an answer if the id is already known
+from an earlier query. You can ignore it.
+
+ip-address is the ip-address of the nameserver asking the question.
+ </para></sect3>
+ <sect3><title>Answers</title>
+ <para>
+
+ Each answer starts with a tag, possibly followed by a TAB and more data.
+ <variablelist>
+ <varlistentry>
+ <term>DATA</term>
+ <listitem>
+ <para>
+ Indicating a successful line of DATA
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>END</term>
+ <listitem>
+ <para>
+ Indicating the end of an answer - no further data
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>FAIL</term>
+ <listitem>
+ <para>
+ Indicating a lookup failure. Also serves as 'END'. No further data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LOG</term>
+ <listitem>
+ <para>
+ For specifying things that should be logged. Can only be sent after
+ a query and before an END line. After the tab, the message to be
+ logged
+
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+
+ So letting it be known that there is no data consists if sending 'END'
+ without anything else.
+
+
+The answer format:
+<screen>
+DATA qname qclass qtype ttl id content
+</screen>
+
+'content' is as specified in <xref linkend="types">.
+
+A sample dialogue may look like this:
+<screen>
+Q www.ds9a.nl IN CNAME -1 213.244.168.210
+DATA www.ds9a.nl IN CNAME 3600 1 ws1.ds9a.nl
+Q ws1.ds9a.nl IN CNAME -1 213.244.168.210
+END
+Q wd1.ds9a.nl IN A -1 213.244.168.210
+DATA ws1.ds9a.nl IN A 3600 1 1.2.3.4
+DATA ws1.ds9a.nl IN A 3600 1 1.2.3.5
+DATA ws1.ds9a.nl IN A 3600 1 1.2.3.6
+END
+</screen>
+
+ This would correspond to a remote webserver 213.244.168.210 wanting to
+resolve the IP address of www.ds9a.nl, and PowerDNS traversing the CNAMEs to
+find the IP addresses of ws1.ds9a.nl
+
+Another dialogue might be:
+<screen>
+Q ds9a.nl IN SOA -1 213.244.168.210
+DATA ds9a.nl IN SOA 86400 1 ahu.ds9a.nl ...
+END
+AXFR 1
+DATA ds9a.nl IN SOA 86400 1 ahu.ds9a.nl ...
+DATA ds9a.nl IN NS 86400 1 ns1.ds9a.nl
+DATA ds9a.nl IN NS 86400 1 ns2.ds9a.nl
+DATA ns1.ds9a.nl IN A 86400 1 213.244.168.210
+DATA ns2.ds9a.nl IN A 86400 1 63.123.33.135
+.
+.
+END
+</screen>
+
+This is a typical zone transfer.
+ </para>
+ </sect3>
+ <sect3>
+ <title>Sample perl backend</title>
+ <para>
+ <screen>
+#!/usr/bin/perl -w
+# sample PowerDNS Coprocess backend
+#
+
+use strict;
+
+
+$|=1; # no buffering
+
+my $line=<>;
+chomp($line);
+
+unless($line eq "HELO\t1") {
+ print "FAIL\n";
+ print STDERR "Recevied '$line'\n";
+ <>;
+ exit;
+}
+print "OK Sample backend firing up\n"; # print our banner
+
+while(<>)
+{
+ print STDERR "$$ Received: $_";
+ chomp();
+ my @arr=split(/\t/);
+ if(@arr<6) {
+ print "LOG PowerDNS sent unparseable line\n";
+ print "FAIL\n";
+ next;
+ }
+
+ my ($type,$qname,$qclass,$qtype,$id,$ip)=split(/\t/);
+
+ if(($qtype eq "A" || $qtype eq "ANY") && $qname eq "webserver.example.com") {
+ print STDERR "$$ Sent A records\n";
+ print "DATA $qname $qclass A 3600 -1 1.2.3.4\n";
+ print "DATA $qname $qclass A 3600 -1 1.2.3.5\n";
+ print "DATA $qname $qclass A 3600 -1 1.2.3.6\n";
+ }
+ elsif(($qtype eq "CNAME" || $qtype eq "ANY") && $qname eq "www.example.com") {
+ print STDERR "$$ Sent CNAME records\n";
+ print "DATA $qname $qclass CNAME 3600 -1 webserver.example.com\n";
+ }
+ elsif($qtype eq "MBOXFW") {
+ print STDERR "$$ Sent MBOXFW records\n";
+ print "DATA $qname $qclass MBOXFW 3600 -1 powerdns\@example.com\n";
+ }
+
+
+ print STDERR "$$ End of data\n";
+ print "END\n";
+}
+ </screen>
+ </para>
+ </sect3>
+ </sect2>
+
+ </sect1>
+ <sect1 id="mysqlbackend"><Title>MySQL backend</title>
+ <para>
+ <table>
+ <title>MySQL backend capabilities</title>
+ <tgroup cols=2>
+ <tbody>
+ <row><entry>Native</entry><entry>Yes</entry></row>
+ <row><entry>Master</entry><entry>No</entry></row>
+ <row><entry>Slave</entry><entry>No</entry></row>
+ <row><entry>Superslave</entry><entry>No</entry></row>
+ <row><entry>Autoserial</entry><entry>Yes</entry></row>
+ <row><entry>Case</entry><entry>Insensitive</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ The MySQL Backend as present in PDNS is fixed - it requires a certain database schema to function. This schema corresponds to this create statement:
+
+ <screen>
+ CREATE TABLE records (
+ id int(11) NOT NULL auto_increment,
+ domain_id int(11) default NULL,
+ name varchar(255) default NULL,
+ type varchar(6) default NULL,
+ content varchar(255) default NULL,
+ ttl int(11) default NULL,
+ prio int(11) default NULL,
+ change_date int(11) default NULL,
+ PRIMARY KEY (id),
+ KEY name_index(name),
+ KEY nametype_index(name,type),
+ KEY domainid_index(domain_id)
+ );
+ </screen>
+
+ Every domain should have a unique domain_id, which should remain identical for all records in a domain. Records with a domain_id that
+ differs from that in the domain SOA record will not appear in a zone transfer.
+
+ </para>
+ <para>
+ The change_date may optionally
+ be updated to the time_t (the number of seconds since midnight UTC at the start of 1970), and is in that case used to auto calculate the
+ SOA serial number in case that is unspecified.
+
+ </para>
+ <sect2><title>Configuration settings</title>
+ <para>
+ WARNING! Make sure that you can actually resolve the hostname of your database without accessing the database! It is advised to supply
+ an IP address here to prevent chicken/egg problems!
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>mysql-dbname</term>
+ <listitem>
+ <para>
+ Database name to connect to
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>mysql-host</term>
+ <listitem>
+ <para>
+ Database host to connect to
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>mysql-password</term>
+ <listitem>
+ <para>
+ Password to connect with
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>mysql-socket</term>
+ <listitem>
+ <para>
+ MySQL socket to use for connecting
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>mysql-table</term>
+ <listitem>
+ <para>
+ MySQL table name. Defaults to 'records'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>mysql-user</term>
+ <listitem>
+ <para>
+ MySQL user to connect as
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ <sect2><title>Notes</title>
+ <para>
+ It has been observed that InnoDB tables outperform the default MyISAM tables by a large margin. Furthermore, the default
+ number of backends (3) should be raised to 10 or 15 for busy servers.
+ </para>
+ </sect2>
+
+ </sect1>
+ <sect1 id="pdnsbackend"><Title>MySQL PDNS backend</title>
+ <para>
+ <table>
+ <title>MySQL backend capabilities</title>
+ <tgroup cols=2>
+ <tbody>
+ <row><entry>Native</entry><entry>Yes</entry></row>
+ <row><entry>Master</entry><entry>No</entry></row>
+ <row><entry>Slave</entry><entry>No</entry></row>
+ <row><entry>Superslave</entry><entry>No</entry></row>
+ <row><entry>Autoserial</entry><entry>Yes</entry></row>
+ <row><entry>Case</entry><entry>Insensitive</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ This is the driver that corresponds to the set of XML-RPC tools available from PowerDNS. For database schemas, see there.
+ </para>
+ <para>
+ It takes a number of parameters:
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>pdns-dbname</term>
+ <listitem>
+ <para>
+ Database name to connect to
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pdns-host</term>
+ <listitem>
+ <para>
+ Database host to connect to
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pdns-password</term>
+ <listitem>
+ <para>
+ Password to connect with
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pdns-socket</term>
+ <listitem>
+ <para>
+ MySQL socket to use for connecting
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pdns-user</term>
+ <listitem>
+ <para>
+ MySQL user to connect as
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <sect2><title>Notes</title>
+ <para>
+ It has been observed that InnoDB tables outperform the default MyISAM tables by a large margin. Furthermore, the default
+ number of backends (3) should be raised to 10 or 15 for busy servers.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="generic-mypgsql-backends"><Title>Generic MySQL and PgSQL backends</title>
+ <para>
+ <table>
+ <title>Generic PgSQL and MySQL backend capabilities</title>
+ <tgroup cols=2>
+ <tbody>
+ <row><entry>Module name</entry><entry>gpgsql / gmysql</entry></row>
+ <row><entry>Native</entry><entry>Yes - but PostgreSQL does not replicate</entry></row>
+ <row><entry>Master</entry><entry>Yes</entry></row>
+ <row><entry>Slave</entry><entry>Yes</entry></row>
+ <row><entry>Superslave</entry><entry>Yes</entry></row>
+ <row><entry>Autoserial</entry><entry>Yes</entry></row>
+ <row><entry>Case</entry><entry>All lower</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ PostgreSQL and MySQL backend with easily configurable SQL statements, allowing you to graft PDNS on any PostgreSQL or MySQL database of your choosing.
+ Because all database schemas will be different, a generic backend is needed to cover all needs.
+ </para>
+ <para>
+ The template queries are expanded using the C function 'snprintf' which implies that substitutions are performed on the basis of %-place holders.
+ To place a a % in a query which will not be substituted, use %%. Make sure to fill out the search key, often called 'name' in lower case!
+ </para>
+ <para>
+ There are in fact two backends, one for PostgreSQL and one for MySQL but they accept the same settings and use almost exactly the same database schema.
+ </para>
+ <sect2><title>MySQL specifics</title>
+ <para>
+ <warning>
+ <para>
+ As of 2.3, the Generic MySQL backend has not been tested a lot. Use the regular MySQL backend if unsure! Especially 'master' support is
+ very new.
+ </para>
+ </warning>
+ <warning>
+ <para>
+ If using MySQL with 'slave' support enabled in PowerDNS you <emphasis>must</emphasis> run MySQL with a table engine that supports transactions.
+ </para>
+ </warning>
+ </para>
+ <para>
+ In practice, great results are achieved with the 'InnoDB' tables. PowerDNS will silently function with non-transaction aware MySQLs but at one point
+ this is going to harm your database, for example when an incoming zone transfer fails.
+ </para>
+ <para>
+ The default setup conforms to the following schema:
+ <programlisting>
+create table domains (
+ id INT auto_increment,
+ name VARCHAR(255) NOT NULL,
+ master VARCHAR(20) DEFAULT NULL,
+ last_check INT DEFAULT NULL,
+ type VARCHAR(6) NOT NULL,
+ notified_serial INT DEFAULT NULL,
+ account VARCHAR(40) DEFAULT NULL,
+ primary key (id)
+)type=InnoDB;
+
+CREATE UNIQUE INDEX name_index ON domains(name);
+
+CREATE TABLE records (
+ id INT auto_increment,
+ domain_id INT DEFAULT NULL,
+ name VARCHAR(255) DEFAULT NULL,
+ type VARCHAR(6) DEFAULT NULL,
+ content VARCHAR(255) DEFAULT NULL,
+ ttl INT DEFAULT NULL,
+ prio INT DEFAULT NULL,
+ change_date INT DEFAULT NULL,
+ primary key(id)
+)type=InnoDB;
+
+CREATE INDEX rec_name_index ON records(name);
+CREATE INDEX nametype_index ON records(name,type);
+CREATE INDEX domain_id ON records(domain_id);
+
+create table supermasters (
+ ip VARCHAR(25) NOT NULL,
+ nameserver VARCHAR(255) NOT NULL,
+ account VARCHAR(40) DEFAULT NULL
+);
+
+GRANT SELECT ON supermasters TO pdns;
+GRANT ALL ON domains TO pdns;
+GRANT ALL ON records TO pdns;
+ </programlisting>
+ </para>
+ <para>
+ This schema contains all elements needed for master, slave and superslave operation. Depending on which features will be used, the 'GRANT' statements
+ can be trimmed to make sure PDNS cannot subvert the contents of your database.
+ </para>
+ <para>
+ Zone2sql with the --gmysql flag also assumes this layout is in place.
+ </para>
+ </sect2>
+ <sect2><title>PostgresSQL specifics</title>
+ <para>
+ The default setup conforms to the following schema:
+ <programlisting>
+create table domains (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ master VARCHAR(20) DEFAULT NULL,
+ last_check INT DEFAULT NULL,
+ type VARCHAR(6) NOT NULL,
+ notified_serial INT DEFAULT NULL,
+ account VARCHAR(40) DEFAULT NULL
+);
+CREATE UNIQUE INDEX name_index ON domains(name);
+
+CREATE TABLE records (
+ id SERIAL PRIMARY KEY,
+ domain_id INT DEFAULT NULL,
+ name VARCHAR(255) DEFAULT NULL,
+ type VARCHAR(6) DEFAULT NULL,
+ content VARCHAR(255) DEFAULT NULL,
+ ttl INT DEFAULT NULL,
+ prio INT DEFAULT NULL,
+ change_date INT DEFAULT NULL,
+ CONSTRAINT domain_exists
+ FOREIGN KEY(domain_id) REFERENCES domains(id)
+ ON DELETE CASCADE
+);
+
+CREATE INDEX rec_name_index ON records(name);
+CREATE INDEX nametype_index ON records(name,type);
+CREATE INDEX domain_id ON records(domain_id);
+
+create table supermasters (
+ ip VARCHAR(25) NOT NULL,
+ nameserver VARCHAR(255) NOT NULL,
+ account VARCHAR(40) DEFAULT NULL
+);
+
+GRANT SELECT ON supermasters TO pdns;
+GRANT ALL ON domains TO pdns;
+GRANT ALL ON domains_id_seq TO pdns;
+GRANT ALL ON records TO pdns;
+GRANT ALL ON records_id_seq TO pdns;
+ </programlisting>
+ </para>
+ <para>
+ This schema contains all elements needed for master, slave and superslave operation. Depending on which features will be used, the 'GRANT' statements
+ can be trimmed to make sure PDNS cannot subvert the contents of your database.
+ </para>
+ <para>
+ Zone2sql with the --gpgsql flag also assumes this layout is in place.
+ </para>
+ </sect2>
+ <sect2><title>Basic functionality</title>
+ <para>
+ 4 queries are needed for regular lookups, 4 for 'fancy records' which are disabled by default and 1 is needed for zone transfers.
+ </para>
+ <para>The 4+4 regular queries must return the following 6 fields, in this exact order:
+ <variablelist>
+ <varlistentry>
+ <term>content</term>
+ <listitem>
+ <para>
+ This is the 'right hand side' of a DNS record. For an A record, this is the IP address for example.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ttl</term>
+ <listitem>
+ <para>
+ TTL of this record, in seconds. Must be a real value, no checking is performed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>prio</term>
+ <listitem>
+ <para>
+ For MX records, this should be the priority of the mail exchanger specified.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>qtype</term>
+ <listitem>
+ <para>
+ The ASCII representation of the qtype of this record. Examples are 'A', 'MX', 'SOA', 'AAAA'. Make sure that this
+ field returns an exact answer - PDNS won't recognise 'A ' as 'A'. This can be achieved by using a VARCHAR instead
+ of a CHAR.
+ </para>
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>domain_id</term>
+ <listitem>
+ <para>
+ Each domain must have a unique domain_id. No two domains may share a domain_id, all records in a domain should have the same. A number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>
+ Actual name of a record. Must not end in a '.' and be fully qualified - it is not relative to the name of the domain!
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ Please note that the names of the fields are not relevant, but the order is!
+ </para>
+ <para>
+ As said earlier, there are 8 SQL queries for regular lookups. To configure them, set 'gmysql-basic-query' or 'gpgsql-basic-query', depending on your
+ choice of backend. If so called 'MBOXFW' fancy records are not used, four queries remain:
+ <variablelist>
+ <varlistentry>
+ <term>basic-query</term>
+ <listitem>
+ <para>
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where qtype='%s' and name='%s'</command>
+ This is the most used query, needed for doing 1:1 lookups of qtype/name values. First %s is replaced by the ASCII representation
+ of the qtype of the question, the second by the name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>id-query</term>
+ <listitem>
+ <para>
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where qtype='%s' and name='%s' and domain_id=%d</command>
+ Used for doing lookups within a domain. First %s is replaced by the qtype, the %d which should appear after the %s by the numeric
+ domain_id.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>any-query</term>
+ <listitem>
+ <para>
+ For doing ANY queries. Also used internally.
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where name='%s'</command>
+ The %s is replaced by the qname of the question.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>any-id-query</term>
+ <listitem>
+ <para>
+ For doing ANY queries within a domain. Also used internally.
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where name='%s' and domain_id=%d</command>
+ The %s is replaced by the name of the domain, the %d by the numerical domain id.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ The last query is for listing the entire contents of a zone. This is needed when performing a zone transfer, but sometimes also internally:
+ <variablelist>
+ <varlistentry>
+ <term>list-query</term>
+ <listitem>
+ <para>
+ To list an entire zone.
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where domain_id=%d</command>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ <sect2><title>Fancy records</title>
+ <para>
+ If PDNS is used with so called 'Fancy Records', the 'MBOXFW' record exists which specifies an email address forwarding instruction,
+ wildcard queries are sometimes needed. This is not enabled by default. A wildcard query is
+ an internal concept - it has no relation to *.domain-type lookups. You can safely leave these queries blank.
+ <variablelist>
+ <varlistentry>
+ <term>wildcard-query</term>
+ <listitem>
+ <para>
+ Can be left blank. See above for an explanation.
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where qtype='%s' and name like '%s'</command>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>wildcard-id-query</term>
+ <listitem>
+ <para>
+ Can be left blank. See above for an explanation.
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where qtype='%s' and name like '%s' and domain_id=%d</command>
+ Used for doing lookups within a domain.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>wildcard-any-query</term>
+ <listitem>
+ <para>
+ For doing wildcard ANY queries.
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where name like '%s'</command>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>wildcard-any-id-query</term>
+ <listitem>
+ <para>
+ For doing wildcard ANY queries within a domain.
+ Default: <command>select content,ttl,prio,type,domain_id,name from records where name like '%s' and domain_id=%d</command>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2><title>Settings and specifying queries</title>
+ <para>
+ The queries above are specified in pdns.conf. For example, the basic-query would appear as:
+ <screen>
+ gpgsql-basic-query=select content,ttl,prio,type,domain_id,name from records where qtype='%s' and name='%s'
+ </screen>
+
+ Queries can span multiple lines, like this:
+ <screen>
+ gpgsql-basic-query=select content,ttl,prio,type,domain_id,name from records \
+ where qtype='%s' and name='%s'
+ </screen>
+ Do not wrap statements in quotes as this will not work.
+ Besides the query related settings, the following configuration options are available:
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>gpgsql-dbname</term>
+ <listitem>
+ <para>
+ Database name to connect to
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>gpgsql-host</term>
+ <listitem>
+ <para>
+ Database host to connect to. WARNING: When specified as a hostname a chicken/egg situation might arise where the database
+ is needed to resolve the IP address of the database. It is best to supply an IP address of the database here.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>gpgsql-password</term>
+ <listitem>
+ <para>
+ Password to connect with
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>gpgsql-user</term>
+ <listitem>
+ <para>
+ PgSQL user to connect as
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ <sect2><title>Native operation</title>
+ <para>
+ For native operation, either drop the FOREIGN KEY on the domain_id field, or (recommended), make sure
+ the <command>domains</command> table is filled properly. To add a domain, issue the following:
+ <programlisting>
+ insert into domains (name,type) values ('powerdns.com','NATIVE');
+ </programlisting>
+ The records table can now be filled by with the domain_id set to the id of the domains table row just inserted.
+ </para>
+ </sect2>
+ <sect2><title>Slave operation</title>
+ <para>
+ The PostgreSQL backend is fully slave capable. To become a slave of the 'powerdns.com' domain, execute this:
+ <programlisting>
+ insert into domains (name,master,type) values ('powerdns.com','213.244.168.217','SLAVE');
+ </programlisting>
+ And wait a while for PDNS to pick up the addition - which happens within one minute. There is no need to inform PDNS that a new domain
+ was added.
+ Typical output is:
+ <programlisting>
+ Apr 09 13:34:29 All slave domains are fresh
+ Apr 09 13:35:29 1 slave domain needs checking
+ Apr 09 13:35:29 Domain powerdns.com is stale, master serial 1, our serial 0
+ Apr 09 13:35:30 [gPgSQLBackend] Connected to database
+ Apr 09 13:35:30 AXFR started for 'powerdns.com'
+ Apr 09 13:35:30 AXFR done for 'powerdns.com'
+ Apr 09 13:35:30 [gPgSQLBackend] Closing connection
+ </programlisting>
+ </para>
+ <para>
+ From now on, PDNS is authoritative for the 'powerdns.com' zone and will respond accordingly for queries within that zone.
+ </para>
+ <para>
+ Periodically, PDNS schedules checks to see if domains are still fresh. The default <command>slave-cycle-interval</command> is 60 seconds, large installations may need to raise this value. Once a domain has been checked, it will not be checked before its SOA refresh timer has expired. Domains whose status is unknown get checked every 60 seconds by default.
+ </para>
+ </sect2>
+ <sect2><title>Superslave operation</title>
+ <para>
+ To configure a supermaster with IP address 10.0.0.11 which lists this installation as 'autoslave.powerdns.com', issue the following:
+ <programlisting>
+ insert into supermasters ('10.0.0.11','autoslave.powerdns.com','internal');
+ </programlisting>
+ From now on, valid notifies from 10.0.0.11 that list a NS record containing 'autoslave.powerdns.com' will lead to the
+ provisioning of a slave domain under the account 'internal'. See <xref linkend="supermaster"> for details.
+ </para>
+ </sect2>
+ <sect2><title>Master operation</title>
+ <para>
+ The PostgreSQL backend is fully master capable with automatic discovery of serial changes. Raising the serial number of a domain
+ suffices to trigger PDNS to send out notifications. To configure a domain for master operation instead of the default native replication,
+ issue:
+ <programlisting>
+ insert into domains (name,type) values ('powerdns.com','MASTER');
+ </programlisting>
+ Make sure that the assigned id in the domains table matches the domain_id field in the records table!
+ </para>
+ </sect1>
+
+ <sect1 id="oracle"><Title>Generic Oracle backend</title>
+ <para>
+ <table>
+ <title>Oracle backend capabilities</title>
+ <tgroup cols=2>
+ <tbody>
+ <row><entry>Native</entry><entry>Yes</entry></row>
+ <row><entry>Master</entry><entry>No</entry></row>
+ <row><entry>Slave</entry><entry>No</entry></row>
+ <row><entry>Superslave</entry><entry>No</entry></row>
+ <row><entry>Autoserial</entry><entry>Yes</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ Oracle backend with easily configurable SQL statements, allowing you to graft PDNS on any Oracle database of your choosing.
+ </para>
+ <para>
+ PowerDNS is currently ascertaining if this backend can be distributed in binary form without violating Oracle licensing. In the meantime,
+ the source code to the Oracle backend is available for runtime linking into dynamic versions of PowerDNS. See
+ <ulink url="http://downloads.powerdns.com/backends">http://downloads.powerdns.com/backends</ulink> for sources.
+ </para>
+ <para>
+ The following configuration settings are available:
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>oracle-debug-queries</term>
+ <listitem>
+ <para>
+ Output all queries to disk for debugging purposes.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-time-queries</term>
+ <listitem>
+ <para>
+ Output all queries to disk for timing purposes.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-uppercase-database</term>
+ <listitem>
+ <para>
+ Change all domain names to uppercase before querying database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-database</term>
+ <listitem>
+ <para>
+ Oracle database name to connect to.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-home</term>
+ <listitem>
+ <para>
+ PDNS can set the ORACLE_HOME environment variable from within the executable, allowing execution of
+ the daemon from init.d scripts where ORACLE_HOME may not yet be set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-sid</term>
+ <listitem>
+ <para>
+ PDNS can set the ORACLE_SID environment variable from within the executable, allowing execution of
+ the daemon from init.d scripts where ORACLE_SID may not yet be set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-username</term>
+ <listitem>
+ <para>
+ Oracle username to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-password</term>
+ <listitem>
+ <para>
+ Oracle password to connect with.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ The generic Oracle backend can be configured to use user-specified queries. The following are the default queries
+ and their names:
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>oracle-forward-query</term>
+ <listitem>
+ <para>
+ select content, TimeToLive, Priority, type, ZoneId, nvl(ChangeDate,0) from Records where name = :name and type = :type
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-forward-query-by-zone</term>
+ <listitem>
+ <para>
+ select content, TimeToLive, Priority, type, ZoneId, nvl(ChangeDate,0) from records where name = :name and type = :type and ZoneId = :id
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-forward-any-query</term>
+ <listitem>
+ <para>
+ select content, TimeToLive, Priority, type, ZoneId, nvl(ChangeDate,0) from records where name = :name
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>oracle-list-query</term>
+ <listitem>
+ <para>
+ select content, TimeToLive, Priority, type, ZoneId, nvl(ChangeDate, 0), name from records where ZoneId = :id
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <sect2><title>Setting up Oracle for use with PowerDNS</title>
+ <para>
+ To setup a database that corresponds to these default queries, issue the following as Oracle user sys:
+ <screen>
+ create user powerdns identified by YOURPASSWORD;
+ grant connect to powerdns;
+
+ create tablespace powerdns datafile '/opt/oracle/oradata/oracle/powerdns.dbf'
+ size 256M extent management local autoallocate;
+
+ alter user powerdns quota unlimited on powerdns;
+ </screen>
+ </para>
+ <para>
+ As user 'powerdns' continue with:
+ <screen>
+create table Domains (
+ ID number(11) NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ MASTER VARCHAR(20) DEFAULT NULL,
+ LAST_CHECK INT DEFAULT NULL,
+ TYPE VARCHAR(6) NOT NULL,
+ NOTIFIED_SERIAL INT DEFAULT NULL,
+ ACCOUNT VARCHAR(40) DEFAULT NULL,
+ primary key (ID)
+)tablespace POWERDNS;
+
+create index DOMAINS$NAME on Domains (NAME) tablespace POWERDNS;
+create sequence DOMAINS_ID_SEQUENCE;
+
+create table Records
+(
+ ID number(11) NOT NULL,
+ ZoneID number(11) default NULL REFERENCES Domains(ID) ON DELETE CASCADE,
+ NAME varchar2(255) default NULL,
+ TYPE varchar2(6) default NULL,
+ CONTENT varchar2(255) default NULL,
+ TimeToLive number(11) default NULL,
+ Priority number(11) default NULL,
+ CreateDate number(11) default NULL,
+ ChangeDate number(11) default NULL,
+ primary key (ID)
+)tablespace POWERDNS;
+
+create index RECORDS$NAME on RECORDS (NAME) tablespace POWERDNS;
+create sequence RECORDS_ID_SEQUENCE;
+ </screen>
+ </para>
+ <para>
+ To insert records, either use <command>zone2sql</command> with the <command>--oracle</command> setting, or execute sql
+ along the lines of:
+ <screen>
+insert into domains (id,name,type) values (domains_id_sequence.nextval,'netherlabs.nl','NATIVE');
+insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'SOA', 'ahu.casema.net. hostmaster.ds9a.nl. 2000081401 28800 7200 604800 86400', 3600, 0 from Domains where name='netherlabs.nl';
+insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'NS', 'ahu.casema.net', 3600, 0 from Domains where name='netherlabs.nl';
+insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'NS', 'ns1.pine.nl', 3600, 0 from Domains where name='netherlabs.nl';
+insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'NS', 'ns2.pine.nl', 3600, 0 from Domains where name='netherlabs.nl';
+insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'A', '213.244.168.210', 3600, 0 from Domains where name='netherlabs.nl';
+insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'MX', 'outpost.ds9a.nl', 3600, 10 from Domains where name='netherlabs.nl';
+
+ </screen>
+ </para>
+ <para>
+ For performance reasons it is best to specify <command>--transactions</command> too!
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="db2"><Title>DB2 backend</title>
+ <para>
+ <table>
+ <title>DB2 backend capabilities</title>
+ <tgroup cols=2>
+ <tbody>
+ <row><entry>Native</entry><entry>Yes</entry></row>
+ <row><entry>Master</entry><entry>No</entry></row>
+ <row><entry>Slave</entry><entry>No</entry></row>
+ <row><entry>Superslave</entry><entry>No</entry></row>
+ <row><entry>Autoserial</entry><entry>Yes</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ PowerDNS is currently ascertaining if this backend can be distributed in binary form without violating IBM DB2 licensing. If you have a DB2 license,
+ please contact pdns@powerdns.com so we can ship you a copy of this driver.
+ </para>
+ <para>
+ The DB2 backend executes the following queries:
+ <variablelist>
+ <varlistentry>
+ <term>Forward Query</term>
+ <listitem>
+ <para>
+ select Content, TimeToLive, Priority, Type, ZoneId, 0 as ChangeDate, Name from Records where Name = ? and type = ?
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Forward By Zone Query</term>
+ <listitem>
+ <para>
+ select Content, TimeToLive, Priority, Type, ZoneId, 0 as ChangeDate, Name from Records where Name = ? and Type = ? and ZoneId = ?
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Forward Any Query</term>
+ <listitem>
+ <para>
+ select Content, TimeToLive, Priority, Type, ZoneId, 0 as ChangeDate, Name from Records where Name = ?
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>List Query</term>
+ <listitem>
+ <para>
+ select Content, TimeToLive, Priority, Type, ZoneId, 0 as ChangeDate, Name from Records where ZoneId = ?
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ Configuration settings:
+ <variablelist>
+ <varlistentry>
+ <term>db2-server</term>
+ <listitem>
+ <para>
+ Server name to connect to. Defaults to 'powerdns'. Make sure that your nameserver is not needed to resolve an IP address needed to connect as
+ this might lead to a chicken/egg situation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>db2-user</term>
+ <listitem>
+ <para>
+ Username to connect as. Defaults to 'powerdns'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>db2-password</term>
+ <listitem>
+ <para>
+ Password to connect with. Defaults to 'powerdns'.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect1>
+
+ <sect1 id="bindbackend"><Title>Bind zone file backend</title>
+ <para>
+ <table>
+ <title>Bind zone file backend capabilities</title>
+ <tgroup cols=2>
+ <tbody>
+ <row><entry>Native</entry><entry>Yes</entry></row>
+ <row><entry>Master</entry><entry>No</entry></row>
+ <row><entry>Slave</entry><entry>Experimental</entry></row>
+ <row><entry>Superslave</entry><entry>No</entry></row>
+ <row><entry>Autoserial</entry><entry>No</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ The BindBackend started life as a demonstration of the versatility of PDNS but quickly gained in importance when there appeared to be demand
+ for a Bind 'workalike'.
+ </para>
+ <para>
+ The BindBackend parses a Bind-style named.conf and extracts information about zones from it. It makes no attempt to honour other configuration flags,
+ which you should configure (when available) using the PDNS native configuration.
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>--help=bind</term>
+ <listitem>
+ <para>
+ Outputs all known parameters related to the bindbackend
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bind-example-zones</term>
+ <listitem>
+ <para>
+ Loads the 'example.com' zone which can be queried to determine if PowerDNS is functioning without configuring
+ database backends.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bind-config=</term>
+ <listitem>
+ <para>
+ Location of the Bind configuration file to parse.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bind-check-interval=</term>
+ <listitem>
+ <para>
+ How often to check for zone changes. See 'Operation' section.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bind-enable-huffman</term>
+ <listitem>
+ <para>
+ Enable Huffman compression on zone data. Currently saves around 20% of memory actually used, but slows down operation
+ somewhat.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <sect2>
+ <title>Operation</title>
+ <para>
+ On launch, the BindBackend first parses the named.conf to determine which zones need to be loaded. These will then be parsed
+ and made available for serving, as they are parsed. So a named.conf with 100.000 zones may take 20 seconds to load, but after 10 seconds,
+ 50.000 zones will already be available. While a domain is being loaded, it is not yet available, to prevent incomplete answers.
+ </para>
+ <para>
+ Reloading is currently done only when a request for a zone comes in, and then only after <command>bind-check-interval</command> seconds have passed
+ after the last check. If a change occurred, access to the zone is disabled, the file is reloaded, access is restored, and the question is answered.
+ For regular zones, reloading is fast enough to answer the question which lead to the reload within the DNS timeout.
+ </para>
+ <para>
+ If <command>bind-check-interval</command> is specified as zero, no checks will be performed.
+ </para>
+ <sect2><title>Performance</title>
+ <para>
+ The BindBackend does not benefit from the packet cache as it is fast enough on its own. Furthermore, on most systems, there will
+ be no benefit in using multiple CPUs for the packetcache, so a noticeable speedup can be attained by specifying
+ <command>distributor-threads=1</command> in <filename>pdns.conf</filename>.
+ </para>
+ </sect2>
+ <sect2><title>Master/slave configuration</title>
+ <para>
+ Currently disabled in prereleases. But see <xref linkend="slave">.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="odbc">
+ <Title>ODBC backend</Title>
+ <para>
+ <table>
+ <title>ODBC backend capabilities</title>
+ <tgroup cols=2>
+ <tbody>
+ <row><entry>Native</entry><entry>Yes</entry></row>
+ <row><entry>Master</entry><entry>Yes (experimental)</entry></row>
+ <row><entry>Slave</entry><entry>Yes (experimental)</entry></row>
+ <row><entry>Superslave</entry><entry>No</entry></row>
+ <row><entry>Autoserial</entry><entry>Yes</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ The ODBC backend can retrieve zone information from any source that has a ODBC driver available.
+ <note><para>This backend is only available on PowerDNS for Windows.</para></note>
+ </para>
+
+ <para>
+ The ODBC backend needs data in a fixed schema which is the same as the data needed by the MySQL backend. The create statement
+ will resemble this:
+ <screen>
+ CREATE TABLE records (
+ id int(11) NOT NULL auto_increment,
+ domain_id int(11) default NULL,
+ name varchar(255) default NULL,
+ type varchar(6) default NULL,
+ content varchar(255) default NULL,
+ ttl int(11) default NULL,
+ prio int(11) default NULL,
+ change_date int(11) default NULL,
+ PRIMARY KEY (id),
+ KEY name_index(name),
+ KEY nametype_index(name,type),
+ KEY domainid_index(domain_id)
+ );
+ </screen>
+ </para>
+
+ <para>
+ To use the ODBC backend an ODBC source has to be created, to do this see the section Installing PowerDNS on Microsoft Windows, <xref linkend="windows">.
+ </para>
+
+ <para>
+ The following configuration settings are available:
+
+ <variablelist>
+ <varlistentry>
+ <term>odbc-datasource</term>
+ <listitem>
+ <para>
+ Specifies the name of the data source to use.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>odbc-user</term>
+ <listitem>
+ <para>
+ Specifies the username that has to be used to log into the datasource.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>odbc-pass</term>
+ <listitem>
+ <para>
+ Specifies the user's password.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>odbc-table</term>
+ <listitem>
+ <para>
+ Specifies the name of the table containing the zone information.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ The ODBC backend has been tested with Microsoft Access, MySQL (via MyODBC) and Microsoft SQLServer. As the SQL statements used are very basic,
+ it is expected to work with many ODBC drivers.
+ </para>
+ </sect1>
+
+</appendix>
+<appendix id="pdns-internals"><title>PDNS internals</title>
+ <para>
+ PDNS is normally launched by the init.d script but is actually a binary called <filename>pdns_server</filename>. This
+ file is started by the <command>start</command> and <command>monitor</command> commands to the init.d script. Other commands
+ are implemented using the controlsocket.
+ </para>
+ <sect1 id="controlsocket"><title>Controlsocket</title>
+ <para>
+ The controlsocket is the means to contact a running PDNS daemon, or as we now know, a running <filename>pdns_server</filename>.
+ Over this sockets, instructions can be sent using the <filename>pdns_control</filename> program. Like the <filename>pdns_server</filename>,
+ this program is normally accessed via the init.d script.
+ </para>
+ <sect2 id="pdnscontrol"><title>pdns_control</title>
+
+ <para>
+ To communicate with PDNS over the controlsocket, the <command>pdns_control</command> command is used. The init.d script also calls
+ pdns_control. The syntax is simple: <command>pdns_control command arguments</command>. Currently this is most useful for telling backends
+ to rediscover domains or to force the transmission of notifications. See <xref linkend="master">.
+ </para>
+ <para>
+ Besides the commands implemented by the init.d script, for which see <xref linkend="pdns-on-unix">, the following pdns_control commands
+ are available:
+ <variablelist>
+ <varlistentry>
+ <term>ccounts</term>
+ <listitem>
+ <para>
+ Returns counts on the contents of the cache.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>version</term>
+ <listitem>
+ <para>
+ returns the version of a running pdns daemon.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>purge</term>
+ <listitem>
+ <para>
+ Purges the entire Packet Cache - see <xref linkend="performance">.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>purge <userinput>record</userinput></term>
+ <listitem>
+ <para>
+ Purges all entries for this exact record name - see <xref linkend="performance">.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>purge <userinput>record</userinput>$</term>
+ <listitem>
+ <para>
+ Purges all entries ending on this name, effectively purging an entire domain - see <xref linkend="performance">.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>set <userinput>variable value</userinput></term>
+ <listitem>
+ <para>
+ Set a configuration parameter. Currently only the 'query-logging' parameter can be set.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="guardian"><title>Guardian</title>
+ <para>
+ When launched by the init.d script, <filename>pdns_server</filename> wraps itself inside a 'guardian'. This guardian monitors the
+ performance of the inner <filename>pdns_server</filename> instance which shows up in the process list of your OS as
+ <filename>pdns_server-instance</filename>.
+
+ It is also this guardian that <filename>pdns_control</filename> talks to. A <command>STOP</command> is interpreted by the guardian,
+ which causes the guardian to sever the connection to the inner process and terminate it, after which it terminates itself.
+
+ The init.d script <command>DUMP</command> and <command>SHOW</command> commands need to access the inner process, because
+ the guardian itself does not run a nameserver. For this purpose, the guardian passes controlsocket requests to the control console of the
+ inner process. This is the same console as seen with init.d <command>MONITOR</command>.
+ </para></sect1>
+ <sect1 id="modules"><title>Modules & Backends</title>
+ <para>
+ PDNS has the concept of backends and modules. Non-static PDNS distributions have the ability to load new modules at runtime, while the
+ static versions come with a number of modules built in, but cannot load more.
+ </para>
+ <para>
+ Related parameters are:
+ <variablelist>
+ <varlistentry>
+ <term>--help</term>
+ <listitem>
+ <para>
+ Outputs all known parameters, including those of launched backends, see below.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--launch=backend,backend1,backend1:name</term>
+ <listitem>
+ <para>
+ Launches backends. In its most simple form, supply all backends that need to be launched. If you find
+ that you need to launch single backends multiple times, you can specify a name for later instantiations.
+ In this case, there are 2 instances of backend1, and the second one is called 'name'.
+
+ This means that <command>--backend1-setting</command> is available to configure the first or main instance, and
+ <command>--backend1-name-setting</command> for the second one.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--load-modules=/directory/libyourbackend.so</term>
+ <listitem>
+ <para>
+ If backends are available in nonstandard directories, specify their location here. Multiple files
+ can be loaded if separated by commas. Only available in non-static PDNS distributions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--list-modules</term>
+ <listitem>
+ <para>
+ Will list all available modules, both compiled in and in dynamically loadable modules.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ To run on the commandline, use the <command>pdns_server</command> binary. For example, to see options for the gpgsql backend,
+ use the following:
+ <screen>
+ $ /usr/sbin/pdns_server --launch=gpgsql --help=gpgsql
+ </screen>
+ </para>
+ </sect1>
+ <sect1 id="dns-to-query"><title>How PDNS translates DNS queries into backend queries</title>
+ <para>
+ A DNS query is not a straightforward lookup. Many DNS queries need to check the backend for additional data, for example to
+ determine of an unfound record should lead to an NXDOMAIN ('we know about this domain, but that record does not exist') or an
+ unauthoritative response.
+ </para>
+ <para>
+ Simplified, without CNAME processing and wildcards, the algorithm is like this:
+ </para>
+ <para>
+ When a query for a <command>qname</command>/<command>qtype</command> tuple comes in, it is requested directly from the backend.
+ If present, PDNS adds the contents of the reply to the list of records to return. A question tuple may generate multiple answer
+ records.
+ </para>
+ <para>
+ Each of these records is now investigated to see if it needs 'additional processing'. This holds for example for MX records which may
+ point to hosts for which the PDNS backends also contain data. This involves further lookups for A or AAAA records.
+ </para>
+ <para>
+ After all additional processing has been performed, PDNS sieves out all double records which may well have appeared. The resulting set of
+ records is added to the answer packet, and sent out.
+ </para>
+ <para>
+ A zone transfer works by looking up the <command>domain_id</command> of the SOA record of the name and then listing all records of that
+ <command>domain_id</command>. This is why all records in a domain need to have the same domain_id.
+ </para>
+ <para>
+ When a query comes in for an unknown domain, PDNS starts looking for SOA records of all subdomains of the qname, so
+ no.such.powerdns.com turns into a SOA query for no.such.powerdns.com, such.powerdns.com, powerdns.com, com, ''. When a SOA is found,
+ that zone is consulted for relevant NS instructions which lead to a referral. If nothing is found within the zone, an authoritative
+ NXDOMAIN is sent out.
+ </para>
+ <para>
+ If no SOA was found, an unauthoritative no-error is returned.
+ </para>
+ <para>
+ In reality, each query for a question tuple first involves checking for a CNAME, unless that resolution has been disabled with the
+ <command>skip-cname</command> option.
+ </para>
+ <para>
+ PDNS breaks strict RFC compatability by not always checking for the presence of a SOA record first. This is unlikely to lead to
+ problems though.
+ </para>
+ </appendix>
+ <appendix id="backend-writers-guide"><title>Backend writers' guide</title>
+ <para>
+ PDNS backends are implemented via a simple yet powerful C++ interface. If your needs are not met by the PipeBackend, you
+ may want to write your own. Doing so requires a copy of the PowerDNS Open Source Backend Development kit which can be found on <ulink
+ url="http://downloads.powerdns.com/releases/dev">http://downloads.powerdns.com/releases/dev</ulink>.
+ </para>
+ <para>
+ A backend contains zero DNS logic. It need not look for CNAMES, it need not return NS records unless explicitly asked for, etcetera.
+ All DNS logic is contained within PDNS itself - backends should simply return records matching the description asked for.
+ </para>
+ <para>
+ <warning><para>
+ However, please note that your backend can get queries in aNy CAsE! If your database is case sensitive, like most are (with the notable
+ exception of MySQL), you must make sure that you do find answers which differ only in case.
+ </para></warning>
+ </para>
+ <sect1 id="simple-backends"><title>Simple read-only native backends</title>
+ <para>
+ Implementing a backend consists of inheriting from the DNSBackend class. For read-only backends, which do not support slave operation,
+ only the following methods are relevant:
+
+ <programlisting>
+ class DNSBackend
+ {
+ public:
+
+ virtual bool lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
+ virtual bool list(int domain_id)=0;
+ virtual bool get(DNSResourceRecord &r)=0;
+ virtual bool getSOA(const string &name, SOAData &soadata);
+ };
+ </programlisting>
+
+ Note that the first three methods must be implemented. <function>getSOA()</function> has a useful default implementation.
+ </para>
+ <para>
+ The semantics are simple. Each instance of your class only handles one (1) query at a time. There is no need for locking as PDNS guarantees
+ that your backend will never be called reentrantly.
+ </para>
+ <para>
+ Some examples, a more formal specification is down below. A normal lookup starts like this:
+
+ <programlisting>
+ YourBackend yb;
+ yb.lookup(QType::CNAME,"www.powerdns.com");
+ </programlisting>
+
+ Your class should now do everything to start this query. Perform as much preparation as possible - handling errors at this stage is better for PDNS
+ than doing so later on. A real error should be reported by throwing an exception.
+ </para>
+ <para>
+ PDNS will then call the <function>get()</function> method to get <command>DNSResourceRecord</command>s back. The following code illustrates
+ a typical query:
+
+ <programlisting>
+ yb.lookup(QType::CNAME,"www.powerdns.com");
+
+ DNSResourceRecord rr;
+ while(yb.get(rr))
+ cout<<"Found cname pointing to '"+rr.content+"'"<<endl;
+ }
+ </programlisting>
+ </para>
+ <para>
+ Each zone starts with a Start of Authority (SOA) record. This record is special so many backends will choose to implement it
+ specially. The default <function>getSOA()</function> method performs a regular lookup on your backend to figure out the SOA,
+ so if you have no special treatment for SOA records, where is no need to implement your own <function>getSOA()</function>.
+ </para>
+ <para>
+ Besides direct queries, PDNS also needs to be able to list a zone, to do zone transfers for example. Each zone has an id which should be
+ unique within the backend. To list all records belonging to a zone id, the <function>list()</function> method is used. Conveniently,
+ the domain_id is also available in the <command>SOAData</command> structure.
+ </para>
+ <para>
+ The following lists the contents of a zone called "powerdns.com".
+
+ <programlisting>
+ SOAData sd;
+ if(!yb.getSOA("powerdns.com",sd)) // are we authoritative over powerdns.com?
+ return RCode::NotAuth; // no
+
+ yb.list(sd.domain_id);
+ while(yb.get(rr))
+ cout<<rr.qname<<"\t IN "<<rr.qtype.getName()<<"\t"<<rr.content<<endl;
+ </programlisting>
+ </para>
+ <para>
+ Please note that when so called 'fancy records' (see <xref linkend="fancy-records">) are enabled, a backend can receive
+ wildcard lookups. These have a % as the first character of the qdomain in lookup.
+ </para>
+ <sect2><title>A sample minimal backend</title>
+ <para>
+ This backend only knows about the host "random.powerdns.com", and furthermore, only about its A record:
+
+ <programlisting>
+/* FIRST PART */
+class RandomBackend : public DNSBackend
+{
+public:
+ bool list(int id) {
+ return false; // we don't support AXFR
+ }
+
+ void lookup(const QType &type, const string &qdomain, DNSPacket *p, int zoneId)
+ {
+ if(type.getCode()!=QType::A || qdomain!="random.powerdns.com") // we only know about random.powerdns.com A
+ d_answer=""; // no answer
+ else {
+ ostringstream os;
+ os<<random()%256<<"."<<random()%256<<"."<<random()%256<<"."<<random()%256;
+ d_answer=os.str(); // our random ip address
+ }
+ }
+
+ bool get(DNSResourceRecord &rr)
+ {
+ if(!d_answer.empty()) {
+ rr.qname="random.powerdns.com"; // fill in details
+ rr.qtype=QType::A; // A record
+ rr.ttl=86400; // 1 day
+ rr.content=d_answer;
+
+ d_answer=""; // this was the last answer
+
+ return true;
+ }
+ return false; // no more data
+ }
+
+private:
+ string d_answer;
+};
+
+/* SECOND PART */
+
+class RandomFactory : public BackendFactory
+{
+public:
+ RandomFactory() : BackendFactory("random") {}
+
+ DNSBackend *make(const string &suffix)
+ {
+ return new RandomBackend();
+ }
+};
+
+/* THIRD PART */
+
+class RandomLoader
+{
+public:
+ Loader()
+ {
+ BackendMakers().report(new RandomFactory);
+
+ L<<Logger::Info<<" [RandomBackend] This is the randombackend ("__DATE__", "__TIME__") reporting"<<endl;
+ }
+};
+
+static RandomLoader randomloader;
+ </programlisting>
+ This simple backend can be used as an 'overlay'. In other words, it only knows about a single record, another loaded backend would have
+ to know about the SOA and NS records and such. But nothing prevents us from loading it without another backend.
+ </para>
+ <para>
+ The first part of the code contains the actual logic and should be pretty straightforward. The second part is a boilerplate
+ 'factory' class which PDNS calls to create randombackend instances. Note that a 'suffix' parameter is passed. Real life backends
+ also declare parameters for the configuration file; these get the 'suffix' appended to them. Note that the "random" in the
+ constructor denotes the name by which the backend will be known.
+ </para>
+ <para>
+ The third part registers the RandomFactory with PDNS. This is a simple C++ trick which makes sure that this function
+ is called on execution of the binary or when loading the dynamic module.
+ </para>
+ <para>
+ Please note that a RandomBackend is actually in most PDNS releases. By default it lives on random.example.com, but you can change
+ that by setting <command>random-hostname</command>.
+ </para>
+ <para>
+ NOTE: this simple backend neglects to handle case properly! For a more complete example, see the full pdns-dev distribution as found on
+ <ulink url="http://www.powerdns.com/pdns">the website</ulink>.
+ </para>
+ </sect2>
+ <sect2><title>Interface definition</title>
+ <para>
+ Classes:
+ <table>
+ <title>DNSResourceRecord class</title>
+ <tgroup cols=2>
+ <tbody>
+ <row>
+ <entry>QType qtype</entry><entry>QType of this record</entry>
+ </row>
+ <row>
+ <entry>string qname</entry><entry>name of this record</entry>
+ </row>
+ <row>
+ <entry>string content</entry><entry>ASCII representation of right hand side</entry>
+ </row>
+ <row>
+ <entry>u_int16_t priority</entry><entry>priority of an MX record.</entry>
+ </row>
+ <row>
+ <entry>u_int32_t ttl</entry><entry>Time To Live of this record</entry>
+ </row>
+ <row>
+ <entry>int domain_id</entry><entry>ID of the domain this record belongs to</entry>
+ </row>
+ <row>
+ <entry>time_t last_modified</entry><entry>If unzero, last time_t this record was changed</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ <table>
+ <title>SOAData struct</title>
+ <tgroup cols=2>
+ <tbody>
+ <row>
+ <entry>string nameserver</entry><entry>Name of the master nameserver of this zone</entry>
+ </row>
+ <row>
+ <entry>string hostmaster</entry><entry>Hostmaster of this domain. May contain an @</entry>
+ </row>
+ <row>
+ <entry>u_int32_t serial</entry><entry>Serial number of this zone</entry>
+ </row>
+ <row>
+ <entry>u_int32_t refresh</entry><entry>How often this zone should be refreshed</entry>
+ </row>
+ <row>
+ <entry>u_int32_t retry</entry><entry>How often a failed zone pull should be retried.</entry>
+ </row>
+ <row>
+ <entry>u_int32_t expire</entry><entry>If zone pulls failed for this long, retire records</entry>
+ </row>
+ <row>
+ <entry>u_int32_t default_ttl</entry><entry>Difficult</entry>
+ </row>
+ <row>
+ <entry>int domain_id</entry><entry>The ID of the domain within this backend. Must be filled!</entry>
+ </row>
+ <row>
+ <entry>DNSBackend *db</entry><entry>Pointer to the backend that feels authoritative for a domain and can act as a slave</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ Methods:
+ <variablelist>
+ <varlistentry>
+ <term>void lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt=0, int zoneId=-1)</term>
+ <listitem>
+ <para>
+ This function is used to initiate a straight lookup for a record of name 'qdomain' and type 'qtype'.
+ A QType can be converted into an integer by invoking its <function>getCode()</function> method and into
+ a string with the <function>getCode()</function>.
+ </para>
+ <para>
+ The original question may or may not be passed in the pointer p. If it is, you can retrieve (from 1.99.11 onwards)
+ information about who asked the question with the <function>getRemote(DNSPacket *)</function> method. Alternatively,
+ <function>bool getRemote(struct sockaddr *sa, socklen_t *len)</function> is available.
+ </para>
+ <para>
+ Note that <command>qdomain</command> can be of any case and that your backend should make sure it is in effect case
+ insensitive. Furthermore, the case of the original question should be retained in answers returned by <function>get()</function>!
+ </para>
+ <para>
+ Finally, the domain_id might also be passed indicating that only answers from the indicated zone need apply. This
+ can both be used as a restriction or as a possible speedup, hinting your backend where the answer might be found.
+ </para>
+ <para>
+ If initiated succesfully, as indicated by returning <command>true</command>, answers should be made available over the
+ <function>get()</function> method.
+ </para>
+ <para>
+ Should throw an AhuException if an error occured accessing the database. Returning otherwise indicates that the query
+ was started succesfully. If it is known that no data is available, no exception should be thrown! An exception indicates
+ that the backend considers itself broken - not that no answers are available for a question.
+ </para>
+ <para>
+ It is legal to return here, and have the first call to <function>get()</function> return false. This is interpreted as 'no data'
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>bool list(int domain_id)
+ <listitem>
+ <para>
+ Initiates a list of the indicated domain. Records should then be made available via the <function>get()</function> method.
+ Need not include the SOA record. If it is, PDNS will not get confused.
+ </para>
+ <para>
+ Should return false if the backend does not consider itself authoritative for this zone.
+ Should throw an AhuException if an error occured accessing the database. Returning true indicates that data is or should be available.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>bool get(DNSResourceRecord &rr)</term>
+ <listitem>
+ <para>
+ Request a DNSResourceRecord from a query started by <function>get()</function> of <function>list()</function>. If this functions returns
+ <command>true</command>, <command>rr</command> has been filled with data. When it returns false, no more data is available,
+ and <command>rr</command> does not contain new data. A backend should make sure that it either fills out all fields of the
+ DNSResourceRecord or resets them to their default values.
+ </para>
+ <para>
+ The qname field of the DNSResourceRecord should be filled out with the exact <function>qdomain</function> passed to lookup, preserving
+ its case. So if a query for 'CaSe.yourdomain.com' comes in and your database contains dat afor 'case.yourdomain.com', the qname field of rr
+ should contin 'CaSe.yourdomain.com'!
+ </para>
+ <para>
+ Should throw an AhuException in case a database error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>bool getSOA(const string &name, SOAData &soadata)</term>
+ <listitem>
+ <para>
+ If the backend considers itself authoritative over domain <function>name</function>, this method should fill out
+ the passed <command>SOAData</command> structure and return a positive number. If the backend is functioning correctly, but
+ does not consider itself authoritative, it should return 0. In case of errors, an AhuException should be thrown.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ </sect1>
+ <sect1 id="backend-error-reporting"><title>Reporting errors</title>
+ <para>
+ To report errors, the Logger class is available which works mostly like an iostream. Example usage is as shown above in the RandomBackend.
+ Note that it is very important that each line is ended with <command>endl</command> as your message won't be visible otherwise.
+ </para>
+ <para>
+ To indicate the importance of an error, the standard syslog errorlevels are available. They can be set by outputting
+ <function>Logger::Critical</function>,
+ <function>Logger::Error</function>,
+ <function>Logger::Warning</function>,
+ <function>Logger::Notice</function>,
+ <function>Logger::Info</function> or
+ <function>Logger::Debug</function> to <function>L</function>, in descending order of graveness.
+ </para>
+ </sect1>
+ <sect1 id="backend-configuration-details"><title>Declaring and reading configuration details</title>
+ <para>
+ It is highly likely that a backend needs configuration details. On launch, these parameters need to be declared with PDNS so it knows it
+ should accept them in the configuration file and on the commandline. Furthermore, they will be listed in the output of
+ <command>--help</command>.
+ </para>
+ <para>
+ Declaring arguments is done by implementing the member function <function>declareArguments()</function> in the factory class of your
+ backend. PDNS will call this method after launching the backend.
+ </para>
+ <para>
+ In the <function>declareArguments()</function> method, the function <function>declare()</function> is available. The exact definitions:
+ <variablelist>
+ <varlistentry>
+ <term>void declareArguments(const string &suffix="")</term>
+ <listitem>
+ <para>
+ This method is called to allow a backend to register configurable parameters. The suffix is the sub-name of this module. There is
+ no need to touch this suffix, just pass it on to the declare method.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>void declare(const string &suffix, const string &param, const string &explanation, const string &value)</term>
+ <listitem>
+ <para>The suffix is passed to your method, and can be passed on to declare. <command>param</command> is the name of your parameter.
+ <command>explanation</command> is what will appear in the output of --help. Furthermore, a default value can be supplied in the
+ <command>value</command> parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ A sample implementation:
+ <programlisting>
+ void declareArguments(const string &suffix)
+ {
+ declare(suffix,"dbname","Pdns backend database name to connect to","powerdns");
+ declare(suffix,"user","Pdns backend user to connect as","powerdns");
+ declare(suffix,"host","Pdns backend host to connect to","");
+ declare(suffix,"password","Pdns backend password to connect with","");
+ }
+ </programlisting>
+ </para>
+ <para>
+ After the arguments have been declared, they can be accessed from your backend using the <function>mustDo()</function>,
+ <function>getArg()</function> and <function>getArgAsNum()</function> methods. The are defined as follows in the DNSBackend class:
+ </para>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>void setArgPrefix(const string &prefix)</term>
+ <listitem>
+ <para>
+ Must be called before any of the other accessing functions are used. Typical usage is '<function>setArgPrefix("mybackend"+suffix)</function>'
+ in the constructor of a backend.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>bool mustDo(const string &key)</term>
+ <listitem>
+ <para>
+ Returns true if the variable <function>key</function> is set to anything but 'no'.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>const string& getArg(const string &key)</term>
+ <listitem>
+ <para>
+ Returns the exact value of a parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>int getArgAsNum(const string &key)</term>
+ <listitem>
+ <para>
+ Returns the numerical value of a parameter. Uses <function>atoi()</function> internally
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ Sample usage from the BindBackend, using the <command>bind-example-zones</command> and <command>bind-config</command>
+ parameters.
+ <programlisting>
+ if(mustDo("example-zones")) {
+ insert(0,"www.example.com","A","1.2.3.4");
+ /* ... */
+ }
+
+
+ if(!getArg("config").empty()) {
+ BindParser BP;
+
+ BP.parse(getArg("config"));
+ }
+
+ </programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="rw-backends"><title>Read/write slave-capable backends</title>
+ <para>
+ The backends above are 'natively capable' in that they contain all data relevant for a domain and do not pull in data from other nameservers.
+ To enable storage of information, a backend must be able to do more.
+ </para>
+ <para>
+ Before diving into the details of the implementation some theory is in order. Slave domains are pulled from the master. PDNS needs to
+ know for which domains it is to be a slave, and for each slave domain, what the IP address of the master is.
+ </para>
+ <para>
+ A slave zone is pulled from a master, after which it is 'fresh', but this is only temporary. In the SOA record of a zone there is a field
+ which specifies the 'refresh' interval. After that interval has elapsed, the slave nameserver needs to check at the master ff the serial
+ number there is higher than what is stored in the backend locally.
+ </para>
+ <para>
+ If this is the case, PDNS dubs the domain 'stale', and schedules a transfer of data from the remote. This transfer remains scheduled
+ until the serial numbers remote and locally are identical again.
+ </para>
+ <para>
+ This theory is implemented by the <function>getUnfreshSlaveInfos</function> method, which is called on all backends periodically.
+ This method fills a vector of <command>SlaveDomain</command>s with domains that are unfresh and possibly stale.
+ </para>
+ <para>
+ PDNS then retrieves the SOA of those domains remotely and locally and creates a list of stale domains. For each of these domains, PDNS
+ starts a zonetransfer to resynchronise. Because zone transfers can fail, it is important that the interface to the backend allows
+ for transaction semantics because a zone might otherwise be left in a halfway updated situation.
+ </para>
+ <para>
+ The following excerpt from the DNSBackend shows the relevant functions:
+ </para>
+ <para>
+ <programlisting>
+ class DNSBackend {
+ public:
+ /* ... */
+ virtual bool getDomainInfo(const string &domain, DomainInfo &di);
+ virtual bool isMaster(const string &name, const string &ip);
+ virtual bool startTransaction(const string &qname, int id);
+ virtual bool commitTransaction();
+ virtual bool abortTransaction();
+ virtual bool feedRecord(const DNSResourceRecord &rr);
+ virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
+ virtual void setFresh(int id);
+ /* ... */
+ }
+ </programlisting>
+ </para>
+ <para>
+ The mentioned DomainInfo struct looks like this:
+ <table>
+ <title>DomainInfo struct</title>
+ <tgroup cols=2>
+ <tbody>
+ <row>
+ <entry>int id</entry><entry>ID of this zone within this backend</entry>
+ </row>
+ <row>
+ <entry>string master</entry><entry>IP address of the master of this domain, if any</entry>
+ </row>
+ <row>
+ <entry>u_int32_t serial</entry><entry>Serial number of this zone</entry>
+ </row>
+ <row>
+ <entry>u_int32_t notified_serial</entry><entry>Last serial number of this zone that slaves have seen</entry>
+ </row>
+ <row>
+ <entry>time_t last_check</entry><entry>Last time this zone was checked over at the master for changes</entry>
+ </row>
+ <row>
+ <entry>enum {Master,Slave,Native} kind</entry><entry>Type of zone</entry>
+ </row>
+ <row>
+ <entry>DNSBackend *backend</entry><entry>Pointer to the backend that feels authoritative for a domain and can act as a slave</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ These functions all have a default implementation that returns false - which explains that these methods can be omitted in simple backends.
+ Furthermore, unlike with simple backends, a slave capable backend must make sure that the 'DNSBackend *db' field of the SOAData record is filled
+ out correctly - it is used to determine which backend will house this zone.
+ <variablelist>
+ <varlistentry>
+ <term>bool isMaster(const string &name, const string &ip);</term>
+ <listitem>
+ <para>
+ If a backend considers itself a slave for the domain <command>name</command> and if the IP address in <command>ip</command>
+ is indeed a master, it should return true. False otherwise. This is a first line of checks to guard against reloading a domain
+ unnecessarily.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>void getUnfreshSlaveInfos(vector<DomainInfo>* domains)</term>
+ <listitem>
+ <para>
+ When called, the backend should examine its list of slave domains and add any unfresh ones to the domains vector.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bool getDomainInfo(const string &name, DomainInfo & di)</term>
+ <listitem>
+ <para>
+ This is like getUnfreshSlaveInfos, but for a specific domain. If the backend considers itself authoritative for the named
+ zone, <function>di</function> should be filled out, and 'true' be returned. Otherwise return false.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bool startTransaction(const string &qname, int id)</term>
+ <listitem>
+ <para>
+ When called, the backend should start a transaction that can be committed or rolled back atomically later on.
+ In SQL terms, this function should <command>BEGIN</command> a transaction and <command>DELETE</command> all
+ records.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bool feedRecord(const DNSResourceRecord &rr)</term>
+ <listitem>
+ <para>
+ Insert this record.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>bool commitTransaction();</term>
+ <listitem>
+ <para>
+ Make the changes effective. In SQL terms, execute <command>COMMIT</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>bool abortTransaction();</term>
+ <listitem>
+ <para>
+ Abort changes. In SQL terms, execute <command>ABORT</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bool setFresh()</term>
+ <listitem>
+ <para>
+ Indicate that a domain has either been updated or refreshed without the need for a retransfer. This causes
+ the domain to vanish from the vector modified by <function>getUnfreshSlaveInfos()</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ <para>
+ PDNS will always call <function>startTransaction()</function> before making calls to <function>feedRecord()</function>.
+ Although it is likely that <function>abortTransaction()</function> will be called in case of problems, backends should also
+ be prepared to abort from their destructor.
+ </para>
+ <para>
+ The actual code in PDNS is currently (1.99.9):
+ <programlisting>
+ Resolver resolver;
+ resolver.axfr(remote,domain.c_str());
+
+ db->startTransaction(domain, domain_id);
+
+ L<<Logger::Error<<"AXFR started for '"<<domain<<"'"<<endl;
+ Resolver::res_t recs;
+
+ while(resolver.axfrChunk(recs)) {
+ for(Resolver::res_t::const_iterator i=recs.begin();i!=recs.end();++i) {
+ db->feedRecord(*i);
+ }
+ }
+ db->commitTransaction();
+ db->setFresh(domain_id);
+ L<<Logger::Error<<"AXFR done for '"<<domain<<"'"<<endl;
+ </programlisting>
+ </para>
+ <sect2><title>Supermaster/Superslave capability</title>
+ <para>
+ A backend that wants to act as a 'superslave' for a master should implement the following method:
+ <programlisting>
+ class DNSBackend
+ {
+ virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
+ };
+ </programlisting>
+ This function gets called with the IP address of the potential supermaster, the domain it is sending a notification for and the set of NS records
+ for this domain at that IP address.
+ </para>
+ <para>
+ Using the supplied data, the backend needs to determine if this is a bonafide 'supernotification' which should be honoured. If it decides that it
+ should, the supplied pointer to 'account' needs to be filled with the configured name of the supermaster (if accounting is desired), and the
+ db needs to be filled with a pointer to your backend.
+ </para>
+ <para>
+ Supermaster/superslave is a complicated concept, if this is all unclear see <xref linkend="supermaster">.
+ </sect2>
+ </sect1>
+ <sect1 id="master-backends"><title>Read/write master-capable backends</title>
+ <para>
+ In order to be a useful master for a domain, notifies must be sent out whenever a domain is changed. Periodically, PDNS
+ queries backends for domains that may have changed, and sends out notifications for slave nameservers.
+ </para>
+ <para>
+ In order to do so, PDNS calls the <function>getUpdatedMasters()</function> method. Like the <function>getUnfreshSlaveInfos()</function>
+ function mentioned above, this should add changed domain names to the vector passed.
+ </para>
+ <para>
+ The following excerpt from the DNSBackend shows the relevant functions:
+ </para>
+ <para>
+ <programlisting>
+ class DNSBackend {
+ public:
+ /* ... */
+ virtual void getUpdatedMasters(vector<DomainInfo>* domains);
+ virtual void setNotifed(int id, u_int32_t serial);
+ /* ... */
+ }
+ </programlisting>
+ </para>
+ <para>
+ These functions all have a default implementation that returns false - which explains that these methods can be omitted in simple backends.
+
+ Furthermore, unlike with simple backends, a slave capable backend must make sure that the 'DNSBackend *db' field of the SOAData record is filled
+ out correctly - it is used to determine which backend will house this zone.
+
+ <variablelist>
+ <varlistentry>
+ <term>void getUpdatedMasters(vector<DomainInfo>* domains)</term>
+ <listitem>
+ <para>
+ When called, the backend should examine its list of master domains and add any changed ones to the DomainInfo vector
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bool setNotified(int domain_id, u_int32_t serial)</term>
+ <listitem>
+ <para>
+ Indicate that notifications have been queued for this domain and that it need not be considered 'updated' anymore
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect1>
+
+ </appendix>
+ <appendix id="compiling-powerdns"><title>Compiling PowerDNS</title>
+ <para>
+ The PowerDNS source is separated from many of its modules. The main PowerDNS source tree however is able
+ to pull in certain files for creating packaged releases.
+ </para>
+ <para>
+ First download the source or retrieve from anoncvs.powerdns.com (module 'powerdns'). If from cvs, you need to execute
+ <filename>./bootstrap</filename> to have the GNU autotools build the configure script and the Makefiles.
+ </para>
+ <para>
+ The run ./configure, followed by 'make'. PowerDNS prefers being compiled with GCC 3.2 but 2.95.4 and 3.0.4 will also work on most systems.
+ It will not compile on Debian Potato because that lacks the <filename>sstream</filename> include file.
+ </para>
+ <para>
+ After compiling, the <filename>./installer</filename> script can be used to install.
+ </para>
+ <sect1><title>Configuring external modules with PowerDNS</title>
+ <para>
+ A module needs to see the PowerDNS sources. See the INSTALL file of a module on how to configure this.
+ </para>
+ </sect1>
+ </book>
--- /dev/null
+<!doctype linuxdoc system>
+
+<article>
+
+<!-- Title information -->
+<title>The case for PowerDNS</title>
+<author>PowerDNS BV (bert hubert <bert@trilab.com>) &nl;
+Trilab BV</author>
+<date>v1.0 $Date: 2002/11/27 15:18:34 $</date>
+<abstract>
+This document describes what PowerDNS is, how it works and how it can be
+maintained and operated.
+</abstract>
+<toc>
+<sect>The PowerDNS modular system
+<p>
+PowerDNS consists of four distinct modules:
+<itemize>
+<item>Internet Nameserver
+<item>Logical Engine
+<item>Query Backend
+<item>Web-enabled configuration
+</itemize>
+
+Each of these modules can function on its own, and is therefore eminently
+testable and provably correct.
+
+When a DNS query comes in ('What is the IP Address of come.to'), it is
+received by the Internet Nameserver, which parses the packet and sends it to
+the Logical Engine. The Logical Engine then tries to find the best answer
+possible to the question.
+
+To do so, it applies certain rules. Is 'come.to' a globally redirected host?
+If it isn't, is it perhaps an alias for another host? Or do we simply need
+to look up the IP address, and return that. Each of these questions is
+fielded to the Query Backend.
+
+This query backend often just translates the question into SQL, and passes
+it to a relational database, like Oracle, MS SQLServer or PostgreSQL.
+
+A web-frontend is provided for configuring PowerDNS. This frontend is
+multi-user aware, so responsibilities can be delegated, whereby each
+operator can only manage his or her domains.
+
+More on the frontend the relevant chapter.
+
+<sect>PowerDNS Operation & Operational Limits
+<p>
+PowerDNS has been designed to be easy to operate and to function robustly.
+For example, should an unexpected exception occur, the program is restarted
+automatically, within seconds.
+
+<sect1>Installation
+<p>
+PowerDNS can span multiple computers, which either all connect to the same
+database, or each have their own mirrored copy. Normally, PowerDNS is sold
+using an ASP model. However, our initial customer may choose to have a
+local, privately owned installation.
+
+We will assist or even perform the installation for such a customer.
+
+Engineered for simplicity, configuring the nameserver itself (not the
+domains, these are configured using the web-frontend) is done from one
+single point, with only a limited number of settings that need to be
+changed.
+
+<sect1>Operational Limits
+<p>
+Extensive benchmarking has convinced us that network capacity is more of a
+limiting factor than PowerDNS itself will ever be. In testing, the PowerDNS
+server sustained 1500 queries/s on a regular desktop PC for a prolonged
+period of time. It is assumed that this is more than even the biggest
+current nameservers need to handle.
+
+<sect1>Maintaining and configuring domains
+<p>
+Great care has been taken to make the maintenance and configuration of
+domains as easy as possible. Two modes are available, 'Wizard'
+and 'Advanced'. This latest mode is 'vocabulary compatible' with the Bind
+nameserver, so existing administrators will feel right at home. The Wizard
+mode has been stripped of all jargon, and should be easy to follow for most
+Internet users.
+
+The Wizard mode also performs stringent tests on the information entered by
+the operator, so as to prevent misconfiguration.
+
+<sect>Features
+<p>
+PowerDNS has the following features:
+<descrip>
+<tag>Regular nameserving</tag>
+A better performing and robust nameserver. Feature set is limited to current
+and near-future internet practices. Other nameservers often support arcane
+and outdated Name Classes, like those used at MIT in the 1980s. Supporting
+these classes involves shipping more code, which might contain more security
+problems and bugs. More on security in the relevant chapter.
+<tag>Failover</tag>
+When multiple webservers are available, PowerDNS can be configured to only
+return IP Addresses of the servers which are actually functioning. This
+feature has been available for a long time from companies like Alteon or
+Arrowpoint (now both Cisco property).
+
+However, these machines can only function on local networks, as they
+function as a network-element. All your servers need to be in the same
+location for this to work. This is clearly not appropriate in case of
+maximum availability.
+<tag>Global Redirection</tag>
+In combination with Failover support, it is possible to support smart global
+redirection, whereby American customers might get connected to a server in
+New York, whereas European customers might be served by a computer in
+Amsterdam.
+
+<tag>Mail forwarding</tag>
+Although not strictly a Nameserver function, PowerDNS supports very rapid
+and robust mail forwarding. This system has already been employed the past
+months to forward mail for the V3 domains. It is specially engineered to not
+fall over in case of database problems, should they occur, for example when
+the database is suffering from a Denial of Service, as recently happened.
+
+<tag>URL Aliasing</tag>
+Much of the same goes for this. Customers can use URL Aliasing to let them
+point their (sub)domain to other webpages.
+
+<tag>Mail hosting</tag>
+The entire concept of mail hosting was re-engineered because it was found
+that existing systems suffered from sub-optimal performance, with a large
+server able to handle only 50.000 mailboxes at a time.
+
+This support consists of SMTP, Pop and IMAP4, which makes it compatible with
+almost all webmail solutions available.
+
+</descrip>
+
+<sect>Security and Reliability
+<p>
+<sect1>Security
+<p>
+Nameserving is a complex business. Currently, it is evident that existing
+servers suffer from security and Denial of Service vulnerabilities.
+
+There are several reasons for these problems:
+<descrip>
+<tag>Support for obsolete protocols</tag>
+Nameservers currently in use support ancient pre-Internet protocols like
+Hesiod and Chaosnet. Even if you are an Internet-only user, like everybody
+these days, your nameserver will still respond to packets containing
+questions for these protocols. The code supporting these features stems from
+the early 1980s and hasn't been audited in ages.
+
+The support for these protocols also causes other nameservers to be bigger
+than they need be.
+
+<tag>Support for undesirable features</tag>
+This is the cause of the most recent bout of Bind problems. Bind
+supports 'inverse queries', also known as 'iqueries'. This is a Jeopardy like
+situation whereby you ask a nameserver 'Which question has this answer'.
+These questions are no longer appropriate in a time where the Internet can
+at best be considered a unfriendly place.
+
+<tag>Complete integration</tag>
+Current nameservers are completely integrated solutions, carrying within
+their codebase a complete database and replication facility - which is
+exposed to the world. By offloading this functionality to a separate
+Relational Database, complexity is vastly reduced. Furthermore, relational
+databases are very trusted systems - it is good to leave the hard work to
+them.
+
+<tag>Use of outdated languages</tag>
+With languages like C it is very easy to make programming mistakes which
+endanger system security. By using C++ with full typechecking and dynamic
+strings, a lot of problems are avoided. It is no longer possible
+to 'overflow the buffer', as it is called.
+</descrip>
+
+<sect1>Reliability
+<p>
+PowerDNS can be operated from two or more completely independent locations.
+Failure of the one does not hamper the other. Each of these locations can
+easily be redundant in itself. UDP, the protocol over which DNS questions
+are asked and answered on the internet, lends itself very well to clustering
+solutions. It is advised that each location consists of two unconnected
+computers in a failover setup. The 'Virtual Router Redundancy Protocol'
+suffices, one of the easiest ways to set up a redundant group of computers.
+
+Regular nameservers can only run off their secondary for a limited period of
+time (often measured in days!). PowerDNS does not have this limitation.
+
+<sect>Statistics, Logging & Monitoring
+<p>
+PowerDNS can be configured to keep extensive details on its operation. From
+these details, which are available in an easily parseable ASCII form, it is
+possible to compile statistics.
+
+Of possible interest are:
+<itemize>
+<item>Number of questions for which PowerDNS had no answer
+<item>Average time needed to find answer to a question
+<item>Number of questions per second handled
+</itemize>
+
+Should there be a need, graphs can be compiled in realtime using the popular
+MRTG utility, which is easily interfaced onto PowerDNS.
+
+<sect>PowerDNS as a Registrar or domain-merchant Backend
+<p>
+The Web-frontend that comes with PowerDNS is engineered to support millions
+of users simultaneously. When stripped of advanced features, it makes a fine
+platform for any Registrar or domain-merchant.
+
+Everything in PowerDNS has been designed for incredibly high performance, so
+it is possible to support huge numbers of users on limited amounts of
+hardware.
+
+There is no point in the system which needs to be implemented as a single
+computer - all parts can be grown to span multiple servers.
+
+<sect>Competition
+<p>
+Besides the widely used Bind nameserver, there are other solutions
+available. Each of these solutions has its pros and cons.
+<sect1>F5 3DNS
+<p>
+
+Based on an expanded version of BIND, it offers a lot of interesting
+features, like global redirection and loadbalancing. It needs
+several 'probes' at your datacenters, which attempt to measure network
+connectivity.
+
+Unclear how it scales to larger number of domains, or even subdomains. Might
+conflict with plans of being a 'subdomain registrar'.
+
+Can combine with the 'Big-IP Controller' for local failover and
+loadbalancing.
+<sect1>Cisco Distributed Director
+<p>
+Is a weird contraption, which has been reported to take up to an hour to
+process any configuration changes. Uses complicated BGP metrics to calculate
+the optimum server for a user. In our experience, BGP is no longer the right
+way to do so. BGP differentiates the internet into so called Autonomous
+Subsystems. These days however, most of the AS's out there spread the globe.
+
+The Cisco Distributed Director will not be able to differentiate via BGP
+between a server or user located in San Francisco or one in Moscow, if both
+are in the MCI Worldcom network.
+
+This machine also appears to require machines at each server location.
+
+Also unclear how it handles large numbers of domains, especially given the
+time it needs to process configuration changes.
+
+</article>
+
--- /dev/null
+<!doctype linuxdoc system>
+<article>
+
+<!-- Title information -->
+
+<title>PowerDNS 1.2 Install & Usage guide
+<author>PowerDNS BV
+Trilab BV
+<date>v1.1 $Date: 2002/11/27 15:18:35 $
+<abstract>
+This document provides information on how to install PowerDNS and on how
+to maintain it afterwards
+</abstract>
+
+<!-- Table of contents -->
+<toc>
+<!-- Begin the document -->
+<sect>Introduction
+<p>
+PowerDNS is a versatile high-performance modular nameserver that can answer
+questions based on a number of data sources, accessed via backend drivers.
+
+<sect>Compilation
+<p>
+See the INSTALL file that comes with the distribution.
+
+<sect>Syntax
+<p>
+The actual process is called 'ahudns' for historical reasons. It is expected
+that this will change in a future release.
+
+On startup, ahudns reads two files in the configuration directory
+(/usr/local/etc or /opt/ahudns/etc, or whatever was specified during
+compilation), ahudns.conf and ahudns.rc.
+
+<sect1>ahudns.conf
+<p>
+In the configuration directory, you will find ahudns.conf-dist which lists
+the small number of runtime configuration parameters available.
+
+These parameters can either be set via the commandline or via ahudns.conf.
+<descrip>
+<tag>cache-ttl=...</tag>
+Seconds to store packets in the PacketCache. Can be set to zero to
+disable the PacketCache entirely. This is non advised for busy sites. Values
+of in the order of 10 seconds already give appreciable hitrates (80%).
+<tag>default-soa-name=...</tag>
+Name to insert in the SOA record if none set in the backend. Either make
+sure that your backend data source contains complete SOA records, or set
+this to a useful value. This default to 'a.misconfigured.powerdns.server'!
+<tag>distributor-threads=...</tag>
+Default number of Distributor (backend) threads to start. This is very
+dependent on your needs and backend. Higher values are generally better, up
+to a point. MySQL performs very well with a value of 5, with tens of queries
+per second.
+<tag>fancy-records=...</tag>
+Process CURL, URL and MBOXFW records. These magic records are presently
+undocumented and should not be used.
+<tag>localaddress=...</tag>
+ Local IP address to which we bind. It can be important to set this -
+PowerDNS can get confused by machines with multiple NICs.
+<tag>localport=...</tag>
+ The port on which we listen. Should probably always be 53.
+<tag>loglevel=...</tag>
+ Amount of logging. Higher is more. Do not set below 3
+<tag>out-of-zone-additional-processing | out-of-zone-additional-processing=yes | out-of-zone-additional-processing=no </tag>
+ Do out of zone additional processing. Use this if all clients are
+trusted.
+<tag>smtpredirector=...</tag>
+ Our smtpredir MX host. Used for the MBOXFW record.
+<tag>urlredirector=...</tag>
+ Where we send hosts to that need to be url redirected. Used for URL
+and CURL.
+<tag>wildcards=...</tag>
+ Honor wildcards in the database. Switch this off for a significant
+performance gain. Off by default.
+</descrip>
+
+<sect1>ahudns.rc
+<p>
+Given the fact that PowerDNS is very modular, it can't expect to have all
+backend modules available at compile time. Therefore modules are loaded
+dynamically at runtime. This is done by executing the ahudns.rc script found
+in the configuration directory, where ahudns.conf also resides.
+
+You will find ahudns.rc-dist which you can rename to ahudns.rc, and edit at
+will to have PowerDNS load additional modules.
+
+When no modules are loaded, the daemon responds to queries with a 'SERVFAIL'
+packet, indicating that client nameservers should query other servers.
+<sect>Controling ahudns
+<p>
+On startup, ahudns opens a 'controlsocket', which can be used to control the
+daemon. Use the provided 'dynloader' program to issue commands. The
+following commands can be useful:
+<descrip>
+<tag>list</tag>List all statistical variables available
+<tag>ping</tag>Ping the daemon - it will reply if all is well
+<tag>show</tag>Show the value of a specified variable
+<tag>quit</tag>Use this to shut ahudns down
+</descrip>
+
+Use like this: dynloader /opt/ahudns/var/ahudns.controlsocket [command]
+whereby the path refers to the controlsocket location. See the 'init.d'
+chapter for an easier way to control ahudns.
+
+<sect>Running ahudns
+<p>
+There are at least three ways of running ahudns & smtpredir.
+
+<sect1>Directly
+<p>
+By default ahudns runs in the foreground, and can be run from any directory.
+The configuration directory to use is compiled in. In case of problems (out
+of memory, fatal errors), it will exit and not restart by default.
+
+Stop the daemon with the 'killall' or 'pkill command'
+<sect2>With the safe_ahudns wrapper
+<p>
+A better way of running ahudns is with the safe_ahudns wrapper, which is
+distributed with PowerDNS.
+
+This approach is a lot like that taken by safe_mysql from the MySQL
+distribution, should ahudns ever fail for whatever reason, safe_ahudns will
+instantly restart it.
+
+To start ahudns, run '/opt/ahudns/bin/safe_ahudns &' and then check the log
+to see if the connection to the database succeeded.
+
+To stop, use the dynloader programm and pass the command 'quit', which will
+make the daemon exit with error code 99. safe_ahudns interprets 99 as a
+healthy exit with no need to restart the daemon.
+
+<sect1>Running controlled with init.d scripts
+<p>
+This is the preferred way of running ahudns. For easy control of both ahudns
+and smtpredir, use the init.d scripts provided in the 'sample' directory.
+They are usually placed in /etc/init.d, but because of unix variations, they
+are not installed there by default.
+
+Available commands are 'stop', 'start', 'status' and 'restart'. The init.d
+scripts use the safe_* wrappers internally, which will take care of
+restarting the daemons if needed.
+
+<sect>Virtual configurations: running multiple nameservers on a single server
+<p>
+In order to have any number of separate ahudns and smtpredir installations
+there is the ability to specify different configuration files and
+configuration names. This allows you to stop and start the right daemon with
+ease.
+
+By default, all configuration lives in /opt/ahudns/etc, but this can be
+changed with the '--config-dir' commandline option. The recommended layout
+for virtual configurations is:
+
+<tscreen><verb>
+/opt/ahudns/etc For default configuration
+/opt/ahudns/etc-customer1 Customer1 directory
+/opt/ahudns/etc-customer1/ahudns.conf Customer1 configuration
+/opt/ahudns/etc-customer1/ahudns.rc Customer1 backends
+/opt/ahudns/etc-customer2 Customer2 directory
+/opt/ahudns/etc-customer2/ahudns.conf Customer2 configuration
+/opt/ahudns/etc-customer2/ahudns.rc Customer2
+/opt/ahudns/var/ahudns.controlsocket Default control socket (for dynloader)
+/opt/ahudns/var/ahudns-customer1.controlsocket
+/opt/ahudns/var/ahudns-customer2.controlsocket
+</verb></tscreen>
+
+The init.d scripts are aware of virtual configurations. If the 'CONFIGNAME'
+parameter is set, they will automatically start and stop the right instance
+of the daemon, and also pass the name of the virtual configuration file.
+
+Be aware that your ahudns.rc script should refer to the right controlsocket!
+
+A typical virtual installation will have several ahudns- files in
+/etc/init.d, with each a differing CONFIGNAME in the first few lines.
+
+<sect>Logging
+<p>
+Logging is regular syslog, with facility DAEMON.
+
+</article>
+
\ No newline at end of file
--- /dev/null
+<!doctype linuxdoc system>
+
+<article>
+
+<!-- Title information -->
+<title>PowerDNS Overview</title>
+<author>PowerDNS BV (bert hubert <bert@trilab.com>) &nl;
+Trilab BV</author>
+<date>v1.0 $Date: 2002/11/27 15:18:35 $</date>
+<abstract>
+This document describes what PowerDNS is and what it is for
+</abstract>
+<toc>
+<sect>What is PowerDNS
+<p>
+PowerDNS consists of:
+<itemize>
+<item>A Nameserver
+<item>A Mailserver
+<item>A Webserver
+</itemize>
+<sect1>What is a Nameserver?
+<p>
+A Nameserver is a device which translates a human-friendly name
+like 'www.cnn.com' into an Internet Protocol (IP) Address that can be used to
+connect to the actual webserver. This functionality is vital as the
+numerical IP Addresses are unknown to end users so an inability to serve
+names means an inability to serve webpages, or to receive mail.
+
+Due to the complexity and arcane rules surrounding the Domain Name System,
+only a very limited number of Nameserver implementations exist, with the
+vast majority of sites running the antiquated Bind program, which can trace
+it roots to the creation days of the Internet.
+
+<sect1>Nameservers are crucial and tricky to maintain
+<p>
+Nameservers are at the very core of the Internet. All domain operators will
+have experienced often day-long outages due to misconfiguration or other
+operator mistakes. This makes Nameservers somewhat of a no-go zone, with the
+actual configuration and server itself often considered sacred. Domain
+maintenance takes experience operators and is hard to delegate to junior
+personnel.
+
+<sect1>Fixing up the existing Nameservers is not enough
+<p>
+The current Bind program has a long history of security incidents, the most
+recent ones affecting nearly all Internet providers. Currently, even major
+providers are still running vulnerable versions of Bind. Neither HP nor Sun
+have released fixes recently, forcing companies running Nameservers to
+download unsupported versions directly from the Internet Software Consortium.
+
+Any enhancements which affect ease of use will not help improve the security
+situation. Bind predates the large-scale use of relational databases and
+therefore comes with its own built in directory. A paradigm of secure design
+is to use modular programs with clear trust relations between them.
+Integrating everything, including a complete database and replications
+mechanism within the Nameserver itself makes security nearly impossible to
+achieve.
+
+There is a clear need to reinvent the Nameserver.
+
+<sect>The PowerDNS Modular System
+<p>
+PowerDNS Nameserver consists of four distinct modules:
+<itemize>
+<item>Internet Nameserver
+<item>Logical Engine
+<item>Query Backend
+<item>Web-enabled configuration
+</itemize>
+
+Each of these modules can function on its own, and is therefore eminently
+testable and provably correct.
+
+When a DNS query comes in ('What is the IP Address of www.cnn.com'), it is
+received by the Internet Nameserver, which parses the packet and sends it to
+the Logical Engine. The Logical Engine then tries to find the best answer
+possible to the question.
+
+To do so, it applies certain rules. Is 'come.to' a globally redirected host?
+If it isn't, is it perhaps an alias for another host? Or do we simply need
+to look up the IP address, and return that. Each of these questions is
+fielded to the Query Backend.
+
+This query backend often just translates the question into SQL, and passes
+it to a relational database, like Oracle, MySQL, MS SQLServer or PostgreSQL.
+
+An error checking web-frontend is provided for configuring PowerDNS. This
+frontend is multi-user aware, so responsibilities can be delegated, whereby
+each operator can only manage his or her domains.
+
+<sect>Benefits
+<sect1>Modular security, use of a trusted database
+<p>
+Because of the fact that all data comes from a central database, the actual
+Nameserver is very small, outsourcing a lot of the complexity to existing
+and very well trusted database products.
+<sect1>Complete ISP integration into a single data warehouse
+<p>
+Use of a central data repository also means that, for the first time ever, a
+complete self contained ISP solution is possible. When a domain is added to
+the Webserver, the PowerDNS Nameserver is aware of this. If an email address
+is added to a domain, PowerDNS automatically sends the Internet to the right
+place to deliver the message.
+
+Although not obvious for the layman, this is a quantum leap improvement over
+the current situation where Nameservers are an unconnected and often
+independently or externally maintained part of a complete ISP solution.
+
+When operators first experience the integrated operation of PowerDNS they
+are often enveloped by a strong 'this is how it is supposed to be' feeling,
+only then realizing the strangeness of the situation up to now.
+
+<sect1>Very high performance
+<p>
+Storing and retrieving data at high speed is a problem that has been well
+solved by cheaply available database servers. By building on these existing
+products, PowerDNS scales just as well as the database. As there are
+database solutions out there that achieve tens of thousands of transactions
+per second, there is no bottleneck in sight.
+<sect1>Instant updates
+<p>
+Because of this high performance, it is possible to lower the so
+called 'Time To Live' of DNS answers. This in turn means that changes to the
+Nameservers configuration go live nearly instantaneously, instead of taking
+over 24 hours to propagate, as is usually the case.
+<sect1>Interoperability
+<p>
+PowerDNS is, by design, very open. By conforming to all Internet RFCs that
+apply, interoperation with everything currently in use is easily possible.
+The source is unencumbered and can easily be supplied to major customers,
+both for improvements or to diagnose operating problems.
+
+<sect>PowerDNS is a complete Nameserving ISP solution
+<p>
+For the first time, the creation of Internet services can be done from an
+integrated high-performance platform. By reinventing the Nameserver, all
+major ISP functionality can be offered from a single database of user and
+domain data.
+
+By allowing easy web-management of this solution, especially Nameserver
+configuration has become easier and more robust then ever, surpassing
+previous 'Bind front-end' solutions in both performance and reliability.
+
+</article>
+
--- /dev/null
+<!doctype linuxdoc system>
+
+<article>
+
+<!-- Title information -->
+<title>PowerDNS technical overview</title>
+<author>PowerDNS BV (bert hubert <bert@trilab.com>) &nl;
+Trilab BV</author>
+<date>v1.1 $Date: 2002/11/27 15:18:35 $</date>
+<abstract>
+This document contains a technical description of PowerDNS.
+</abstract>
+<toc>
+<sect>PowerDNS is a next generation authoritative nameserver
+<p>
+DNS is among the most mission-critical parts of the internet. While in
+essence very simple, current implementations are complicated applications
+with source code often spanning dozens of megabytes.
+
+The growth of the number of domains means that there is a growing need for a
+lean and mean nameserver that is capable of serving millions of users with
+millions of domains.
+
+The operation of PowerDNS consists of three different parts:
+<itemize>
+<item>Internet Interface
+<item>Logical Engine
+<item>Query Backend
+</itemize>
+
+The Internet Interface receives a question, and hands it to the Logical
+Engine. This Logical Engine then splits up the question into the
+sub-queries, which are handed to the Query Backend, which in turn sends
+queries to any number of data sources. The answer is then transferred back by
+the Logical Engine to the Internet Interface, which sends out the packet
+containing the requested data.
+
+<descrip>
+<tag>The Internet Interface</tag>
+PowerDNS supports receiving queries over UDP and TCP. When a question is
+received, relevant parts of the packet containing the question are compared
+to queries received earlier.
+
+<tag>The Logical Engine</tag>
+A DNS query cannot be translated directly into a backend query. A question
+might be 'What is the IP Address of www.site.com'. In order to answer this
+question, some separate steps need to be performed:
+
+<itemize>
+<item>Is this nameserver Authoritative for this domain, or any of its parent
+domains?
+<item>Do we have a Canonical Name for www.site.com?
+<item>Does www.site.com exist?
+<item>Do we have an IP address for it?
+<item>If we don't, do we know who does?
+<item>Possibly send IP addresses for the nameservers who do know
+</itemize>
+
+This algorithm is described at length in RFC 1034.
+
+<tag>The Query Backend</tag>
+A real life nameserver may have many data sources. Several customer
+databases might exist, as well as standard Zone files. The Query Backend
+fields questions to any number of backends, in a prescribed order. This
+allows for maximum flexibility.
+</descrip>
+
+<sect>Simplicity brings reliability
+<p>
+
+By building on top of existing databases, PowerDNS is as trustworthy as your
+favorite database. Data storage and retrieval is a well solved problem. A
+nameserver should not reinvent it. We support almost all industry standard
+databases and also do custom backend development to graft PowerDNS on an
+existing database or schema.
+
+Due to the completely from scratch implementation without an existing
+installed base to appease, PowerDNS has remained very lean and mean.
+
+Monitoring is at the root of reliability, so the PowerDNS runtime can be
+queried by external scripts. This enables the operator to be informed of any
+problems at an early stage. Some sample scripts for the popular MRTG program
+are supplied.
+
+<sect>Incredible performance
+<p>
+Because of the many steps of the algorithm prescribed by RFC 1034, just
+hooking on a database to a nameserver is not a recipe for great performance.
+Steps need to be taken to streamline the process.
+
+PowerDNS does so in two ways:
+<descrip>
+<tag>Reordering the steps of the algorithm</tag>
+It is often possible to skip some of the steps in the algorithm initially,
+and only perform the other steps when it is really needed, which is often
+not the case.
+<tag>The PacketCache</tag>
+The PacketCache is quite revolutionary in that it caches entire query
+packets for short amounts of time. This PacketCache is consulted before
+running the RFC 1034 Algorithm in the Logical Engine. In production, it has
+been confirmed that even a 1 minute cache can achieve a 80% hitrate and
+thereby prevent 4 out of 5 database queries from ever happening.
+</descrip>
+
+Benchmarking has shown that PowerDNS should be able to reach in the order of
+20.000 queries/second on a reasonably fast database. When using direct
+tables like those supported by Berkeley DB, 50.000 should be achievable.
+
+The use of POSIX Threads also allows PowerDNS to use a large number of
+processors efficiently on architectures that support it.
+<sect>Complete security
+<p>
+PowerDNS is written in highly portable C++ using the ISO Standard C++
+Library (STL). This Library comes with dynamic string classes which all but
+erase the possibility of the much feared buffer overflows that have been
+hitting other nameservers.
+
+The very modular design of PowerDNS also makes for strict internal
+interfaces which can prevent any undesired action from having deleterious
+effects.
+
+Due to the use of modern tools and libraries, PowerDNS consists of only 7000
+lines of source. This is very well auditable in a reasonable period of time
+and can be regarded as a trusted computing base.
+
+Because the database is most often external, it is highly useful to grant
+PowerDNS read-only access to that database. Even a successful compromise can
+than not easily be exploited, because the database refuses to accept updates
+from the nameserver.
+
+<sect>Special Functions
+<p>
+Besides doing lookups in well known databases such as Oracle, Microsoft SQL
+Server, MySQL, PostgreSQL and Sybase, there are special purpose backends
+available.
+
+<sect1>Very Large Zone support
+<p>
+For customers with very large zones and a lots of secondaries, a special
+module has been developed to meet the following goals:
+<itemize>
+<item>Absolute 100% robustness
+<item>Incremental updates
+<item>Near realtime updates
+<item>Idempotent update packets
+<item>Instantaneous zone reloading
+</itemize>
+
+In short, this means that updates are broadcast from a central point. These
+updates can be broadcast as many times as desired because there is no harm
+in applying them more than once. Each of these updates is applied within
+seconds.
+
+It does not use a relational database but instead relies on any of the
+well known table engines that are available, with a strong slant towards
+Berkeley DB.
+<sect1>Global Redirection
+<p>
+With the aid of a comprehensive map of IP addresses, it is possible to do
+smart routing of customers to servers geographically near them. While not
+providing pin-point accuracy, it is broadly effective and very fast.
+
+<sect1>DNS based loadbalancing and failover
+<p>
+Because of the efficiency of PowerDNS, it is feasible to use very low TTLs
+on answers. This in turn makes it possible to perform DNS based
+loadbalancing and failover. This can be very robust because the DNS
+infrastructure itself is redundant, whereas regular loadbalancing agents are
+themselves a single point of failure.
+
+<sect1>CORBA backend
+<p>
+By allowing questions to be asked over this industry standard protocol,
+it becomes trivially easy to integrate PowerDNS with existing middleware
+applications and/or customer databases.
+
+<sect>Standards compliance
+<p>
+PowerDNS is committed to being fully standards compliant. Current supported
+standards include RFC 1034, RFC 1035 and RFC 2181.
+
+<sect>Availability
+<p>
+PowerDNS is available immediately for use. It comes with completely
+documented source and a license that allows the end-user to improve and or
+change the source.
+
+Licensing is possible on a per-CPU or on a per-Domain basis.
+
+PowerDNS is a fully supported product with different levels of support
+available.
+</article>
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include "dynhandler.hh"
+#include "statbag.hh"
+#include "logger.hh"
+#include "dns.hh"
+#include "arguments.hh"
+#include <signal.h>
+#include "misc.hh"\r
+#include "communicator.hh"
+
+static bool s_pleasequit;
+
+bool DLQuitPlease()
+{
+ return s_pleasequit;
+}
+
+string DLQuitHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ string ret="No return value";
+ if(parts[0]=="QUIT") {
+ s_pleasequit=true;
+ ret="Scheduling exit";
+ L<<Logger::Error<<"Scheduling exit on remote request"<<endl;
+ }
+ return ret;
+
+}
+
+static void dokill(int)
+{
+ exit(1);
+}
+
+string DLRQuitHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+#ifndef WIN32
+ signal(SIGALRM, dokill);
+
+ alarm(1);
+
+#else
+
+ if ( !PDNSService::instance()->isRunningAsService())
+ GenerateConsoleCtrlEvent( CTRL_C_EVENT, 0 );
+ else
+ PDNSService::instance()->stop();
+
+#endif // WIN32
+
+ return "Exiting";
+}
+
+string DLPingHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ return "PONG";
+}
+
+string DLShowHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ extern StatBag S;
+ string ret("Wrong number of parameters");
+ if(parts.size()==2) {
+ if(parts[1]=="*")
+ ret=S.directory();
+ else
+ ret=S.getValueStr(parts[1]);
+ }
+
+ return ret;
+}
+
+static string d_status;
+
+void setStatus(const string &str)
+{
+ d_status=str;
+}
+
+string DLStatusHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ ostringstream os;
+ os<<ppid<<": "<<d_status;
+ return os.str();
+}
+
+string DLUptimeHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ ostringstream os;
+ os<<humanDuration(time(0)-s_starttime);
+ return os.str();
+}
+
+string DLPurgeHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ extern PacketCache PC;
+ ostringstream os;
+ int ret;
+
+ if(parts.size()>1)
+ ret=PC.purge(parts[1]);
+ else
+ ret=PC.purge();
+ os<<ret;
+ return os.str();
+}
+
+string DLCCHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ extern PacketCache PC;
+ map<char,int> counts=PC.getCounts();
+ ostringstream os;
+ bool first=true;
+ for(map<char,int>::const_iterator i=counts.begin();i!=counts.end();++i) {
+ if(!first)
+ os<<", ";
+ first=false;
+
+ if(i->first=='!')
+ os<<"negative queries: ";
+ else if(i->first=='Q')
+ os<<"queries: ";
+ else if(i->first=='n')
+ os<<"non-recursive packets: ";
+ else if(i->first=='r')
+ os<<"recursive packets: ";
+ else
+ os<<"unknown: ";
+
+ os<<i->second;
+ }
+
+ return os.str();
+}
+
+
+string DLSettingsHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ static const char *whitelist[]={"query-logging",0};
+ const char **p;
+
+ if(parts.size()!=3) {
+ return "Syntax: set variable value";
+ }
+
+ for(p=whitelist;*p;p++)
+ if(*p==parts[1])
+ break;
+ if(p) {
+ arg().set(parts[1])=parts[2];
+ return "done";
+ }
+ else
+ return "This setting cannot be changed at runtime";
+
+}
+
+
+string DLVersionHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+
+ return VERSION;
+}
+
+
+string DLNotifyHostHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ extern CommunicatorClass Communicator;
+ ostringstream os;
+ if(parts.size()!=3)
+ return "syntax: notify domain ip";
+ L<<Logger::Warning<<"Notification request to host "<<parts[2]<<" for domain '"<<parts[1]<<"' received"<<endl;
+ Communicator.notify(parts[1],parts[2]);
+ return "Added to queue";
+}
+
+string DLNotifyHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ extern CommunicatorClass Communicator;
+ ostringstream os;
+ if(parts.size()!=2)
+ return "syntax: notify domain";
+ L<<Logger::Warning<<"Notification request for domain '"<<parts[1]<<"' received"<<endl;
+ if(!Communicator.notifyDomain(parts[1]))
+ return "Failed to add to the queue - see log";
+ return "Added to queue";
+}
+
+string DLRediscoverHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ PacketHandler P;
+ P.getBackend()->rediscover();
+ L<<Logger::Error<<"Rediscovery was requested"<<endl;
+ return "Ok";
+}
+
+string DLReloadHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+ PacketHandler P;
+ P.getBackend()->reload();
+ L<<Logger::Error<<"Reload was requested"<<endl;
+ return "Ok";
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PDNS_DYNHANDLER_HH
+#define PDNS_DYNHANDLER_HH
+
+#include <vector>
+#include <string>
+#include <stdlib.h>
+#include <sys/types.h>
+\r
+#ifndef WIN32\r
+# include "config.h"\r
+# include <unistd.h>\r
+#else\r
+# include "pdnsservice.hh"\r
+#endif // WIN32\r
+
+using namespace std;
+
+
+bool DLQuitPlease();
+string DLQuitHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLRQuitHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLPingHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLShowHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLUptimeHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLSettingsHandler(const vector<string>&parts, Utility::pid_t ppid);
+void setStatus(const string &str);
+string DLCCHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLStatusHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLNotifyHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLNotifyHostHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLReloadHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLRediscoverHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLVersionHandler(const vector<string>&parts, Utility::pid_t ppid);
+string DLPurgeHandler(const vector<string>&parts, Utility::pid_t ppid);
+#endif /* PDNS_DYNHANDLER_HH */
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: dynlistener.cc,v 1.1 2002/11/27 15:18:33 ahu Exp $
+/* (C) Copyright 2002 PowerDNS.COM BV */
+#include <cstring>
+#include <string>
+#include <map>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <iostream>
+#include <sstream>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "misc.hh"
+#include "dns.hh"
+#include "arguments.hh"
+#include "dnsbackend.hh"
+#include "dynlistener.hh"
+#include "dnspacket.hh"
+#include "logger.hh"
+#include "statbag.hh"
+
+
+
+extern StatBag S;
+
+DynListener::DynListener(const string &pname)
+{
+ d_restfunc=0;
+ string programname=pname;
+
+ if(!programname.empty()) {
+ struct sockaddr_un local;
+ d_s=socket(AF_UNIX,SOCK_DGRAM,0);
+
+ if(d_s<0) {
+ L<<Logger::Error<<"creating socket for dynlistener: "<<strerror(errno)<<endl;;
+ exit(1);
+ }
+
+ int tmp=1;
+ if(setsockopt(d_s,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0)
+ throw AhuException(string("Setsockopt failed: ")+strerror(errno));
+
+ string socketname=arg()["socket-dir"]+"/";
+ cleanSlashes(socketname);
+
+ if(!mkdir(socketname.c_str(),0700)) // make /var directory, if needed
+ L<<Logger::Warning<<"Created local state directory '"<<socketname<<"'"<<endl;
+ else if(errno!=EEXIST) {
+ L<<Logger::Critical<<"FATAL: Unable to create socket directory ("<<socketname<<") and it does not exist yet"<<endl;
+ exit(1);
+ }
+
+ socketname+=programname+".controlsocket";
+ unlink(socketname.c_str());
+ memset(&local,0,sizeof(local));
+ local.sun_family=AF_UNIX;
+ strcpy(local.sun_path,socketname.c_str());
+
+ if(bind(d_s, (sockaddr*)&local,sizeof(local))<0) {
+ L<<Logger::Critical<<"binding to dynlistener '"<<socketname<<"': "<<strerror(errno)<<endl;
+ exit(1);
+ }
+
+ if(!arg()["setgid"].empty()) {
+ if(chown(socketname.c_str(),static_cast<uid_t>(-1),Utility::makeGidNumeric(arg()["setgid"]))<0)
+ L<<Logger::Error<<"Unable to change group ownership of controlsocket: "<<strerror(errno)<<endl;
+ if(chmod(socketname.c_str(),0660)<0)
+ L<<Logger::Error<<"Unable to change group access mode of controlsocket: "<<strerror(errno)<<endl;
+ }
+
+
+ L<<Logger::Warning<<"Listening on controlsocket in '"<<socketname<<"'"<<endl;
+ d_udp=true;
+ }
+ else
+ d_udp=false;
+
+
+}
+
+void DynListener::go()
+{
+ d_ppid=getpid();
+ pthread_create(&d_tid,0,&DynListener::theListenerHelper,this);
+}
+
+void *DynListener::theListenerHelper(void *p)
+{
+ DynListener *us=static_cast<DynListener *>(p);
+ us->theListener();
+ return 0;
+}
+
+string DynListener::getLine()
+{
+ char mesg[512];
+ memset(mesg,0,sizeof(mesg));
+ int len;
+
+ if(d_udp) {
+ d_addrlen=sizeof(d_remote);
+
+ if((len=recvfrom(d_s,mesg,512,0,(sockaddr*) &d_remote, &d_addrlen))<0) {
+ L<<Logger::Error<<"Unable to receive packet from controlsocket ("<<d_s<<") - exiting: "<<strerror(errno)<<endl;
+ exit(1);
+ }
+ }
+ else {
+ if(isatty(0))
+ write(1, "% ", 2);
+ if((len=read(0,mesg,512))<0)
+ throw AhuException("Reading from the control pipe: "+stringerror());
+ else if(len==0)
+ throw AhuException("Guardian exited - going down as well");
+ }
+
+ return mesg;
+}
+
+void DynListener::sendLine(const string &l)
+{
+ if(d_udp)
+ sendto(d_s,l.c_str(),l.length()+1,0,(struct sockaddr *)&d_remote,d_addrlen);
+ else {
+ string line=l;
+ line.append("\n");
+ write(1,line.c_str(),line.length());
+ }
+}
+
+void DynListener::registerFunc(const string &name, g_funk_t *gf)
+{
+ d_funcdb[name]=gf;
+}
+
+void DynListener::registerRestFunc(g_funk_t *gf)
+{
+ d_restfunc=gf;
+}
+
+void DynListener::theListener()
+{
+ try {
+ map<string,string> parameters;
+
+ for(;;) {
+ string line=getLine();
+ chomp(line,"\n");
+
+ vector<string>parts;
+ stringtok(parts,line," ");
+ if(parts.empty()) {
+ sendLine("Empty line");
+ continue;
+ }
+ upperCase(parts[0]);
+ if(!d_funcdb[parts[0]]) {
+ if(d_restfunc)
+ sendLine((*d_restfunc)(parts,d_ppid));
+ else
+ sendLine("Unknown command: '"+parts[0]+"'");
+ continue;
+ }
+
+ sendLine((*d_funcdb[parts[0]])(parts,d_ppid));
+ }
+ }
+ catch(AhuException &AE)
+ {
+ L<<Logger::Error<<"Fatal: "<<AE.reason<<endl;
+ }
+ catch(string &E)
+ {
+ L<<Logger::Error<<"Fatal: "<<E<<endl;
+ }
+ catch(...)
+ {
+ L<<Logger::Error<<"Fatal: unknown exception occured"<<endl;
+ }
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PDNS_DYNLISTENER
+#define PDNS_DYNLISTENER
+
+#include <string>
+#include <vector>
+#include <pthread.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <iostream>
+#include <sstream>
+\r
+#ifndef WIN32\r
+#include <unistd.h>\r
+#include <sys/un.h>\r
+#include <dlfcn.h>\r
+\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#endif // WIN32\r
+\r
+using namespace std;
+
+class DynListener
+{
+public:
+ DynListener(const string &pname="");
+ void go();
+ void theListener();
+ static void *theListenerHelper(void *p);
+
+ typedef string g_funk_t(const vector<string> &parts, Utility::pid_t ppid); // guido!
+ typedef map<string,g_funk_t *> g_funkdb_t;
+
+ void registerFunc(const string &name, g_funk_t *gf);
+ void registerRestFunc(g_funk_t *gf);
+private:
+ void sendLine(const string &line);
+ string getLine();\r
+\r
+#ifndef WIN32
+ struct sockaddr_un d_remote;\r
+#else\r
+ HANDLE m_pipeHandle;\r
+#endif // WIN32\r
+
+ Utility::socklen_t d_addrlen;
+
+ int d_s;
+ pthread_t d_tid;
+ bool d_udp;
+ pid_t d_ppid;
+
+
+ g_funkdb_t d_funcdb;
+ g_funk_t* d_restfunc;
+
+};
+#endif /* PDNS_DYNLISTENER */
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include <iostream>
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <unistd.h>
+#include <errno.h>
+#include <climits>
+#include <string>
+#include <map>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include <sys/stat.h>
+#include "ahuexception.hh"
+#include "misc.hh"
+#include "dynmessenger.hh"
+#include "arguments.hh"
+#include "config.h"
+#include "statbag.hh"
+#include "misc.hh"
+using namespace std;
+
+ArgvMap &arg()
+{
+ static ArgvMap arg;
+ return arg;
+}
+
+StatBag S;
+
+int main(int argc, char **argv)
+{
+ string s_programname="pdns";
+ string localdir;
+
+ static char pietje[128]="!@@SYSCONFDIR@@:";
+ arg().set("config-dir","Location of configuration directory (pdns.conf)")=
+ strcmp(pietje+1,"@@SYSCONFDIR@@:") ? pietje+strlen("@@SYSCONFDIR@@:")+1 : SYSCONFDIR;
+
+ arg().set("socket-dir","Where the controlsocket will live")=LOCALSTATEDIR;
+ arg().set("config-name","Name of this virtual configuration - will rename the binary image")="";
+ arg().set("chroot","")="";
+ arg().laxParse(argc,argv);
+
+ if(arg()["config-name"]!="")
+ s_programname+="-"+arg()["config-name"];
+
+ string configname=arg()["config-dir"]+"/"+s_programname+".conf";
+ cleanSlashes(configname);
+
+ arg().laxFile(configname.c_str());
+ string socketname=arg()["socket-dir"]+"/"+s_programname+".controlsocket";
+ if(arg()["chroot"].empty())
+ localdir="/tmp";
+ else
+ localdir=dirname(strdup(socketname.c_str()));
+
+
+ const vector<string>&commands=arg().getCommands();
+
+ if(commands.empty()) {
+ cerr<<"No command passed"<<endl;
+ return 0;
+ }
+
+ try {
+ string command=commands[0];
+
+ DynMessenger D(localdir,socketname);
+
+ string message;
+ for(vector<string>::const_iterator i=commands.begin();i!=commands.end();++i) {
+ if(i!=commands.begin())
+ message+=" ";
+ message+=*i;
+ }
+
+ if(command=="show") {
+ message="SHOW ";
+ for(unsigned int n=1;n<commands.size();n++) {
+ message+=commands[n];
+ message+=" ";
+ }
+ }
+ else if(command=="list") {
+ message="SHOW *";
+ command="show";
+ }
+ else if(command=="quit" || command=="QUIT") {
+ message="QUIT";
+ }
+ else if(command=="status" || command=="STATUS") {
+ message="STATUS";
+ }
+ else if(command=="version" || command=="VERSION") {
+ message="VERSION";
+ }
+
+
+ if(D.send(message)<0) {
+ cerr<<"Error sending command"<<endl;
+ return 1;
+ }
+
+ string resp=D.receive();
+
+ cout<<resp<<endl;
+ }
+ catch(AhuException &ae) {
+ cerr<<"Fatal error: "<<ae.reason<<endl;
+ }
+ return 0;
+}
+
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "dynmessenger.hh"
+#include <cstdio>
+#include <cstring>
+#include <cerrno>
+#include <iostream>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+DynMessenger::DynMessenger(const string &localdir, const string &fname)
+{
+ d_s=socket(AF_UNIX,SOCK_DGRAM,0);
+
+ if(d_s<0) {
+ throw AhuException(string("socket")+strerror(errno));
+ }
+
+ memset(&d_local,0,sizeof(d_local));
+
+ string localname=localdir;
+
+ localname+="/lsockXXXXXX";
+ d_local.sun_family=AF_UNIX;
+ strcpy(d_local.sun_path,localname.c_str());
+
+ if(mkstemp(d_local.sun_path)<0)
+ throw AhuException("Unable to generate local temporary file: "+string(strerror(errno)));
+
+ unlink(d_local.sun_path);
+
+ if(bind(d_s, (sockaddr*)&d_local,sizeof(d_local))<0)
+ throw AhuException("Unable to bind to local temporary file: "+string(strerror(errno)));
+
+ if(chmod(d_local.sun_path,0666)<0) { // make sure that pdns can reply!
+ perror("fchmod");
+ exit(1);
+ }
+
+ memset(&d_remote,0,sizeof(d_remote));
+
+ d_remote.sun_family=AF_UNIX;
+ strcpy(d_remote.sun_path,fname.c_str());
+}
+
+DynMessenger::~DynMessenger()
+{
+ if(unlink(d_local.sun_path)<0)
+ cerr<<"Warning: unable to unlink local unix domain endpoint: "<<strerror(errno)<<endl;
+ close(d_s);
+}
+
+int DynMessenger::send(const string &msg) const
+{
+ if(sendto(d_s,msg.c_str(),strlen(msg.c_str())+1,
+ 0,(struct sockaddr *)&(d_remote),
+ sizeof(d_remote))<0)
+ {
+ perror("sendto");
+ return -1;
+ }
+ return 0;
+
+}
+
+/*
+ int recvfrom(int s, void *buf, size_t len, int flags,
+ struct sockaddr *from, socklen_t *fromlen);
+*/
+
+string DynMessenger::receive() const
+{
+ char buffer[512];
+ struct sockaddr_un dontcare;
+ unsigned int len=sizeof(dontcare);
+ int retlen;
+ retlen=recvfrom(d_s,buffer,sizeof(buffer),0,(struct sockaddr *)&dontcare,&len);
+ // FIXME XXX error checking!
+ buffer[retlen]=0;
+ string answer=buffer;
+ return answer;
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef DYNMESSENGER_HH
+#define DYNMESSENGER_HH
+
+#include <string>
+#include <sys/types.h>
+
+#ifndef WIN32
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <sys/un.h>
+# include <unistd.h>
+# include <libgen.h>
+
+#else
+# include "pdnsservice.hh"
+
+#endif // WIN32
+
+#include <errno.h>
+#include "ahuexception.hh"
+
+using namespace std;
+
+//! The DynMessenger can send messages to UNIX domain sockets
+class DynMessenger
+{
+ int d_s;
+
+#ifndef WIN32
+ struct sockaddr_un d_local; // our local address
+ struct sockaddr_un d_remote; // our remote address
+
+#else
+ HANDLE m_pipeHandle; // Named pipe handle.
+
+#endif // WIN32
+
+
+ DynMessenger(const DynMessenger &); // NOT IMPLEMENTED
+
+public:
+ // CREATORS
+
+ DynMessenger(const string &ldir, const string &filename); //!< Create a DynMessenger sending to this file
+ ~DynMessenger();
+
+ // ACCESSORS
+ int send(const string &message) const; //!< Send a message to a DynListener
+ string receive() const; //!< receive an answer from a DynListener
+};
+
+#endif
--- /dev/null
+# $Id: Makefile,v 1.1 2002/11/27 15:18:37 ahu Exp $
+
+all: null.o
+
+install:
+
+distdir:
+
+distclean: clean
+
+clean:
+ rm -f null.o *.o *.so
--- /dev/null
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
--- /dev/null
+#!/bin/sh
+#
+# The installer queries the user for right places to install the software.
+# It offers three standard possibilities:
+#
+# Overwriting strategy. Binaries are overwritten, configuration files not,
+# new files are placed suffixed by '.new'. Example:
+# /etc/powerdns/pdns.conf-new
+
+if [ "x$1" != "x" ]
+then
+ . $1
+else
+ . ./pathconfig
+fi
+
+DESTDIR=${DESTDIR:-} # debian interface
+
+BINARIES="pdns_server pdns_control backends/bind/zone2sql"
+
+if test -n "$LD_LIBRARY_PATH"
+then
+ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:`pwd`/libs"
+else
+ LD_LIBRARY_PATH="`pwd`/libs"
+fi
+
+./binpatch ./pdns_server $CONFIGPATH
+./binpatch ./pdns_control $CONFIGPATH
+mkdir -p $DESTDIR$BINARYPATH > /dev/null 2> /dev/null
+strip $BINARIES
+cp $BINARIES $DESTDIR$BINARYPATH
+
+if test -n "$DOCPATH"
+then
+ mkdir -p $DESTDIR$DOCPATH > /dev/null 2> /dev/null
+ cp -r README LICENSE docs/pdns.txt docs/pdns.pdf docs/pdns.txt docs/html $DESTDIR$DOCPATH 2> /dev/null
+fi
+
+mkdir -p $DESTDIR$CONFIGPATH > /dev/null 2> /dev/null
+
+if test -d ./libs
+then
+ mkdir -p $DESTDIR$LIBRARYPATH > /dev/null 2> /dev/null
+ cp ./libs/* $DESTDIR$LIBRARYPATH
+fi
+
+if test -s $DESTDIR$CONFIGPATH/pdns.conf
+then
+ suf=".new"
+ echo $DESTDIR$CONFIGPATH/pdns.conf exists, making $DESTDIR$CONFIGPATH/pdns.conf$suf
+else
+ suf=""
+fi
+
+echo "# Added by install script" > $DESTDIR$CONFIGPATH/pdns.conf$suf
+echo "module-dir=$LIBRARYPATH" >> $DESTDIR$CONFIGPATH/pdns.conf$suf
+echo "socket-dir=$SOCKETPATH" >> $DESTDIR$CONFIGPATH/pdns.conf$suf
+echo "setuid=$PDNSUID" >> $DESTDIR$CONFIGPATH/pdns.conf$suf
+echo "setgid=$PDNSGID" >> $DESTDIR$CONFIGPATH/pdns.conf$suf
+echo "launch=bind" >> $DESTDIR$CONFIGPATH/pdns.conf$suf
+
+echo "# end " >> $DESTDIR$CONFIGPATH/pdns.conf$suf
+$DESTDIR$BINARYPATH/pdns_server --config >> $DESTDIR$CONFIGPATH/pdns.conf$suf
+
+
+mkdir -p $DESTDIR$INITDPATH/ > /dev/null 2> /dev/null
+mkdir -p $DESTDIR$SOCKETPATH/ > /dev/null 2> /dev/null
+
+echo "#!/bin/sh" > $DESTDIR$INITDPATH/pdns
+echo "BINARYPATH=$BINARYPATH" >> $DESTDIR$INITDPATH/pdns
+echo "SOCKETPATH=$SOCKETPATH" >> $DESTDIR$INITDPATH/pdns
+echo export LD_LIBRARY_PATH=$LIBRARYPATH:\$LD_LIBRARY_PATH >> $DESTDIR$INITDPATH/pdns
+
+cat pdns.in >> $DESTDIR$INITDPATH/pdns
+chmod +x $DESTDIR$INITDPATH/pdns
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PDNS_IPUTILSHH
+#define PDNS_IPUTILSHH
+
+#include <string>
+\r
+#ifndef WIN32\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#endif // WIN32\r
+\r
+#include <iostream>
+#include <stdio.h>
+#include <functional>
+#include "ahuexception.hh"
+
+using namespace std;
+
+/** This exception is thrown by the Netmask class and by extension by the NetmaskGroup class */
+class NetmaskException: public AhuException
+{
+public:
+ NetmaskException(const string &a) : AhuException(a) {}
+};
+
+/** This class represents a netmask and can be queried to see if a certain
+ IP address is matched by this mask */
+
+class Netmask
+{
+public:
+ //! Constructor supplies the mask, which cannot be changed
+ Netmask(const string &mask)
+ {
+ char *p;
+ char bits=32;
+ if((p=strchr(mask.c_str(),'/')))
+ bits=atoi(p+1);
+
+ d_mask=~((1<<(32-bits))-1); // 1<<16 0000 0000 0000 0000 0000 0000 0000 0000
+
+ struct in_addr a;
+ if(!Utility::inet_aton(mask.substr(0,p-mask.c_str()).c_str(), &a))
+ throw NetmaskException("Unable to convert '"+mask+"' to a netmask");
+ d_network=htonl(a.s_addr);
+ }
+
+ //! If this IP address in socket address matches
+ bool match(const struct sockaddr_in *ip) const
+ {
+ return match(htonl((unsigned int)ip->sin_addr.s_addr));
+ }
+
+ //! If this ASCII IP address matches
+ bool match(const string &ip) const
+ {
+ struct in_addr a;
+ Utility::inet_aton(ip.c_str(), &a);
+ return match(htonl(a.s_addr));
+ }
+
+ //! If this IP address in native format matches
+ bool match(u_int32_t ip) const
+ {
+ return (ip & d_mask) == (d_network & d_mask);
+ }
+
+
+private:
+ u_int32_t d_network;
+ u_int32_t d_mask;
+};
+
+/** This class represents a group of supplemental Netmask classes. An IP address matchs
+ if it is matched by zero or more of the Netmask classes within.
+*/
+class NetmaskGroup
+{
+public:
+ //! If this IP address is matched by any of the classes within
+ bool match(struct sockaddr_in *ip)
+ {
+ for(container_t::const_iterator i=d_masks.begin();i!=d_masks.end();++i)
+ if(i->match(ip))
+ return true;
+
+ return false;
+ }
+ //! Add this Netmask to the list of possible matches
+ void addMask(const string &ip)
+ {
+ d_masks.push_back(Netmask(ip));
+ }
+
+ bool empty()
+ {
+ return d_masks.empty();
+ }
+
+private:
+ typedef vector<Netmask> container_t;
+ container_t d_masks;
+
+};
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef LOCK_HH
+#define LOCK_HH
+
+#include <pthread.h>
+#include <errno.h>
+#include "misc.hh"
+#include "ahuexception.hh"
+class Lock
+{
+ pthread_mutex_t *d_lock;
+public:
+
+ Lock(pthread_mutex_t *lock) : d_lock(lock)
+ {
+ if((errno=pthread_mutex_lock(d_lock)))
+ throw AhuException("error acquiring lock: "+stringerror());
+ }
+ ~Lock()
+ {
+ pthread_mutex_unlock(d_lock);
+ }
+};
+
+class WriteLock
+{
+ pthread_rwlock_t *d_lock;
+public:
+
+ WriteLock(pthread_rwlock_t *lock) : d_lock(lock)
+ {
+ if((errno=pthread_rwlock_wrlock(d_lock))) {
+ throw AhuException("error acquiring rwlock wrlock: "+stringerror());
+ }
+ }
+ ~WriteLock()
+ {
+ pthread_rwlock_unlock(d_lock);
+ }
+};
+
+class TryWriteLock
+{
+ pthread_rwlock_t *d_lock;
+ bool d_havelock;
+public:
+
+ TryWriteLock(pthread_rwlock_t *lock) : d_lock(lock)
+ {
+ d_havelock=false;
+ if((errno=pthread_rwlock_trywrlock(d_lock)) && errno!=EBUSY)
+ throw AhuException("error acquiring rwlock tryrwlock: "+stringerror());
+ d_havelock=(errno==0);
+ }
+ ~TryWriteLock()
+ {
+ if(d_havelock)
+ pthread_rwlock_unlock(d_lock);
+ }
+ bool gotIt()
+ {
+ return d_havelock;
+ }
+};
+
+class TryReadLock
+{
+ pthread_rwlock_t *d_lock;
+ bool d_havelock;
+public:
+
+ TryReadLock(pthread_rwlock_t *lock) : d_lock(lock)
+ {
+
+ d_havelock=false;
+ if((errno=pthread_rwlock_tryrdlock(d_lock)) && errno!=EBUSY)
+ throw AhuException("error acquiring rwlock tryrdlock: "+stringerror());
+ d_havelock=(errno==0);
+ }
+ ~TryReadLock()
+ {
+ if(d_havelock)
+ pthread_rwlock_unlock(d_lock);
+ }
+ bool gotIt()
+ {
+ return d_havelock;
+ }
+};
+
+
+class ReadLock
+{
+ pthread_rwlock_t *d_lock;
+public:
+
+ ReadLock(pthread_rwlock_t *lock) : d_lock(lock)
+ {
+ if((errno=pthread_rwlock_rdlock(d_lock)))
+ throw AhuException("error acquiring rwlock tryrwlock: "+stringerror());
+ }
+ ~ReadLock()
+ {
+ pthread_rwlock_unlock(d_lock);
+ }
+
+ void upgrade()
+ {
+ pthread_rwlock_unlock(d_lock);
+ pthread_rwlock_wrlock(d_lock);
+ }
+
+};
+
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "logger.hh"
+#include "statbag.hh"
+
+using namespace std;
+
+Logger &theL(const string &pname)
+{
+ static Logger l("");
+ if(!pname.empty())
+ l.setName(pname);
+ return l;
+}
+
+void Logger::log(const string &msg, Urgency u)
+{
+ struct tm tm;
+ time_t t;
+ time(&t);
+ tm=*localtime(&t);
+
+ if(u<=consoleUrgency) {// Sep 14 06:52:09
+ char buffer[50];
+ strftime(buffer,sizeof(buffer),"%b %d %H:%M:%S ", &tm);
+ clog<<buffer;
+ clog <<msg <<endl;
+ }
+ extern StatBag S;
+ S.ringAccount("logmessages",msg);
+ syslog(u,"%s",msg.c_str());
+}
+
+void Logger::toConsole(Urgency u)
+{
+
+ consoleUrgency=u;
+}
+
+void Logger::open()
+{
+ if(opened)
+ closelog();
+ openlog(name.c_str(),flags,d_facility);
+ opened=true;
+}
+
+void Logger::setName(const string &_name)
+{
+ name=_name;
+ open();
+}
+
+Logger::Logger(const string &n, int facility)
+{
+ opened=false;
+ flags=LOG_PID|LOG_NDELAY;
+ d_facility=facility;
+ consoleUrgency=Error;
+ name=n;
+ pthread_mutex_init(&lock,0);
+ open();
+
+}
+
+Logger& Logger::operator<<(Urgency u)
+{
+ pthread_mutex_lock(&lock);
+
+ d_outputurgencies[pthread_self()]=u;
+
+ pthread_mutex_unlock(&lock);
+ return *this;
+}
+
+Logger& Logger::operator<<(const string &s)
+{
+ pthread_mutex_lock(&lock);
+
+ if(!d_outputurgencies.count(pthread_self())) // default urgency
+ d_outputurgencies[pthread_self()]=Info;
+
+ // if(d_outputurgencies[pthread_self()]<=(unsigned int)consoleUrgency) // prevent building strings we won't ever print
+ d_strings[pthread_self()].append(s);
+
+ pthread_mutex_unlock(&lock);
+ return *this;
+}
+
+Logger& Logger::operator<<(int i)
+{
+ ostringstream tmp;
+ tmp<<i;
+
+ *this<<tmp.str();
+
+ return *this;
+}
+
+Logger& Logger::operator<<(ostream & (&)(ostream &))
+{
+ // *this<<" ("<<(int)d_outputurgencies[pthread_self()]<<", "<<(int)consoleUrgency<<")";
+ pthread_mutex_lock(&lock);
+
+
+ log(d_strings[pthread_self()], d_outputurgencies[pthread_self()]);
+ d_strings.erase(pthread_self());
+ d_outputurgencies.erase(pthread_self());
+
+ pthread_mutex_unlock(&lock);
+ return *this;
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef LOGGER_HH
+#define LOGGER_HH
+/* (C) 2002 POWERDNS.COM BV */
+
+#include <string>
+#include <map>
+#include <ctime>
+#include <iostream>
+#include <sstream>
+#include <pthread.h>
+
+#ifndef WIN32
+# include <syslog.h>
+
+#else
+# define WINDOWS_LEAN_AND_MEAN
+# include <windows.h>
+
+#endif // WIN32
+
+using namespace std;
+
+//! The Logger class can be used to log messages in various ways.
+class Logger
+{
+public:
+#ifndef WIN32
+ Logger(const string &, int facility=LOG_DAEMON); //!< pass the identification you wish to appear in the log
+
+ //! The urgency of a log message
+ enum Urgency {All=99999,NTLog=12345,Alert=LOG_ALERT, Critical=LOG_CRIT, Error=LOG_ERR, Warning=LOG_WARNING,
+ Notice=LOG_NOTICE,Info=LOG_INFO, Debug=LOG_DEBUG, None=-1};
+
+#else
+ Logger( const string &, int facility = 0 ); //!< pass the identification you wish to appear in the log
+
+ //! The urgency of a log message
+ enum Urgency
+ {
+ All = 99999,
+ NTLog = 12345,
+ Alert = EVENTLOG_ERROR_TYPE,
+ Critical= EVENTLOG_ERROR_TYPE,
+ Error = EVENTLOG_ERROR_TYPE,
+ Warning = EVENTLOG_WARNING_TYPE,
+ Notice = EVENTLOG_INFORMATION_TYPE,
+ Info = EVENTLOG_INFORMATION_TYPE,
+ Debug = EVENTLOG_INFORMATION_TYPE,
+ None = -1
+ };
+
+ void toNTLog( void );
+
+private:
+ //! Handle used to communicate with the event log.
+ HANDLE m_eventLogHandle;
+
+ //! Log file handle.
+ FILE *m_pLogFile;
+
+ //! Log current message to the NT log?
+ map< pthread_t, bool > m_toNTLog;
+
+public:
+
+#endif // WIN32
+
+ /** Log a message.
+ \param msg Message you wish to log
+ \param Urgency Urgency of the message you wish to log
+ */
+ void log(const string &msg, Urgency u=Notice);
+
+ void setFacility(int f){d_facility=f;open();} //!< Choose logging facility
+ void setFlag(int f){flags|=f;open();} //!< set a syslog flag
+ void setName(const string &);
+
+ //! set lower limit of urgency needed for console display. Messages of this urgency, and higher, will be displayed
+ void toConsole(Urgency);
+
+ //! Log to a file.
+ void toFile( const string & filename );
+
+ void resetFlags(){flags=0;open();} //!< zero the flags
+ /** Use this to stream to your log, like this:
+ \code
+ L<<"This is an informational message"<<endl; // logged at default loglevel (Info)
+ L<<Logger::Warning<<"Out of diskspace"<<endl; // Logged as a warning
+ L<<"This is an informational message"<<endl; // logged AGAIN at default loglevel (Info)
+ \endcode
+ */
+ Logger& operator<<(const string &s); //!< log a string
+ Logger& operator<<(int); //!< log an int
+ Logger& operator<<(Urgency); //!< set the urgency, << style
+
+#ifndef WIN32
+ Logger& operator<<(ostream & (&)(ostream &)); //!< this is to recognise the endl, and to commit the log
+#else
+ // This is a hack to keep MSVC from generating a internal compiler error.
+ Logger& operator<<(ostream & (hack)(ostream &)); //!< this is to recognise the endl, and to commit the log
+#endif // WIN32
+
+private:
+ map<pthread_t,string>d_strings;
+ map<pthread_t,Urgency> d_outputurgencies;
+ void open();
+ string name;
+ int flags;
+ int d_facility;
+ bool opened;
+ Urgency consoleUrgency;
+ pthread_mutex_t lock;
+};
+
+extern Logger &theL(const string &pname="");
+
+#ifdef VERBOSELOG
+#define DLOG(x) x
+#else
+#define DLOG(x)
+#endif
+
+
+#endif
--- /dev/null
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.4.2a
+TIMESTAMP=" (1.922.2.79 2001/11/28 21:50:31)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+: ${IFS=" "}
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case $arg in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ execute_dlfiles)
+ execute_dlfiles="$execute_dlfiles $arg"
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case $arg in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ exit 0
+ ;;
+
+ --config)
+ sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --preserve-dup-deps) duplicate_deps="yes" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case $nonopt in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case $arg in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case $mode in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ prev=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+
+ user_target=no
+ for arg
+ do
+ case $prev in
+ "") ;;
+ xcompiler)
+ # Aesthetically quote the previous argument.
+ prev=
+ lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+
+ case $arg in
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ continue
+ ;;
+ esac
+
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ if test "$user_target" != "no"; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ user_target=next
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Wc,*)
+ args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ lastarg="$lastarg $arg"
+ done
+ IFS="$save_ifs"
+ lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+ # Add the arguments to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ continue
+ ;;
+ esac
+
+ case $user_target in
+ next)
+ # The next one is the -o target name
+ user_target=yes
+ continue
+ ;;
+ yes)
+ # We got the output file
+ user_target=set
+ libobj="$arg"
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ case $lastarg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ case $user_target in
+ set)
+ ;;
+ no)
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ *)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ xform='[cCFSfmso]'
+ case $libobj in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case $libobj in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $libobj"
+ else
+ removelist="$libobj"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2*)
+ pic_mode=default
+ ;;
+ esac
+ if test $pic_mode = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $run ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $srcfile $pic_flag -DPIC"
+ else
+ # Don't build PIC code
+ command="$base_compile $srcfile"
+ fi
+ if test "$build_old_libs" = yes; then
+ lo_libobj="$libobj"
+ dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$libobj"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+ if test -d "$dir"; then
+ $show "$rm $libobj"
+ $run $rm $libobj
+ else
+ $show "$mkdir $dir"
+ $run $mkdir $dir
+ status=$?
+ if test $status -ne 0 && test ! -d $dir; then
+ exit $status
+ fi
+ fi
+ fi
+ if test "$compiler_o_lo" = yes; then
+ output_obj="$libobj"
+ command="$command -o $output_obj"
+ elif test "$compiler_c_o" = yes; then
+ output_obj="$obj"
+ command="$command -o $output_obj"
+ fi
+
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test x"$output_obj" != x"$libobj"; then
+ $show "$mv $output_obj $libobj"
+ if $run $mv $output_obj $libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # If we have no pic_flag, then copy the object into place and finish.
+ if (test -z "$pic_flag" || test "$pic_mode" != default) &&
+ test "$build_old_libs" = yes; then
+ # Rename the .lo from within objdir to obj
+ if test -f $obj; then
+ $show $rm $obj
+ $run $rm $obj
+ fi
+
+ $show "$mv $libobj $obj"
+ if $run $mv $libobj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+ libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ # Now arrange that obj and lo_libobj become the same file
+ $show "(cd $xdir && $LN_S $baseobj $libobj)"
+ if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $run $rm "$lockfile"
+ fi
+ exit 0
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $srcfile"
+ else
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $srcfile $pic_flag -DPIC"
+ fi
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test x"$output_obj" != x"$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ else
+ # Move the .lo from within objdir
+ $show "$mv $libobj $lo_libobj"
+ if $run $mv $libobj $lo_libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+ fi
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $run $rm "$lockfile"
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link | relink)
+ modename="$modename: link"
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invokation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args="$nonopt"
+ compile_command="$nonopt"
+ finalize_command="$nonopt"
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static"; then
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ else
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ prefer_static_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test $# -gt 0; do
+ arg="$1"
+ shift
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+ ;;
+ *) qarg=$arg ;;
+ esac
+ libtool_args="$libtool_args $qarg"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ xcompiler)
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ compile_command="$compile_command $qarg"
+ finalize_command="$finalize_command $qarg"
+ continue
+ ;;
+ xlinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $wl$qarg"
+ prev=
+ compile_command="$compile_command $wl$qarg"
+ finalize_command="$finalize_command $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n $prev
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: more than one -exported-symbols argument is not allowed"
+ exit 1
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | no/*-*-nonstopux*)
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+ exit 1
+ fi
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "*) ;;
+ *)
+ deplibs="$deplibs -L$dir"
+ lib_search_path="$lib_search_path $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$dir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-pw32* | *-*-beos*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-mingw* | *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # in order for the loader to find any dlls it needs.
+ $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+ $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -static)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -Wc,*)
+ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ case $flag in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ flag="\"$flag\""
+ ;;
+ esac
+ arg="$arg $wl$flag"
+ compiler_flags="$compiler_flags $flag"
+ done
+ IFS="$save_ifs"
+ arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+ ;;
+
+ -Wl,*)
+ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ case $flag in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ flag="\"$flag\""
+ ;;
+ esac
+ arg="$arg $wl$flag"
+ compiler_flags="$compiler_flags $wl$flag"
+ linker_flags="$linker_flags $flag"
+ done
+ IFS="$save_ifs"
+ arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.lo | *.$objext)
+ # A library or standard object.
+ if test "$prev" = dlfiles; then
+ # This file was specified with -dlopen.
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $arg"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+ prev=
+ else
+ case $arg in
+ *.lo) libobjs="$libobjs $arg" ;;
+ *) objs="$objs $arg" ;;
+ esac
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ deplibs="$deplibs $arg"
+ old_deplibs="$old_deplibs $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ dlfiles="$dlfiles $arg"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ dlprefiles="$dlprefiles $arg"
+ prev=
+ else
+ deplibs="$deplibs $arg"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done # argument parsing loop
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+ # Create the object directory.
+ if test ! -d $output_objdir; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ # Determine the type of output
+ case $output in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ libs="$libs $deplib"
+ done
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+ case $linkmode in
+ lib)
+ passes="conv link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+ for pass in $passes; do
+ if test $linkmode = prog; then
+ # Determine which files to process
+ case $pass in
+ dlopen)
+ libs="$dlfiles"
+ save_deplibs="$deplibs" # Collect dlpreopened libraries
+ deplibs=
+ ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -l*)
+ if test $linkmode = oldlib && test $linkmode = obj; then
+ $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2
+ continue
+ fi
+ if test $pass = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+ for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}.la"
+ if test -f "$lib"; then
+ found=yes
+ break
+ fi
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ ;; # -l
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test $pass = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ ;;
+ prog)
+ if test $pass = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test $pass = scan; then
+ deplibs="$deplib $deplibs"
+ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ ;;
+ *)
+ $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test $pass = link; then
+ dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la) lib="$deplib" ;;
+ *.$libext)
+ if test $pass = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ if test "$deplibs_check_method" != pass_all; then
+ echo
+ echo "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not used here."
+ else
+ echo
+ echo "*** Warning: Linking the shared library $output against the"
+ echo "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ continue
+ ;;
+ prog)
+ if test $pass != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ newdlprefiles="$newdlprefiles $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ newdlfiles="$newdlfiles $deplib"
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+ if test $found = yes || test -f "$lib"; then :
+ else
+ $echo "$modename: cannot find the library \`$lib'" 1>&2
+ exit 1
+ fi
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$ladir" = "X$lib" && ladir="."
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variable installed.
+ installed=yes
+
+ # Read the .la file
+ case $lib in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test $linkmode = oldlib && test $linkmode = obj; }; then
+ # Add dl[pre]opened files of deplib
+ test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ fi
+
+ if test $pass = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+ exit 1
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $ladir/$objdir/$old_library"
+ old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+ elif test $linkmode != prog && test $linkmode != lib; then
+ $echo "$modename: \`$lib' is not a convenience library" 1>&2
+ exit 1
+ fi
+ continue
+ fi # $pass = conv
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+ exit 1
+ fi
+
+ # This library was specified with -dlopen.
+ if test $pass = dlopen; then
+ if test -z "$libdir"; then
+ $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+ exit 1
+ fi
+ if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload.
+ dlprefiles="$dlprefiles $lib"
+ else
+ newdlfiles="$newdlfiles $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ $echo "$modename: warning: library \`$lib' was moved." 1>&2
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$libdir"
+ absdir="$libdir"
+ fi
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ fi # $installed = yes
+ name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+ # This library was specified with -dlpreopen.
+ if test $pass = dlpreopen; then
+ if test -z "$libdir"; then
+ $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+ exit 1
+ fi
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ newdlprefiles="$newdlprefiles $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ newdlprefiles="$newdlprefiles $dir/$dlname"
+ else
+ newdlprefiles="$newdlprefiles $dir/$linklib"
+ fi
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test $linkmode = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs"
+ fi
+ continue
+ fi
+
+ if test $linkmode = prog && test $pass != link; then
+ newlib_search_path="$newlib_search_path $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+ esac
+ # Need to link against all dependency_libs?
+ if test $linkalldeplibs = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ link_static=no # Whether the deplib will be linked statically
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ # Link against this shared library
+
+ if test "$linkmode,$pass" = "prog,link" ||
+ { test $linkmode = lib && test $hardcode_into_libs = yes; }; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ if test $linkmode = prog; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *" $absdir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+ fi
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+
+ if test "$installed" = no; then
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=yes
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+ libname=`eval \\$echo \"$libname_spec\"`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin*)
+ major=`expr $current - $age`
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ soname=`echo $soroot | sed -e 's/^.*\///'`
+ newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a"
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ $show "extracting exported symbol list from \`$soname'"
+ save_ifs="$IFS"; IFS='~'
+ eval cmds=\"$extract_expsyms_cmds\"
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ $show "generating import library for \`$soname'"
+ save_ifs="$IFS"; IFS='~'
+ eval cmds=\"$old_archive_from_expsyms_cmds\"
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n $old_archive_from_expsyms_cmds
+
+ if test $linkmode = prog || test "$mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+ esac
+ fi
+ if test $linkmode = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes && \
+ test "$hardcode_minus_L" != yes && \
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test $linkmode = prog || test "$mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ add="-l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ add="-l$name"
+ fi
+
+ if test $linkmode = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test $linkmode = prog; then
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+
+ # Try to link the static library
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ echo "*** Warning: This system can not link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test $linkmode = lib; then
+ if test -n "$dependency_libs" &&
+ { test $hardcode_into_libs != yes || test $build_old_libs = yes ||
+ test $link_static = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ *) temp_deplibs="$temp_deplibs $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ newlib_search_path="$newlib_search_path $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+
+ if test $link_all_deplibs != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$deplib" && dir="."
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if grep "^installed=no" $deplib > /dev/null; then
+ path="-L$absdir/$objdir"
+ else
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ if test "$absdir" != "$libdir"; then
+ $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+ fi
+ path="-L$absdir"
+ fi
+ ;;
+ *) continue ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$deplibs $path" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test $pass = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test $pass != dlopen; then
+ test $pass != scan && dependency_libs="$newdependency_libs"
+ if test $pass != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ if test "$pass" = "conv" &&
+ { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then
+ libs="$deplibs" # reset libs
+ deplibs=
+ fi
+ done # for pass
+ if test $linkmode = prog; then
+ dlfiles="$newdlfiles"
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ objs="$objs$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ if test "$module" = no; then
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval libname=\"$libname_spec\"
+ else
+ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+ exit 1
+ else
+ echo
+ echo "*** Warning: Linking the shared library $output against the non-libtool"
+ echo "*** objects $objs is not portable!"
+ libobjs="$libobjs $objs"
+ fi
+ fi
+
+ if test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test $# -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ libext=al
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ current="$2"
+ revision="$3"
+ age="$4"
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case $revision in
+ 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case $age in
+ 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test $age -gt $current; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ minor_current=`expr $current + 1`
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ irix | nonstopux)
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ major=`expr $current - $age + 1`
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test $loop != 0; do
+ iface=`expr $revision - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test $loop != 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ major=`expr $current - $age`
+ versuffix="-$major"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ verstring="0.0"
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=""
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+ fi
+
+ if test "$mode" != relink; then
+ # Remove our outputs.
+ $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+ $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ for path in $notinst_path; do
+ lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'`
+ deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'`
+ dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'`
+ done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ if test $hardcode_into_libs != yes || test $build_old_libs = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) dlfiles="$dlfiles $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) dlprefiles="$dlprefiles $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ deplibs="$deplibs -framework System"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test $build_libtool_need_lc = "yes"; then
+ deplibs="$deplibs -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behaviour.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm conftest
+ $CC -o conftest conftest.c $deplibs
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occured in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ $rm conftest
+ $CC -o conftest conftest.c $i
+ # Did it work?
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method
+ file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null \
+ | grep " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+ | sed 10q \
+ | egrep "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ echo "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ echo "*** with $libname and none of the candidates passed a file format test"
+ echo "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method
+ match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check below in file_magic test
+ if eval echo \"$potent_lib\" 2>/dev/null \
+ | sed 10q \
+ | egrep "$match_pattern_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ echo "*** with $libname and none of the candidates passed a file format test"
+ echo "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' |
+ grep . >/dev/null; then
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ echo "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test $allow_undefined = no; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ if test $hardcode_into_libs = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ dep_rpath="$dep_rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ test -z "$dlname" && dlname=$soname
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Ensure that we have .o objects for linkers which dislike .lo
+ # (e.g. aix) in case we are running --disable-static
+ for obj in $libobjs; do
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ if test ! -f $xdir/$oldobj; then
+ $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+ $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+ fi
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ eval cmds=\"$export_symbols_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex"; then
+ $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+ $run eval '$mv "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+ fi
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linker_flags="$linker_flags $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+ exit 0
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case $output in
+ *.lo)
+ if test -n "$objs$old_deplibs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${obj}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show $rm $libobj
+ $run $rm $libobj
+ xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$libobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ $show "(cd $xdir && $LN_S $oldobj $baseobj)"
+ $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+ fi
+
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;;
+ esac
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test "$preload" = yes; then
+ if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+ test "$dlopen_self_static" = unknown; then
+ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+ fi
+ fi
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ ;;
+ esac
+
+ compile_command="$compile_command $compile_deplibs"
+ finalize_command="$finalize_command $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$libdir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ dlsyms=
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$dlsyms"; then
+ case $dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${outputname}.nm"
+
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+ # Parse the name list into a source file.
+ $show "creating $output_objdir/$dlsyms"
+
+ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`echo "$arg" | sed -e 's%^.*/%%'`
+ $run eval 'echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+ :
+ else
+ grep -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+ esac;;
+ *-*-hpux*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+ esac
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+ # Clean up the generated files.
+ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test $need_relink = no || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$link_command"
+ $run eval "$link_command"
+ status=$?
+
+ # Delete the generated files.
+ if test -n "$dlsyms"; then
+ $show "$rm $output_objdir/${outputname}S.${objext}"
+ $run $rm "$output_objdir/${outputname}S.${objext}"
+ fi
+
+ exit $status
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $run $rm $output
+ # Link the executable and exit
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+ exit 0
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+ relink_command="$var=\"$var_value\"; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case $0 in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*) exeext=.exe ;;
+ *) exeext= ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variable:
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ echo >> $output "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" || \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $mkdir \"\$progdir\"
+ else
+ $rm \"\$progdir/\$file\"
+ fi"
+
+ echo >> $output "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $echo \"\$relink_command_output\" >&2
+ $rm \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $rm \"\$progdir/\$program\";
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $rm \"\$progdir/\$file\"
+ fi"
+ else
+ echo >> $output "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ echo >> $output "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $echo >> $output "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # win32 systems need to use the prog path for dll
+ # lookup to work
+ *-*-cygwin* | *-*-pw32*)
+ $echo >> $output "\
+ exec \$progdir/\$program \${1+\"\$@\"}
+"
+ ;;
+
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2*)
+ $echo >> $output "\
+ exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $echo >> $output "\
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $echo >> $output "\
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ # Ensure that we have .o objects in place in case we decided
+ # not to build a shared library, and have fallen back to building
+ # static libs even though --disable-static was passed!
+ for oldobj in $oldobjs; do
+ if test ! -f $oldobj; then
+ xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$oldobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+ obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+ $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+ fi
+ done
+
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+ relink_command="$var=\"$var_value\"; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args)"
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdependency_libs="$newdependency_libs $libdir/$name"
+ ;;
+ *) newdependency_libs="$newdependency_libs $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+ for lib in $dlfiles; do
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdlfiles="$newdlfiles $libdir/$name"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $rm $output
+ # place dlname in correct position for cygwin
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ esac
+ $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test $need_relink = yes; then
+ $echo >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+ $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test $# -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ relink_command=
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ if test -n "$relink_command"; then
+ $echo "$modename: warning: relinking \`$file'" 1>&2
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ continue
+ fi
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$srcname $destdir/$realname"
+ $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+ if test -n "$stripme" && test -n "$striplib"; then
+ $show "$striplib $destdir/$realname"
+ $run eval "$striplib $destdir/$realname" || exit $?
+ fi
+
+ if test $# -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin*|*mingw*)
+ wrapper=`echo $file | sed -e 's,.exe$,,'`
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if (sed -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
+ notinst_deplibs=
+ relink_command=
+
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $wrapper ;;
+ *) . ./$wrapper ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$notinst_deplibs"; then
+ $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case $lib in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $wrapper ;;
+ *) . ./$wrapper ;;
+ esac
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ if test "$finalize" = yes && test -z "$run"; then
+ tmpdir="/tmp"
+ test -n "$TMPDIR" && tmpdir="$TMPDIR"
+ tmpdir="$tmpdir/libtool-$$"
+ if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+ else
+ $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+ continue
+ fi
+ file=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ ${rm}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ $echo "$modename: warning: cannot relink \`$file'" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyways
+ case $install_prog,$host in
+ /usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ destfile=`echo $destfile | sed -e 's,.exe$,,'`
+ ;;
+ esac
+ ;;
+ esac
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ test -n "$outputname" && ${rm}r "$tmpdir"
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ if test -n "$stripme" && test -n "$striplib"; then
+ $show "$old_striplib $oldlib"
+ $run eval "$old_striplib $oldlib" || exit $?
+ fi
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $0 --finish$current_libdirs'
+ else
+ exit 0
+ fi
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ test "$show" = ":" && exit 0
+
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case $file in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved enviroment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ fi
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool clean and uninstall mode
+ clean | uninstall)
+ modename="$modename: $mode"
+ rm="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) rm="$rm $arg"; rmforce=yes ;;
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ rmdirs=
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$file"; then
+ dir=.
+ objdir="$objdir"
+ else
+ objdir="$dir/$objdir"
+ fi
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ test $mode = uninstall && objdir="$dir"
+
+ # Remember objdir for removal later, being careful to avoid duplicates
+ if test $mode = clean; then
+ case " $rmdirs " in
+ *" $objdir "*) ;;
+ *) rmdirs="$rmdirs $objdir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if (test -L "$file") >/dev/null 2>&1 \
+ || (test -h "$file") >/dev/null 2>&1 \
+ || test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $objdir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+ test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+
+ if test $mode = uninstall; then
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ if test $? != 0 && test "$rmforce" != yes; then
+ exit_status=1
+ fi
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ if test $? != 0 && test "$rmforce" != yes; then
+ exit_status=1
+ fi
+ done
+ IFS="$save_ifs"
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ ;;
+
+ *)
+ # Do a test to see if this is a libtool program.
+ if test $mode = clean &&
+ (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ relink_command=
+ . $dir/$file
+
+ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ rmfiles="$rmfiles $objdir/lt-$name"
+ fi
+ fi
+ ;;
+ esac
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles || exit_status=1
+ done
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ $show "rmdir $dir"
+ $run rmdir $dir >/dev/null 2>&1
+ fi
+ done
+
+ exit $exit_status
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$exec_cmd"; then
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+ eval exec $exec_cmd
+ exit 1
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+clean)
+ $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -prefer-pic try to building PIC objects only
+ -prefer-non-pic try to building non-PIC objects only
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "misc.hh"
+#include <vector>
+#include <sstream>
+#include <errno.h>
+#include <sys/param.h>
+#include <cstring>\r
+\r
+#include <iomanip>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+\r
+#ifndef WIN32\r
+# include <sys/time.h>\r
+# include <time.h>\r
+# include <netinet/in.h>
+# include <unistd.h>
+#endif // WIN32\r
+
+#include "utility.hh"
+
+
+
+int sendData(const char *buffer, int replen, int outsock)
+{
+ u_int16_t nlen=htons(replen);
+ Utility::iovec iov[2];
+ iov[0].iov_base=(char*)&nlen;
+ iov[0].iov_len=2;
+ iov[1].iov_base=(char*)buffer;
+ iov[1].iov_len=replen;
+ int ret=Utility::writev(outsock,iov,2);
+
+ if(ret<0) {
+ return -1;
+ }
+ if(ret!=replen+2) {
+ return -1;
+ }
+ return 0;
+}
+
+
+void parseService(const string &descr, ServiceTuple &st)
+{
+ vector<string>parts;
+ stringtok(parts,descr,":");
+ st.host=parts[0];
+ if(parts.size()>1)
+ st.port=atoi(parts[1].c_str());
+}
+
+int matchNetmask(const char *address, const char *omask)
+{
+ struct in_addr a,m;
+ int bits=32;
+ char *sep;
+
+ char *mask=strdup(omask);
+ sep=strchr(mask,'/');
+
+ if(sep) {
+ bits=atoi(sep+1);
+ *sep=0;
+ }
+
+ if(!Utility::inet_aton(address, &a) || !Utility::inet_aton(mask, &m))\r
+ {\r
+ free(mask);
+ return -1;
+ }
+
+ free(mask);
+
+ // bits==32 -> 0xffffffff
+ // bits==16 -> 0xffff0000
+ // bits==0 -> 0x00000000
+ unsigned int bmask=~((1<<(32-bits))-1); // 1<<16 0000 0000 0000 0000 0000 0000 0000 0000
+
+ /*
+ fprintf(stderr,"%x\n",bmask);
+ fprintf(stderr,"%x\n",(htonl((unsigned int)a.s_addr) & bmask));
+ fprintf(stderr,"%x\n",(htonl((unsigned int)m.s_addr) & bmask));
+ */
+
+ return ((htonl((unsigned int)a.s_addr) & bmask) == (htonl((unsigned int)m.s_addr) & bmask));
+}
+
+int waitForData(int fd, int seconds)
+{
+ struct timeval tv;\r
+ int ret;\r
+\r
+ tv.tv_sec = seconds;\r
+ tv.tv_usec = 0;\r
+\r
+ fd_set readfds;\r
+ FD_ZERO( &readfds );\r
+ FD_SET( fd, &readfds );\r
+\r
+ ret = select( fd + 1, &readfds, NULL, NULL, &tv );\r
+ if ( ret == -1 )\r
+ {\r
+ ret = -1;\r
+ errno = ETIMEDOUT;\r
+ }\r
+\r
+ return ret;
+}
+
+
+string humanDuration(time_t passed)
+{
+ ostringstream ret;
+ if(passed<60)
+ ret<<passed<<" seconds";
+ else if(passed<3600)
+ ret<<setprecision(2)<<passed/60.0<<" minutes";
+ else if(passed<86400)
+ ret<<setprecision(3)<<passed/3600.0<<" hours";
+ else if(passed<(86400*30.41))
+ ret<<setprecision(3)<<passed/86400.0<<" days";
+ else
+ ret<<setprecision(3)<<passed/(86400*30.41)<<" months";
+
+ return ret.str();
+}
+
+DTime::DTime()
+{
+// set();
+}
+
+DTime::DTime(const DTime &dt)
+{
+ d_set=dt.d_set;
+}
+
+time_t DTime::time()
+{
+ return d_set.tv_sec;
+}
+
+// Make s uppercase:
+void upperCase(string& s) {
+ for(unsigned int i = 0; i < s.length(); i++)
+ s[i] = toupper(s[i]);
+}
+
+
+void chomp(string &line, const string &delim)
+{
+ string::reverse_iterator i;
+ for( i=line.rbegin();i!=line.rend();++i)
+ if(delim.find(*i)==string::npos)
+ break;
+
+ line.resize(line.rend()-i);
+}
+
+
+
+
+void stripLine(string &line)
+{
+ unsigned int pos=line.find_first_of("\r\n");
+ if(pos!=string::npos) {
+ line.resize(pos);
+ }
+}
+
+string urlEncode(const string &text)
+{
+ string ret;
+ for(string::const_iterator i=text.begin();i!=text.end();++i)
+ if(*i==' ')ret.append("%20");
+ else ret.append(1,*i);
+ return ret;
+}
+
+string getHostname()
+{
+ char tmp[MAXHOSTNAMELEN];
+ if(gethostname(tmp, MAXHOSTNAMELEN))
+ return "UNKNOWN";
+
+ return tmp;
+}
+
+string itoa(int i)
+{
+ ostringstream o;
+ o<<i;
+ return o.str();
+}
+
+string stringerror()
+{
+ return strerror(errno);
+}
+
+void cleanSlashes(string &str)
+{
+ string::const_iterator i;
+ string out;
+ for(i=str.begin();i!=str.end();++i) {
+ if(*i=='/' && i!=str.begin() && *(i-1)=='/')
+ continue;
+ out.append(1,*i);
+ }
+ str=out;
+}
+
+const string sockAddrToString(struct sockaddr_in *remote, socklen_t socklen)
+{
+ if(socklen==sizeof(struct sockaddr_in))
+ return inet_ntoa(((struct sockaddr_in *)remote)->sin_addr);
+
+ // TODO: Add ipv6 support here.
+#ifndef WIN32
+ else {
+ char tmp[128];
+
+ if(!inet_ntop(AF_INET6, (void*)&((struct sockaddr_in6 *)remote)->sin6_addr, tmp, sizeof(tmp)))
+ return "IPv6 untranslateable";
+
+ return tmp;
+ }
+#endif // WIN32
+
+ return "untranslateable";
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef MISC_HH
+#define MISC_HH
+/* (C) 2002 POWERDNS.COM BV */
+\r
+
+#include "utility.hh"
+
+#ifndef WIN32
+# include <sys/time.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <time.h>\r
+\r
+#else\r
+# pragma warning ( disable: 4786 )\r
+# define WINDOWS_LEAN_AND_MEAN\r
+# include <windows.h>\r
+# include "utility.hh"\r
+\r
+\r
+#endif // WIN32\r
+\r
+
+#include <string>
+#include <ctype.h>
+using namespace std;
+int matchNetmask(const char *address, const char *omask);
+string humanDuration(time_t passed);
+void chomp(string &line, const string &delim);
+void stripLine(string &line);
+string getHostname();
+string urlEncode(const string &text);
+int waitForData(int fd, int seconds);
+
+void upperCase(string& s);
+
+struct ServiceTuple
+{
+ string host;
+ u_int16_t port;
+};
+void parseService(const string &descr, ServiceTuple &st);
+
+template <typename Container>
+void
+stringtok (Container &container, string const &in,
+ const char * const delimiters = " \t\n")
+{
+ const string::size_type len = in.length();
+ string::size_type i = 0;
+
+ while (i<len) {
+ // eat leading whitespace
+ i = in.find_first_not_of (delimiters, i);
+ if (i == string::npos)
+ return; // nothing left but white space
+
+ // find the end of the token
+ string::size_type j = in.find_first_of (delimiters, i);
+
+ // push token
+ if (j == string::npos) {
+ container.push_back (in.substr(i));
+ return;
+ } else
+ container.push_back (in.substr(i, j-i));
+
+ // set up for next loop
+ i = j + 1;
+ }
+}
+string toLower(const string &upper);
+
+string stringerror();
+string itoa(int i);
+
+void dropPrivs(int uid, int gid);
+int makeGidNumeric(const string &group);
+int makeUidNumeric(const string &user);
+void cleanSlashes(string &str);
+
+/** The DTime class can be used for timing statistics with microsecond resolution.
+On 32 bits systems this means that 2147 seconds is the longest time that can be measured. */
+class DTime
+{
+public:
+ DTime(); //!< This constructor calls set() for you so the timer is set on construction
+ DTime(const DTime &dt);
+ time_t time();
+ inline void set(); //!< Reset the timer
+ inline int udiff(); //!< Return the number of microseconds since the timer was last set.
+private:
+ struct timeval d_set;
+};
+const string sockAddrToString(struct sockaddr_in *remote, socklen_t socklen);
+int sendData(const char *buffer, int replen, int outsock);
+
+
+inline void DTime::set()
+{
+ Utility::gettimeofday(&d_set,0);
+}
+
+inline int DTime::udiff()
+{
+ struct timeval now;
+ Utility::gettimeofday(&now,0);
+
+ return 1000000*(now.tv_sec-d_set.tv_sec)+(now.tv_usec-d_set.tv_usec);
+}
+
+inline string toLower(const string &upper)
+{
+ string reply(upper);
+ for(unsigned int i = 0; i < reply.length(); i++)
+ reply[i] = tolower(reply[i]);
+ return reply;
+}
+
+
+#endif
--- /dev/null
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing 0.3 - GNU automake"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+ # We have makeinfo, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ tar)
+ shift
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ fi
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar ${1+"$@"} && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar ${1+"$@"} && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" ${1+"$@"} && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" ${1+"$@"} && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+#!/bin/sh
+
+DIR=pdns-nameserver-$(uname -m -s | tr L l | tr ' ' '-')-@VERSION@
+rm -rf $DIR
+mkdir $DIR
+cp backends/bind/zone2sql pdns_server pdns_control binpatch $DIR
+strip $DIR/*
+cp choosepaths installer pdns.in pathconfig LICENSE README $DIR
+
+
+if file ./pdns_server | grep -q dynamic
+then
+ mkdir $DIR/libs
+ cp libs/* $DIR/libs # backends
+ strip $DIR/libs/*.so
+# ldd ./pdns_server | cut -f2 -d\> | cut -f1 -d\( | grep -v ld-linux.so | \
+# grep -v libm.so | grep -v libc.so | grep -v libpthread.so | grep -v libdl.so \
+# > libs.tmp
+# cp $(cat libs.tmp) $DIR/libs
+# rm libs.tmp
+fi
+
+
+mkdir $DIR/docs
+cp docs/pdns.pdf $DIR/docs
+cp docs/pdns.txt $DIR/docs
+cp docs/html.tar.gz $DIR/docs
+
+tar cvzf $DIR.tar.gz $DIR
--- /dev/null
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.1 2002/11/27 15:18:30 ahu Exp $
+
+errstatus=0
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "mtasker.hh"
+#include <stdio.h>
+#include <iostream>
+
+/** \mainpage
+ Simple system for implementing cooperative multitasking of functions, with
+ support for waiting on events which can return values.
+
+ \section copyright Copyright and License
+ MTasker is (c) 2002 by bert hubert. It is licensed to you under the terms of the GPL version 2.
+
+ \section overview High level overview
+ MTasker is designed to support very simple cooperative multitasking to facilitate writing
+ code that would ordinarily require a statemachine, for which the author does not consider
+ himself smart enough.
+
+ This class does not perform any magic it only makes calls to makecontext() and swapcontext().
+ Getting the details right however is complicated and MTasker does that for you.
+
+ If preemptive multitasking or more advanced concepts such as semaphores, locks or mutexes
+ are required, the use of POSIX threads is advised.
+
+ MTasker is designed to offer the performance of statemachines while maintaining simple thread semantics. It is not
+ a replacement for a full threading system.
+
+ \section concepts Concepts
+
+ There are two important concepts, the 'kernel' and the 'thread'. Each thread starts out as a function,
+ which is passed to MTasker::makeThread(), together with a possible argument.
+
+ This function is now free to do whatever it wants, but realise that MTasker implements cooperative
+ multitasking, which means that the coder has the responsiblilty of not taking the CPU overly long.
+ Other threads can only get the CPU if MTasker::yield() is called or if a thread sleeps to wait for an event,
+ using the MTasker::waitEvent() method.
+
+ \section kernel The Kernel
+ The Kernel consists of functions that do housekeeping, but also of code that the client coder
+ can call to report events. A minimal kernel loop looks like this:
+ \code
+ for(;;) {
+ MT.schedule();
+ if(MT.noProcesses()) // exit if no processes are left
+ break;
+ }
+ \endcode
+
+ The kernel typically starts from the main() function of your program. New threads are also
+ created from the kernel. This can also happen before entering the main loop. To start a thread,
+ the method MTasker::makeThread is provided.
+
+ \section events Events
+ By default, Events are recognized by an int and their value is also an int.
+ This can be overriden by specifying the EventKey and EventVal template parameters.
+
+ An event can be a keypress, but also a UDP packet, or a bit of data from a TCP socket. The
+ sample code provided works with keypresses, but that is just a not very useful example.
+
+ A thread can also wait for an event only for a limited time, and receive a timeout of that
+ event did not occur within the specified timeframe.
+
+ \section example A simple menu system
+ \code
+MTasker<> MT;
+
+void menuHandler(void *p)
+{
+ int num=(int)p;
+ cout<<"Key handler for key "<<num<<" launched"<<endl;
+
+ MT.waitEvent(num);
+ cout<<"Key "<<num<<" was pressed!"<<endl;
+}
+
+
+int main()
+{
+ char line[10];
+
+ for(int i=0;i<10;++i)
+ MT.makeThread(menuHandler,(void *)i);
+
+ for(;;) {
+ while(MT.schedule()); // do everything we can do
+ if(MT.noProcesses()) // exit if no processes are left
+ break;
+
+ if(!fgets(line,sizeof(line),stdin))
+ break;
+
+ MT.sendEvent(*line-'0');
+ }
+}
+\endcode
+
+\section example2 Canonical multitasking example
+This implements the canonical multitasking example, alternately printing an 'A' and a 'B'. The Linux kernel
+ started this way too.
+\code
+void printer(void *p)
+{
+ char c=(char)p;
+ for(;;) {
+ cout<<c<<endl;
+ MT.yield();
+ }
+
+}
+
+int main()
+{
+ MT.makeThread(printer,(void*)'a');
+ MT.makeThread(printer,(void*)'b');
+
+ for(;;) {
+ while(MT.schedule()); // do everything we can do
+ if(MT.noProcesses()) // exit if no processes are left
+ break;
+ }
+}
+\endcode
+
+*/
+
+//! puts a thread to sleep waiting until a specified event arrives
+/** Threads can call waitEvent to register that they are waiting on an event with a certain key.
+ If so desidered, the event can carry data which is returned in val in case that is non-zero.
+
+ Furthermore, a timeout can be specified in seconds.
+
+ Only one thread can be waiting on a key, results of trying to have more threads
+ waiting on the same key are undefined.
+
+ \param key Event key to wait for. Needs to match up to a key reported to sendEvent
+ \param val If non-zero, the value of the event will be stored in *val
+ \param timeout If non-zero, number of seconds to wait for an event.
+
+ \return returns -1 in case of error, 0 in case of timeout, 1 in case of an answer
+*/
+
+template<class EventKey, class EventVal>int MTasker<EventKey,EventVal>::waitEvent(const EventKey &key, EventVal *val, unsigned int timeout)
+{
+ Waiter w;
+ w.context=new ucontext_t;
+ w.ttd= timeout ? time(0)+timeout : 0;
+ w.tid=d_tid;
+
+ d_waiters[key]=w;
+
+ swapcontext(d_waiters[key].context,&d_kernel); // 'A' will return here when 'key' has arrived, hands over control to kernel first
+ if(val && d_waitstatus==Answer)
+ *val=d_waitval;
+ return d_waitstatus;
+}
+
+//! yields control to the kernel or other threads
+/** Hands over control to the kernel, allowing other processes to run, or events to arrive */
+
+template<class Key, class Val>void MTasker<Key,Val>::yield()
+{
+ d_runQueue.push(d_tid);
+ swapcontext(d_threads[d_tid],&d_kernel); // give control to the kernel
+}
+
+//! reports that an event took place for which threads may be waiting
+/** From the kernel loop, sendEvent can be called to report that something occured for which there may be waiters.
+ \param key Key of the event for which threads may be waiting
+ \param val If non-zero, pointer to the content of the event
+ \return Returns -1 in case of error, 0 if there were no waiters, 1 if a thread was woken up.
+*/
+template<class EventKey, class EventVal>int MTasker<EventKey,EventVal>::sendEvent(const EventKey& key, const EventVal* val)
+{
+ if(!d_waiters.count(key)) {
+ return 0;
+ }
+
+ d_waitstatus=Answer;
+ if(val)
+ d_waitval=*val;
+
+ ucontext_t *userspace=d_waiters[key].context;
+ d_tid=d_waiters[key].tid; // set tid
+
+ d_waiters.erase(key); // removes the waitpoint
+ swapcontext(&d_kernel,userspace); // swaps back to the above point 'A'
+
+ delete userspace;
+ return 1;
+}
+
+//! launches a new thread
+/** The kernel can call this to make a new thread, which starts at the function start and gets passed the val void pointer.
+ \param start Pointer to the function which will form the start of the thread
+ \param val A void pointer that can be used to pass data to the thread
+*/
+template<class Key, class Val>void MTasker<Key,Val>::makeThread(tfunc_t *start, void* val)
+{
+ ucontext_t *uc=new ucontext_t;
+ getcontext(uc);
+
+ uc->uc_link = &d_kernel; // come back to kernel after dying
+ uc->uc_stack.ss_sp = new char[d_stacksize];
+
+ uc->uc_stack.ss_size = d_stacksize;
+ makecontext (uc, (void (*)(void))threadWrapper, 4, this, start, d_maxtid, val);
+ d_threads[d_maxtid]=uc;
+ d_runQueue.push(d_maxtid++); // will run at next schedule invocation
+}
+
+
+//! needs to be called periodically so threads can run and housekeeping can be performed
+/** The kernel should call this function every once in a while. It makes sense
+ to call this function if you:
+ - reported an event
+ - called makeThread
+ - want to have threads running waitEvent() to get a timeout if enough time passed
+
+ \return Returns if there is more work scheduled and recalling schedule now would be useful
+
+*/
+template<class Key, class Val>bool MTasker<Key,Val>::schedule()
+{
+
+ if(!d_runQueue.empty()) {
+ d_tid=d_runQueue.front();
+ swapcontext(&d_kernel, d_threads[d_tid]);
+ d_runQueue.pop();
+ return true;
+ }
+ if(!d_zombiesQueue.empty()) {
+ delete (char *)d_threads[d_zombiesQueue.front()]->uc_stack.ss_sp;
+ delete d_threads[d_zombiesQueue.front()];
+ d_threads.erase(d_zombiesQueue.front());
+ d_zombiesQueue.pop();
+ return true;
+ }
+ if(!d_waiters.empty()) {
+ time_t now=time(0);
+ for(typename waiters_t::const_iterator i=d_waiters.begin();i!=d_waiters.end();++i) {
+ if(i->second.ttd && i->second.ttd<now) {
+ d_waitstatus=TimeOut;
+ swapcontext(&d_kernel,i->second.context); // swaps back to the above point 'A'
+ delete i->second.context;
+ d_waiters.erase(i->first); // removes the waitpoint
+ }
+ }
+ }
+ return false;
+}
+
+//! returns true if there are no processes
+/** Call this to check if no processes are running anymore
+ \return true if no processes are left
+ */
+template<class Key, class Val>bool MTasker<Key,Val>::noProcesses()
+{
+ return d_threads.empty();
+}
+
+//! gives access to the list of Events threads are waiting for
+/** The kernel can call this to get a list of Events threads are waiting for. This is very useful
+ to setup 'select' or 'poll' or 'aio' events needed to satisfy these requests.
+ getEvents clears the events parameter before filling it.
+
+ \param events Vector which is to be filled with keys threads are waiting for
+*/
+template<class Key, class Val>void MTasker<Key,Val>::getEvents(std::vector<Key>& events)
+{
+ events.clear();
+ for(typename waiters_t::const_iterator i=d_waiters.begin();i!=d_waiters.end();++i) {
+ events.push_back(i->first);
+ }
+}
+
+
+template<class Key, class Val>void MTasker<Key,Val>::threadWrapper(MTasker *self, tfunc_t *tf, int tid, void* val)
+{
+ (*tf)(val);
+ self->d_zombiesQueue.push(tid);
+
+ // we now jump to &kernel, automatically
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: nameserver.cc,v 1.1 2002/11/27 15:18:31 ahu Exp $ \r
+#include "utility.hh"
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <cerrno>
+#include <iostream>
+#include <string>
+#include <sys/types.h>
+
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "dnspacket.hh"
+#include "nameserver.hh"
+#include "distributor.hh"
+#include "logger.hh"
+#include "arguments.hh"
+#include "statbag.hh"
+
+extern StatBag S;
+
+/** \mainpage
+ ahudns is a very versatile nameserver that can answer questions from different backends. To implement your
+ own backend, see the documentation for the DNSBackend class.
+
+ \section copyright Copyright and License
+ AhuDNS is (C) 2002 PowerDNS BV.
+
+ AhuDNS is NOT open source (yet), so treat this code as a trade secret. If it has been supplied to you for evaluation,
+ this does not mean that you can deploy the code!
+
+ \section overview High level overview
+
+ AhuDNS is highly threaded, which means that several tasks each have their own process thread. Two of the pivotal
+ threads are the qthread() and the athread().
+
+ - The qthread() receives questions over the network (via the Nameserver class, which returns DNSPacket objects), and gives them to the Distributor.
+ - The athread() waits on the Distributor to return answers, ready to send back over the network, again via UDPNameserver.
+
+ The Distributor contains a configurable number of PacketHandler instances, each in its own thread, for connection pooling
+
+ The PacketHandler implements the RFC1034 algorithm and converts question packets into DNSBackend queries.
+
+ A DNSBackend is an entity that returns DNSResourceRecord objects in return to explicit questions for domains with a specified QType
+
+ AhuDNS uses the UeberBackend as its DNSBackend. The UeberBackend by default has no DNSBackends within itself, those are loaded
+ using the dynloader tool. This way DNSBackend implementations can be kept completely separate.
+
+ If one or more DNSBackends are loaded, the UeberBackend fields the queries to all of them until one answers.
+
+ \section TCP TCP Operations
+
+ The TCP operation runs within a single thread called tcpreceiver(), that also queries the PacketHandler.
+
+ \section Cache Caching
+
+ On its own, this setup is not suitable for high performance operations. A single DNS query can turn into many DNSBackend questions,
+ each taking many miliseconds to complete. This is why the qthread() first checks the PacketCache to see if an answer is known to a packet
+ asking this question. If so, the entire Distributor is shunted, and the answer is sent back *directly*, within a few microseconds.
+
+ In turn, the athread() offers each outgoing packet to the PacketCache for possible inclusion.
+
+ \section misc Miscellaneous
+ Configuration details are available via the ArgvMap instance arg. Statistics are created by making calls to the StatBag object called S.
+ These statistics are made available via the UeberBackend on the same socket that is used for dynamic module commands.
+
+ \section Main Main
+ The main() of AhuDNS can be found in receiver.cc - start reading there for further insights into the operation of the nameserver
+
+
+*/
+
+void UDPNameserver::bindIPv4()
+{
+ vector<string>locals;
+ stringtok(locals,arg()["local-address"]," ,");
+
+ if(locals.empty())
+ throw AhuException("No local address specified");
+
+ int s;
+ for(vector<string>::const_iterator i=locals.begin();i!=locals.end();++i) {
+ string localname(*i);
+ struct sockaddr_in locala;
+
+ s=socket(AF_INET,SOCK_DGRAM,0);
+ if(s<0)
+ throw AhuException("Unable to acquire a UDP socket: "+string(strerror(errno)));
+
+ memset(&locala,0,sizeof(locala));
+ locala.sin_family=AF_INET;
+
+ if(localname=="0.0.0.0") {
+ L<<Logger::Warning<<"It is advised to bind to explicit addresses with the --local-address option"<<endl;
+
+ locala.sin_addr.s_addr = INADDR_ANY;
+ }
+ else
+ {
+ struct hostent *h=0;
+ h=gethostbyname(localname.c_str());
+ if(!h)
+ throw AhuException("Unable to resolve local address");
+
+ locala.sin_addr.s_addr=*(int*)h->h_addr;
+ }
+
+ locala.sin_port=htons(arg().asNum("local-port"));
+
+ if(bind(s, (sockaddr*)&locala,sizeof(locala))<0) {
+ L<<Logger::Error<<"binding to UDP socket: "<<strerror(errno)<<endl;
+ throw AhuException("Unable to bind to UDP socket");
+ }
+ d_highfd=max(s,d_highfd);
+ d_sockets.push_back(s);
+ L<<Logger::Error<<"UDP server bound to "<<localname<<":"<<arg()["local-port"]<<endl;
+ FD_SET(s, &d_rfds);
+ }
+}
+
+void UDPNameserver::bindIPv6()
+{
+ // TODO: Add Windows ipv6 support.
+#ifndef WIN32
+ vector<string>locals;
+ stringtok(locals,arg()["local-ipv6"]," ,");
+
+ if(locals.empty())
+ return;
+
+
+ int s;
+ for(vector<string>::const_iterator i=locals.begin();i!=locals.end();++i) {
+ string localname(*i);
+ struct sockaddr_in6 locala;
+
+ s=socket(AF_INET6,SOCK_DGRAM,0);
+ if(s<0)
+ throw AhuException("Unable to acquire a UDPv6 socket: "+string(strerror(errno)));
+
+ memset(&locala,0,sizeof(locala));
+ locala.sin6_family=AF_INET6;
+
+ if(localname=="::0") {
+ L<<Logger::Warning<<"It is advised to bind to explicit addresses with the --local-ipv6 option"<<endl;
+ }
+
+ struct hostent *h;
+
+ h=gethostbyname2(localname.c_str(),AF_INET6);
+
+ if(!h)
+ throw AhuException("Unable to resolve local IPv6 address");
+
+ memcpy(&locala.sin6_addr.s6_addr,h->h_addr,16);
+
+ locala.sin6_port=htons(arg().asNum("local-port"));
+
+ if(bind(s, (sockaddr*)&locala,sizeof(locala))<0) {
+ L<<Logger::Error<<"binding to UDP ipv6 socket: "<<strerror(errno)<<endl;
+ throw AhuException("Unable to bind to UDP ipv6 socket");
+ }
+ d_highfd=max(s,d_highfd);
+ d_sockets.push_back(s);
+ L<<Logger::Error<<"UDPv6 server bound to "<<localname<<":"<<arg()["local-port"]<<endl;
+ FD_SET(s, &d_rfds);
+ }
+#endif // WIN32
+}
+
+UDPNameserver::UDPNameserver()
+{
+ d_highfd=0;
+ FD_ZERO(&d_rfds);
+ if(!arg()["local-address"].empty())
+ bindIPv4();
+ if(!arg()["local-ipv6"].empty())
+ bindIPv6();
+
+ if(arg()["local-address"].empty() && arg()["local-ipv6"].empty())
+ L<<Logger::Critical<<"PDNS is deaf and mute! Not listening on any interfaces"<<endl;
+
+}
+
+void UDPNameserver::send(DNSPacket *p)
+{
+ const char *buffer=p->getData();
+ DLOG(L<<Logger::Notice<<"Sending a packet to "<<inet_ntoa( reinterpret_cast< sockaddr_in * >(( p->remote ))->sin_addr)<<" ("<<p->len<<" octets)"<<endl);
+ if(p->len>512) {
+ p=new DNSPacket(*p);
+ p->truncate(512);
+ buffer=p->getData();
+ if(sendto(p->getSocket(),buffer,p->len,0,(struct sockaddr *)(p->remote),p->d_socklen)<0)
+ L<<Logger::Error<<"Error sending reply with sendto (socket="<<p->getSocket()<<"): "<<strerror(errno)<<endl;
+ delete p;
+ }
+ else {
+
+ if(sendto(p->getSocket(),buffer,p->len,0,(struct sockaddr *)(p->remote),p->d_socklen)<0)
+ L<<Logger::Error<<"Error sending reply with sendto (socket="<<p->getSocket()<<"): "<<strerror(errno)<<endl;
+
+
+
+ }
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: nameserver.hh,v 1.1 2002/11/27 15:18:32 ahu Exp $
+#ifndef NAMESERVER_HH
+#define NAMESERVER_HH
+\r
+#ifndef WIN32
+# include <sys/select.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <sys/time.h>
+# include <unistd.h>\r
+# include <arpa/inet.h>\r
+# include <netdb.h>\r
+\r
+#endif // WIN32\r
+
+#include <vector>
+#include "statbag.hh"
+using namespace std;
+
+/** This is the main class. It opens a socket on udp port 53 and waits for packets. Those packets can
+ be retrieved with the receive() member function, which returns a DNSPacket.
+
+ Some sample code in main():
+ \code
+ typedef Distributor<DNSPacket,DNSPacket,PacketHandler> DNSDistributor;
+ DNSDistributor D(6); // the big dispatcher!
+
+ pthread_t qtid, atid;
+ N=new UDPNameserver;
+
+ pthread_create(&qtid,0,qthread,static_cast<void *>(&D)); // receives packets
+ pthread_create(&atid,0,athread,static_cast<void *>(&D)); // sends packets
+ \endcode
+
+ Code for qthread:
+ \code
+ void *qthread(void *p)
+ {
+ DNSDistributor *D=static_cast<DNSDistributor *>(p);
+
+ DNSPacket *P;
+
+ while((P=N->receive())) // receive a packet
+ {
+ D->question(P); // and give to the distributor, they will delete it
+ }
+ return 0;
+ }
+
+ \endcode
+
+*/
+
+class UDPNameserver
+{
+public:
+ UDPNameserver(); //!< Opens the socket
+ inline DNSPacket *receive(DNSPacket *prefilled=0); //!< call this in a while or for(;;) loop to get packets
+ void send(DNSPacket *); //!< send a DNSPacket. Will call DNSPacket::truncate() if over 512 bytes
+
+private:
+ vector<int> d_sockets;
+ void bindIPv4();
+ void bindIPv6();
+ fd_set d_rfds;
+ int d_highfd;
+};
+
+inline DNSPacket *UDPNameserver::receive(DNSPacket *prefilled)
+{
+ char remote[ 30 ];
+ extern StatBag S;
+
+ Utility::socklen_t addrlen;
+ int len=-1;
+ char mesg[513];
+ Utility::sock_t sock=-1;
+
+ memset( remote, 0, sizeof( remote ));
+
+ if(d_sockets.size()>1) {
+ fd_set rfds=d_rfds;
+
+ select(d_highfd+1, &rfds, 0, 0, 0); // blocks
+
+ for(vector<int>::const_iterator i=d_sockets.begin();i!=d_sockets.end();++i) {
+ if(FD_ISSET(*i, &rfds)) {
+ sock=*i;
+ addrlen=sizeof(remote);
+
+ len=0;
+ if((len=recvfrom(sock,mesg,512,0,(sockaddr*) remote, &addrlen))<0) {
+ L<<Logger::Error<<"recvfrom gave error, ignoring: "<<strerror(errno)<<endl;
+ return 0;
+ }
+ break;
+ }
+ }
+ if(sock==-1)
+ throw AhuException("select betrayed us! (should not happen)");
+ }
+ else {
+ sock=d_sockets[0];
+ addrlen=sizeof(remote);
+ len=0;
+ if((len=recvfrom(sock,mesg,512,0,(sockaddr*) remote, &addrlen))<0) {
+ L<<Logger::Error<<"recvfrom gave error, ignoring: "<<strerror(errno)<<endl;
+ return 0;
+ }
+ }
+
+ DLOG(L<<"Received a packet " << len <<" bytes long from "<<inet_ntoa( reinterpret_cast< sockaddr_in * >( &remote )->sin_addr )<<endl);
+
+ DNSPacket *packet;
+ if(prefilled) // they gave us a preallocated packet
+ packet=prefilled;
+ else
+ packet=new DNSPacket; // don't forget to free it!
+ packet->d_dt.set(); // timing
+ packet->setSocket(sock);
+ packet->setRemote((struct sockaddr *)remote, addrlen);
+ if(packet->parse(mesg, len)<0) {
+ S.inc("corrupt-packets");
+ S.ringAccount("remotes-corrupt", packet->getRemote());
+
+ if(!prefilled)
+ delete packet;
+ return 0; // unable to parse
+ }
+
+ return packet;
+}
+
+
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include "packetcache.hh"
+#include "logger.hh"
+#include "arguments.hh"
+#include "statbag.hh"
+#include <map>
+
+extern StatBag S;
+
+PacketCache::PacketCache()
+{
+ pthread_rwlock_init(&d_mut,0);
+ pthread_mutex_init(&d_dellock,0);
+ d_hit=d_miss=0;
+
+ d_ttl=-1;
+ d_recursivettl=-1;
+
+ S.declare("packetcache-hit");
+ S.declare("packetcache-miss");
+ S.declare("packetcache-size");
+
+ statnumhit=S.getPointer("packetcache-hit");
+ statnummiss=S.getPointer("packetcache-miss");
+ statnumentries=S.getPointer("packetcache-size");
+}
+
+
+void PacketCache::insert(DNSPacket *q, DNSPacket *r)
+{
+
+ if(ntohs(q->d.qdcount)!=1) {
+ L<<"Warning - tried to cache a packet with wrong number of questions: "<<ntohs(q->d.qdcount)<<endl;
+ return; // do not try to cache packets with multiple questions
+ }
+
+ bool packetMeritsRecursion=d_doRecursion && q->d.rd;
+
+ char ckey[512];
+ int len=q->qdomain.length();
+ memcpy(ckey,q->qdomain.c_str(),len); // add TOLOWER HERE FIXME XXX
+ ckey[len]='|';
+ ckey[len+1]=packetMeritsRecursion ? 'r' : 'n';
+ ckey[len+2]=(q->qtype.getCode()>>8) & 0xff;
+ ckey[len+3]=(q->qtype.getCode()) & 0xff;
+ string key;
+ key.assign(ckey,q->qdomain.length()+4);
+
+ insert(key,r->getString(), packetMeritsRecursion ? d_recursivettl : d_ttl);
+}
+
+void PacketCache::getTTLS()
+{
+ d_ttl=arg().asNum("cache-ttl");
+ d_recursivettl=arg().asNum("recursive-cache-ttl");
+
+ d_doRecursion=arg().mustDo("recursor");
+}
+
+void PacketCache::insert(const char *packet, int length)
+{
+ if(d_ttl<0)
+ getTTLS();
+
+ DNSPacket p;
+ p.parse(packet,length);
+
+ bool packetMeritsRecursion=d_doRecursion && p.d.rd;
+
+ char ckey[512];
+ int len=p.qdomain.length();
+ memcpy(ckey,p.qdomain.c_str(),len); // add TOLOWER HERE FIXME XXX
+ ckey[len]='|';
+ ckey[len+1]=packetMeritsRecursion ? 'r' : 'n';
+ ckey[len+2]=(p.qtype.getCode()>>8) & 0xff;
+ ckey[len+3]=(p.qtype.getCode()) & 0xff;
+ string key;
+ key.assign(ckey,p.qdomain.length()+4);
+ // string key=toLower(p.qdomain+"|"+(packetMeritsRecursion ? "R" : "N")+"|"+p.qtype.getName());
+
+ string buffer;
+ buffer.assign(packet,length);
+ insert(key,buffer, packetMeritsRecursion ? d_recursivettl : d_ttl);
+}
+
+void PacketCache::insert(const string &key, const string &packet, unsigned int ttl)
+{
+ if(!ttl)
+ return;
+
+ cvalue_t val;
+ val.ttd=time(0)+ttl;
+ val.value=packet;
+
+ TryWriteLock l(&d_mut);
+ if(l.gotIt())
+ d_map[key]=val;
+ else
+ S.inc("deferred-cache-inserts");
+}
+
+/** purges entries from the packetcache. If prefix ends on a $, it is treated as a suffix */
+int PacketCache::purge(const string &f_prefix)
+{
+ Lock pl(&d_dellock);
+
+ string prefix(f_prefix);
+ if(prefix.empty()) {
+ cmap_t *tmp=new cmap_t;
+ {
+ DTime dt;
+ dt.set();
+ WriteLock l(&d_mut);
+ tmp->swap(d_map);
+ L<<Logger::Error<<"cache clean time: "<<dt.udiff()<<"usec"<<endl;
+ }
+
+ int size=tmp->size();
+ delete tmp;
+
+ *statnumentries=0;
+ return size;
+ }
+
+ bool suffix=false;
+ if(prefix[prefix.size()-1]=='$') {
+ prefix=prefix.substr(0,prefix.size()-1);
+ suffix=true;
+ }
+ string check=prefix+"|";
+
+ vector<cmap_t::iterator> toRemove;
+
+ ReadLock l(&d_mut);
+
+ for(cmap_t::iterator i=d_map.begin();i!=d_map.end();++i) {
+ string::size_type pos=i->first.find(check);
+
+ if(!pos || (suffix && pos!=string::npos))
+ toRemove.push_back(i);
+ }
+
+ l.upgrade();
+
+ for(vector<cmap_t::iterator>::const_iterator i=toRemove.begin();i!=toRemove.end();++i)
+ d_map.erase(*i);
+ *statnumentries=d_map.size();
+ return toRemove.size();
+}
+
+bool PacketCache::getKey(const string &key, string &content)
+{
+ TryReadLock l(&d_mut); // take a readlock here
+ if(!l.gotIt()) {
+ S.inc("deferred-cache-lookup");
+ return false;
+ }
+
+ // needs to do ttl check here
+ cmap_t::const_iterator i=d_map.find(key);
+ time_t now=time(0);
+ bool ret=(i!=d_map.end() && i->second.ttd>now);
+ if(ret)
+ content=i->second.value;
+ return ret;
+}
+
+map<char,int> PacketCache::getCounts()
+{
+ ReadLock l(&d_mut);
+ int counts[256];
+ unsigned int offset;
+ memset(counts,0,256*sizeof(counts[0]));
+ char key;
+ for(cmap_t::const_iterator i=d_map.begin();i!=d_map.end();++i) {
+ if((offset=i->first.find_first_of("|"))==string::npos || offset+1>i->first.size())
+ continue;
+
+ key=i->first[offset+1];
+ if((key=='Q' || key=='q') && !i->second.value.empty())
+ key='!';
+ counts[key]++;
+ }
+
+ map<char,int>ret;
+ for(int i=0;i<256;++i)
+ if(counts[i])
+ ret[i]=counts[i];
+ return ret;
+
+}
+
+
+int PacketCache::size()
+{
+ ReadLock l(&d_mut);
+ return d_map.size();
+}
+
+/** readlock for figuring out which iterators to delete, upgrade to writelock when actually cleaning */
+void PacketCache::cleanup()
+{
+ Lock pl(&d_dellock); // ALWAYS ACQUIRE DELLOCK FIRST
+ ReadLock l(&d_mut);
+
+ *statnumentries=d_map.size();
+
+ time_t now=time(0);
+
+ DLOG(L<<"Starting cache clean"<<endl);
+ if(d_map.begin()==d_map.end()) {
+ return; // clean
+ }
+
+ vector<cmap_t::iterator> toRemove;
+
+ for(cmap_t::iterator i=d_map.begin();i!=d_map.end();++i) {
+ if(now>i->second.ttd)
+ toRemove.push_back(i);
+ }
+
+ l.upgrade();
+
+ for(vector<cmap_t::iterator>::const_iterator i=toRemove.begin();i!=toRemove.end();++i)
+ d_map.erase(*i);
+
+ *statnumentries=d_map.size();
+ DLOG(L<<"Done with cache clean"<<endl);
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PACKETCACHE_HH
+#define PACKETCACHE_HH
+
+#include <string>
+#include <utility>
+#include <map>
+
+#ifndef WIN32
+# if __GNUC__ >= 3
+# include <ext/hash_map>
+using namespace __gnu_cxx;
+# else
+# include <hash_map>
+# endif // __GNUC__
+
+#else
+# include <map>
+
+#endif // WIN32
+
+using namespace std;
+
+#include "dnspacket.hh"
+#include "lock.hh"
+#include "statbag.hh"
+
+/** This class performs 'whole packet caching'. Feed it a question packet and it will
+ try to find an answer. If you have an answer, insert it to have it cached for later use.
+ Take care not to replace existing cache entries. While this works, it is wasteful. Only
+ insert packets that where not found by get()
+
+ Locking!
+
+ The cache itself is protected by a read/write lock. Because deleting is a two step process, which
+ first marks and then sweeps, a second lock is present to prevent simultaneous inserts and deletes.
+
+ Overloading!
+
+ The packet cache contains packets but also negative UeberBackend queries. Those last are recognized
+ because they start with a | and have empty content. One day, this content may also contain queries.
+
+*/
+class PacketCache
+{
+public:
+ PacketCache();
+ void insert(DNSPacket *q, DNSPacket *r); //!< We copy the contents of *p into our cache. Do not needlessly call this to insert questions already in the cache as it wastes resources
+ void PacketCache::insert(const char *packet, int length);
+
+ inline int get(DNSPacket *p, DNSPacket *q); //!< We return a dynamically allocated copy out of our cache. You need to delete it. You also need to spoof in the right ID with the DNSPacket.spoofID() method.
+ bool getKey(const string &key, string &content);
+ int size(); //!< number of entries in the cache
+ void cleanup(); //!< force the cache to preen itself from expired packets
+ int purge(const string &prefix="");
+ void insert(const string &key, const string &packet, unsigned int ttl);
+ map<char,int> getCounts();
+private:
+ typedef string ckey_t;
+
+ class CacheContent
+ {
+ public:
+ time_t ttd;
+ string value;
+ };
+
+ typedef CacheContent cvalue_t;
+ void getTTLS();
+#ifndef WIN32
+
+ struct compare_string
+ {
+ bool operator()(const string& s1, const string& s2) const
+ {
+ return s1 == s2;
+ }
+ };
+
+ struct hash_string
+ {
+ size_t operator()(const string& s) const
+ {
+ return __stl_hash_string(s.c_str());
+ }
+ };
+
+ typedef hash_map<ckey_t,cvalue_t, hash_string, compare_string > cmap_t;
+
+#else
+ typedef map< ckey_t, cvalue_t > cmap_t;
+
+#endif // WIN32
+
+ cmap_t d_map;
+
+ pthread_rwlock_t d_mut;
+ pthread_mutex_t d_dellock;
+
+ int d_hit;
+ int d_miss;
+ int d_ttl;
+ int d_recursivettl;
+ bool d_doRecursion;
+ int *statnumhit;
+ int *statnummiss;
+ int *statnumentries;
+};
+
+inline int PacketCache::get(DNSPacket *p, DNSPacket *cached)
+{
+ extern StatBag S;
+ if(!((d_hit+d_miss)%5000)) {
+ cleanup();
+ }
+
+ if(d_ttl<0)
+ getTTLS();
+
+ if(d_doRecursion && p->d.rd) { // wants recursion
+ if(!d_recursivettl) {
+ (*statnummiss)++;
+ d_miss++;
+ return 0;
+ }
+ }
+ else { // does not
+ if(!d_ttl) {
+ (*statnummiss)++;
+ d_miss++;
+ return 0;
+ }
+ }
+
+ bool packetMeritsRecursion=d_doRecursion && p->d.rd;
+ char ckey[512];
+ int len=p->qdomain.length();
+ memcpy(ckey,p->qdomain.c_str(),len); // add TOLOWER HERE FIXME XXX
+ ckey[len]='|';
+ ckey[len+1]=packetMeritsRecursion ? 'r' : 'n';
+ ckey[len+2]=(p->qtype.getCode()>>8)&0xff;
+ ckey[len+3]=(p->qtype.getCode())&0xff;
+ string key;
+
+ key.assign(ckey,p->qdomain.length()+4);
+ // cout<<"key lookup: '"<<key<<"'"<<endl;
+ // string key=toLower(p->qdomain+"|"+(packetMeritsRecursion ? "R" : "N")+ "|"+p->qtype.getName());
+
+ if(ntohs(p->d.qdcount)!=1) // we get confused by packets with more than one question
+ return 0;
+
+ {
+ TryReadLock l(&d_mut); // take a readlock here
+ if(!l.gotIt()) {
+ S.inc("deferred-cache-lookup");
+ return 0;
+ }
+
+ if(!((d_hit+d_miss)%1000)) {
+ *statnumentries=d_map.size(); // needs lock
+ }
+ cmap_t::const_iterator i;
+ if((i=d_map.find(key))!=d_map.end()) { // HIT!
+
+ if(i->second.ttd>time(0)) { // it is still fresh
+ (*statnumhit)++;
+ d_hit++;
+ cached->parse(i->second.value.c_str(),i->second.value.size());
+ cached->spoofQuestion(p->qdomain); // for correct case
+ return 1;
+ }
+ }
+ }
+ (*statnummiss)++;
+ d_miss++;
+ return 0; // bummer
+}
+
+
+#endif /* PACKETCACHE_HH */
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"
+#include <string>
+#include <sys/types.h>
+
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "ueberbackend.hh"
+#include "dnspacket.hh"
+#include "nameserver.hh"
+#include "distributor.hh"
+#include "logger.hh"
+#include "arguments.hh"
+#include "packethandler.hh"
+#include "statbag.hh"
+#include "resolver.hh"
+#include "communicator.hh"
+#include "dnsproxy.hh"
+
+extern StatBag S;
+extern PacketCache PC;
+extern CommunicatorClass Communicator;
+extern DNSProxy *DP;
+
+int PacketHandler::s_count;
+extern string s_programname;
+
+
+PacketHandler::PacketHandler():B(s_programname)
+{
+ s_count++;
+ d_doFancyRecords = (arg()["fancy-records"]!="no");
+ d_doWildcards = (arg()["wildcards"]!="no");
+ d_doCNAME = (arg()["skip-cname"]=="no");
+ d_doRecursion= arg().mustDo("recursor");
+ d_doLazyRecursion= arg().mustDo("lazy-recursion");
+ d_logDNSDetails= arg().mustDo("log-dns-details");
+}
+
+DNSBackend *PacketHandler::getBackend()
+{
+ return &B;
+}
+
+PacketHandler::~PacketHandler()
+{
+ --s_count;
+ DLOG(L<<Logger::Error<<"PacketHandler destructor called - "<<s_count<<" left"<<endl);
+
+}
+
+
+int PacketHandler::findMboxFW(DNSPacket *p, DNSPacket *r, string &target)
+{
+ DNSResourceRecord rr;
+ bool wedoforward=false;
+
+ B.lookup("MBOXFW",string("%@")+target,p);
+
+ while(B.get(rr))
+ wedoforward=true;
+
+ if(wedoforward) {
+ rr.content=arg()["smtpredirector"];
+ rr.priority=25;
+ rr.ttl=7200;
+ rr.qtype=QType::MX;
+ rr.qname=target;
+
+ r->addRecord(rr);
+ }
+
+ return wedoforward;
+}
+
+int PacketHandler::findUrl(DNSPacket *p, DNSPacket *r, string &target)
+{
+ DNSResourceRecord rr;
+
+ bool found=false;
+
+ B.lookup("URL",target,p); // search for a URL before we search for an A
+
+ while(B.get(rr)) {
+ found=true;
+ DLOG(L << "Found a URL!" << endl);
+ rr.content=arg()["urlredirector"];
+ rr.qtype=QType::A;
+ rr.qname=target;
+
+ r->addRecord(rr);
+ }
+
+ if(found)
+ return 1;
+
+ // now try CURL
+
+ B.lookup("CURL",target,p); // search for a URL before we search for an A
+
+ while(B.get(rr)) {
+ found=true;
+ DLOG(L << "Found a CURL!" << endl);
+ rr.content=arg()["urlredirector"];
+ rr.qtype=1; // A
+ rr.qname=target;
+ rr.ttl=300;
+ r->addRecord(rr);
+ }
+
+ if(found)
+ return found;
+ return 0;
+}
+
+/** Returns 0 if nothing was found, -1 if an error occured or 1 if the search
+ was satisfied */
+int PacketHandler::doFancyRecords(DNSPacket *p, DNSPacket *r, string &target)
+{
+ DNSResourceRecord rr;
+
+ if(p->qtype.getCode()==QType::MX) // check if this domain has smtp service from us
+ return findMboxFW(p,r,target);
+
+ if(p->qtype.getCode()==QType::A) // search for a URL record for an A
+ return findUrl(p,r,target);
+
+ return 0;
+}
+
+int PacketHandler::doDNSCheckRequest(DNSPacket *p, DNSPacket *r, string &target)
+{
+ int result = 0;
+ DNSResourceRecord rr;
+
+ if (p->qclass == 3 && p->qtype.getName() == "HINFO") {
+ rr.content = "PowerDNS $Id: packethandler.cc,v 1.1 2002/11/27 15:18:31 ahu Exp $";
+ rr.ttl = 5;
+ rr.qname=target;
+ rr.qtype=13; // hinfo
+ r->addRecord(rr);
+ result = 1;
+ }
+
+ return result;
+}
+
+/** This catches version requests. Returns 1 if it was handled, 0 if it wasn't */
+int PacketHandler::doVersionRequest(DNSPacket *p, DNSPacket *r, string &target)
+{
+ DNSResourceRecord rr;
+ if(p->qtype.getCode()==QType::TXT && target=="version.bind") {// TXT
+ rr.content="Served by POWERDNS "VERSION" $Id: packethandler.cc,v 1.1 2002/11/27 15:18:31 ahu Exp $";
+ rr.ttl=5;
+ rr.qname=target;
+ rr.qtype=QType::TXT; // TXT
+ r->addRecord(rr);
+
+ return 1;
+ }
+ return 0;
+}
+
+/** Determines if we are authoritative for a zone, and at what level */
+bool PacketHandler::getTLDAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId)
+{
+ static string theSOA="."+arg()["only-soa"];
+ static SOAData cachedSD;
+ static bool haveIt;
+
+ if((target.size()-toLower(target).rfind(toLower(theSOA)))!=theSOA.size()) {
+ // cerr<<"target '"<<target<<"' does not end on '"<<theSOA<<"'"<<endl;
+ return false;
+ }
+ if(!haveIt) {
+ if(B.getSOA(arg()["only-soa"], cachedSD)) {
+ cachedSD.qname=arg()["only-soa"];
+
+ haveIt=true;
+ }
+ }
+ if(haveIt) {
+ *zoneId=sd->domain_id;
+ *sd=cachedSD;
+ }
+ return haveIt;
+}
+
+/** Determines if we are authoritative for a zone, and at what level */
+bool PacketHandler::getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId)
+{
+ DNSResourceRecord rr;
+
+ vector<string>parts;
+ stringtok(parts,target,"."); // www.us.powerdns.com -> 'www' 'us' 'powerdns' 'com'
+
+ unsigned int spos=0;
+ string subdomain;
+
+ while(spos<=parts.size()) {
+ if(spos<parts.size()) { // www.us.powerdns.com -> us.powerdns.com -> powerdns.com -> com ->
+ subdomain=parts[spos++];
+ for(unsigned int i=spos;i<parts.size();++i) {
+ subdomain+=".";
+ subdomain+=parts[i];
+ }
+ }
+ else {
+ subdomain=""; // ROOT!
+ spos++;
+ }
+ if(B.getSOA(subdomain, *sd)) {
+ sd->qname=subdomain;
+ *zoneId=sd->domain_id;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/** returns 1 in case of a straight match, 2 in case of a wildcard CNAME (groan), 0 in case of no hit */
+int PacketHandler::doWildcardRecords(DNSPacket *p, DNSPacket *r, string &target)
+{
+ DNSResourceRecord rr;
+ bool found=false, retargeted=false;
+
+ // try chopping off domains and look for wildcard matches
+
+ // *.pietje.nl IN A 1.2.3.4
+ // pietje.nl should now NOT match, but www.pietje.nl should
+
+ string subdomain=target;
+ unsigned int pos;
+ while((pos=subdomain.find("."))!=string::npos) {
+ subdomain=subdomain.substr(pos+1);
+ // DLOG();
+
+ string searchstr=string("*.")+subdomain;
+
+ B.lookup(QType(QType::ANY), searchstr,p); // start our search at the backend
+
+ while(B.get(rr)) { // read results
+ found=true;
+ if(rr.qtype==p->qtype || rr.qtype.getCode()==QType::CNAME) {
+ rr.qname=target;
+ r->addRecord(rr); // and add
+ if(rr.qtype.getCode()==QType::CNAME) {
+ if(target==rr.content) {
+ L<<Logger::Error<<"Ignoring wildcard CNAME '"<<rr.qname<<"' pointing at itself"<<endl;
+ r->setRcode(RCode::ServFail);
+ continue;
+ }
+
+ DLOG(L<<Logger::Error<<"Retargeting because of wildcard cname, from "<<target<<" to "<<rr.content<<endl);
+
+ target=rr.content; // retarget
+ retargeted=true;
+ }
+ }
+ else if(d_doFancyRecords && arg().mustDo("wildcard-url") && p->qtype.getCode()==QType::A && rr.qtype.getName()=="URL") {
+ rr.content=arg()["urlredirector"];
+ rr.qtype=QType::A;
+ rr.qname=target;
+
+ r->addRecord(rr);
+ }
+ }
+ if(found) {
+ DLOG(L<<"Wildcard match on '"<<string("*.")+subdomain<<"'"<<endl);
+ return retargeted ? 2 : 1;
+ }
+ }
+ return 0;
+}
+
+/** dangling is declared true if we were unable to resolve everything */
+int PacketHandler::doAdditionalProcessing(DNSPacket *p, DNSPacket *r, bool &dangling)
+{
+ DNSResourceRecord rr;
+ dangling=false;
+ if(p->qtype.getCode()!=QType::AXFR && r->needAP()) { // this packet needs additional processing
+ DLOG(L<<Logger::Warning<<"This packet needs additional processing!"<<endl);
+
+ vector<DNSResourceRecord> arrs=r->getAPRecords();
+
+ for(vector<DNSResourceRecord>::const_iterator i=arrs.begin();
+ i!=arrs.end();
+ ++i) {
+ B.lookup("A",i->content,p);
+ bool foundOne=false;
+ while(B.get(rr)) {
+ foundOne=true;
+ if(rr.domain_id!=i->domain_id && arg()["out-of-zone-additional-processing"]=="no") {
+ DLOG(L<<Logger::Warning<<"Not including out-of-zone additional processing of "<<i->qname<<" ("<<rr.qname<<")"<<endl);
+ continue; // not adding out-of-zone additional data
+ }
+
+ rr.d_place=DNSResourceRecord::ADDITIONAL;
+ r->addRecord(rr);
+
+ }
+ if(!foundOne)
+ dangling=true;
+ }
+ }
+ return 1;
+}
+
+/* returns 1 if everything is done & ready, 0 if the search should continue */
+int PacketHandler::makeCanonic(DNSPacket *p, DNSPacket *r, string &target)
+{
+ DNSResourceRecord rr;
+
+ bool found=false, rfound=false;
+
+ if(p->qtype.getCode()!=QType::CNAME && !d_doCNAME)
+ return 0;
+
+ // Traverse a CNAME chain if needed
+ for(int numloops=0;;numloops++) {
+ if(numloops==10) {
+ L<<Logger::Error<<"Detected a CNAME loop involving "<<target<<", sending SERVFAIL"<<endl;
+ r->setRcode(2);
+ return 1;
+ }
+
+ B.lookup(QType(QType::ANY),target,p);
+
+ bool shortcut=p->qtype.getCode()!=QType::SOA && p->qtype.getCode()!=QType::ANY;
+
+ while(B.get(rr)) {
+ if(!rfound && rr.qtype.getCode()==QType::CNAME) {
+ found=true;
+ r->addRecord(rr);
+ target=rr.content; // for retargeting
+ }
+ if(shortcut && !found && rr.qtype==p->qtype) {
+ rfound=true;
+ r->addRecord(rr);
+ }
+ }
+ if(rfound)
+ return 1; // ANY lookup found the right answer immediately
+
+ if(found) {
+ if(p->qtype.getCode()==QType::CNAME) // they really wanted a CNAME!
+ return 1;
+ DLOG(L<<"Looping because of a CNAME to "<<target<<endl);
+ found=false;
+ }
+ else break;
+ }
+
+ // we now have what we really search for ready in 'target'
+ return 0;
+}
+
+/* Semantics:
+
+- only one backend owns the SOA of a zone
+- only one AXFR per zone at a time - double startTransaction should fail
+- backends need to implement transaction semantics
+
+
+How BindBackend would implement this:
+ startTransaction makes a file
+ feedRecord sends everything to that file
+ commitTransaction moves that file atomically over the regular file, and triggers a reload
+ rollbackTransaction removes the file
+
+
+How PostgreSQLBackend would implement this:
+ startTransaction starts a sql transaction, which also deletes all records
+ feedRecord is an insert statement
+ commitTransaction commits the transaction
+ rollbackTransaction aborts it
+
+How MySQLBackend would implement this:
+ (good question!)
+
+*/
+
+int PacketHandler::trySuperMaster(DNSPacket *p)
+{
+ Resolver::res_t nsset;
+ try {
+ Resolver resolver;
+ u_int32_t theirserial;
+ int res=resolver.getSoaSerial(p->getRemote(),p->qdomain, &theirserial);
+ if(res<=0) {
+ L<<Logger::Error<<"Unable to determine SOA serial for "<<p->qdomain<<" at potential supermaster "<<p->getRemote()<<endl;
+ return RCode::ServFail;
+ }
+
+ resolver.resolve(p->getRemote(),p->qdomain.c_str(), QType::NS);
+
+ nsset=resolver.result();
+ }
+ catch(ResolverException &re) {
+ L<<Logger::Error<<"Error resolving SOA or NS for '"<<p->qdomain<<"' at "<<p->getRemote()<<endl;
+ return RCode::ServFail;
+ }
+
+ string account;
+ DNSBackend *db;
+ if(!B.superMasterBackend(p->getRemote(), p->qdomain, nsset, &account, &db)) {
+ L<<Logger::Error<<"Unable to find backend willing to host "<<p->qdomain<<" for potential supermaster "<<p->getRemote()<<endl;
+ return RCode::Refused;
+ }
+ db->createSlaveDomain(p->getRemote(),p->qdomain,account);
+ Communicator.addSuckRequest(p->qdomain, p->getRemote());
+ L<<"Created new slave zone '"<<p->qdomain<<"' from supermaster "<<p->getRemote()<<", queued axfr"<<endl;
+ return RCode::NoError;
+}
+
+int PacketHandler::doNotify(DNSPacket *p)
+{
+ /* now what?
+ was this notification from an approved address?
+ We determine our internal SOA id (via UeberBackend)
+ We determine the SOA at our (known) master
+ if master is higher -> do stuff
+ */
+ if(!arg().mustDo("slave")) {
+ L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" but slave support is disabled in the configuration"<<endl;
+ return RCode::NotImp;
+ }
+ SOAData sd;
+ sd.serial=0;
+ DNSBackend *db=0;
+ DomainInfo di;
+ if(!B.getDomainInfo(p->qdomain,di) || !(db=di.backend)) {
+ L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" for which we are not authoritative"<<endl;
+ return trySuperMaster(p);
+ }
+
+ if(!db->isMaster(p->qdomain, p->getRemote())) {
+ L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" which is not a master"<<endl;
+ return RCode::Refused;
+ }
+
+ u_int32_t theirserial=0;
+
+ Resolver resolver;
+ int res=resolver.getSoaSerial(p->getRemote(),p->qdomain, &theirserial);
+ if(res<=0) {
+ L<<Logger::Error<<"Unable to determine SOA serial for "<<p->qdomain<<" at "<<p->getRemote()<<endl;
+ return RCode::ServFail;
+ }
+
+ if(theirserial<=sd.serial) {
+ L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from master "<<p->getRemote()<<", we are up to date: "<<
+ theirserial<<"<="<<sd.serial<<endl;
+ return RCode::NoError;
+ }
+ else {
+ L<<Logger::Error<<"Received valid NOTIFY for "<<p->qdomain<<" (id="<<sd.domain_id<<") from master "<<p->getRemote()<<": "<<
+ theirserial<<" > "<<sd.serial<<endl;
+
+ Communicator.addSuckRequest(p->qdomain, p->getRemote());
+ }
+ return -1;
+}
+
+
+//! Called by the Distributor to ask a question. Returns 0 in case of an error
+DNSPacket *PacketHandler::question(DNSPacket *p)
+{
+ DNSResourceRecord rr;
+ SOAData sd;
+
+ string subdomain="";
+ string soa;
+ int retargetcount=0;
+ bool noSameLevelNS;
+
+ DNSPacket *r=0;
+ try {
+ DLOG(L << Logger::Notice<<"Remote "<<inet_ntoa( reinterpret_cast< struct sockaddr_in * >( &( p->remote ))->sin_addr )<<" wants a type " << p->qtype.getName() << " ("<<p->qtype.getCode()<<") about '"<<p->qdomain << "'" << endl);
+
+ if(p->d.qr) { // QR bit from dns packet (thanks RA from N)
+ L<<Logger::Error<<"Received an answer (non-query) packet from "<<p->getRemote()<<", dropping"<<endl;
+ S.inc("corrupt-packets");
+ return 0;
+ }
+
+ // XXX FIXME do this in DNSPacket::parse ?
+
+ if(!p->qdomain.empty() && (p->qdomain[0]=='%' || p->qdomain.find('|')!=string::npos) ) {
+ L<<Logger::Error<<"Received a malformed qdomain from "<<p->getRemote()<<", '"<<p->qdomain<<"': dropping"<<endl;
+ S.inc("corrupt-packets");
+ return 0;
+ }
+ if(p->d.opcode) { // non-zero opcode (again thanks RA!)
+ if(p->d.opcode==Opcode::Update) {
+ if(arg().mustDo("log-failed-updates"))
+ L<<Logger::Notice<<"Received an UPDATE opcode from "<<p->getRemote()<<" for "<<p->qdomain<<", sending NOTIMP"<<endl;
+ r=p->replyPacket();
+ r->setRcode(RCode::NotImp); // notimp;
+ return r;
+ }
+ else if(p->d.opcode==Opcode::Notify) {
+ int res=doNotify(p);
+ if(res>=0) {
+ DNSPacket *r=p->replyPacket();
+ r->setRcode(res);
+ return r;
+ }
+ return 0;
+ }
+
+ L<<Logger::Error<<"Received an unknown opcode "<<p->d.opcode<<" from "<<p->getRemote()<<" for "<<p->qdomain<<endl;
+
+ r=p->replyPacket();
+ r->setRcode(RCode::NotImp);
+ return r;
+ }
+
+ r=p->replyPacket(); // generate an empty reply packet
+ bool found=false;
+
+ string target=p->qdomain;
+
+ if (doDNSCheckRequest(p, r, target))
+ goto sendit;
+
+ if(doVersionRequest(p,r,target)) // catch version.bind requests
+ goto sendit;
+
+ // now we start doing things
+ // if the packet wants to be recursed, and we do recursion (but not lazy recursion!), hand it off
+ if(p->d.rd && !d_doLazyRecursion && d_doRecursion && DP->sendPacket(p)) {
+ // handed off to our recursor friend and forget all about it
+ return 0; // p will now be deleted, it is safe to answer 0 here
+ }
+
+ if(p->qclass==255) // any class query
+ r->setA(false);
+ else if(p->qclass!=1) // we only know about IN, so we don't find anything
+ goto sendit;
+
+ retargeted:;
+ if(retargetcount++>10) {
+ L<<Logger::Error<<"Detected wildcard CNAME loop involving '"<<target<<"'"<<endl;
+ r->setRcode(RCode::ServFail);
+ goto sendit;
+ }
+
+ if(makeCanonic(p,r,target)>0) // traverse CNAME chain until we have a useful record (may actually give the correct answer!)
+ goto sendit; // this might be the end of it (client requested a CNAME, or we found the answer already)
+
+ if(d_doFancyRecords) { // MBOXFW, URL <- fake records, emulated with MX and A
+ int res=doFancyRecords(p,r,target);
+ if(res) { // had a result
+ if(res<0) // it was an error
+ r->setRcode(RCode::ServFail);
+ goto sendit;
+ }
+ }
+
+ // now ready to start the real direct search
+
+ if(p->qtype.getCode()==QType::SOA || p->qtype.getCode()==QType::ANY) { // this is special
+
+ if(B.getSOA(target,sd)) {
+ rr.qname=target;
+ rr.qtype=QType::SOA;
+ rr.content=DNSPacket::serializeSOAData(sd);
+ rr.ttl=sd.ttl;
+ rr.domain_id=sd.domain_id;
+ rr.d_place=DNSResourceRecord::ANSWER;
+ r->addRecord(rr);
+ if(p->qtype.getCode()==QType::SOA) { // we are done
+ goto sendit;
+ }
+ }
+ }
+
+ noSameLevelNS=true;
+
+ if(p->qtype.getCode()!=QType::SOA) { // regular direct lookup
+ B.lookup(QType(QType::ANY), target,p);
+
+ while(B.get(rr)) {
+ if(rr.qtype.getCode()==QType::SOA) // skip any direct SOA responses as they may be different
+ continue;
+ if(rr.qtype==p->qtype || p->qtype.getCode()==QType::ANY ) {
+ DLOG(L<<"Found a direct answer: "<<rr.content<<endl);
+ found=true;
+ r->addRecord(rr); // and add
+ }
+ else
+ if(rr.qtype.getCode()==QType::NS)
+ noSameLevelNS=false;
+ }
+
+ if(p->qtype.getCode()==QType::ANY) {
+ if(d_doFancyRecords) {
+ int res=findMboxFW(p,r,target);
+ if(res<0)
+ L<<Logger::Error<<"Error finding a mailbox record after an ANY query"<<endl;
+ if(res>0) {
+ DLOG(L<<Logger::Error<<"Frobbed an MX in!"<<endl);
+ found=true;
+ }
+ }
+ }
+
+ if(found)
+ goto sendit;
+ }
+
+ // not found yet, try wildcards (we only try here in case of recursion)
+
+ if(p->d.rd && d_doRecursion && d_doLazyRecursion && d_doWildcards) {
+ int res=doWildcardRecords(p,r,target);
+ if(res) { // had a result
+
+ // FIXME: wildCard may retarget us in the future
+ if(res==1) // had a straight result
+ goto sendit;
+ if(res==2)
+ goto retargeted;
+ goto sendit;
+ }
+ }
+
+ // LAZY RECURSION CUT-OUT!
+
+ if(p->d.rd && d_doRecursion && d_doLazyRecursion && DP->sendPacket(p)) {
+ delete r;
+ return 0;
+ }
+
+ unsigned int pos;
+
+ DLOG(L<<"Nothing found so far for '"<<target<<"', do we even have authority over this domain?"<<endl);
+
+ bool weAuth;
+ int zoneId;
+
+ weAuth=getAuth(p, &sd, target, &zoneId); // TLDAuth perhaps
+ if(weAuth) {
+ DLOG(L<<Logger::Warning<<"Soa found: "<<soa<<endl);
+ ;
+ }
+
+ if(!weAuth) {
+ if(p->d.rd || target==p->qdomain) { // only servfail if we didn't follow a CNAME
+ if(d_logDNSDetails)
+ L<<Logger::Warning<<"Not authoritative for '"<< target<<"', sending servfail to "<<
+ p->getRemote()<< (p->d.rd ? " (recursion was desired)" : "") <<endl;
+
+ r->setA(false);
+ r->setRcode(RCode::ServFail); // 'sorry' - this is where we might send out a root referral
+ }
+
+ S.ringAccount("unauth-queries",p->qdomain+"/"+p->qtype.getName());
+ S.ringAccount("remotes-unauth",p->getRemote());
+ }
+ else {
+ DLOG(L<<Logger::Warning<<"We ARE authoritative for a subdomain of '"<<target<<"' ("<<sd.qname<<"), perhaps we have a suitable NS record then"<<endl);
+ subdomain=target;
+ found=0;
+ pos=0;
+
+ do {
+ if(pos) // skip dot
+ pos++;
+
+ subdomain=subdomain.substr(pos);
+ if(noSameLevelNS) { // skip first lookup if it is known not to exist
+ noSameLevelNS=false;
+ continue;
+ }
+
+ if(!Utility::strcasecmp(subdomain.c_str(),sd.qname.c_str())) // about to break out of our zone
+ break;
+
+ B.lookup("NS", subdomain,p,zoneId); // start our search at the backend
+
+ while(B.get(rr)) {
+ found=true;
+ rr.d_place=DNSResourceRecord::AUTHORITY; // this for the authority section
+ r->addRecord(rr);
+ }
+ if(found || (!subdomain.empty() && subdomain[0]=='.')) { // this catches '..'
+ r->setA(false); // send out an NS referral, which should be unauth
+ break;
+ }
+ }while((pos=subdomain.find("."))!=string::npos);
+
+ if(!found) {
+ // try wildcards then
+ if(d_doWildcards) {
+ int res=doWildcardRecords(p,r,target);
+
+ if(res==1) // had a straight result
+ goto sendit;
+ if(res==2)
+ goto retargeted;
+ }
+
+ // we have authority but no answer, so we add the SOA for negative caching
+ rr.qname=sd.qname;
+ rr.qtype=QType::SOA;
+ rr.content=DNSPacket::serializeSOAData(sd);
+ rr.ttl=sd.ttl;
+ rr.domain_id=sd.domain_id;
+ rr.d_place=DNSResourceRecord::AUTHORITY;
+ r->addRecord(rr);
+
+
+ // need to send NXDOMAIN if there are 0 records for whatever type for target
+
+ B.lookup("ANY",target,p);
+ while(B.get(rr))
+ found=true;
+
+ if(!found) {
+ SOAData sd2;
+ if(B.getSOA(target,sd2)) // is there a SOA perhaps? (which may not appear in an ANY query)
+ found=true;
+ }
+
+ if(!found) {
+ if(d_logDNSDetails)
+ L<<Logger::Notice<<"Authoritative NXDOMAIN to "<< p->getRemote() <<" for '"<<target<<"' ("<<p->qtype.getName()<<")"<<endl;
+
+ r->setRcode(RCode::NXDomain);
+ S.ringAccount("nxdomain-queries",p->qdomain+"/"+p->qtype.getName());
+ }
+ else {
+ if(d_logDNSDetails)
+ L<<Logger::Notice<<"Authoritative empty NO ERROR to "<< p->getRemote() <<" for '"<<target<<"' ("<<p->qtype.getName()<<"), other types do exist"<<endl;
+ S.ringAccount("noerror-queries",p->qdomain+"/"+p->qtype.getName());
+ }
+ }
+ }
+
+ // whatever we've built so far, do additional processing
+
+ sendit:;
+ bool dangling=false;
+ if(doAdditionalProcessing(p,r, dangling)<0)
+ return 0;
+
+ /* we were unable to resolve everything, so give it away */
+ if(p->d.rd && dangling && d_doRecursion && d_doLazyRecursion && DP->sendPacket(p)) {
+ delete r;
+ return 0;
+ }
+
+ r->wrapup(); // needed for inserting in cache
+ PC.insert(p,r); // in the packet cache
+ }
+ catch(DBException &e) {
+ L<<Logger::Error<<"Database module reported condition which prevented lookup - sending out servfail"<<endl;
+ r->setRcode(RCode::ServFail);
+ S.inc("servfail-packets");
+ S.ringAccount("servfail-queries",p->qdomain);
+ }
+ return r;
+
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PACKETHANDLER_HH
+#define PACKETHANDLER_HH
+\r
+#ifndef WIN32\r
+# include <sys/socket.h>\r
+# include <netinet/in.h>\r
+# include <arpa/inet.h>\r
+#endif // WIN32\r
+\r
+#include "ueberbackend.hh"
+#include "dnspacket.hh"
+#include "packetcache.hh"
+
+using namespace std;
+
+/** Central DNS logic according to RFC1034. Ask this class a question in the form of a DNSPacket
+ and it will return, synchronously, a DNSPacket answer, suitable for
+ sending out over the network.
+
+ The PacketHandler gives your question to the PacketCache for possible inclusion
+ in the cache.
+
+ In order to do so, the PacketHandler contains a reference to the global extern PacketCache PC
+
+ It also contains an UeberBackend instance for answering the subqueries needed to generate
+ a complete reply.
+
+*/
+
+class PacketHandler
+{
+public:
+ template<class T> class Guard
+ {
+ public:
+ Guard(T **guard)
+ {
+ d_guard=guard;
+ }
+
+ ~Guard()
+ {
+ if(*d_guard)
+ delete *d_guard;
+ }
+
+ private:
+ T **d_guard;
+ };
+
+
+ DNSPacket *question(DNSPacket *); //!< hand us a DNS packet with a question, we give you an answer
+ PacketHandler();
+ ~PacketHandler(); // defined in packethandler.cc, and does --count
+ static int numRunning(){return s_count;}; //!< Returns the number of running PacketHandlers
+
+ void soaMagic(DNSResourceRecord *rr);
+ DNSBackend *getBackend();
+ class DBException{};
+
+private:
+ int doNotify(DNSPacket *);
+ int PacketHandler::trySuperMaster(DNSPacket *p);
+ int makeCanonic(DNSPacket *p, DNSPacket *r, string &target);
+ int doWildcardRecords(DNSPacket *p, DNSPacket *r, string &target);
+ int findMboxFW(DNSPacket *p, DNSPacket *r, string &target);
+ int findUrl(DNSPacket *p, DNSPacket *r, string &target);
+ int doFancyRecords(DNSPacket *p, DNSPacket *r, string &target);
+ int doDNSCheckRequest(DNSPacket *p, DNSPacket *r, string &target);
+ int doVersionRequest(DNSPacket *p, DNSPacket *r, string &target);
+ bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId);
+ bool getTLDAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId);
+ int doAdditionalProcessing(DNSPacket *p, DNSPacket *r, bool &dangling);
+
+
+ static int s_count;
+ bool d_doFancyRecords;
+ bool d_doRecursion;
+ bool d_doLazyRecursion;
+ bool d_doWildcards;
+ bool d_doCNAME;
+ bool d_logDNSDetails;
+
+ UeberBackend B; // every thread an own instance
+};
+
+#endif /* PACKETHANDLER */
--- /dev/null
+INITDPATH=/etc/init.d
+BINARYPATH=/usr/sbin
+CONFIGPATH=/etc/powerdns
+SOCKETPATH=/var/run/
+DOCPATH=/usr/doc/pdns
+LIBRARYPATH=/usr/lib/powerdns
+PDNSUID=pdns
+PDNSGID=pdns
--- /dev/null
+INITDPATH=/usr/local/etc/rc.d/
+BINARYPATH=/usr/local/sbin
+CONFIGPATH=/usr/local/etc/powerdns
+SOCKETPATH=/var/run/
+DOCPATH=/usr/local/share/doc/powerdns
+LIBRARYPATH=/usr/local/lib/powerdns
+PDNSUID=pdns
+PDNSGID=pdns
--- /dev/null
+INITDPATH=/etc/init.d
+BINARYPATH=/usr/sbin
+CONFIGPATH=/etc/powerdns
+SOCKETPATH=/var/run/
+DOCPATH=""
+LIBRARYPATH=/usr/lib/powerdns
+PDNSUID=pdns
+PDNSGID=pdns
--- /dev/null
+INITDPATH=/etc/init.d
+BINARYPATH=/usr/sbin
+CONFIGPATH=/etc/powerdns
+SOCKETPATH=/var/run/
+DOCPATH=/usr/doc/pdns
+LIBRARYPATH=/usr/lib/powerdns
+PDNSUID=pdns
+PDNSGID=pdns
--- /dev/null
+# Generated automatically from pdns.conf-dist.in by configure.
+
+# cache-ttl=...
+# Seconds to store packets in the PacketCache
+# default-soa-name=...
+# name to insert in the SOA record if none set in the backend
+# distributor-threads=...
+# Default number of Distributor (backend) threads to start
+# fancy-records=...
+# Process URL and MBOXFW records
+# help=...
+# Provide a helpful message
+# localaddress=...
+# Local IP address to which we bind
+# localport=...
+# The port on which we listen
+# loglevel=...
+# Amount of logging. Higher is more. Do not set below 3
+# out-of-zone-additional-processing | out-of-zone-additional-processing=yes | out-of-zone-additional-processing=no
+# Do out of zone additional processing
+# smtpredirector=...
+# Our smtpredir MX host
+# urlredirector=...
+# Where we send hosts to that need to be url redirected
+# wildcards=...
+# Honor wildcards in the database
--- /dev/null
+# @configure_input@
+
+# cache-ttl=...
+# Seconds to store packets in the PacketCache
+# default-soa-name=...
+# name to insert in the SOA record if none set in the backend
+# distributor-threads=...
+# Default number of Distributor (backend) threads to start
+# fancy-records=...
+# Process URL and MBOXFW records
+# help=...
+# Provide a helpful message
+# localaddress=...
+# Local IP address to which we bind
+# localport=...
+# The port on which we listen
+# loglevel=...
+# Amount of logging. Higher is more. Do not set below 3
+# out-of-zone-additional-processing | out-of-zone-additional-processing=yes | out-of-zone-additional-processing=no
+# Do out of zone additional processing
+# smtpredirector=...
+# Our smtpredir MX host
+# urlredirector=...
+# Where we send hosts to that need to be url redirected
+# wildcards=...
+# Honor wildcards in the database
--- /dev/null
+# chkconfig: - 80 75
+# description: PDNS is a versatile high performance authoritative nameserver
+
+cd $SOCKETPATH
+suffix=`basename $0 | awk -F- '{print $2}'`
+if [ $suffix ]
+then
+ EXTRAOPTS=--config-name=$suffix
+ PROGNAME=pdns-$suffix
+else
+ PROGNAME=pdns
+fi
+
+pdns_server="$BINARYPATH/pdns_server $EXTRAOPTS"
+
+doPC()
+{
+ ret=$($BINARYPATH/pdns_control $EXTRAOPTS $1 $2 2> /dev/null)
+}
+
+
+if [ "$1" != "mrtg" -a "$1" != "cricket" ]
+then
+ echo -n "$PROGNAME: "
+fi
+
+doPC ping
+NOTRUNNING=$?
+
+case "$1" in
+ status)
+ if test "$NOTRUNNING" = "0"
+ then
+ doPC status
+ echo $ret
+ else
+ echo "not running"
+ fi
+ ;;
+
+ stop)
+ if test "$NOTRUNNING" = "0"
+ then
+ doPC quit
+ echo $ret
+ else
+ echo "not running"
+ fi
+ ;;
+
+ force-stop)
+ killall -v -9 pdns_server
+ ;;
+
+ start)
+ if test "$NOTRUNNING" = "0"
+ then
+ echo "already running"
+ else
+ $pdns_server --daemon --guardian=yes
+ if test "$?" = "0"
+ then
+ echo "started"
+ fi
+ fi
+ ;;
+
+ force-reload | restart)
+ echo -n stopping and waiting
+ doPC quit
+ sleep 3
+ echo
+ $0 start
+ ;;
+
+ reload)
+ if test "$NOTRUNNING" = "0"
+ then
+ doPC cycle
+ echo requested reload
+ else
+ echo not running yet
+ $0 start
+ fi
+ ;;
+
+ monitor)
+ if test "$NOTRUNNING" = "0"
+ then
+ echo "already running"
+ else
+ $pdns_server --daemon=no --guardian=no --control-console --loglevel=9
+ fi
+ ;;
+
+ dump)
+ if test "$NOTRUNNING" = "0"
+ then
+ doPC list
+ echo $ret
+ else
+ echo "not running"
+ fi
+ ;;
+
+ show)
+ if [ $# -lt 2 ]
+ then
+ echo Insufficient parameters
+ exit
+ fi
+ if test "$NOTRUNNING" = "0"
+ then
+ echo -n "$2="
+ doPC show $2 ; echo $ret
+ else
+ echo "not running"
+ fi
+ ;;
+
+ mrtg)
+ if [ $# -lt 2 ]
+ then
+ echo Insufficient parameters
+ exit
+ fi
+ if test "$NOTRUNNING" = "0"
+ then
+ doPC show $2 ; echo $ret
+ if [ "$3x" != "x" ]
+ then
+ doPC show $3 ; echo $ret
+ else
+ echo 0
+ fi
+ doPC uptime ; echo $ret
+ echo PowerDNS daemon
+ else
+ echo "not running"
+ fi
+
+ ;;
+
+ cricket)
+ if [ $# -lt 2 ]
+ then
+ echo Insufficient parameters
+ exit
+ fi
+ if test "$NOTRUNNING" = "0"
+ then
+ doPC show $2 ; echo $ret
+ else
+ echo "not running"
+ fi
+
+ ;;
+
+
+
+ *)
+ echo pdns [start\|stop\|restart\|status\|dump\|show\|mrtg]
+
+ ;;
+esac
+
+
--- /dev/null
+Buildroot: /tmp/pdns
+Name: pdns
+Version: 2.8
+Release: 1
+Summary: extremely powerful and versatile nameserver
+Copyright: see /usr/doc/pdns/copyright
+Distribution: Neutral
+Vendor: PowerDNS.COM BV
+Group: System/DNS
+AutoReqProv: no
+
+%define _rpmdir ../
+%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
+
+%description
+PowerDNS is a versatile nameserver which supports a large number
+of different backends ranging from simple zonefiles to relational
+databases and load balancing/failover algorithms.
+
+This RPM is statically compiled and should work on all Linux distributions.
+It comes with support for MySQL, PostgreSQL, Bind zonefiles and the 'pipe
+backend'.
+
+%files
+%defattr(-,root,root)
+"/usr/sbin/pdns_server"
+"/usr/sbin/pdns_control"
+"/usr/sbin/zone2sql"
+"/usr/doc/pdns/LICENSE"
+"/usr/doc/pdns/README"
+"/usr/doc/pdns/html/"
+"/usr/doc/pdns/pdns.txt"
+"/usr/doc/pdns/pdns.pdf"
+%dir "/etc/powerdns/"
+%config(noreplace) "/etc/powerdns/pdns.conf"
+%config "/etc/init.d/pdns"
+
+%post
+echo Remember to create a 'pdns' user before starting pdns
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include <iostream>
+#include <string>
+#include <vector>
+#include <utility>
+#include <sstream>
+#include "qtype.hh"
+#include "misc.hh"
+
+bool QType::uninit=true;
+vector<QType::namenum> QType::names;
+
+void QType::insert(char *p, int n)
+{
+ names.push_back(make_pair(string(p),n));
+}
+\r
+
+QType::QType()
+{
+ if(uninit)
+ {
+ uninit=false;
+ insert("A",1);
+ insert("NS",2);
+ insert("CNAME",5);
+ insert("SOA",6);
+ insert("PTR",12);
+ insert("HINFO",13);
+ insert("MX",15);
+ insert("TXT",16);
+ insert("RP",17);
+ insert("SRV",33);
+ insert("A6",38);
+ insert("AAAA",28);
+ insert("NAPTR",35);
+ insert("AXFR",252);
+ insert("ANY",255);
+ insert("URL",256);
+ insert("MBOXFW",257);
+ insert("CURL",258);
+ }
+}
+
+int QType::getCode() const
+{
+ return code;
+}
+
+string QType::getName() const
+{\r
+ vector<namenum>::iterator pos;
+ for(pos=names.begin();pos<names.end();++pos)
+ if(pos->second==code)
+ return pos->first;
+
+ return "#"+itoa(code);
+}
+
+QType &QType::operator=(int n)
+{
+ code=n;
+ return *this;
+}
+
+int QType::chartocode(const char *p)
+{
+ vector<namenum>::iterator pos;
+ for(pos=names.begin();pos<names.end();++pos)
+ if(pos->first==p)
+ return pos->second;
+
+ return 0;
+}
+
+QType &QType::operator=(const char *p)
+{
+ code=chartocode(p);
+ return *this;
+}
+
+bool QType::operator==(const QType &comp) const
+{
+ return(comp.code==code);
+}
+
+QType &QType::operator=(const string &s)
+{
+ code=chartocode(s.c_str());
+ return *this;
+}
+
+
+QType::QType(int n)
+{
+ QType();
+ code=n;
+}
+
+QType::QType(char *p)
+{
+ QType();
+ code=chartocode(p);
+}
+
+#if 0
+int main(int argc, char **argv)
+{
+ QType t;
+
+ cout << endl;
+ cout << "Assiging a '6'" << endl;
+ t=6;
+ cout << "Code is now " << t.getCode() << endl;
+ cout << "Name is now " << t.getName() << endl;
+
+ cout << endl;
+
+ cout << "Assiging a 'CNAME'" << endl;
+ t="CNAME";
+ cout << "Code is now " << t.getCode() << endl;
+ cout << "Name is now " << t.getName() << endl;
+
+ QType u;
+ u="SOA";
+ cout << u.getCode() << endl;
+
+
+}
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef QTYPE_HH
+#define QTYPE_HH
+/* (C) 2002 POWERDNS.COM BV */
+// $Id: qtype.hh,v 1.1 2002/11/27 15:18:32 ahu Exp $
+#include <string>
+#include <vector>
+#include <utility>
+
+using namespace std;
+
+/** The QType class is meant to deal easily with the different kind of resource types, like 'A', 'NS',
+ * 'CNAME' etcetera. These types have both a name and a number. This class can seemlessly move between
+ * them. Use it like this:
+
+\code
+ QType t;
+ t="CNAME";
+ cout<<t.getCode()<<endl; // prints '5'
+ t=6;
+ cout<<t.getName()<<endl; // prints 'SOA'
+\endcode
+
+*/
+
+
+
+class QType
+{
+public:
+ QType(); //!< Naked constructor
+ explicit QType(int); //!< convert from an integer to a QType
+ QType(char *p); //!< convert from a char* to a QType\r
+
+ QType &operator=(int); //!< Assigns integers to us
+ QType &operator=(const char *); //!< Assings strings to us
+ QType &operator=(const string &); //!< Assings strings to us
+ bool operator==(const QType &) const; //!< equality operator
+
+ string getName() const; //!< Get a string representation of this type
+ int getCode() const; //!< Get the integer representation of this type
+
+ static int chartocode(const char *p); //!< convert a character string to a code
+
+ enum {A=1,NS=2,CNAME=5,SOA=6,PTR=12,MX=15,TXT=16,AAAA=28,NAPTR=35,AXFR=252, ANY=255} types;
+private:
+ short int code;
+ typedef pair<string,int> namenum;
+ void insert(char *p, int n);
+
+ static vector<namenum> names;
+ static bool uninit;
+};
+
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include "dnsbackend.hh"
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "dnspacket.hh"
+#include "ahuexception.hh"
+#include "logger.hh"
+
+/* FIRST PART */
+class RandomBackend : public DNSBackend
+{
+public:
+ RandomBackend(const string &suffix="")
+ {
+ setArgPrefix("random"+suffix);
+ d_ourname=getArg("hostname");
+ }
+
+ bool list(int id) {
+ return false; // we don't support AXFR
+ }
+
+ void lookup(const QType &type, const string &qdomain, DNSPacket *p, int zoneId)
+ {
+ if((type.getCode()!=QType::ANY && type.getCode()!=QType::A) || qdomain!=d_ourname) // we only know about random.powerdns.com A
+ d_answer=""; // no answer
+ else {
+ ostringstream os;
+ os<<Utility::random()%256<<"."<<Utility::random()%256<<"."<<Utility::random()%256<<"."<<Utility::random()%256;
+ d_answer=os.str(); // our random ip address
+ }
+
+ }
+
+ bool get(DNSResourceRecord &rr)
+ {
+ if(!d_answer.empty()) {
+ rr.qname=d_ourname; // fill in details
+ rr.qtype=QType::A; // A record
+ rr.ttl=5; // 5 seconds
+ rr.content=d_answer;
+
+ d_answer=""; // this was the last answer
+
+ return true;
+ }
+ return false; // no more data
+ }
+
+private:
+ string d_answer;
+ string d_ourname;
+};
+
+/* SECOND PART */
+
+class RandomFactory : public BackendFactory
+{
+public:
+ RandomFactory() : BackendFactory("random") {}
+ void declareArguments(const string &suffix="")
+ {
+ declare(suffix,"hostname","Hostname which is to be random","random.example.com");
+ }
+ DNSBackend *make(const string &suffix="")
+ {
+ return new RandomBackend(suffix);
+ }
+};
+
+/* THIRD PART */
+
+class RandomLoader
+{
+public:
+ RandomLoader()
+ {
+ BackendMakers().report(new RandomFactory);
+
+ L<<Logger::Info<<" [RandomBackend] This is the randombackend version "VERSION" ("__DATE__", "__TIME__") reporting"<<endl;
+ }
+};
+
+static RandomLoader randomLoader;
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: receiver.cc,v 1.1 2002/11/27 15:18:32 ahu Exp $
+#include <cstdio>
+#include <signal.h>
+#include <cstring>
+#include <cstdlib>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <iostream>
+#include <string>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <fstream>
+
+#include "config.h"
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "ueberbackend.hh"
+#include "dnspacket.hh"
+#include "nameserver.hh"
+#include "distributor.hh"
+#include "logger.hh"
+#include "arguments.hh"
+#include "packethandler.hh"
+#include "statbag.hh"
+#include "tcpreceiver.hh"
+#include "packetcache.hh"
+#include "ws.hh"
+#include "misc.hh"
+#include "dynlistener.hh"
+#include "dynhandler.hh"
+#include "communicator.hh"
+#include "dnsproxy.hh"
+#include "utility.hh"\r
+#include "common_startup.hh"
+
+time_t s_starttime;
+
+string s_programname="pdns"; // used in packethandler.cc
+
+char *funnytext=
+"*****************************************************************************\n"\
+"Ok, you just ran pdns_server through 'strings' hoping to find funny messages.\n"\
+"Well, you found one. \n"\
+"Two ions are flying through their particle accelerator, says the one to the\n"
+"other 'I think I've lost an electron!' \n"\
+"So the other one says, 'Are you sure?'. 'YEAH! I'M POSITIVE!'\n"\
+" the pdns crew - pdns@powerdns.com\n"
+"*****************************************************************************\n";
+
+
+// start (sys)logging
+
+/** \var Logger L
+\brief All logging is done via L, a Logger instance
+*/
+
+
+/**
+\file receiver.cc
+\brief The main loop of powerdns
+
+This file is where it all happens - main is here, as are the two pivotal threads qthread() and athread()
+*/
+
+void daemonize(void)
+{
+ if(fork())
+ exit(0); // bye bye
+
+ setsid();
+
+ // cleanup open fds, but skip sockets
+ close(0);
+ close(1);
+ close(2);
+
+}
+
+
+static int cpid;
+
+static void takedown(int i)
+{
+ if(cpid) {
+ L<<Logger::Error<<"Guardian is killed, taking down children with us"<<endl;
+ kill(cpid,SIGKILL);
+ exit(1);
+ }
+}
+
+static void writePid(void)
+{
+ string fname=arg()["socket-dir"]+"/"+s_programname+".pid";
+ ofstream of(fname.c_str());
+ if(of)
+ of<<getpid()<<endl;
+ else
+ L<<Logger::Error<<"Requested to write pid for "<<getpid()<<" to "<<fname<<" failed: "<<strerror(errno)<<endl;
+}
+
+int d_fd1[2], d_fd2[2];
+FILE *d_fp;
+
+static string DLRestHandler(const vector<string>&parts, pid_t ppid)
+{
+ string line;
+
+ for(vector<string>::const_iterator i=parts.begin();i!=parts.end();++i) {
+ if(i!=parts.begin())
+ line.append(1,' ');
+ line.append(*i);
+ }
+ line.append(1,'\n');
+
+ write(d_fd1[1],line.c_str(),line.size()+1);
+ char mesg[512];
+ fgets(mesg,sizeof(mesg),d_fp);
+ line=mesg;
+ chomp(line,"\n");
+ return line;
+}
+
+static string DLCycleHandler(const vector<string>&parts, pid_t ppid)
+{
+ kill(cpid,SIGKILL);
+ return "ok";
+}
+
+static int guardian(int argc, char **argv)
+{
+ if(isGuarded(argv))
+ return 0;
+
+ int infd=0, outfd=1;
+
+ DynListener dlg(s_programname);
+ dlg.registerFunc("QUIT",&DLQuitHandler);
+ dlg.registerFunc("CYCLE",&DLCycleHandler);
+ dlg.registerFunc("PING",&DLPingHandler);
+ dlg.registerFunc("STATUS",&DLStatusHandler);
+ dlg.registerRestFunc(&DLRestHandler);
+ dlg.go();
+ string progname=argv[0];
+
+ bool first=true;
+ cpid=0;
+
+ for(;;) {
+ int pid;
+ setStatus("Launching child");
+
+ if(pipe(d_fd1)<0 || pipe(d_fd2)<0) {
+ L<<Logger::Critical<<"Unable to open pipe for coprocess: "<<strerror(errno)<<endl;
+ exit(1);
+ }
+
+ if(!(pid=fork())) { // child
+ signal(SIGTERM, SIG_DFL);
+
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGUSR1, SIG_DFL);
+ signal(SIGUSR2, SIG_DFL);
+
+ char **const newargv=new char*[argc+2];
+ int n;
+
+ if(arg()["config-name"]!="") {
+ progname+="-"+arg()["config-name"];
+ L<<Logger::Error<<"Virtual configuration name: "<<arg()["config-name"]<<endl;
+ }
+
+ newargv[0]=strdup(const_cast<char *>((progname+"-instance").c_str()));
+ for(n=1;n<argc;n++) {
+ newargv[n]=argv[n];
+ }
+ newargv[n]=0;
+
+ L<<Logger::Error<<"Guardian is launching an instance"<<endl;
+ close(d_fd1[1]);
+ close(d_fd2[0]);
+
+ if(d_fd1[0]!= infd) {
+ dup2(d_fd1[0], infd);
+ close(d_fd1[0]);
+ }
+
+ if(d_fd2[1]!= outfd) {
+ dup2(d_fd2[1], outfd);
+ close(d_fd2[1]);
+ }
+ if(execv(argv[0], newargv)<0) {
+ L<<Logger::Error<<"Unable to execv '"<<argv[0]<<"': "<<strerror(errno)<<endl;
+ char **p=newargv;
+ while(*p)
+ L<<Logger::Error<<*p++<<endl;
+
+ exit(1);
+ }
+ L<<Logger::Error<<"execve returned!!"<<endl;
+ // never reached
+ }
+ else if(pid>0) { // parent
+ close(d_fd1[0]);
+ close(d_fd2[1]);
+ if(!(d_fp=fdopen(d_fd2[0],"r"))) {
+ L<<Logger::Critical<<"Unable to associate a file pointer with pipe: "<<stringerror()<<endl;
+ exit(1);
+ }
+ setbuf(d_fp,0); // no buffering please, confuses select
+
+ if(first) {
+ first=false;
+ signal(SIGTERM, takedown);
+
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGUSR1, SIG_IGN);
+ signal(SIGUSR2, SIG_IGN);
+
+ writePid();
+ }
+
+ int status;
+ cpid=pid;
+ for(;;) {
+ int ret=waitpid(pid,&status,WNOHANG);
+
+ if(ret<0) {
+ L<<Logger::Error<<"In guardian loop, waitpid returned error: "<<strerror(errno)<<endl;
+ L<<Logger::Error<<"Dying"<<endl;
+ exit(1);
+ }
+ else if(ret) // something exited
+ break;
+ else { // child is alive
+ // execute some kind of ping here
+ if(DLQuitPlease())
+ takedown(1);
+ setStatus("Child running on pid "+itoa(pid));
+ sleep(1);
+ }
+ }
+ close(d_fd1[1]);
+ fclose(d_fp);
+
+ if(WIFEXITED(status)) {
+ int ret=WEXITSTATUS(status);
+
+ if(ret==99) {
+ L<<Logger::Error<<"Child requested a stop, exiting"<<endl;
+ exit(1);
+ }
+ setStatus("Child died with code "+itoa(ret));
+ L<<Logger::Error<<"Our pdns instance exited with code "<<ret<<endl;
+ L<<Logger::Error<<"Respawning"<<endl;
+
+ sleep(1);
+ continue;
+ }
+ if(WIFSIGNALED(status)) {
+ int sig=WTERMSIG(status);
+ setStatus("Child died because of signal "+itoa(sig));
+ L<<Logger::Error<<"Our pdns instance ("<<pid<<") exited after signal "<<sig<<endl;
+#ifdef WCOREDUMP
+ if(WCOREDUMP(status))
+ L<<Logger::Error<<"Dumped core"<<endl;
+#endif
+
+ L<<Logger::Error<<"Respawning"<<endl;
+ sleep(1);
+ continue;
+ }
+ L<<Logger::Error<<"No clue what happened! Respawning"<<endl;
+ }
+ else {
+ L<<Logger::Error<<"Unable to fork: "<<strerror(errno)<<endl;
+ exit(1);
+ }
+ }
+}
+
+static void UNIX_declareArguments()
+{
+ static char pietje[128]="!@@SYSCONFDIR@@:";
+ arg().set("config-dir","Location of configuration directory (pdns.conf)")=
+ strcmp(pietje+1,"@@SYSCONFDIR@@:") ? pietje+strlen("@@SYSCONFDIR@@:")+1 : SYSCONFDIR;
+
+ arg().set("config-name","Name of this virtual configuration - will rename the binary image")="";
+ arg().set("socket-dir","Where the controlsocket will live")=LOCALSTATEDIR;
+ arg().set("module-dir","Default directory for modules")=BINDIR+string("/../lib");
+ arg().set("chroot","If set, chroot to this directory for more security")="";
+ arg().set("setuid","If set, change user id to this uid for more security")="";
+ arg().set("setgid","If set, change group id to this gid for more security")="";
+ arg().set("logging-facility","Log under a specific facility")="";
+ arg().set("daemon","Operate as a daemon")="no";
+
+}
+
+static void loadModules()
+{
+ if(!arg()["load-modules"].empty()) {
+ vector<string>modules;
+
+ stringtok(modules,arg()["load-modules"],",");
+
+ for(vector<string>::const_iterator i=modules.begin();i!=modules.end();++i) {
+ bool res;
+ const string &module=*i;
+
+ if(module.find(".")==string::npos)
+ res=UeberBackend::loadmodule(arg()["module-dir"]+"/lib"+module+"backend.so");
+ else if(module[0]=='/' || (module[0]=='.' && module[1]=='/') || (module[0]=='.' && module[1]=='.')) // absolute or current path
+ res=UeberBackend::loadmodule(module);
+ else
+ res=UeberBackend::loadmodule(arg()["module-dir"]+"/"+module);
+
+ if(res==false) {
+ L<<Logger::Error<<"Unable to load module "<<module<<endl;
+ exit(1);
+ }
+ }
+ }
+}
+
+
+
+#ifdef __linux__
+#include <execinfo.h>
+static void tbhandler(int num)
+{
+ L<<Logger::Critical<<"Got a signal "<<num<<", attempting to print trace: "<<endl;
+ void *array[20]; //only care about last 17 functions (3 taken with tracing support)
+ size_t size;
+ char **strings;
+ size_t i;
+
+ size = backtrace (array, 20);
+ strings = backtrace_symbols (array, size); //Need -rdynamic gcc (linker) flag for this to work
+
+ for (i = 0; i < size; i++) //skip useless functions
+ L<<Logger::Error<<strings[i]<<endl;
+
+
+ signal(SIGABRT, SIG_DFL);
+ abort();//hopefully will give core
+
+}
+#endif
+
+//! The main function of pdns, the pdns process
+int main(int argc, char **argv)
+{
+ s_programname="pdns";
+ s_starttime=time(0);
+
+#ifdef __linux__
+ signal(SIGSEGV,tbhandler);
+ signal(SIGFPE,tbhandler);
+ signal(SIGABRT,tbhandler);
+ signal(SIGILL,tbhandler);
+#endif
+
+
+ L.toConsole(Logger::Warning);
+ try {
+ declareArguments();
+ UNIX_declareArguments();
+
+ arg().laxParse(argc,argv); // do a lax parse
+
+ if(arg()["config-name"]!="")
+ s_programname+="-"+arg()["config-name"];
+
+ (void)theL(s_programname);
+
+ string configname=arg()["config-dir"]+"/"+s_programname+".conf";
+ cleanSlashes(configname);
+
+ if(!arg().mustDo("config") && !arg().mustDo("no-config")) // "config" == print a configuration file
+ arg().laxFile(configname.c_str());
+
+ arg().laxParse(argc,argv); // reparse so the commandline still wins
+ if(!arg()["logging-facility"].empty()) {
+ int facility=arg().asNum("logging-facility");
+ switch(facility) {
+ case 0:
+ theL().setFacility(LOG_LOCAL0);
+ break;
+ case 1:
+ theL().setFacility(LOG_LOCAL1);
+ break;
+ case 2:
+ theL().setFacility(LOG_LOCAL2);
+ break;
+ case 3:
+ theL().setFacility(LOG_LOCAL3);
+ break;
+ case 4:
+ theL().setFacility(LOG_LOCAL4);
+ break;
+ case 5:
+ theL().setFacility(LOG_LOCAL5);
+ break;
+ case 6:
+ theL().setFacility(LOG_LOCAL6);
+ break;
+ case 7:
+ theL().setFacility(LOG_LOCAL7);
+ break;
+ default:
+ L<<Logger::Error<<"Unknown logging facility level"<<facility<<endl;
+ break;
+ }
+ }
+
+ L.toConsole((Logger::Urgency)(arg().asNum("loglevel")));
+
+ if(arg().mustDo("help") || arg().mustDo("config")) {
+ arg().set("daemon")="no";
+ arg().set("guardian")="no";
+ }
+
+ if(arg().mustDo("guardian") && !isGuarded(argv)) {
+ if(arg().mustDo("daemon")) {
+ L.toConsole(Logger::Critical);
+ daemonize();
+ }
+ guardian(argc, argv);
+ // never get here, guardian will reinvoke process
+ cerr<<"Um, we did get here!"<<endl;
+ }
+
+ // we really need to do work - either standalone or as an instance
+
+ loadModules();
+ BackendMakers().launch(arg()["launch"]); // vrooooom!
+
+ if(arg().mustDo("help")) {
+ cerr<<"syntax:"<<endl<<endl;
+ cerr<<arg().helpstring(arg()["help"])<<endl;
+ exit(99);
+ }
+
+ if(arg().mustDo("config")) {
+ cout<<arg().configstring()<<endl;
+ exit(99);
+ }
+
+ if(arg().mustDo("list-modules")) {
+ vector<string>modules=BackendMakers().getModules();
+ cerr<<"Modules available:"<<endl;
+ for(vector<string>::const_iterator i=modules.begin();i!=modules.end();++i)
+ cout<<*i<<endl;
+
+ exit(99);
+ }
+ if(!BackendMakers().numLauncheable()) {
+ L<<Logger::Error<<"Unable to launch, no backends configured for querying"<<endl;
+ exit(99); // this isn't going to fix itself either
+ }
+ if(arg().mustDo("daemon")) {
+ L.toConsole(Logger::None);
+ if(!isGuarded(argv))
+ daemonize();
+ }
+
+ if(isGuarded(argv)) {
+ L<<Logger::Warning<<"This is a guarded instance of pdns"<<endl;
+ dl=new DynListener; // listens on stdin
+ }
+ else {
+ L<<Logger::Warning<<"This is a standalone pdns"<<endl;
+
+ if(arg().mustDo("control-console"))
+ dl=new DynListener();
+ else
+ dl=new DynListener(s_programname);
+
+ writePid();
+ }
+ dl->registerFunc("SHOW",&DLShowHandler);
+ dl->registerFunc("RPING",&DLPingHandler);
+ dl->registerFunc("QUIT",&DLRQuitHandler);
+ dl->registerFunc("UPTIME",&DLUptimeHandler);
+ dl->registerFunc("NOTIFY-HOST",&DLNotifyHostHandler);
+ dl->registerFunc("NOTIFY",&DLNotifyHandler);
+ dl->registerFunc("RELOAD",&DLReloadHandler);
+ dl->registerFunc("REDISCOVER",&DLRediscoverHandler);
+ dl->registerFunc("VERSION",&DLVersionHandler);
+ dl->registerFunc("PURGE",&DLPurgeHandler);
+ dl->registerFunc("CCOUNTS",&DLCCHandler);
+ dl->registerFunc("SET",&DLSettingsHandler);
+
+
+ // reparse, with error checking
+ if(!arg().mustDo("no-config"))
+ arg().file(configname.c_str());
+ arg().parse(argc,argv);
+ UeberBackend::go();
+ N=new UDPNameserver; // this fails when we are not root, throws exception
+
+ if(!arg().mustDo("disable-tcp"))
+ TN=new TCPNameserver;
+ }
+ catch(const ArgException &A) {
+ L<<Logger::Error<<"Fatal error: "<<A.reason<<endl;
+ exit(1);
+ }
+
+ declareStats();
+ DLOG(L<<Logger::Warning<<"Verbose logging in effect"<<endl);
+
+ L<<Logger::Warning<<"PowerDNS "<<VERSION<<" (C) 2002 PowerDNS.COM BV ("<<__DATE__", "__TIME__<<") starting up"<<endl;
+
+ L<<Logger::Warning<<"PowerDNS comes with ABSOLUTELY NO WARRANTY. "
+ "This is free software, and you are welcome to redistribute it "
+ "according to the terms of the GPL version 2."<<endl;
+
+
+ try {
+
+ mainthread();
+ }
+ catch(AhuException &AE) {
+ if(!arg().mustDo("daemon"))
+ cerr<<"Exiting because: "<<AE.reason<<endl;
+ L<<Logger::Error<<"Exiting because: "<<AE.reason<<endl;
+ }
+ catch(exception &e) {
+ if(!arg().mustDo("daemon"))
+ cerr<<"Exiting because of STL error: "<<e.what()<<endl;
+ L<<Logger::Error<<"Exiting because of STL error: "<<e.what()<<endl;
+ }
+ catch(...) {
+ cerr<<"Uncaught exception of unknown type - sorry"<<endl;
+ }
+
+ exit(1);
+
+}
+
+
--- /dev/null
+-ldl -L/opt/oracle/lib -ldl -lclient8 -ldl -lclntst8
--- /dev/null
+#!/usr/local/bin/gmake -f
+
+all: compile package
+
+compile: compilation
+
+precompile:
+ gmake clean
+ gmake -k distclean
+ ./bootstrap
+ ./configure --enable-static-binaries
+ cd ../pdns-pipebackend ; gmake clean; gmake
+ cd ../ahudns-mysqlbackend ; gmake clean ; gmake
+ cd ../pdns-gpgsqlbackend; gmake clean ; gmake
+ cd ../pdns-gmysqlbackend; gmake clean ; gmake
+ # cd backends/bind ; gmake
+
+extras: precompile
+ -rm extra/*.o
+ cd extra ; ln -s ../backends/bind/bindbackend.o .
+ cd extra ; ln -s ../backends/bind/zoneparser2.o .
+ cd extra ; ln -s ../backends/bind/bindparser.o .
+ cd extra ; ln -s ../backends/bind/bindlexer.o .
+ cd extra ; ln -s ../backends/bind/huffman.o .
+ cd extra ; ln -s ../../pdns-pipebackend/*.o .
+ cd extra; ln -s ../../ahudns-mysqlbackend/*.o .
+ cd extra; ln -s ../../pdns-gpgsqlbackend/*.o .
+ cd extra; ln -s ../../pdns-gmysqlbackend/*.o .
+ echo "-L/usr/local/lib -lz -L/usr/local/lib/mysql -lmysqlclient -lz -lpq++ -lpq -lssl -lcrypt -lcrypto" > extra/ld
+ -rm libs/*
+
+compilation: extras
+ gmake
+ gmake mkbindist
+
+
+package:
+ mkdir -p release-files/freebsd-static
+ cp backends/bind/zone2sql .
+
+ -rm pdns*tar.gz
+ cp pathconfig.bsd pathconfig
+ . ./mkbindist
+ mv pdns*tar.gz release-files/freebsd-static
+
+
--- /dev/null
+#!/usr/bin/make -f
+
+all: compile package
+
+compile:
+ make clean
+ make -k distclean
+ ./bootstrap
+ ./configure
+ cd ../pdns-pipebackend ; make clean; make
+ cd ../ahudns-mysqlbackend ; make clean ; make
+ cd ../ahudns-pdnsbackend ; make clean ; make
+ cd ../pdns-gpgsqlbackend; make clean ; make
+ cd ../pdns-gmysqlbackend; make clean ; make
+
+ cd extra ; make clean ; make
+ -rm libs/*
+ cd libs ; ln -s ../backends/bind/.libs/libbindbackend.so .
+ cd libs ; ln -s ../../pdns-pipebackend/.libs/libpipebackend.so .
+ cd libs; ln -s ../../ahudns-mysqlbackend/.libs/libmysqlbackend.so .
+ cd libs; ln -s ../../ahudns-pdnsbackend/.libs/libpdnsbackend.so .
+ cd libs; ln -s ../../pdns-gpgsqlbackend/*.so .
+ cd libs; ln -s ../../pdns-gmysqlbackend/*.so .
+ echo "" > extra/ld
+ make
+ make mkbindist
+
+
+package:
+ mkdir -p release-files/deb/unstable
+ mkdir -p release-files/rpm-dynamic
+ mkdir -p release-files/linux-dynamic
+
+ rm -rf ../pdns_*deb
+ rm -rf ../pdns-*rpm
+
+ cp backends/bind/zone2sql .
+
+ sudo debian/rules clean
+ sudo debian/rules binary
+
+ mv ../pdns_*deb release-files/deb/unstable
+ DESTDIR=/tmp/pdns sudo ./installer
+ sudo rpm -bb ./pdns-dynamic.spec
+ mv ../pdns-*rpm release-files/rpm-dynamic
+
+ . ./mkbindist
+ mv pdns*tar.gz release-files/linux-dynamic
+
--- /dev/null
+make clean
+make -k distclean
+./bootstrap
+./configure --enable-static-binaries
+cd extra
+ln -sf ../backends/bind/{bindbackend.o,zoneparser2.o,bindparser.o,bindlexer.o} .
+ln -sf ../backends/bind/huffman.o .
+ln -sf ../../pdns-oraclebackend/*.o .
+echo "-ldl -L/opt/oracle/lib -ldl -lclient8 -ldl -lclntst8" > ld
+cd ..
+rm libs/*
+make
+cp backends/bind/zone2sql .
+
--- /dev/null
+make clean
+make -k distclean
+./bootstrap
+./configure --enable-static-binaries
+cd extra
+ln -sf ../backends/bind/{bindbackend.o,zoneparser2.o,bindparser.o,bindlexer.o} .
+ln -sf ../backends/bind/huffman.o .
+ln -sf ../../pdns-pipebackend/*.o .
+ln -sf ../../ahudns-mysqlbackend/*.o .
+ln -sf ../../ahudns-pdnsbackend/*.o .
+ln -sf ../../pdns-gpgsqlbackend/*.o .
+echo "-lmysqlclient -L/opt/postgresql/lib -lpq++ -lpq -lssl -lcrypt -lcrypto" > ld
+cd ..
+rm libs/*
+make
+cp backends/bind/zone2sql .
+
--- /dev/null
+#!/usr/bin/make -f
+
+all: compile package
+
+compile:
+ make distclean
+ ./configure --enable-static-binaries
+ cd ../pdns-pipebackend ; ./configure ; make clean; make
+ cd ../ahudns-mysqlbackend ; ./configure ; make clean ; make && cd -
+ cd ../ahudns-pdnsbackend ; ./configure ; make clean ; make && cd -
+ cd ../pdns-gpgsqlbackend; ./configure ; make clean ; make && cd -
+ cd ../pdns-gmysqlbackend; ./configure ; make clean ; make && cd -
+ rm -f extra/*.o
+ cd extra; ln -s ../backends/bind/{bindbackend.o,zoneparser2.o,bindparser.o,bindlexer.o} . ; cd -
+ cd extra ; ln -s ../backends/bind/huffman.o . ; cd -
+ cd extra ; ln -s ../../pdns-pipebackend/*.o . ; cd -
+ cd extra; ln -s ../../ahudns-mysqlbackend/*.o . ; cd -
+ cd extra; ln -s ../../ahudns-pdnsbackend/*.o . ; cd -
+ cd extra; ln -s ../../pdns-gpgsqlbackend/*.o . ; cd -
+ cd extra; ln -s ../../pdns-gmysqlbackend/*.o . ; cd -
+ echo "-lmysqlclient -L/opt/postgresql/lib -lpq++ -lpq -lssl -lcrypt -lcrypto" > extra/ld
+ rm -f libs/*
+ make
+ make mkbindist
+
+
+package:
+ mkdir -p release-files/deb/stable
+ mkdir -p release-files/linux-static
+ mkdir -p release-files/rpm
+
+ rm -rf ../pdns_*deb
+ rm -rf ../pdns-*rpm
+
+ cp backends/bind/zone2sql .
+
+ sudo debian/rules.stable clean
+ sudo debian/rules.stable binary
+
+ mv ../pdns_*deb release-files/deb/stable
+
+ cp pathconfig.redhat pathconfig
+ DESTDIR=/tmp/pdns sudo ./installer
+ sudo rpm -bb ./pdns.spec
+ mv ../pdns-*rpm release-files/rpm
+
+ rm -f pdns*tar.gz
+
+ . ./mkbindist
+ mv pdns*tar.gz release-files/linux-static
+
+
--- /dev/null
+#!/usr/bin/make -f
+
+all: compile package
+
+compile: prepare realcompile
+
+prepare:
+ make distclean
+ ./configure --enable-static-binaries
+ cd ../pdns-pipebackend ; ./configure ; make clean; make
+ cd ../ahudns-mysqlbackend ; ./configure ; make clean ; make && cd -
+ cd ../ahudns-pdnsbackend ; ./configure ; make clean ; make && cd -
+ cd ../pdns-gpgsqlbackend; ./configure ; make clean ; make && cd -
+ cd ../pdns-xdbbackend; make clean ; make && cd -
+ cd ../pdns-gmysqlbackend; ./configure ; make clean ; make && cd -
+ rm -f extra/*.o
+ cd extra ; ln -s ../../pdns-pipebackend/*.o . ; cd -
+ cd extra; ln -s ../../ahudns-mysqlbackend/*.o . ; cd -
+ cd extra; ln -s ../../ahudns-pdnsbackend/*.o . ; cd -
+ cd extra; ln -s ../../pdns-gpgsqlbackend/*.o . ; cd -
+ cd extra; ln -s ../../pdns-gmysqlbackend/*.o . ; cd -
+# cd extra; ln -s ../../pdns-xdbbackend/*.o . ; cd -
+ echo "-lmysqlclient -L/opt/postgresql-with-3.2/lib -lpq++ -lpq -lssl -lcrypt -lcrypto" > extra/ld
+ rm -f libs/*
+
+realcompile:
+ make
+ make mkbindist
+
+
+package:
+ mkdir -p release-files/deb/stable
+ mkdir -p release-files/linux-static
+ mkdir -p release-files/rpm
+
+ rm -rf ../pdns_*deb
+ rm -rf ../pdns-*rpm
+
+ cp backends/bind/zone2sql .
+
+ sudo debian/rules clean
+ sudo debian/rules binary
+
+ mv ../pdns_*deb release-files/deb/stable
+
+ cp pathconfig.redhat pathconfig
+ DESTDIR=/tmp/pdns sudo ./installer
+ sudo rpm -bb ./pdns.spec
+ mv ../pdns-*rpm release-files/rpm
+
+ rm -f pdns*tar.gz
+
+ . ./mkbindist
+ mv pdns*tar.gz release-files/linux-static
+
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include "resolver.hh"
+#include <pthread.h>
+#include <semaphore.h>
+#include <iostream>
+#include <errno.h>
+#include "misc.hh"
+#include <algorithm>
+#include <sstream>
+#include <cstring>
+#include <string>
+#include <vector>
+#include "dnspacket.hh"
+#include "dns.hh"
+#include "qtype.hh"
+#include "tcpreceiver.hh"
+#include "ahuexception.hh"
+#include "statbag.hh"
+#include "arguments.hh"
+
+void Resolver::makeUDPSocket()
+{
+ makeSocket(SOCK_DGRAM);
+}
+
+void Resolver::makeSocket(int type)
+{
+ static u_int16_t port_counter=5000;
+ if(d_sock>0)
+ return;
+
+ d_sock=socket(AF_INET, type,0);
+ if(d_sock<0)
+ throw AhuException("Making a socket for resolver: "+stringerror());
+
+ struct sockaddr_in sin;
+ memset((char *)&sin,0, sizeof(sin));
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+
+ int tries=10;
+ while(--tries) {
+ sin.sin_port = htons(10000+(port_counter++)%10000); // should be random!
+
+ if (bind(d_sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ break;
+
+ }
+ if(!tries)
+ throw AhuException("Resolver binding to local socket: "+stringerror());
+}
+
+Resolver::Resolver()
+{
+ d_sock=-1;
+ d_timeout=500000;
+ d_buf=new unsigned char[66000];
+}
+
+Resolver::~Resolver()
+{
+ if(d_sock>=0)
+ Utility::closesocket(d_sock);
+ delete[] d_buf;
+}
+
+void Resolver::timeoutReadn(char *buffer, int bytes)
+{
+ time_t start=time(0);
+ int n=0;
+ int numread;
+ while(n<bytes) {
+ if(waitForData(d_sock, 10-(time(0)-start))<0)
+ throw ResolverException("Reading data from remote nameserver over TCP: "+stringerror());
+
+ numread=recv(d_sock,buffer+n,bytes-n,0);
+ if(numread<0)
+ throw ResolverException("Reading data from remote nameserver over TCP: "+stringerror());
+ if(numread==0)
+ throw ResolverException("Remote nameserver closed TCP connection");
+ n+=numread;
+ }
+}
+
+char* Resolver::sendReceive(const string &ip, u_int16_t remotePort, const char *packet, int length, unsigned int *replen)
+{
+ makeTCPSocket(ip, remotePort);
+
+ if(sendData(packet,length,d_sock)<0)
+ throw ResolverException("Unable to send packet to remote nameserver "+ip+": "+stringerror());
+
+ int plen=getLength();
+ if(plen<0)
+ throw ResolverException("EOF trying to get length of answer from remote TCP server");
+
+ char *answer=new char[plen];
+ try {
+ timeoutReadn(answer,plen);
+ *replen=plen;
+ return answer;
+ }
+ catch(...) {
+ delete answer;
+ throw; // whop!
+ }
+ return 0;
+}
+
+int Resolver::notify(int sock, const string &domain, const string &ip, u_int16_t id)
+{
+ DNSPacket p;
+ p.setQuestion(Opcode::Notify,domain,QType::SOA);
+ p.wrapup();
+ p.spoofID(id);
+
+ struct in_addr inp;
+ Utility::inet_aton(ip.c_str(),&inp);
+
+ struct sockaddr_in toaddr;
+ toaddr.sin_addr.s_addr=inp.s_addr;
+
+ toaddr.sin_port=htons(53);
+ toaddr.sin_family=AF_INET;
+
+ if(sendto(sock, p.getData(), p.len, 0, (struct sockaddr*)(&toaddr), sizeof(toaddr))<0) {
+ throw ResolverException("Unable to send notify to "+ip+": "+stringerror());
+ }
+ return true;
+}
+
+
+int Resolver::resolve(const string &ip, const char *domain, int type)
+{
+ makeUDPSocket();
+ DNSPacket p;
+ p.setQuestion(Opcode::Query,domain,type);
+ p.wrapup();
+
+ d_domain=domain;
+ d_type=type;
+ d_inaxfr=false;
+
+ struct sockaddr_in toaddr;
+ struct in_addr inp;
+ Utility::inet_aton(ip.c_str(),&inp);
+ toaddr.sin_addr.s_addr=inp.s_addr;
+
+ toaddr.sin_port=htons(53);
+ toaddr.sin_family=AF_INET;
+
+ if(sendto(d_sock, p.getData(), p.len, 0, (struct sockaddr*)(&toaddr), sizeof(toaddr))<0) {
+ throw ResolverException("Unable to ask query of "+ip+": "+stringerror());
+ }
+
+ Utility::socklen_t addrlen=sizeof(toaddr);
+
+ fd_set rd;
+ FD_ZERO(&rd);
+ FD_SET(d_sock, &rd);
+
+ struct timeval timeout;
+ timeout.tv_sec=1;
+ timeout.tv_usec=500000;
+
+ int res=select(d_sock+1,&rd,0,0,&timeout);
+ if(!res)
+ throw ResolverException("Timeout waiting for answer from "+ip);
+ if(res<0)
+ throw ResolverException("Error waiting for answer: "+stringerror());
+
+
+ if((d_len=recvfrom(d_sock, reinterpret_cast< char * >( d_buf ), 512,0,(struct sockaddr*)(&toaddr), &addrlen))<0)
+ throw ResolverException("recvfrom error waiting for answer: "+stringerror());
+
+ return 1;
+}
+
+void Resolver::makeTCPSocket(const string &ip, u_int16_t port)
+{
+ if(d_sock>=0)
+ return;
+ struct sockaddr_in toaddr;
+ struct in_addr inp;
+ Utility::inet_aton(ip.c_str(),&inp);
+ toaddr.sin_addr.s_addr=inp.s_addr;
+
+ toaddr.sin_port=htons(port);
+ toaddr.sin_family=AF_INET;
+
+
+ d_sock=socket(AF_INET,SOCK_STREAM,0);
+ if(d_sock<0)
+ throw ResolverException("Unable to make a TCP socket for resolver: "+stringerror());
+
+ Utility::setNonBlocking( d_sock );
+
+ int err;
+#ifndef WIN32
+ if((err=connect(d_sock,(struct sockaddr*)&toaddr,sizeof(toaddr)))<0 && errno!=EINPROGRESS) {
+#else
+ if((err=connect(d_sock,(struct sockaddr*)&toaddr,sizeof(toaddr)))<0 && WSAGetLastError() != WSAEWOULDBLOCK ) {
+#endif // WIN32
+ throw ResolverException("connect: "+stringerror());
+ }
+
+ if(!err)
+ goto done;
+
+ fd_set rset,wset;
+ struct timeval tval;
+
+ FD_ZERO(&rset);
+ FD_SET(d_sock, &rset);
+ wset=rset;
+ tval.tv_sec=10;
+ tval.tv_usec=0;
+
+ if(!select(d_sock+1,&rset,&wset,0,tval.tv_sec ? &tval : 0)) {
+ Utility::closesocket(d_sock); // timeout
+ d_sock=-1;
+ errno=ETIMEDOUT;
+
+ throw ResolverException("Timeout connecting to server");
+ }
+
+ if(FD_ISSET(d_sock, &rset) || FD_ISSET(d_sock, &wset))
+ {
+ Utility::socklen_t len=sizeof(err);
+ if(getsockopt(d_sock, SOL_SOCKET,SO_ERROR,(char *)&err,&len)<0)
+ throw ResolverException("Error connecting: "+stringerror()); // Solaris
+
+ if(err)
+ throw ResolverException("Error connecting: "+string(strerror(err)));
+
+ }
+ else
+ throw ResolverException("nonblocking connect failed");
+
+ done:
+ Utility::setBlocking( d_sock );
+ // d_sock now connected
+}
+
+
+//! returns -1 for permanent error, 0 for timeout, 1 for success
+int Resolver::axfr(const string &ip, const char *domain)
+{
+ d_domain=domain;
+
+ makeTCPSocket(ip);
+
+ d_type=QType::AXFR;
+ DNSPacket p;
+ p.setQuestion(Opcode::Query,domain,QType::AXFR);
+ p.wrapup();
+
+ int replen=htons(p.len);
+ Utility::iovec iov[2];
+ iov[0].iov_base=(char*)&replen;
+ iov[0].iov_len=2;
+ iov[1].iov_base=(char*)p.getData();
+ iov[1].iov_len=p.len;
+
+ int ret=Utility::writev(d_sock,iov,2);
+ if(ret<0)
+ throw ResolverException("Error sending question to "+ip+": "+stringerror());
+
+ fd_set rd;
+ FD_ZERO(&rd);
+ FD_SET(d_sock, &rd);
+
+ struct timeval timeout;
+ timeout.tv_sec=10;
+ timeout.tv_usec=0;
+
+ int res=select(d_sock+1,&rd,0,0,&timeout);
+ if(!res)
+ throw ResolverException("Timeout waiting for answer from "+ip+" during AXFR");
+ if(res<0)
+ throw ResolverException("Error waiting for answer from "+ip+": "+stringerror());
+
+ d_soacount=0;
+ d_inaxfr=true;
+ return 1;
+}
+
+int Resolver::getLength()
+{
+ int bytesLeft=2;
+ unsigned char buf[2];
+
+ while(bytesLeft) {
+ int ret=waitForData(d_sock, 10);
+ if(ret<0) {
+ Utility::closesocket(d_sock);
+ throw ResolverException("Waiting on data from remote TCP client: "+stringerror());
+ }
+
+ ret=recv(d_sock, reinterpret_cast< char * >( buf ) +2-bytesLeft, bytesLeft,0);
+ if(ret<0)
+ throw ResolverException("Trying to read data from remote TCP client: "+stringerror());
+ if(!ret)
+ return -1;
+
+ bytesLeft-=ret;
+ }
+ return buf[0]*256+buf[1];
+}
+
+int Resolver::axfrChunk(Resolver::res_t &res)
+{
+ // d_sock is connected and is about to spit out a packet
+ int len=getLength();
+ if(len<0)
+ return 0;
+
+ timeoutReadn((char *)d_buf,len);
+ d_len=len;
+ res=result();
+ if(!res.empty())
+ if(res.begin()->qtype.getCode()==QType::SOA || res.end()->qtype.getCode()==QType::SOA)
+ d_soacount++;
+
+ if(d_soacount==2) {
+ Utility::closesocket(d_sock);
+ d_sock=-1;
+ return 0;
+ }
+
+ return 1;
+}
+
+
+Resolver::res_t Resolver::result()
+{
+ try {
+ DNSPacket p;
+
+ if(p.parse((char *)d_buf, d_len)<0)
+ throw ResolverException("resolver: unable to parse packet of "+itoa(d_len)+" bytes");
+
+ if(p.d.rcode)
+ if(d_inaxfr)
+ throw ResolverException("Remote nameserver unable/unwilling to AXFR with us: RCODE="+itoa(p.d.rcode));
+ else
+ throw ResolverException("Remote nameserver reported error: RCODE="+itoa(p.d.rcode));
+
+ if(!d_inaxfr) {
+ if(ntohs(p.d.qdcount)!=1)
+ throw ResolverException("resolver: received answer with wrong number of questions ("+itoa(ntohs(p.d.qdcount))+")");
+
+ if(p.qdomain!=d_domain)
+ throw ResolverException(string("resolver: received an answer to another question (")+p.qdomain+"!="+d_domain+")");
+ }
+ return p.getAnswers();
+ }
+ catch(AhuException &ae) { // translate
+ throw ResolverException(ae.reason);
+ }
+}
+
+
+int Resolver::getSoaSerial(const string &ip, const string &domain, u_int32_t *serial)
+{
+ resolve(ip,domain.c_str(),QType::SOA);
+ res_t res=result();
+ if(res.empty())
+ return 0;
+
+ vector<string>parts;
+ stringtok(parts,res[0].content);
+ if(parts.size()<3)
+ return 0;
+
+ *serial=atoi(parts[2].c_str());
+ return 1;
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+\r
+#include <string>
+#include <vector>
+#include <sys/types.h>\r
+\r
+#ifndef WIN32\r
+
+# include <arpa/nameser.h>\r
+# include <resolv.h>\r
+# include <netdb.h> \r
+# include <unistd.h>\r
+# include <sys/time.h>\r
+# include <sys/uio.h>\r
+# include <fcntl.h>\r
+# include <sys/socket.h>\r
+# include <netinet/in.h>\r
+# include <arpa/inet.h>\r
+# undef res_mkquery
+#endif // WIN32\r
+
+#include "ahuexception.hh"
+#include "dns.hh"
+using namespace std;
+
+class ResolverException : public AhuException
+{
+public:
+ ResolverException(const string &reason) : AhuException(reason){}
+};
+
+//! Resolver class
+class Resolver
+{
+public:
+ Resolver();
+ ~Resolver();
+ string i;
+
+ typedef vector<DNSResourceRecord> res_t;
+ void makeSocket(int type);
+ void makeUDPSocket();
+ void makeTCPSocket(const string &ip, u_int16_t port=53);
+ int notify(int sock, const string &domain, const string &ip, u_int16_t id);
+ int resolve(const string &ip, const char *domain, int type);
+ char* sendReceive(const string &ip, u_int16_t remotePort, const char *packet, int length, unsigned int *replylen);
+ int getSoaSerial(const string &, const string &, u_int32_t *);
+ int axfrChunk(Resolver::res_t &res);
+ vector<DNSResourceRecord> result();
+
+ void setRemote(const string &remote);
+ int axfr(const string &ip, const char *domain);
+
+private:
+ void timeoutReadn(char *buffer, int bytes);
+ int d_sock;
+ unsigned char *d_buf;
+ int getLength();
+ int d_len;
+ int d_soacount;
+ string d_domain;
+ int d_type;
+ int d_timeout;
+ u_int32_t d_ip;
+ bool d_inaxfr;
+};
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include "session.hh"
+#include "ahuexception.hh"
+#include "misc.hh"
+#include <cstring>
+#include <iostream>
+#include <sys/types.h>\r
+#include <fcntl.h>
+#include <sstream>
+
+
+
+void Session::init()
+{
+ d_bufsize=15049;
+
+ d_verbose=false;
+
+ rdbuf=new char[d_bufsize];
+ rdoffset=0;
+ wroffset=0;
+}
+
+void Session::beVerbose()
+{
+ d_verbose=true;
+}
+
+Session::Session(int s, struct sockaddr_in r)
+{
+ init();
+ remote=r;
+ clisock=s;
+}
+
+int Session::close()
+{
+ int rc=0;
+
+ if(clisock>=0)
+ rc=Utility::closesocket(clisock);
+
+ clisock=-1;
+ return rc;
+}
+
+Session::~Session()
+{
+
+ /* NOT CLOSING AUTOMATICALLY ANYMORE!
+ if(clisock>=0)
+ ::close(clisock);
+ */
+
+ delete[] rdbuf;
+}
+
+//! This function makes a deep copy of Session
+Session::Session(const Session &s)
+{
+ d_bufsize=s.d_bufsize;
+
+ init(); // needs d_bufsize, but will reset rdoffset & wroffset
+
+ rdoffset=s.rdoffset;
+ wroffset=s.wroffset;
+ clisock=s.clisock;
+ remote=s.remote;
+
+ memcpy(rdbuf,s.rdbuf,d_bufsize);
+}
+
+Session::Session(const string &dest, int port, int timeout)
+{
+ struct hostent *h;
+ h=gethostbyname(dest.c_str());
+ if(!h)
+ throw SessionException("Unable to resolve target name");
+
+ if(timeout)
+ d_timeout=timeout;
+
+ doConnect(*(int*)h->h_addr, port);
+}
+
+Session::Session(u_int32_t ip, int port, int timeout)
+{
+ if(timeout)
+ d_timeout=timeout;
+
+ doConnect(ip, port);
+}
+
+void Session::setTimeout(unsigned int seconds)
+{
+ d_timeout=seconds;
+}
+
+
+void Session::doConnect(u_int32_t ip, int port)
+{
+ init();
+ clisock=socket(AF_INET,SOCK_STREAM,0);
+
+ memset(&remote,0,sizeof(remote));
+ remote.sin_family=AF_INET;
+ remote.sin_port=htons(port);
+
+ remote.sin_addr.s_addr=ip;
+
+ Utility::setNonBlocking( clisock );\r
+
+ int err;
+#ifndef WIN32\r
+ if((err=connect(clisock,(struct sockaddr*)&remote,sizeof(remote)))<0 && errno!=EINPROGRESS) {\r
+#else\r
+ if((err=connect(clisock,(struct sockaddr*)&remote,sizeof(remote)))<0 && WSAGetLastError() != WSAEWOULDBLOCK ) {\r
+#endif // WIN32\r
+ throw SessionException("connect: "+stringerror());\r
+\r
+ }\r
+
+ if(!err)
+ goto done;
+
+ fd_set rset,wset;
+ struct timeval tval;
+
+ FD_ZERO(&rset);
+ FD_SET(clisock, &rset);
+ wset=rset;
+ tval.tv_sec=d_timeout;
+ tval.tv_usec=0;
+
+ if(!select(clisock+1,&rset,&wset,0,tval.tv_sec ? &tval : 0))
+ {
+ Utility::closesocket(clisock); // timeout
+ clisock=-1;
+ errno=ETIMEDOUT;
+
+ throw SessionTimeoutException("Timeout connecting to server");
+ }
+
+ if(FD_ISSET(clisock, &rset) || FD_ISSET(clisock, &wset))
+ {
+ Utility::socklen_t len=sizeof(err);
+ if(getsockopt(clisock, SOL_SOCKET,SO_ERROR,(char *)&err,&len)<0)
+ throw SessionException("Error connecting: "+stringerror()); // Solaris
+
+ if(err)
+ throw SessionException("Error connecting: "+string(strerror(err)));
+
+ }
+ else
+ throw SessionException("nonblocking connect failed");
+
+ done:\r
+ Utility::setBlocking( clisock );
+}
+
+bool Session::putLine(const string &s)
+{
+ int length=s.length();
+ int written=0;
+ int err;
+
+ while(written<length)
+ {
+ fd_set wset;
+ FD_ZERO(&wset);
+ FD_SET(clisock, &wset);
+ struct timeval tval;
+ tval.tv_sec=d_timeout;
+ tval.tv_usec=0;
+
+ if(!select(clisock+1,0,&wset,0,tval.tv_sec ? &tval : 0))
+ throw SessionTimeoutException("timeout writing line");
+
+ if(FD_ISSET(clisock, &wset))
+ {
+ Utility::socklen_t len=sizeof(err);
+ if(getsockopt(clisock, SOL_SOCKET,SO_ERROR,(char *) &err,&len)<0)
+ throw SessionException(+strerror(err)); // Solaris..
+
+ if(err)
+ throw SessionException(strerror(err));
+ }
+ else
+ throw SessionException("nonblocking write failed"+string(strerror(errno)));
+
+ err=send(clisock,s.c_str()+written,length-written,0);
+
+ if(err<0)
+ return false;
+
+ written+=err;
+ }
+
+ return true;
+}
+
+char *strnchr(char *p, char c, int len)
+{
+ int n;
+ for(n=0;n<len;n++)
+ if(p[n]==c)
+ return p+n;
+ return 0;
+}
+
+int Session::timeoutRead(int s, char *buf, size_t len)
+{
+ fd_set rset;
+ FD_ZERO(&rset);
+ FD_SET(clisock, &rset);
+ struct timeval tval;
+ tval.tv_sec=d_timeout;
+ tval.tv_usec=0;
+
+ int err;
+
+ if(!select(clisock+1,&rset,0,0,tval.tv_sec ? &tval : 0))
+ throw SessionTimeoutException("timeout reading");
+
+ if(FD_ISSET(clisock, &rset))
+ {
+ Utility::socklen_t len=sizeof(err);
+ if(getsockopt(clisock, SOL_SOCKET,SO_ERROR,(char *)&err,&len)<0)
+ throw SessionException(strerror(errno)); // Solaris..
+
+ if(err)
+ throw SessionException(strerror(err));
+ }
+ else
+ throw SessionException("nonblocking read failed"+string(strerror(errno)));
+
+ return recv(s,buf,len,0);
+
+
+}
+
+bool
+Session::haveLine()
+{
+ return (wroffset!=rdoffset && (strnchr(rdbuf+rdoffset,'\n',wroffset-rdoffset)!=NULL));
+}
+
+
+bool
+Session::getLine(string &line)
+{
+ int bytes;
+ char *p;
+
+ int linelength;
+
+ // read data into a buffer
+ // find first \n, and return that as string, store how far we were
+
+
+ for(;;)
+ {
+ if(wroffset==rdoffset)
+ {
+ wroffset=rdoffset=0;
+ }
+
+ if(wroffset!=rdoffset && (p=strnchr(rdbuf+rdoffset,'\n',wroffset-rdoffset))) // we have a full line in store, return that
+ {
+ // from rdbuf+rdoffset to p should become the new line
+
+ linelength=p-(rdbuf+rdoffset);
+
+ *p=0; // terminate
+
+ line=rdbuf+rdoffset;
+ line+="\n";
+
+ rdoffset+=linelength+1;
+
+ return true;
+ }
+ // we need more data before we can return a line
+
+ if(wroffset==d_bufsize) // buffer is full, flush to left
+ {
+ if(!rdoffset) // line too long!
+ {
+ // FIXME: do stuff
+ close();
+ return false;
+ }
+
+ memmove(rdbuf,rdbuf+rdoffset,wroffset-rdoffset);
+ wroffset-=rdoffset;
+ rdoffset=0;
+ }
+ bytes=timeoutRead(clisock,rdbuf+wroffset,d_bufsize-wroffset);
+
+ if(bytes<0)
+ throw SessionException("error on read from socket: "+string(strerror(errno)));
+
+ if(bytes==0)
+ throw SessionException("Remote closed connection");
+
+ wroffset+=bytes;
+ }
+ // we never get here
+}
+
+int Session::getSocket()
+{
+ return clisock;
+}
+
+string Session::getRemote ()
+{
+ ostringstream o;
+ u_int32_t rint=htonl(remote.sin_addr.s_addr);
+ o<< (rint>>24 & 0xff)<<".";
+ o<< (rint>>16 & 0xff)<<".";
+ o<< (rint>>8 & 0xff)<<".";
+ o<< (rint & 0xff);
+ o<<":"<<htons(remote.sin_port);
+
+ return o.str();
+}
+
+u_int32_t Session::getRemoteAddr()
+{
+
+ return htonl(remote.sin_addr.s_addr);
+}
+
+string Session::getRemoteIP()
+{
+ ostringstream o;
+ u_int32_t rint=htonl(remote.sin_addr.s_addr);
+ o<< (rint>>24 & 0xff)<<".";
+ o<< (rint>>16 & 0xff)<<".";
+ o<< (rint>>8 & 0xff)<<".";
+ o<< (rint & 0xff);
+
+ return o.str();
+}
+
+
+Session *Server::accept()
+{
+ struct sockaddr_in remote;
+ Utility::socklen_t len=sizeof(remote);
+
+ int clisock=-1;
+
+
+ while((clisock=::accept(s,(struct sockaddr *)(&remote),&len))==-1) // repeat until we have a succesful connect
+ {
+ // L<<Logger::Error<<"accept() returned: "<<strerror(errno)<<endl;
+ if(errno==EMFILE) {
+ throw SessionException("Out of file descriptors - won't recover from that");
+ }
+
+ }
+
+ return new Session(clisock, remote);
+}
+
+
+
+Server::Server(int p, const string &p_localaddress)
+{
+ d_localaddress="0.0.0.0";
+ string localaddress=p_localaddress;
+ port=p;
+
+ struct sockaddr_in local;
+ s=socket(AF_INET,SOCK_STREAM,0);
+
+ if(s<0)
+ {
+ throw Exception(string("socket: ")+strerror(errno));
+ }
+
+ memset(&local,0,sizeof(local));
+
+ local.sin_family=AF_INET;
+
+ struct hostent *h;
+ if(localaddress=="")
+ localaddress=d_localaddress;
+\r
+ if ( localaddress != "0.0.0.0" )
+ {\r
+ h=gethostbyname(localaddress.c_str());
+
+ if(!h)
+ throw Exception();
+
+ local.sin_addr.s_addr=*(int*)h->h_addr;\r
+ }\r
+ else\r
+ {\r
+ local.sin_addr.s_addr = INADDR_ANY;\r
+ }
+
+ local.sin_port=htons(port);
+
+ int tmp=1;
+ if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0)
+ throw SessionException(string("Setsockopt failed: ")+strerror(errno));
+
+
+ if(bind(s, (sockaddr*)&local,sizeof(local))<0)
+ throw SessionException("binding to port "+itoa(port)+string(": ")+strerror(errno));
+
+ if(listen(s,128)<0)
+ throw SessionException("listen: "+stringerror());
+
+}
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef SESSION_HH
+#define SESSION_HH
+
+#include <string>
+#include <cerrno>
+\r
+#ifndef WIN32\r
+# include <sys/stat.h>\r
+# include <netdb.h>\r
+# include <unistd.h>\r
+# include <sys/time.h>\r
+# include <sys/socket.h>\r
+# include <arpa/inet.h> \r
+# include <netinet/in.h>\r
+# include <sys/types.h>\r
+# include <strings.h>\r
+\r
+#endif // WIN32\r
+
+#include "ahuexception.hh"
+
+class SessionException: public AhuException
+{
+public:
+ SessionException(const string &reason) : AhuException(reason){}
+};
+
+class SessionTimeoutException: public SessionException
+{
+public:
+ SessionTimeoutException(const string &reason) : SessionException(reason){}
+};
+
+//! The Session class represents a TCP/IP session, which can either be created or run on an existing socket
+class Session
+{
+public:
+ bool getLine(string &); //!< Read a line from the remote
+ bool haveLine(); //!< returns true if a line is available
+ bool putLine(const string &s); //!< Write a line to the remote
+ bool sendFile(int fd); //!< Send a file out
+ int timeoutRead(int s,char *buf, size_t len);
+
+ Session(int s, struct sockaddr_in r); //!< Start a session on an existing socket, and inform this class of the remotes name
+
+ /** Create a session to a remote host and port. This function reads a timeout value from the ArgvMap class
+ and does a nonblocking connect to support this timeout. It should be noted that nonblocking connects
+ suffer from bad portability problems, so look here if you see weird problems on new platforms */
+ Session(const string &remote, int port, int timeout=0);
+ Session(u_int32_t ip, int port, int timeout=0);
+
+ Session(const Session &s);
+
+ ~Session();
+ int getSocket(); //!< return the filedescriptor for layering violations
+ string getRemote();
+ u_int32_t getRemoteAddr();
+ string getRemoteIP();
+ void beVerbose();
+ int close(); //!< close and disconnect the connection
+ void setTimeout(unsigned int seconds);
+private:
+ void doConnect(u_int32_t ip, int port);
+ bool d_verbose;
+ char *rdbuf;
+ int d_bufsize;
+ int rdoffset;
+ int wroffset;
+ int clisock;
+ struct sockaddr_in remote;
+ void init();
+ int d_timeout;
+
+};
+
+//! The server class can be used to create listening servers
+class Server
+{
+public:
+ Server(int p, const string &localaddress=""); //!< port on which to listen
+ Session* accept(); //!< Call accept() in an endless loop to accept new connections
+private:
+ int s;
+ int port;
+ int backlog;
+
+ string d_localaddress;
+};
+
+class Exception
+{
+public:
+ Exception(){reason="Unspecified";};
+ Exception(string r){reason=r;};
+ string reason;
+};
+
+#endif /* SESSION_HH */
--- /dev/null
+#!/bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+# unplug the nameserver: go
+for a in "$@";
+do
+ @bindir@/dynloader @localstatedir@/ahudns.controlsocket show "$a"
+done
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+\r
+#include "utility.hh"\r
+#include "statbag.hh"
+#include "ahuexception.hh"
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include "arguments.hh"
+#include "lock.hh"
+
+using namespace std;
+
+StatBag::StatBag()
+{
+ d_doRings=false;
+ pthread_mutex_init(&d_lock,0);
+}
+
+
+
+/** this NEEDS TO HAVE THE LOCK held already! */
+void StatBag::exists(const string &key)
+{
+ if(!d_stats.count(key))
+ {
+ unlock(); // it's the details that count
+ throw AhuException("Trying to deposit into unknown StatBag key '"+key+"'");
+ }
+}
+
+string StatBag::directory()
+{
+ string dir;
+ ostringstream o;
+ lock();
+ for(map<string,int *>::const_iterator i=d_stats.begin();
+ i!=d_stats.end();
+ i++)
+ {
+ o<<i->first<<"="<<*(i->second)<<",";
+ }
+ unlock();
+ dir=o.str();
+ return dir;
+}
+
+
+vector<string>StatBag::getEntries()
+{
+ vector<string> ret;
+ lock();
+ for(map<string,int *>::const_iterator i=d_stats.begin();
+ i!=d_stats.end();
+ i++)
+ ret.push_back(i->first);
+
+ unlock();
+ return ret;
+
+}
+
+string StatBag::getDescrip(const string &item)
+{
+ lock();
+ string tmp=d_keyDescrips[item];
+ unlock();
+ return tmp;
+}
+
+void StatBag::declare(const string &key, const string &descrip)
+{
+ lock();
+ int *i=new int(0);
+ d_stats[key]=i;
+ d_keyDescrips[key]=descrip;
+ unlock();
+}
+
+
+
+void StatBag::set(const string &key, int value)
+{
+ lock();
+ exists(key);
+ *d_stats[key]=value;
+
+ unlock();
+}
+
+int StatBag::read(const string &key)
+{
+ lock();
+
+ if(!d_stats.count(key))
+ {
+ unlock();
+ return 0;
+ }
+
+ int tmp=*d_stats[key];
+
+ unlock();
+ return tmp;
+
+}
+
+int StatBag::readZero(const string &key)
+{
+ lock();
+
+
+ if(!d_stats.count(key))
+ {
+ unlock();
+ return 0;
+ }
+
+
+ int tmp=*d_stats[key];
+ d_stats[key]=0;
+
+ unlock();
+
+ return tmp;
+}
+
+
+string StatBag::getValueStr(const string &key)
+{
+ ostringstream o;
+ o<<read(key);
+ return o.str();
+}
+
+string StatBag::getValueStrZero(const string &key)
+{
+ ostringstream o;
+ o<<readZero(key);
+ return o.str();
+}
+
+int *StatBag::getPointer(const string &key)
+{
+ exists(key);
+ return d_stats[key];
+}
+
+StatBag::~StatBag()
+{
+ for(map<string,int *>::const_iterator i=d_stats.begin();
+ i!=d_stats.end();
+ i++)
+ {
+ delete i->second;
+ }
+
+}
+
+StatRing::StatRing(int size)
+{
+ d_size=size;
+ d_items.resize(d_size);
+ d_lock=0;
+ d_pos=0;
+ d_lock=new pthread_mutex_t;
+ pthread_mutex_init(d_lock, 0);
+}
+
+void StatRing::resize(int newsize)
+{
+ if(d_size==newsize)
+ return;
+ Lock l(d_lock);
+
+ if(newsize>d_size) {
+ d_size=newsize;
+ d_items.resize(d_size);
+ return;
+ }
+
+ // this is the hard part, shrink
+ int startpos=d_pos-newsize;
+ int rpos;
+ vector<string>newring;
+ for(int i=startpos;i<d_pos;++i) {
+ rpos=i>=0 ? i : i+d_size;
+
+ newring.push_back(d_items[rpos%d_size]);
+ }
+ d_items=newring;
+ d_size=newsize;
+ d_pos=d_size-1;
+
+}
+StatRing::~StatRing()
+{
+ // do not clean up d_lock, it is shared
+}
+
+void StatRing::setHelp(const string &str)
+{
+ d_help=str;
+}
+
+string StatRing::getHelp()
+{
+ return d_help;
+}
+
+static bool popisort(const pair<string,int> &a, const pair<string,int> &b)
+{
+ return (a.second > b.second);
+}
+
+vector<pair<string,int> >StatRing::get() const
+{
+ Lock l(d_lock);
+ map<string,int> res;
+ for(vector<string>::const_iterator i=d_items.begin();i!=d_items.end();++i) {
+ if(!i->empty())
+ res[*i]++;
+ }
+
+ vector<pair<string,int> > tmp;
+ for(map<string,int>::const_iterator i=res.begin();i!=res.end();++i)
+ tmp.push_back(*i);
+
+ sort(tmp.begin(),tmp.end(),popisort);
+
+ return tmp;
+}
+
+void StatBag::declareRing(const string &name, const string &help, unsigned int size)
+{
+ d_rings[name]=StatRing(size);
+ d_rings[name].setHelp(help);
+}
+
+vector<pair<string,int> > StatBag::getRing(const string &name)
+{
+ return d_rings[name].get();
+}
+
+void StatRing::reset()
+{
+ Lock l(d_lock);
+ for(vector<string>::iterator i=d_items.begin();i!=d_items.end();++i) {
+ if(!i->empty())
+ *i="";
+ }
+}
+
+void StatBag::resetRing(const string &name)
+{
+ d_rings[name].reset();
+}
+
+void StatBag::resizeRing(const string &name, int newsize)
+{
+ d_rings[name].resize(newsize);
+}
+
+
+int StatBag::getRingSize(const string &name)
+{
+ return d_rings[name].getSize();
+}
+
+
+string StatBag::getRingTitle(const string &name)
+{
+ return d_rings[name].getHelp();
+}
+
+vector<string>StatBag::listRings()
+{
+ vector<string> ret;
+ for(map<string,StatRing>::const_iterator i=d_rings.begin();i!=d_rings.end();++i)
+ ret.push_back(i->first);
+ return ret;
+}
+
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef STATBAG_HH
+#define STATBAG_HH
+#include <pthread.h>
+#include <map>
+#include <string>
+#include <vector>
+#include "lock.hh"
+using namespace std;
+
+class StatRing
+{
+public:
+ StatRing(int size=10000);
+ ~StatRing();
+ void account(const string &item)
+ {
+ Lock l(d_lock);
+ d_items[d_pos++ % d_size]=item;
+ }
+
+
+ int getSize()
+ {
+ return d_size;
+ }
+ void resize(int newsize);
+ void reset();
+ void setHelp(const string &str);
+ string getHelp();
+ vector<pair<string,int> >get() const;
+private:
+ int d_size;
+ int d_pos;
+ vector<string>d_items;
+ pthread_mutex_t *d_lock;
+ string d_help;
+};
+
+
+//! use this to gather and query statistics
+class StatBag
+{
+ map<string,int *> d_stats;
+ map<string, string> d_keyDescrips;
+ map<string,StatRing>d_rings;
+ bool d_doRings;
+ pthread_mutex_t d_lock;
+
+public:
+ StatBag(); //!< Naked constructor. You need to declare keys before this class becomes useful
+ ~StatBag();
+ void declare(const string &key, const string &descrip=""); //!< Before you can store or access a key, you need to declare it
+
+ void declareRing(const string &name, const string &title, unsigned int size=10000);
+ vector<pair<string,int> >getRing(const string &name);
+ string getRingTitle(const string &name);
+ void ringAccount(const string &name, const string &item)
+ {
+ if(d_doRings)
+ d_rings[name].account(item);
+ }
+ void doRings()
+ {
+ d_doRings=true;
+ }
+
+ vector<string>listRings();
+ void resetRing(const string &name);
+ void resizeRing(const string &name, int newsize);
+ int getRingSize(const string &name);
+
+ string directory(); //!< Returns a list of all data stored
+ vector<string> getEntries(); //!< returns a vector with datums (items)
+ string getDescrip(const string &item); //!< Returns the description of this datum/item
+ void exists(const string &key); //!< call this function to throw an exception in case a key does not exist
+ inline void deposit(const string &key, int value); //!< increment the statistics behind this key by value amount
+ inline void inc(const string &key); //!< increase this key's value by one
+ void set(const string &key, int value); //!< set this key's value
+ int read(const string &key); //!< read the value behind this key
+ int readZero(const string &key); //!< read the value behind this key, and zero it afterwards
+ int *getPointer(const string &key); //!< get a direct pointer to the value behind a key. Use this for high performance increments
+ string getValueStr(const string &key); //!< read a value behind a key, and return it as a string
+ string getValueStrZero(const string &key); //!< read a value behind a key, and return it as a string, and zero afterwards
+
+private:
+ void lock(){pthread_mutex_lock(&d_lock);}
+ void unlock(){pthread_mutex_unlock(&d_lock);}
+};
+
+inline void StatBag::deposit(const string &key, int value)
+{
+ lock();
+ exists(key);
+
+ *d_stats[key]+=value;
+
+ unlock();
+}
+
+inline void StatBag::inc(const string &key)
+{
+ deposit(key,1);
+}
+
+
+#endif /* STATBAG_HH */
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <sys/types.h>
+#include <iostream>
+#include <string>
+#include "tcpreceiver.hh"
+\r
+#include <errno.h>
+#include <signal.h>
+
+#include "ueberbackend.hh"
+#include "dnspacket.hh"
+#include "nameserver.hh"
+#include "distributor.hh"
+#include "lock.hh"
+#include "logger.hh"
+#include "arguments.hh"
+#include "packetcache.hh"
+#include "packethandler.hh"
+#include "statbag.hh"
+#include "resolver.hh"
+#include "communicator.hh"
+
+extern PacketCache PC;
+extern StatBag S;
+
+/**
+\file tcpreceiver.cc
+\brief This file implements the tcpreceiver that receives and answers questions over TCP/IP
+*/
+
+pthread_mutex_t TCPNameserver::s_plock;
+Semaphore *TCPNameserver::d_connectionroom_sem;
+PacketHandler *TCPNameserver::s_P;
+int TCPNameserver::s_timeout;
+
+
+int TCPNameserver::sendDelPacket(DNSPacket *p, int outsock)
+{
+ const char *buf=p->getData();
+ int res=sendData(buf, p->len, outsock);
+ delete p;
+ return res;
+}
+
+
+void TCPNameserver::go()
+{
+ L<<Logger::Error<<"Creating backend connection for TCP"<<endl;
+ s_P=0;
+ try {
+ s_P=new PacketHandler;
+ }
+ catch(AhuException &ae) {
+ L<<Logger::Error<<Logger::NTLog<<"TCP server is unable to launch backends - will try again when questions come in"<<endl;
+ }
+ pthread_create(&d_tid, 0, launcher, static_cast<void *>(this));
+}
+
+void *TCPNameserver::launcher(void *data)
+{
+ static_cast<TCPNameserver *>(data)->thread();
+ return 0;
+}
+
+
+int TCPNameserver::readLength(int fd, struct sockaddr_in *remote)
+{
+ int bytesLeft=2;
+ unsigned char buf[2];
+
+ Utility::socklen_t remotelen=sizeof(*remote);
+ getpeername(fd, (struct sockaddr *)remote, &remotelen);
+
+ while(bytesLeft) {
+ int ret=waitForData(fd, s_timeout);
+ if(ret<0)
+ throw AhuException("Waiting on data from remote TCP client "+string(inet_ntoa(remote->sin_addr))+": "+stringerror());
+
+ ret=recv(fd, reinterpret_cast< char * >( buf ) +2-bytesLeft, bytesLeft,0);
+ if(ret<0)
+ throw AhuException("Trying to read data from remote TCP client "+string(inet_ntoa(remote->sin_addr))+": "+stringerror());
+ if(!ret) {
+ DLOG(L<<"Remote TCP client "+string(inet_ntoa(remote->sin_addr))+" closed connection");
+ return -1;
+ }
+ bytesLeft-=ret;
+ }
+ return buf[0]*256+buf[1];
+}
+
+void TCPNameserver::getQuestion(int fd, char *mesg, int pktlen, const struct sockaddr_in &remote)
+{
+ int ret=0, bytesread=0;
+ while(bytesread<pktlen) {
+ if((ret=waitForData(fd,s_timeout))<0 || (ret=recv(fd,mesg+bytesread,pktlen-bytesread,0))<=0)
+ goto err;
+
+ bytesread+=ret;
+ }
+ return;
+
+ err:;
+ if(ret<0)
+ throw AhuException("Error reading DNS data from TCP client "+string(inet_ntoa(remote.sin_addr))+": "+stringerror());
+ else
+ throw AhuException("Remote TCP client "+string(inet_ntoa(remote.sin_addr))+" closed connection");
+}
+
+void *TCPNameserver::doConnection(void *data)
+{
+ int fd=(int)data; // gotta love C
+ pthread_detach(pthread_self());
+
+ try {
+ if(!s_P) {
+ L<<Logger::Error<<"TCP server is without backend connections, launching"<<endl;
+ s_P=new PacketHandler;
+ }
+ char mesg[512];
+
+ DLOG(L<<"TCP Connection accepted on fd "<<fd<<endl);
+
+ for(;;) {
+ struct sockaddr_in remote;
+
+ int pktlen=readLength(fd, &remote);
+ if(pktlen<0) // EOF
+ break;
+
+ if(pktlen>511) {
+ L<<Logger::Error<<"Received an overly large question from "<<inet_ntoa(remote.sin_addr)<<", dropping"<<endl;
+ break;
+ }
+
+ getQuestion(fd,mesg,pktlen,remote);
+ S.inc("tcp-queries");
+ DNSPacket *packet=new DNSPacket;
+
+ if(packet->parse(mesg, pktlen)<0)
+ break;
+
+ packet->setRemote((struct sockaddr *)&remote,sizeof(remote));
+
+ if(packet->qtype.getCode()==QType::AXFR) {
+ if(doAXFR(packet->qdomain, packet, fd))
+ S.inc("tcp-answers");
+ continue;
+ }
+
+ if(packet->d.rd && arg().mustDo("recursor")) {
+ // now what
+ // this is a pretty rare event all in all, so we can afford to be slow
+ S.inc("recursing-questions");
+ Resolver res;
+ unsigned int len;
+ DLOG(L<<"About to hand query to recursor"<<endl);
+ ServiceTuple st;
+ st.port=53;
+ parseService(arg()["recursor"],st);
+
+ char *buffer=res.sendReceive(st.host,st.port,packet->getRaw(),packet->len,&len);
+ DLOG(L<<"got an answer from recursor: "<<len<<" bytes, "<<(int)buffer<<endl);
+ if(buffer) {
+ sendData(buffer,len,fd);
+ DLOG(L<<"sent out to customer: "<<len<<" bytes"<<endl);
+ delete buffer;
+ S.inc("recursing-answers");
+ S.inc("tcp-answers");
+ }
+ continue;
+ }
+
+ DNSPacket* cached=new DNSPacket;
+ if(!packet->d.rd && (PC.get(packet, cached))) { // short circuit - does the PacketCache recognize this question?
+ cached->setRemote((struct sockaddr *)(packet->remote), sizeof(struct sockaddr_in));
+ cached->spoofID(packet->d.id);
+ if(sendDelPacket(cached, fd)<0)
+ goto out;
+
+ S.inc("tcp-answers");
+ continue;
+ }
+ else
+ delete cached;
+
+ DNSPacket *reply;
+ {
+ Lock l(&s_plock);
+ reply=s_P->question(packet); // we really need to ask the backend :-)
+ }
+
+ delete packet;
+
+ if(!reply) // unable to write an answer?
+ break;
+
+ S.inc("tcp-answers");
+ sendDelPacket(reply, fd);
+ }
+
+ out:;
+ }
+ catch(AhuException &ae) {
+ L<<Logger::Error<<"TCP nameserver: "<<ae.reason<<endl;
+ }
+ catch(PacketHandler::DBException &e) {
+ L<<Logger::Error<<"TCP Connection Thread unable to answer a question because of a backend error"<<endl;
+ }
+ catch(exception &e) {
+ L<<Logger::Error<<"TCP Connection Thread died because of STL error: "<<e.what()<<endl;
+ }
+ catch( ... )
+ {
+ L << Logger::Error << "TCP Connection Thread caught unknown exception." << endl;
+ }
+ Utility::closesocket(fd);
+ d_connectionroom_sem->post();
+
+ return 0;
+}
+
+static bool canDoAXFR(DNSPacket *q)
+{
+ if(!arg().mustDo("disable-axfr")) // default is 'everybody can do axfr'
+ return true;
+
+ vector<string>parts;
+ stringtok(parts,arg()["allow-axfr-ips"],", "); // is this IP on the guestlist?
+ for(vector<string>::const_iterator i=parts.begin();i!=parts.end();++i) {
+ if(matchNetmask(q->getRemote().c_str(),i->c_str())==1)
+ return true;
+ }
+
+ extern CommunicatorClass Communicator;
+
+ if(Communicator.justNotified(q->qdomain, q->getRemote())) { // we just notified this ip
+ L<<Logger::Warning<<"Approved AXFR of '"<<q->qdomain<<"' from recently notified slave "<<q->getRemote()<<endl;
+ return true;
+ }
+
+ return false;
+}
+
+/** do the actual zone transfer. Return 0 in case of error, 1 in case of success */
+int TCPNameserver::doAXFR(const string &target, DNSPacket *q, int outsock)
+{
+ DNSPacket *outpacket=0;
+ if(!canDoAXFR(q)) {
+ DLOG(L<<"AXFR denied for "<<q->getRemote()<<endl);
+
+ outpacket=q->replyPacket();
+ outpacket->setRcode(RCode::Refused);
+ // FIXME: should actually figure out if we are auth over a zone, and send out 9 if we aren't
+ sendDelPacket(outpacket,outsock);
+ return 0;
+ }
+
+ outpacket=q->replyPacket();
+
+ DNSResourceRecord soa;
+ DNSResourceRecord rr;
+
+ SOAData sd;
+ {
+ Lock l(&s_plock);
+
+ // find domain_id via SOA and list complete domain. No SOA, no AXFR
+
+ DLOG(L<<"Looking for SOA"<<endl);
+
+ if(!s_P->getBackend()->getSOA(target,sd)) {
+ outpacket->setRcode(9); // 'NOTAUTH'
+ sendDelPacket(outpacket,outsock);
+ return 0;
+ }
+ soa.qname=target;
+ soa.qtype=QType::SOA;
+ soa.content=DNSPacket::serializeSOAData(sd);
+ soa.ttl=sd.default_ttl;
+ soa.domain_id=sd.domain_id;
+ soa.d_place=DNSResourceRecord::ANSWER;
+ }
+
+ DLOG(L<<"Issuing list command - opening dedicated database connection"<<endl);
+ PacketHandler P;
+ DNSBackend *B=P.getBackend();
+
+ // now list zone
+ if(!(B->list(sd.domain_id))) {
+ L<<Logger::Error<<"Backend signals error condition"<<endl;
+ outpacket->setRcode(2); // 'SERVFAIL'
+ sendDelPacket(outpacket,outsock);
+ return 0;
+ }
+
+ /* write first part of answer */
+
+ DLOG(L<<"Sending out SOA"<<endl);
+ outpacket->addRecord(soa); // AXFR format begins and ends with a SOA record, so we add one
+ sendDelPacket(outpacket, outsock);
+
+ /* now write all other records */
+
+ int count=0;
+ int chunk=100; // FIXME: this should probably be autosizing
+ if(arg().mustDo("strict-rfc-axfrs"))
+ chunk=1;
+
+ outpacket=q->replyPacket();
+ outpacket->setCompress(false);
+
+ while(B->get(rr)) {
+ if(rr.qtype.getCode()==6)
+ continue; // skip SOA - would indicate end of AXFR
+
+ outpacket->addRecord(rr);
+
+ if(!((++count)%chunk)) {
+ count=0;
+
+ if(sendDelPacket(outpacket, outsock)<0) // FIXME: this leaks memory!
+ return 0;
+
+ outpacket=q->replyPacket();
+ outpacket->setCompress(false);
+ // FIXME: Subsequent messages SHOULD NOT have a question section, though the final message MAY.
+ }
+ }
+ if(count) {
+ sendDelPacket(outpacket, outsock);
+ }
+
+ DLOG(L<<"Done writing out records"<<endl);
+ /* and terminate with yet again the SOA record */
+ outpacket=q->replyPacket();
+ outpacket->addRecord(soa);
+ sendDelPacket(outpacket, outsock);
+ DLOG(L<<"last packet - close"<<endl);
+
+ return 1;
+}
+
+TCPNameserver::~TCPNameserver()
+{
+ delete d_connectionroom_sem;
+}
+
+TCPNameserver::TCPNameserver()
+{
+// sem_init(&d_connectionroom_sem,0,arg().asNum("max-tcp-connections"));
+ d_connectionroom_sem = new Semaphore( arg().asNum( "max-tcp-connections" ));
+
+ s_timeout=10;
+ vector<string>locals;
+ stringtok(locals,arg()["local-address"]," ,");
+
+ vector<string>locals6;
+ stringtok(locals6,arg()["local-ipv6"]," ,");
+
+
+ if(locals.empty() && locals6.empty())
+ throw AhuException("No local address specified");
+
+ d_highfd=0;
+
+#ifndef WIN32
+ signal(SIGPIPE,SIG_IGN);
+#endif // WIN32
+ FD_ZERO(&d_rfds);
+
+ for(vector<string>::const_iterator laddr=locals.begin();laddr!=locals.end();++laddr) {
+ struct sockaddr_in local;
+ int s=socket(AF_INET,SOCK_STREAM,0);
+
+ if(s<0)
+ throw AhuException("Unable to acquire TCP socket: "+stringerror());
+
+ memset(&local,0,sizeof(local));
+ local.sin_family=AF_INET;
+
+ struct hostent *h;
+
+ if ( *laddr == "0.0.0.0" )
+ {
+ local.sin_addr.s_addr = INADDR_ANY;
+ }
+ else
+ {
+ h=gethostbyname(laddr->c_str());
+
+ if(!h)
+ throw AhuException("Unable to resolve local address '"+*laddr+"'");
+
+ local.sin_addr.s_addr=*(int*)h->h_addr;
+ }
+
+ int tmp=1;
+ if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) {
+ L<<Logger::Error<<"Setsockopt failed"<<endl;
+ exit(1);
+ }
+
+ local.sin_port=htons(arg().asNum("local-port"));
+
+ if(bind(s, (sockaddr*)&local,sizeof(local))<0) {
+ L<<Logger::Error<<"binding to TCP socket: "<<strerror(errno)<<endl;
+ throw AhuException("Unable to bind to TCP socket");
+ }
+
+ listen(s,128);
+ L<<Logger::Error<<"TCP server bound to "<<*laddr<<":"<<arg()["local-port"]<<endl;
+ d_sockets.push_back(s);
+ FD_SET(s, &d_rfds);
+ d_highfd=max(s,d_highfd);
+ }
+
+ // TODO: Implement ipv6
+#ifndef WIN32
+ for(vector<string>::const_iterator laddr=locals6.begin();laddr!=locals6.end();++laddr) {
+ struct sockaddr_in6 local;
+ int s=socket(AF_INET6,SOCK_STREAM,0);
+
+ if(s<0)
+ throw AhuException("Unable to acquire TCPv6 socket: "+stringerror());
+
+ memset(&local,0,sizeof(local));
+ local.sin6_family=AF_INET6;
+ struct hostent *h;
+ h=gethostbyname2(laddr->c_str(),AF_INET6);
+
+ if(!h)
+ throw AhuException("Unable to resolve local address '"+*laddr+"'");
+
+ memcpy(&local.sin6_addr.s6_addr,h->h_addr,16);
+ local.sin6_port=htons(arg().asNum("local-port"));
+
+ int tmp=1;
+ if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) {
+ L<<Logger::Error<<"Setsockopt failed"<<endl;
+ exit(1);
+ }
+
+ if(bind(s, (sockaddr*)&local,sizeof(local))<0) {
+ L<<Logger::Error<<"binding to TCP socket: "<<strerror(errno)<<endl;
+ throw AhuException("Unable to bind to TCPv6 socket");
+ }
+
+ listen(s,128);
+ L<<Logger::Error<<"TCPv6 server bound to "<<*laddr<<":"<<arg()["local-port"]<<endl;
+ d_sockets.push_back(s);
+ FD_SET(s, &d_rfds);
+ d_highfd=max(s,d_highfd);
+ }
+#endif // WIN32
+}
+
+
+//! Start of TCP operations thread
+void TCPNameserver::thread()
+{
+ struct timeval tv;
+ tv.tv_sec=1;
+ tv.tv_usec=0;
+ try {
+ for(;;) {
+ int fd;
+ struct sockaddr_in remote;
+ Utility::socklen_t addrlen=sizeof(remote);
+
+ fd_set rfds=d_rfds;
+
+ select(d_highfd+1, &rfds, 0, 0, 0); // blocks
+ int sock=-1;
+ for(vector<int>::const_iterator i=d_sockets.begin();i!=d_sockets.end();++i) {
+ if(FD_ISSET(*i, &rfds)) {
+ sock=*i;
+ addrlen=sizeof(remote);
+
+ if((fd=accept(sock, (sockaddr*)&remote, &addrlen))<0) {
+ L<<Logger::Error<<"TCP question accept error: "<<strerror(errno)<<endl;
+
+ if(errno==EMFILE) {
+ L<<Logger::Error<<Logger::NTLog<<"TCP handler out of filedescriptors, exiting, won't recover from this"<<endl;
+ exit(1);
+ }
+ }
+ else {
+ pthread_t tid;
+ d_connectionroom_sem->wait(); // blocks if no connections are available
+
+ int room;
+ d_connectionroom_sem->getValue( &room);
+ if(room<1)
+ L<<Logger::Warning<<Logger::NTLog<<"Limit of simultaneous TCP connections reached - raise max-tcp-connections"<<endl;
+
+ if(pthread_create(&tid, 0, &doConnection, (void *)fd)) {
+ L<<Logger::Error<<"Error creating thread: "<<stringerror()<<endl;
+ d_connectionroom_sem->post();
+ }
+ }
+ }
+ }
+ }
+ }
+ catch(AhuException &AE) {
+ L<<Logger::Error<<"TCP Namerserver thread dying because of fatal error: "<<AE.reason<<endl;
+ }
+ catch(...) {
+ L<<Logger::Error<<"TCPNameserver dying because of an unexpected fatal error"<<endl;
+ }
+ exit(1); // take rest of server with us
+}
+
+
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef PDNS_TCPRECEIVER_HH
+#define PDNS_TCPRECEIVER_HH
+
+#include "dns.hh"
+#include "dnsbackend.hh"
+#include "packethandler.hh"
+#include <vector>\r
+\r
+#ifndef WIN32
+# include <sys/select.h>\r
+# include <sys/socket.h>\r
+# include <netinet/in.h>\r
+# include <arpa/inet.h>\r
+# include <sys/stat.h>\r
+# include <unistd.h>\r
+# include <netdb.h>\r
+# include <sys/uio.h>\r
+# include <sys/select.h>\r
+#endif // WIN32
+
+using namespace std;
+
+class TCPNameserver
+{
+public:
+ TCPNameserver();\r
+ ~TCPNameserver();
+ void go();
+private:
+
+ static int sendDelPacket(DNSPacket *p, int outsock);
+ static int readLength(int fd, struct sockaddr_in *remote);
+ static void getQuestion(int fd, char *mesg, int pktlen, const struct sockaddr_in &remote);
+ static int doAXFR(const string &target, DNSPacket *q, int outsock);
+ static void *doConnection(void *data);
+ static void *launcher(void *data);
+ void thread(void);
+ static pthread_mutex_t s_plock;
+ static PacketHandler *s_P;
+ pthread_t d_tid;
+ static Semaphore *d_connectionroom_sem;
+
+ vector<int>d_sockets;
+ int d_highfd;
+ fd_set d_rfds;
+ static int s_timeout;
+};
+
+#endif /* PDNS_TCPRECEIVER_HH */
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// $Id: ueberbackend.cc,v 1.1 2002/11/27 15:18:33 ahu Exp $
+/* (C) Copyright 2002 PowerDNS.COM BV */\r
+#include "utility.hh"
+#include <string>
+#include <map>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <iostream>
+#include <sstream>
+#include <functional>
+
+#include "dns.hh"
+#include "arguments.hh"
+#include "dnsbackend.hh"
+#include "ueberbackend.hh"
+#include "dnspacket.hh"
+#include "logger.hh"
+#include "statbag.hh"
+#include "packetcache.hh"
+
+extern StatBag S;
+
+vector<UeberBackend *>UeberBackend::instances;
+pthread_mutex_t UeberBackend::instances_lock=PTHREAD_MUTEX_INITIALIZER;
+
+sem_t UeberBackend::d_dynserialize;
+string UeberBackend::programname;
+string UeberBackend::s_status;
+
+// initially we are blocked
+bool UeberBackend::d_go=false;
+pthread_mutex_t UeberBackend::d_mut = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t UeberBackend::d_cond = PTHREAD_COND_INITIALIZER;
+
+int UeberBackend::s_s=-1; // ?
+
+//! Loads a module and reports it to all UeberBackend threads
+bool UeberBackend::loadmodule(const string &name)
+{
+ // TODO: Implement dynamic loading?
+#if !defined(WIN32) && !defined(DARWIN)
+ void *dlib=dlopen(name.c_str(), RTLD_NOW);
+
+ if(dlib == NULL) {
+ L<<Logger::Warning <<"Unable to load module '"<<name<<"': "<<dlerror() << endl;
+ return false;
+ }
+
+ return true;
+
+#else
+ L << Logger::Warning << "This version doesn't support dynamic loading (yet)." << endl;
+ return false;
+
+#endif // WIN32
+
+}
+
+void UeberBackend::go(void)
+{
+ pthread_mutex_lock(&d_mut);
+ d_go=true;
+ pthread_cond_broadcast(&d_cond);
+ pthread_mutex_unlock(&d_mut);
+}
+
+bool UeberBackend::getDomainInfo(const string &domain, DomainInfo &di)
+{
+ for(vector<DNSBackend *>::const_iterator i=backends.begin();i!=backends.end();++i)
+ if((*i)->getDomainInfo(domain, di))
+ return true;
+ return false;
+}
+
+void UeberBackend::reload()
+{
+ for ( vector< DNSBackend * >::iterator i = backends.begin(); i != backends.end(); ++i )
+ {
+ ( *i )->reload();
+ }
+}
+
+void UeberBackend::rediscover()
+{
+ for ( vector< DNSBackend * >::iterator i = backends.begin(); i != backends.end(); ++i )
+ {
+ ( *i )->rediscover();
+ }
+}
+
+
+void UeberBackend::getUnfreshSlaveInfos(vector<DomainInfo>* domains)
+{
+ for ( vector< DNSBackend * >::iterator i = backends.begin(); i != backends.end(); ++i )
+ {
+ ( *i )->getUnfreshSlaveInfos( domains );
+ }
+}
+
+
+
+void UeberBackend::getUpdatedMasters(vector<DomainInfo>* domains)
+{
+ for ( vector< DNSBackend * >::iterator i = backends.begin(); i != backends.end(); ++i )
+ {
+ ( *i )->getUpdatedMasters( domains );
+ }
+}
+
+
+bool UeberBackend::getSOA(const string &domain, SOAData &sd)
+{
+ d_question.qtype=QType::SOA;
+ d_question.qname=domain;
+ d_question.zoneId=-1;
+
+ int cstat=cacheHas(d_question,d_answer);
+ if(cstat==0) {
+ return false;
+ }
+ else if(cstat==1) {
+ // ehm
+ DNSPacket::fillSOAData(d_answer.content,sd);
+ sd.domain_id=d_answer.domain_id;
+ sd.ttl=d_answer.ttl;
+ cout<<"from cache: sd.ttl: "<<sd.ttl<<endl;
+ return true;
+ }
+
+
+ for(vector<DNSBackend *>::const_iterator i=backends.begin();i!=backends.end();++i)
+ if((*i)->getSOA(domain, sd)) {
+ DNSResourceRecord rr;
+ rr.qname=domain;
+ rr.qtype=QType::SOA;
+ rr.content=DNSPacket::serializeSOAData(sd);
+ rr.ttl=sd.ttl;
+ cout<<"Set rr.ttl to "<<sd.ttl<<endl;
+ rr.domain_id=sd.domain_id;
+ addOneCache(d_question,rr);
+ return true;
+ }
+
+ addNegCache(d_question);
+ return false;
+}
+
+bool UeberBackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
+{
+ for(vector<DNSBackend *>::const_iterator i=backends.begin();i!=backends.end();++i)
+ if((*i)->superMasterBackend(ip,domain,nsset,account, db))
+ return true;
+ return false;
+
+}
+
+void UeberBackend::setStatus(const string &st)
+{
+ s_status=st;
+}
+
+UeberBackend::UeberBackend()
+{
+ UeberBackend("default");
+}
+
+UeberBackend::UeberBackend(const string &pname)
+{
+ programname=pname;
+ pthread_mutex_lock(&instances_lock);
+ instances.push_back(this); // report to the static list of ourself
+ pthread_mutex_unlock(&instances_lock);
+
+ tid=pthread_self();
+ stale=false;
+
+ backends=BackendMakers().all();
+}
+
+void UeberBackend::die()
+{
+ cleanup();
+ stale=true;
+}
+
+void del(DNSBackend* d)
+{
+ delete d;
+}
+
+void UeberBackend::cleanup()
+{
+ pthread_mutex_lock(&instances_lock);
+
+ remove(instances.begin(),instances.end(),this);
+ instances.resize(instances.size()-1);
+
+ pthread_mutex_unlock(&instances_lock);
+
+ for_each(backends.begin(),backends.end(),del);
+}
+
+int UeberBackend::cacheHas(const Question &q, DNSResourceRecord &rr)
+{
+ extern PacketCache PC;
+ static int *qcachehit=S.getPointer("query-cache-hit");
+ static int *qcachemiss=S.getPointer("query-cache-miss");
+
+ static int negqueryttl=arg().asNum("negquery-cache-ttl");
+ static int queryttl=arg().asNum("query-cache-ttl");
+ if(!negqueryttl && !queryttl) {
+ (*qcachemiss)++;
+ return -1;
+ }
+
+ string content;
+ // L<<Logger::Warning<<"looking up: "<<q.qname+"|N|"+q.qtype.getName()+"|"+itoa(q.zoneId)<<endl;
+ bool ret=PC.getKey(q.qname+"|Q|"+q.qtype.getName()+"|"+itoa(q.zoneId), content); // think about lowercasing here
+
+ if(!ret) {
+ (*qcachemiss)++;
+ return -1;
+ }
+
+ (*qcachehit)++;
+ if(content.empty())
+ return 0;
+ rr.unSerialize(content);
+ return 1;
+}
+
+void UeberBackend::addNegCache(const Question &q)
+{
+ extern PacketCache PC;
+ static int negqueryttl=arg().asNum("negquery-cache-ttl");
+ if(!negqueryttl)
+ return;
+ // L<<Logger::Warning<<"negative inserting: "<<q.qname+"|N|"+q.qtype.getName()+"|"+itoa(q.zoneId)<<endl;
+ PC.insert(q.qname+"|Q|"+q.qtype.getName()+"|"+itoa(q.zoneId),"",negqueryttl);
+}
+
+void UeberBackend::addOneCache(const Question &q, const DNSResourceRecord &rr)
+{
+ extern PacketCache PC;
+ static int queryttl=arg().asNum("query-cache-ttl");
+ if(!queryttl)
+ return;
+
+ PC.insert(q.qname+"|Q|"+q.qtype.getName()+"|"+itoa(q.zoneId),rr.serialize(),queryttl);
+}
+
+
+UeberBackend::~UeberBackend()
+{
+ DLOG(L<<Logger::Error<<"UeberBackend destructor called, removing ourselves from instances, and deleting our backends"<<endl);
+ cleanup();
+}
+
+// this handle is more magic than most
+void UeberBackend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_p, int zoneId)
+{
+ if(stale) {
+ L<<Logger::Error<<"Stale ueberbackend received question, signalling that we want to be recycled"<<endl;
+ throw AhuException("We are stale, please recycle");
+ }
+
+ DLOG(L<<"UeberBackend received question for "<<qtype.getName()<<" of "<<qname<<endl);
+ if(!d_go) {
+ pthread_mutex_lock(&d_mut);
+ while (d_go==false) {
+ L<<Logger::Error<<"UeberBackend is blocked, waiting for 'go'"<<endl;
+ pthread_cond_wait(&d_cond, &d_mut);
+ L<<Logger::Error<<"Broadcast received, unblocked"<<endl;
+ }
+ pthread_mutex_unlock(&d_mut);
+ }
+
+ d_handle.i=0;
+ d_handle.qtype=qtype;
+ d_handle.qname=qname;
+ d_handle.pkt_p=pkt_p;
+ d_ancount=0;
+
+ if(!backends.size()) {
+ L<<Logger::Error<<Logger::NTLog<<"No database backends available - unable to answer questions."<<endl;
+ stale=true; // please recycle us!
+ throw AhuException("We are stale, please recycle");
+ }
+ else {
+ d_question.qtype=qtype;
+ d_question.qname=qname;
+ d_question.zoneId=zoneId;
+ int cstat=cacheHas(d_question,d_answer);
+ if(cstat<0) { // nothing
+ d_negcached=d_cached=false;
+ (d_handle.d_hinterBackend=backends[d_handle.i++])->lookup(qtype, qname,pkt_p,zoneId);
+ }
+ else if(cstat==0) {
+ d_negcached=true;
+ d_cached=false;
+ }
+ else {
+ d_negcached=false;
+ d_cached=true;
+ }
+ }
+
+ d_handle.parent=this;
+
+}
+
+bool UeberBackend::get(DNSResourceRecord &rr)
+{
+ if(d_negcached) {
+ return false;
+ }
+
+ if(d_cached) {
+ rr=d_answer;
+ d_negcached=true; // ugly, confusing
+ return true;
+ }
+
+ if(!d_handle.get(rr)) {
+ if(!d_ancount && !d_handle.qname.empty()) // don't cache axfr
+ addNegCache(d_question);
+
+ if(d_ancount==1) {
+ addOneCache(d_question,lastrr);
+ }
+
+ return false;
+ }
+
+ if(!d_ancount++) {
+ lastrr=rr;
+ }
+ return true;
+}
+
+bool UeberBackend::list(int domain_id)
+{
+ d_cached=d_negcached=false;
+ d_ancount=0;
+ if(stale) {
+ L<<Logger::Error<<"Stale ueberbackend received question, signalling that we want to be recycled"<<endl;
+ throw AhuException("We are stale, please recycle");
+ }
+
+ DLOG(L<<"UeberBackend received list request for domain id "<<domain_id<<endl);
+
+ pthread_mutex_lock(&d_mut);
+ while (d_go==false) {
+ L<<Logger::Error<<"UeberBackend is blocked, waiting for 'go'"<<endl;
+ pthread_cond_wait(&d_cond, &d_mut);
+ L<<Logger::Error<<"Broadcast received, unblocked"<<endl;
+ }
+
+ pthread_mutex_unlock(&d_mut);
+
+ d_handle.i=0;
+ d_handle.pkt_p=0;
+ d_handle.qname="";
+ d_negcached=false;
+
+ if(!backends.size()) {
+ return 0; // we failed
+ }
+ else {
+ while(!(d_handle.d_hinterBackend=backends[d_handle.i++])->list(domain_id) && d_handle.i<backends.size())
+ ;
+ }
+ d_handle.parent=this;
+
+ return true;
+}
+
+
+int UeberBackend::handle::instances=0;
+
+UeberBackend::handle::handle()
+{
+ // L<<Logger::Warning<<"Handle instances: "<<instances<<endl;
+ instances++;
+}
+
+UeberBackend::handle::~handle()
+{
+ instances--;
+}
+
+
+
+
+
+bool UeberBackend::handle::get(DNSResourceRecord &r)
+{
+ DLOG(L << "Ueber get() was called for a "<<qtype.getName()<<" record" << endl);
+ bool isMore=false;
+ while(d_hinterBackend && !(isMore=d_hinterBackend->get(r))) { // this backend out of answers
+ if(i<parent->backends.size()) {
+ DLOG(L<<"Backend #"<<i<<" of "<<parent->backends.size()
+ <<" out of answers, taking next"<<endl);
+
+ d_hinterBackend=parent->backends[i++];
+ d_hinterBackend->lookup(qtype,qname,pkt_p);
+ }
+ else
+ break;
+
+ DLOG(L<<"Now asking backend #"<<i<<endl);
+ }
+
+ if(!isMore && i==parent->backends.size()) {
+ DLOG(L<<"UeberBackend reached end of backends"<<endl);
+ return false;
+ }
+
+ DLOG(L<<"Found an answering backend - will not try another one"<<endl);
+ i=parent->backends.size(); // don't go on to the next backend
+ return true;
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef UEBERBACKEND_HH
+#define UEBERBACKEND_HH
+
+#include <vector>
+#include <map>
+#include <string>
+#include <algorithm>
+#include <pthread.h>
+#include <semaphore.h>\r
+\r
+#ifndef WIN32\r
+#include <sys/un.h>\r
+#include <dlfcn.h>\r
+#include <unistd.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <sys/stat.h>\r
+#include <fcntl.h>\r
+#include <unistd.h>\r
+#endif // WIN32\r
+
+#include "dnspacket.hh"
+#include "dnsbackend.hh"
+
+using namespace std;
+
+class BackendReporter;
+
+/** This is a very magic backend that allows us to load modules dynamically,
+ and query them in order. This is persistent over all UeberBackend instantiations
+ across multiple threads. Very magic */
+
+class UeberBackend : public DNSBackend
+{
+public:
+ UeberBackend();
+ UeberBackend(const string &);
+ ~UeberBackend();
+ typedef DNSBackend *BackendMaker(); //!< typedef for functions returning pointers to new backends
+
+ bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db);
+
+ /** contains BackendReporter objects, which contain maker functions and information about
+ weather a module has already been reported to existing instances of the UeberBackend
+ */
+ static vector<BackendReporter>backendmakers;
+
+ /** Tracks all created UeberBackend instances for us. We use this vector to notify
+ existing threads of new modules
+ */
+ static vector<UeberBackend *>instances;
+ static pthread_mutex_t instances_lock;
+
+ static bool loadmodule(const string &name);
+
+ /** Thread function that listens on our unix domain socket for commands, for example
+ instructions to load new modules */
+ static void *DynListener(void *);
+ static void go(void);
+
+
+ /** This contains all registered backends. The DynListener modifies this list for us when
+ new modules are loaded */
+ vector<DNSBackend*>backends;
+
+ void die();
+ void cleanup();
+
+ //! the very magic handle for UeberBackend questions
+ class handle
+ {
+ public:
+ bool get(DNSResourceRecord &r);
+ handle();
+ ~handle();
+
+ //! The UeberBackend class where this handle belongs to
+ UeberBackend *parent;
+ //! The current real backend, which is answering questions
+ DNSBackend *d_hinterBackend;
+
+ //! Index of the current backend within the backends vector
+ unsigned int i;
+
+ //! DNSPacket who asked this question
+ DNSPacket *pkt_p;
+ string qname;
+ QType qtype;
+ private:
+
+ static int instances;
+ };
+
+ void lookup(const QType &, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1);
+
+ bool getSOA(const string &domain, SOAData &sd);
+ bool list(int domain_id);
+ bool get(DNSResourceRecord &r);
+
+ static DNSBackend *maker(const map<string,string> &);
+ static void closeDynListener();
+ static void UeberBackend::setStatus(const string &st);
+ void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
+ void getUpdatedMasters(vector<DomainInfo>* domains);
+ bool getDomainInfo(const string &domain, DomainInfo &di);
+ void rediscover();
+ void reload();
+private:
+ DNSResourceRecord lastrr;
+ pthread_t tid;
+ handle d_handle;
+ bool d_negcached;
+ bool d_cached;
+ struct Question
+ {
+ QType qtype;
+ string qname;
+ int zoneId;
+ }d_question;
+ DNSResourceRecord d_answer;
+
+ int cacheHas(const Question &q, DNSResourceRecord &rr);
+ void addNegCache(const Question &q);
+ void addOneCache(const Question &q, const DNSResourceRecord &rr);
+
+ static pthread_mutex_t d_mut;
+ static pthread_cond_t d_cond;
+ static sem_t d_dynserialize;
+ static bool d_go;
+ static int s_s;
+ static string s_status;
+ int d_ancount;
+ static string programname;
+ bool stale;
+};
+
+
+/** Class used to report new backends. It stores a maker function, and a flag that indicates that
+ this module has been reported */
+class BackendReporter
+{
+public:
+ BackendReporter(UeberBackend::BackendMaker *p)
+ {
+ maker=p;
+ reported=false;
+ };
+ map<string,string>d_parameters;
+ UeberBackend::BackendMaker *maker; //!< function to make this backend
+ bool reported; //!< if this backend has been reported to running UeberBackend threads
+private:
+};
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// Utility class win32 implementation.
+
+#include "utility.hh"
+#include <cstring>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "ahuexception.hh"
+#include "logger.hh"
+#include "misc.hh"
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+
+using namespace std;
+
+// Closes a socket.
+int Utility::closesocket( Utility::sock_t socket )
+{
+ return ::close( socket );
+}
+
+bool Utility::setNonBlocking(sock_t sock)
+{
+ int flags=fcntl(sock,F_GETFL,0);
+ if(flags<0 || fcntl(sock, F_SETFL,flags|O_NONBLOCK) <0)
+ return false;
+ return true;
+}
+
+bool Utility::setBlocking(sock_t sock)
+{
+ int flags=fcntl(sock,F_GETFL,0);
+ if(flags<0 || fcntl(sock, F_SETFL,flags&(~O_NONBLOCK)) <0)
+ return false;
+ return true;
+}
+
+const char *Utility::inet_ntop(int af, const char *src, char *dst, size_t size)
+{
+ return const_cast<char *>(::inet_ntop(af,src,dst,size));
+}
+
+unsigned int Utility::sleep(unsigned int sec)
+{
+ return ::sleep(sec);
+}
+
+void Utility::usleep(unsigned long usec)
+{
+ ::usleep(usec);
+}
+
+
+// Drops the program's privileges.
+void Utility::dropPrivs( int uid, int gid )
+{
+ if(gid) {
+ if(setgid(gid)<0) {
+ theL()<<Logger::Error<<"Unable to set effective group id to "<<gid<<": "<<stringerror()<<endl;
+ exit(1);
+ }
+ else
+ theL()<<Logger::Error<<"Set effective group id to "<<uid<<endl;
+
+ }
+
+ if(uid) {
+ if(setuid(uid)<0) {
+ theL()<<Logger::Error<<"Unable to set effective user id to "<<uid<<": "<<stringerror()<<endl;
+ exit(1);
+ }
+ else
+ theL()<<Logger::Error<<"Set effective user id to "<<uid<<endl;
+ }
+}
+
+
+// Returns the current process id.
+Utility::pid_t Utility::getpid( void )
+{
+ return ::getpid();
+}
+
+
+// Returns the current time.
+int Utility::gettimeofday( struct timeval *tv, void *tz )
+{
+ return ::gettimeofday(tv,0);
+}
+
+
+// Converts an address from dot and numbers format to binary data.
+int Utility::inet_aton( const char *cp, struct in_addr *inp )
+{
+ return ::inet_aton(cp,inp);
+
+}
+
+
+// Converts an address from presentation format to network format.
+int Utility::inet_pton( int af, const char *src, void *dst )
+{
+ return ::inet_pton(af, src, dst);
+}
+
+
+// Retrieves a gid using a groupname.
+int Utility::makeGidNumeric(const string &group)
+{
+ int newgid;
+ if(!(newgid=atoi(group.c_str()))) {
+ struct group *gr=getgrnam(group.c_str());
+ if(!gr) {
+ theL()<<Logger::Error<<"Unable to look up gid of group '"<<group<<"': "<<strerror(errno)<<endl;
+ exit(1);
+ }
+ newgid=gr->gr_gid;
+ }
+ return newgid;
+}
+
+
+// Retrieves an uid using a username.
+int Utility::makeUidNumeric(const string &username)
+{
+ int newuid;
+ if(!(newuid=atoi(username.c_str()))) {
+ struct passwd *pw=getpwnam(username.c_str());
+ if(!pw) {
+ theL()<<Logger::Error<<"Unable to look up uid of user '"<<username<<"': "<<strerror(errno)<<endl;
+ exit(1);
+ }
+ newuid=pw->pw_uid;
+ }
+ return newuid;
+}
+
+
+// Returns a random number.
+long int Utility::random( void )
+{
+ return rand();
+}
+
+// Sets the random seed.
+void Utility::srandom( unsigned int seed )
+{
+ ::srandom(seed);
+}
+
+// Compares two string, ignoring the case.
+int Utility::strcasecmp( const char *s1, const char *s2 )
+{
+ return ::strcasecmp( s1, s2 );
+}
+
+
+// Writes a vector.
+int Utility::writev(int socket, const struct iovec *vector, size_t count )
+{
+ return ::writev(socket,vector,count);
+}
+
+#ifdef DARWIN
+
+// Darwin 6.0 Compatible implementation, uses pthreads so it portable across more platforms.
+
+#define SEM_VALUE_MAX 32767
+#define SEM_MAGIC ((u_int32_t) 0x09fa4012)
+
+Semaphore::Semaphore(unsigned int value)
+{
+ if (value > SEM_VALUE_MAX) {
+ throw AhuException("Cannot create semaphore: value too large");
+ }
+
+ // Initialize
+
+ if (pthread_mutex_init(&m_lock, NULL) != 0) {
+ throw AhuException("Cannot create semaphore: cannot allocate mutex");
+ }
+
+ if (pthread_cond_init(&m_gtzero, NULL) != 0) {
+ pthread_mutex_destroy(&m_lock);
+ throw AhuException("Cannot create semaphore: cannot allocate condition");
+ }
+
+ m_count = (u_int32_t) value;
+ m_nwaiters = 0;
+ m_magic = SEM_MAGIC;
+}
+
+int Semaphore::post()
+{
+ pthread_mutex_lock(&m_lock);
+
+ m_count++;
+ if (m_nwaiters > 0) {
+ pthread_cond_signal(&m_gtzero);
+ }
+
+ pthread_mutex_unlock(&m_lock);
+
+ return 0;
+}
+
+int Semaphore::wait()
+{
+ pthread_mutex_lock(&m_lock);
+
+ while (m_count == 0) {
+ m_nwaiters++;
+ pthread_cond_wait(&m_gtzero, &m_lock);
+ m_nwaiters--;
+ }
+
+ m_count--;
+
+ pthread_mutex_unlock(&m_lock);
+
+ return 0;
+}
+
+int Semaphore::tryWait()
+{
+ int retval = 0;
+
+ pthread_mutex_lock(&m_lock);
+
+ if (m_count > 0) {
+ m_count--;
+ } else {
+ errno = EAGAIN;
+ retval = -1;
+ }
+
+ pthread_mutex_unlock(&m_lock);
+
+ return retval;
+}
+
+int Semaphore::getValue(Semaphore::sem_value_t *sval)
+{
+ pthread_mutex_lock(&m_lock);
+ *sval = m_count;
+ pthread_mutex_unlock(&m_lock);
+
+ return 0;
+}
+
+Semaphore::~Semaphore()
+{
+ // Make sure there are no waiters.
+
+ pthread_mutex_lock(&m_lock);
+ if (m_nwaiters > 0) {
+ pthread_mutex_unlock(&m_lock);
+ //errno = EBUSY;
+ //return -1;
+ }
+ pthread_mutex_unlock(&m_lock);
+
+ // Destroy it.
+
+ pthread_mutex_destroy(&m_lock);
+ pthread_cond_destroy(&m_gtzero);
+ m_magic = 0;
+
+ //return 0;
+}
+
+#else /* not DARWIN from here on */
+
+
+Semaphore::Semaphore(unsigned int value)
+{
+ m_pSemaphore=new sem_t;
+ if (sem_init(m_pSemaphore, 0, value) == -1) {
+ theL() << Logger::Error << "Cannot create semaphore: " << stringerror() << endl;
+ exit(1);
+ }
+}
+
+int Semaphore::post()
+{
+ return sem_post(m_pSemaphore);
+}
+
+int Semaphore::wait()
+{
+ return sem_wait(m_pSemaphore);
+}
+int Semaphore::tryWait()
+{
+ return sem_trywait(m_pSemaphore);
+}
+
+int Semaphore::getValue(Semaphore::sem_value_t *sval)
+{
+ return sem_getvalue(m_pSemaphore, sval);
+}
+
+Semaphore::~Semaphore()
+{
+}
+
+#endif
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+// Utility class specification.
+
+#ifndef UTILITY_HH
+#define UTILITY_HH
+
+#ifndef WIN32
+# include <arpa/inet.h>
+# include <netinet/in.h>
+# include <sys/socket.h>
+# include <sys/time.h>
+# include <sys/uio.h>
+# include <signal.h>
+# include <pthread.h>
+# include <semaphore.h>
+# include <signal.h>
+# include <errno.h>
+#else
+// Disable debug info truncation warning.
+# pragma warning ( disable: 4786 )
+# pragma warning ( disable: 4503 )
+# pragma warning ( disable: 4101 )
+
+# define WINDOWS_LEAN_AND_MEAN
+# include <windows.h>
+# include <signal.h>
+# include <map>
+
+// For scope fix.
+# define for if ( false ) {} else for
+
+# define ETIMEDOUT WSAETIMEDOUT
+# define EINPROGRESS WSAEWOULDBLOCK
+
+# define AF_INET6 -1
+
+# define VERSION "2.0rc1-WIN32"
+
+# define snprintf _snprintf
+
+// Custom bittypes.
+typedef unsigned char int8_t;
+typedef unsigned int int16_t;
+typedef unsigned long int32_t;
+typedef unsigned char u_int8_t;
+typedef unsigned int u_int16_t;
+typedef unsigned long u_int32_t;
+
+#endif // WIN32
+
+#include <semaphore.h>
+#include <string>
+
+using namespace std;
+
+
+//! A semaphore class.
+class Semaphore
+{
+private:
+ sem_t *m_pSemaphore;
+#ifdef WIN32
+ typedef int sem_value_t;
+
+ //! The semaphore.
+
+
+
+ //! Semaphore counter.
+ long m_counter;
+
+#else
+ typedef int sem_value_t;
+
+ u_int32_t m_magic;
+ pthread_mutex_t m_lock;
+ pthread_cond_t m_gtzero;
+ sem_value_t m_count;
+ u_int32_t m_nwaiters;
+#endif
+
+protected:
+public:
+ //! Default constructor.
+ Semaphore( unsigned int value = 0 );
+
+ //! Destructor.
+ ~Semaphore( void );
+
+ //! Posts to a semaphore.
+ int post( void );
+
+ //! Waits for a semaphore.
+ int wait( void );
+
+ //! Tries to wait for a semaphore.
+ int tryWait( void );
+
+ //! Retrieves the semaphore value.
+ int getValue( Semaphore::sem_value_t *sval );
+
+};
+
+
+//! This is a utility class used for platform independant abstraction.
+class Utility
+{
+#ifdef WIN32
+private:
+ static int inet_pton4( const char *src, void *dst );
+ static int inet_pton6( const char *src, void *dst );
+
+ static const char *inet_ntop4( const char *src, char *dst, size_t size );
+ static const char *inet_ntop6( const char *src, char *dst, size_t size );
+
+#endif // WIN32
+
+public:
+#ifdef WIN32
+
+ //! iovec structure for windows.
+ typedef struct
+ {
+ void *iov_base; //!< Base address.
+ size_t iov_len; //!< Number of bytes.
+ } iovec;
+
+ // A few type defines.
+ typedef DWORD pid_t;
+ typedef SOCKET sock_t;
+ typedef int socklen_t;
+
+#else
+ typedef ::iovec iovec;
+ typedef ::pid_t pid_t;
+ typedef int sock_t;
+ typedef ::socklen_t socklen_t;
+
+#endif // WIN32
+
+ //! Closes a socket.
+ static int closesocket( sock_t socket );
+
+ //! Returns the process id of the current process.
+ static pid_t getpid( void );
+
+ //! Gets the current time.
+ static int gettimeofday( struct timeval *tv, void *tz = NULL );
+
+ //! Converts an address from dot and numbers format to binary data.
+ static int inet_aton( const char *cp, struct in_addr *inp );
+
+ //! Converts an address from presentation format to network format.
+ static int inet_pton( int af, const char *src, void *dst );
+
+ //! The inet_ntop() function converts an address from network format (usually a struct in_addr or some other binary form, in network byte order) to presentation format.
+ static const char *inet_ntop( int af, const char *src, char *dst, size_t size );
+
+ //! Retrieves a gid using a groupname.
+ static int makeGidNumeric( const string & group );
+
+ //! Retrieves an uid using an username.
+ static int makeUidNumeric( const string & username );
+
+ //! Writes a vector.
+ static int writev( Utility::sock_t socket, const iovec *vector, size_t count );
+ //! Returns a random number.
+ static long int random( void );
+
+ //! Sets the random seed.
+ static void srandom( unsigned int seed );
+
+ //! Compares two strings and ignores case.
+ static int strcasecmp( const char *s1, const char *s2 );
+
+ //! Drops the program's privileges.
+ static void dropPrivs( int uid, int gid );
+
+ //! Sets the socket into blocking mode.
+ static bool setBlocking( Utility::sock_t socket );
+
+ //! Sets the socket into non-blocking mode.
+ static bool setNonBlocking( Utility::sock_t socket );
+
+ //! Sleeps for a number of seconds.
+ static unsigned int sleep( unsigned int seconds );
+
+ //! Sleeps for a number of microseconds.
+ static void usleep( unsigned long usec );
+
+};
+
+
+#endif // UTILITY_HH
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "utility.hh"\r
+#include "webserver.hh"
+#include "session.hh"
+#include "misc.hh"
+#include <vector>
+#include "logger.hh"
+#include <stdio.h>
+#include "dns.hh"
+
+
+map<string,WebServer::HandlerFunction *>WebServer::d_functions;
+void *WebServer::d_that;
+string WebServer::d_password;
+
+char WebServer::B64Decode1(char cInChar)
+{
+ // The incoming character will be A-Z, a-z, 0-9, +, /, or =.
+ // The idea is to quickly determine which grouping the
+ // letter belongs to and return the associated value
+ // without having to search the global encoding string
+ // (the value we're looking for would be the resulting
+ // index into that string).
+ //
+ // To do that, we'll play some tricks...
+ unsigned char iIndex = '\0';
+ switch ( cInChar ) {
+ case '+':
+ iIndex = 62;
+ break;
+
+ case '/':
+ iIndex = 63;
+ break;
+
+ case '=':
+ iIndex = 0;
+ break;
+
+ default:
+ // Must be 'A'-'Z', 'a'-'z', '0'-'9', or an error...
+ //
+ // Numerically, small letters are "greater" in value than
+ // capital letters and numerals (ASCII value), and capital
+ // letters are "greater" than numerals (again, ASCII value),
+ // so we check for numerals first, then capital letters,
+ // and finally small letters.
+ iIndex = '9' - cInChar;
+ if ( iIndex > 0x3F ) {
+ // Not from '0' to '9'...
+ iIndex = 'Z' - cInChar;
+ if ( iIndex > 0x3F ) {
+ // Not from 'A' to 'Z'...
+ iIndex = 'z' - cInChar;
+ if ( iIndex > 0x3F ) {
+ // Invalid character...cannot
+ // decode!
+ iIndex = 0x80; // set the high bit
+ } // if
+ else {
+ // From 'a' to 'z'
+ iIndex = (('z' - iIndex) - 'a') + 26;
+ } // else
+ } // if
+ else {
+ // From 'A' to 'Z'
+ iIndex = ('Z' - iIndex) - 'A';
+ } // else
+ } // if
+ else {
+ // Adjust the index...
+ iIndex = (('9' - iIndex) - '0') + 52;
+ } // else
+ break;
+
+ } // switch
+
+ return iIndex;
+}
+
+int WebServer::B64Decode(const std::string& strInput, std::string& strOutput)
+{
+ // Set up a decoding buffer
+ long cBuf = 0;
+ char* pBuf = (char*)&cBuf;
+
+ // Decoding management...
+ short iBitGroup = 0, iInNum = 0;
+
+ // While there are characters to process...
+ //
+ // We'll decode characters in blocks of 4, as
+ // there are 4 groups of 6 bits in 3 bytes. The
+ // incoming Base64 character is first decoded, and
+ // then it is inserted into the decode buffer
+ // (with any relevant shifting, as required).
+ // Later, after all 3 bytes have been reconsituted,
+ // we assign them to the output string, ultimately
+ // to be returned as the original message.
+ int iInSize = strInput.size();
+ unsigned char cChar = '\0';
+ while ( iInNum < iInSize ) {
+ // Fill the decode buffer with 4 groups of 6 bits
+ cBuf = 0; // clear
+ for ( iBitGroup = 0; iBitGroup < 4; ++iBitGroup ) {
+ if ( iInNum < iInSize ) {
+ // Decode a character
+ cChar = B64Decode1(strInput.at(iInNum++));
+ } // if
+ else {
+ // Decode a padded zero
+ cChar = '\0';
+ } // else
+
+ // Check for valid decode
+ if ( cChar > 0x7F )
+ return -1;
+
+ // Adjust the bits
+ switch ( iBitGroup ) {
+ case 0:
+ // The first group is copied into
+ // the least significant 6 bits of
+ // the decode buffer...these 6 bits
+ // will eventually shift over to be
+ // the most significant bits of the
+ // third byte.
+ cBuf = cBuf | cChar;
+ break;
+
+ default:
+ // For groupings 1-3, simply shift
+ // the bits in the decode buffer over
+ // by 6 and insert the 6 from the
+ // current decode character.
+ cBuf = (cBuf << 6) | cChar;
+ break;
+
+ } // switch
+ } // for
+
+ // Interpret the resulting 3 bytes...note there
+ // may have been padding, so those padded bytes
+ // are actually ignored.
+ strOutput += pBuf[2];
+ strOutput += pBuf[1];
+ strOutput += pBuf[0];
+ } // while
+
+ return 1;
+}
+
+
+
+
+void WebServer::registerHandler(const string&s, HandlerFunction *ptr)
+{
+ d_functions[s]=ptr;
+}
+
+void WebServer::setCaller(void *that)
+{
+ d_that=that;
+}
+
+void *WebServer::serveConnection(void *p)
+{
+ Session *client=static_cast<Session *>(p);
+ try {
+ string line;
+ client->getLine(line);
+ stripLine(line);
+ // L<<"page: "<<line<<endl;
+
+ vector<string> parts;
+ stringtok(parts,line);
+
+ string uri;
+ if(parts.size()>1)
+ uri=parts[1];
+
+ vector<string>variables;
+
+ parts.clear();
+ stringtok(parts,uri,"?");
+
+ // L<<"baseUrl: '"<<parts[0]<<"'"<<endl;
+
+ vector<string>urlParts;
+ stringtok(urlParts,parts[0],"/");
+ string baseUrl;
+ if(urlParts.empty())
+ baseUrl="";
+ else
+ baseUrl=urlParts[0];
+
+ // L<<"baseUrl real: '"<<baseUrl<<"'"<<endl;
+
+ if(parts.size()>1) {
+ stringtok(variables,parts[1],"&");
+ }
+
+ map<string,string>varmap;
+
+ for(vector<string>::const_iterator i=variables.begin();
+ i!=variables.end();++i) {
+
+ parts.clear();
+ stringtok(parts,*i,"=");
+ if(parts.size()>1)
+ varmap[parts[0]]=parts[1];
+ else
+ varmap[parts[0]]="";
+
+ L<<"'"<<parts[0]<<"' = '"<<varmap[parts[0]]<<"'"<<endl;
+ }
+
+ bool authOK=0;
+
+ // read & ignore other lines
+ do {
+ client->getLine(line);
+ stripLine(line);
+
+ if(!line.find("Authorization: Basic ")) {
+ string cookie=line.substr(21);
+ string plain;
+
+ B64Decode(cookie,plain);
+ vector<string>cparts;
+ stringtok(cparts,plain,":");
+
+ if(cparts.size()==2 && !strcmp(cparts[1].c_str(),d_password.c_str())) { // this gets rid of terminating zeros
+ authOK=1;
+ }
+ }
+ }while(!line.empty());
+
+
+ if(!d_password.empty() && !authOK) {
+ client->putLine("HTTP/1.1 401 OK\n");
+ client->putLine("WWW-Authenticate: Basic realm=\"PowerDNS\"\n");
+
+ client->putLine("Connection: close\n");
+ client->putLine("Content-type: text/html\n\n");
+ client->putLine("Please enter a valid password!\n");
+ client->close();
+ delete client;
+ return 0;
+ }
+
+ HandlerFunction *fptr;
+ if((fptr=d_functions[baseUrl])) {
+
+ bool custom;
+ string ret=(*fptr)(varmap, d_that, &custom);
+
+ if(!custom) {
+ client->putLine("HTTP/1.1 200 OK\n");
+ client->putLine("Connection: close\n");
+ client->putLine("Content-type: text/html\n\n");
+ }
+ client->putLine(ret);
+ }
+ else {
+ client->putLine("HTTP/1.1 404 Not found\n");
+ client->putLine("Connection: close\n");
+ client->putLine("Content-type: text/html\n\n");
+ // FIXME: CSS problem?
+ client->putLine("<html><body><h1>Did not find file '"+baseUrl+"'</body></html>\n");
+ }
+
+ client->close();
+ delete client;
+ client=0;
+ return 0;
+
+ }
+ catch(SessionTimeoutException &e) {
+ L<<Logger::Error<<"Timeout in webserver"<<endl;
+ }
+ catch(SessionException &e) {
+ L<<Logger::Error<<"Fatal error in webserver: "<<e.reason<<endl;
+ }
+ catch(Exception &e) {
+ L<<Logger::Error<<"Exception in webserver: "<<e.reason<<endl;
+ }
+ catch(exception &e) {
+ L<<Logger::Error<<"STL Exception in webserver: "<<e.what()<<endl;
+ }
+ catch(...) {
+ L<<Logger::Error<<"Unknown exception in webserver"<<endl;
+ }
+ if(client) {
+ client->close();
+ delete client;
+ client=0;
+ }
+ return 0;
+}
+
+WebServer::WebServer(const string &listenaddress, int port, const string &password)
+{
+ d_listenaddress=listenaddress;
+ d_port=port;
+ d_password=password;
+}
+
+void WebServer::go()
+{
+ try {
+ Server *s=new Server(d_port, d_listenaddress);
+
+ Session *client;
+ pthread_t tid;
+
+ L<<Logger::Error<<"Launched webserver on "<<d_listenaddress<<":"<<d_port<<endl;
+
+ while((client=s->accept())) {
+ pthread_create(&tid, 0 , &serveConnection, (void *)client);
+ }
+ }
+ catch(SessionTimeoutException &e) {
+ L<<Logger::Error<<"Timeout in webserver"<<endl;
+ }
+ catch(SessionException &e) {
+ L<<Logger::Error<<"Fatal error in webserver: "<<e.reason<<endl;
+ }
+ catch(Exception &e) {
+ L<<Logger::Error<<"Fatal error in main webserver thread: "<<e.reason<<endl;
+ }
+ catch(exception &e) {
+ L<<Logger::Error<<"STL Exception in main webserver thread: "<<e.what()<<endl;
+ }
+ catch(...) {
+ L<<Logger::Error<<"Unknown exception in main webserver thread"<<endl;
+ }
+ exit(1);
+
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef WEBSERVER_HH
+#define WEBSERVER_HH
+#include <map>
+#include <string>
+
+
+using namespace std;
+
+class WebServer
+{
+public:
+ WebServer(const string &listenaddress, int port, const string &password="");
+ void go();
+ static void* serveConnection(void *);
+ void setCaller(void *that);
+ typedef string HandlerFunction(const map<string,string>&varmap, void *that, bool *custom);
+ void registerHandler(const string &, HandlerFunction *ptr);
+private:
+ static char B64Decode1(char cInChar);
+ static int B64Decode(const std::string& strInput, std::string& strOutput);
+ string d_listenaddress;
+ int d_port;
+ static map<string,HandlerFunction *>d_functions;
+ static void *d_that;
+ static string d_password;
+};
+#endif /* WEBSERVER_HH */
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/#include "utility.hh"\r
+#include "ws.hh"
+#include "webserver.hh"
+#include "logger.hh"
+#include "statbag.hh"
+#include "misc.hh"
+#include "arguments.hh"
+#include "dns.hh"
+
+extern StatBag S;
+
+StatWebServer::StatWebServer()
+{
+ d_start=time(0);
+ d_min10=d_min5=d_min1=0;
+}
+
+void StatWebServer::go()
+{
+ S.doRings();
+ pthread_create(&d_tid, 0, threadHelper, this);
+ pthread_create(&d_tid, 0, statThreadHelper, this);
+}
+
+
+
+void StatWebServer::statThread()
+{
+ try {
+ for(;;) {
+ d_queries.submit(S.read("udp-queries"));
+ d_cachehits.submit(S.read("packetcache-hit"));
+ d_cachemisses.submit(S.read("packetcache-miss"));
+ d_qcachehits.submit(S.read("query-cache-hit"));
+ d_qcachemisses.submit(S.read("query-cache-miss"));
+ Utility::sleep(1);
+ }
+ }
+ catch(...) {
+ L<<Logger::Error<<"Webserver statThread caught an exception, dying"<<endl;
+ exit(1);
+ }
+}
+
+void *StatWebServer::statThreadHelper(void *p)
+{
+ StatWebServer *sws=static_cast<StatWebServer *>(p);
+ sws->statThread();
+ return 0; // never reached
+}
+
+
+void *StatWebServer::threadHelper(void *p)
+{
+ StatWebServer *sws=static_cast<StatWebServer *>(p);
+ sws->launch();
+ return 0; // never reached
+}
+
+void printtable(ostringstream &ret, const string &ringname, const string &title, int limit=10)
+{
+ int tot=0;
+ int entries=0;
+ vector<pair <string,int> >ring=S.getRing(ringname);
+
+ for(vector<pair<string,int> >::const_iterator i=ring.begin(); i!=ring.end();++i) {
+ tot+=i->second;
+ entries++;
+ }
+
+
+ ret<<"<table border=1><tr><td colspan=3 bgcolor=#0000ff>"
+ "<a href=?ring="<<ringname<<"><font color=#ffffff>Top-"<<limit<<" of ";
+ ret<<entries<<": "<<title<<"</a></td>"<<endl;
+
+ ret<<"<tr><td colspan=3><table bgcolor=#ff0000 width=100%><tr><td align=left>"
+ "<a href=?resetring="<<ringname<<"><font color=#ffffff>Reset</a></td>";
+ ret<<"<td align=right>Resize: ";
+
+ int sizes[]={10,100,500,1000,10000,500000,0};
+ for(int i=0;sizes[i];++i) {
+ if(S.getRingSize(ringname)!=sizes[i])
+ ret<<"<a href=?resizering="<<ringname<<"&size="<<sizes[i]<<">"<<sizes[i]<<"</a> ";
+ else
+ ret<<"("<<sizes[i]<<") ";
+ }
+ ret<<"</td></table>"<<endl;
+
+
+ int printed=0;
+ for(vector<pair<string,int> >::const_iterator i=ring.begin();limit && i!=ring.end();++i,--limit) {
+ ret<<"<tr><td>"<<i->first<<"</td><td>"<<i->second<<"</td><td align=right>"<<setprecision(2)<<i->second*100.0/tot<<"%</td>"<<endl;
+ printed+=i->second;
+ }
+ ret<<"<tr><td colspan=3></td></tr>"<<endl;
+ if(printed!=tot)
+ ret<<"<tr><td><b>Rest:</b></td><td><b>"<<tot-printed<<"</b></td><td align=right><b>"<<setprecision(2)<<(tot-printed)*100.0/tot<<"%</b></td>"<<endl;
+
+ ret<<"<tr><td><b>Total:</b></td><td><b>"<<tot<<"</td><td align=right><b>100%</b></td>";
+ ret<<"</table><p>"<<endl;
+}
+
+void StatWebServer::printvars(ostringstream &ret)
+{
+ ret<<"<table border=1><tr><td colspan=3 bgcolor=#0000ff><font color=#ffffff>Variables</td>"<<endl;
+
+
+ vector<string>entries=S.getEntries();
+ for(vector<string>::const_iterator i=entries.begin();i!=entries.end();++i) {
+ ret<<"<tr><td>"<<*i<<"</td><td>"<<S.read(*i)<<"</td><td>"<<S.getDescrip(*i)<<"</td>"<<endl;
+ }
+}
+
+void StatWebServer::printargs(ostringstream &ret)
+{
+ ret<<"<table border=1><tr><td colspan=3 bgcolor=#0000ff><font color=#ffffff>Arguments</td>"<<endl;
+
+ vector<string>entries=arg().list();
+ for(vector<string>::const_iterator i=entries.begin();i!=entries.end();++i) {
+ ret<<"<tr><td>"<<*i<<"</td><td>"<<arg()[*i]<<"</td><td>"<<arg().getHelp(*i)<<"</td>"<<endl;
+ }
+}
+
+
+string StatWebServer::indexfunction(const map<string,string> &varmap, void *ptr, bool *custom)
+{
+
+ StatWebServer *sws=static_cast<StatWebServer *>(ptr);
+ map<string,string>rvarmap=varmap;
+ if(!rvarmap["resetring"].empty()){
+ *custom=true;
+ S.resetRing(rvarmap["resetring"]);
+ return "HTTP/1.1 301 Moved Permanently\nLocation: /\nConnection: close\n\n";
+ }
+ if(!rvarmap["resizering"].empty()){
+ *custom=true;
+ S.resizeRing(rvarmap["resizering"], atoi(rvarmap["size"].c_str()));
+ return "HTTP/1.1 301 Moved Permanently\nLocation: /\nConnection: close\n\n";
+ }
+
+ ostringstream ret;
+
+ ret<<"<html><head><title>PowerDNS Operational Monitor</title></head><body bgcolor=#ffffff>"<<endl;
+
+
+ if(rvarmap["ring"].empty())
+ ret<<"<h2>PDNS "VERSION" Main Page</h2>"<<endl;
+ else
+ ret<<"<h2>Details page</h2><a href=/>Back to main page</a><p>"<<endl;
+
+ time_t passed=time(0)-s_starttime;
+
+ ret<<"Uptime: ";
+ ret<<humanDuration(passed)<<endl;
+
+
+ ret<<"Queries/second, 1, 5, 10 minute averages: "<<setprecision(3)<<
+ sws->d_queries.get1()<<", "<<
+ sws->d_queries.get5()<<", "<<
+ sws->d_queries.get10()<<". Max queries/second: "<<sws->d_queries.getMax()<<
+ "<br>"<<endl;
+
+ if(sws->d_cachemisses.get10()+sws->d_cachehits.get10()>0)
+ ret<<"Cache hitrate, 1, 5, 10 minute averages: "<<setprecision(2)<<
+ (sws->d_cachehits.get1()*100.0)/((sws->d_cachehits.get1())+(sws->d_cachemisses.get1()))<<"%, "<<
+ (sws->d_cachehits.get5()*100.0)/((sws->d_cachehits.get5())+(sws->d_cachemisses.get5()))<<"%, "<<
+ (sws->d_cachehits.get10()*100.0)/((sws->d_cachehits.get10())+(sws->d_cachemisses.get10()))<<
+ "%<br>"<<endl;
+
+ if(sws->d_qcachemisses.get10()+sws->d_qcachehits.get10()>0)
+ ret<<"Backend query cache hitrate, 1, 5, 10 minute averages: "<<setprecision(2)<<
+ (sws->d_qcachehits.get1()*100.0)/((sws->d_qcachehits.get1())+(sws->d_qcachemisses.get1()))<<"%, "<<
+ (sws->d_qcachehits.get5()*100.0)/((sws->d_qcachehits.get5())+(sws->d_qcachemisses.get5()))<<"%, "<<
+ (sws->d_qcachehits.get10()*100.0)/((sws->d_qcachehits.get10())+(sws->d_qcachemisses.get10()))<<
+ "%<br>"<<endl;
+
+ ret<<"Backend query load, 1, 5, 10 minute averages: "<<setprecision(3)<<
+ sws->d_qcachemisses.get1()<<", "<<
+ sws->d_qcachemisses.get5()<<", "<<
+ sws->d_qcachemisses.get10()<<". Max queries/second: "<<sws->d_qcachemisses.getMax()<<
+ "<br>"<<endl;
+
+ ret<<"Total queries: "<<S.read("udp-queries")<<". Question/answer latency: "<<S.read("latency")/1000.0<<"ms<p>"<<endl;
+ if(rvarmap["ring"].empty()) {
+ vector<string>entries=S.listRings();
+ for(vector<string>::const_iterator i=entries.begin();i!=entries.end();++i)
+ printtable(ret,*i,S.getRingTitle(*i));
+
+ sws->printvars(ret);
+ if(arg().mustDo("webserver-print-arguments"))
+ sws->printargs(ret);
+ }
+ else
+ printtable(ret,rvarmap["ring"],S.getRingTitle(rvarmap["ring"]),100);
+
+ ret<<"</body></html>"<<endl;
+
+ return ret.str();
+}
+
+void StatWebServer::launch()
+{
+ try {
+ WebServer ws(arg()["webserver-address"], arg().asNum("webserver-port"),arg()["webserver-password"]);
+ ws.setCaller(this);
+ ws.registerHandler("",&indexfunction);
+ ws.go();
+ }
+ catch(...) {
+ L<<Logger::Error<<"StatWebserver thread caught an exception, dying"<<endl;
+ exit(1);
+ }
+}
--- /dev/null
+/*
+ PowerDNS Versatile Database Driven Nameserver
+ Copyright (C) 2002 PowerDNS.COM BV
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef WS_HH
+#define WS_HH
+#include <string>
+#include <map>
+#include <time.h>
+#include <pthread.h>
+#include <sstream>
+#include <iomanip>\r
+\r
+#ifndef WIN32\r
+# include <unistd.h>\r
+#endif // WIN32\r
+\r
+#ifdef HAVE_CONFIG_H\r
+# include <config.h>\r
+#endif // HAVE_CONFIG_H\r
+
+#include "misc.hh"
+using namespace std;
+
+class Ewma
+{
+public:
+ Ewma() : d_last(0), d_10(0), d_5(0), d_1(0), d_max(0){dt.set();}
+ void submit(int val)
+ {
+ int rate=val-d_last;
+ double difft=dt.udiff()/1000000.0;
+ dt.set();
+
+ d_10=((600.0-difft)*d_10+(difft*rate))/600.0;
+ d_5=((300.0-difft)*d_5+(difft*rate))/300.0;
+ d_1=((60.0-difft)*d_1+(difft*rate))/60.0;
+ d_max=max(d_1,d_max);
+
+ d_last=val;
+ }
+ double get10()
+ {
+ return d_10;
+ }
+ double get5()
+ {
+ return d_5;
+ }
+ double get1()
+ {
+ return d_1;
+ }
+ double getMax()
+ {
+ return d_max;
+ }
+private:
+ DTime dt;
+ int d_last;
+ double d_10, d_5, d_1, d_max;
+};
+
+
+class StatWebServer
+{
+public:
+ StatWebServer();
+ void go();
+private:
+ static void *threadHelper(void *);
+ static void *statThreadHelper(void *p);
+ static string indexfunction(const map<string,string> &varmap, void *ptr, bool *custom);
+ void printvars(ostringstream &ret);
+ void printargs(ostringstream &ret);
+ void launch();
+ void statThread();
+ pthread_t d_tid;
+
+ time_t d_start;
+ double d_min10, d_min5, d_min1;
+ Ewma d_queries, d_cachehits, d_cachemisses;
+ Ewma d_qcachehits, d_qcachemisses;
+};
+
+#endif
--- /dev/null
+#! /bin/sh
+# ylwrap - wrapper for lex/yacc invocations.
+# Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Usage:
+# ylwrap INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
+# * INPUT is the input file
+# * OUTPUT is file PROG generates
+# * DESIRED is file we actually want
+# * PROGRAM is program to run
+# * ARGS are passed to PROG
+# Any number of OUTPUT,DESIRED pairs may be used.
+
+# The input.
+input="$1"
+shift
+case "$input" in
+ [\\/]* | ?:[\\/]*)
+ # Absolute path; do nothing.
+ ;;
+ *)
+ # Relative path. Make it absolute.
+ input="`pwd`/$input"
+ ;;
+esac
+
+# The directory holding the input.
+input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'`
+# Quote $INPUT_DIR so we can use it in a regexp.
+# FIXME: really we should care about more than `.' and `\'.
+input_rx=`echo "$input_dir" | sed -e 's,\\\\,\\\\\\\\,g' -e 's,\\.,\\\\.,g'`
+
+echo "got $input_rx"
+
+pairlist=
+while test "$#" -ne 0; do
+ if test "$1" = "--"; then
+ shift
+ break
+ fi
+ pairlist="$pairlist $1"
+ shift
+done
+
+# The program to run.
+prog="$1"
+shift
+# Make any relative path in $prog absolute.
+case "$prog" in
+ [\\/]* | ?:[\\/]*) ;;
+ *[\\/]*) prog="`pwd`/$prog" ;;
+esac
+
+# FIXME: add hostname here for parallel makes that run commands on
+# other machines. But that might take us over the 14-char limit.
+dirname=ylwrap$$
+trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15
+mkdir $dirname || exit 1
+
+cd $dirname
+
+$prog ${1+"$@"} "$input"
+status=$?
+
+if test $status -eq 0; then
+ set X $pairlist
+ shift
+ first=yes
+ # Since DOS filename conventions don't allow two dots,
+ # the DOS version of Bison writes out y_tab.c instead of y.tab.c
+ # and y_tab.h instead of y.tab.h. Test to see if this is the case.
+ y_tab_nodot="no"
+ if test -f y_tab.c || test -f y_tab.h; then
+ y_tab_nodot="yes"
+ fi
+
+ while test "$#" -ne 0; do
+ from="$1"
+ # Handle y_tab.c and y_tab.h output by DOS
+ if test $y_tab_nodot = "yes"; then
+ if test $from = "y.tab.c"; then
+ from="y_tab.c"
+ else
+ if test $from = "y.tab.h"; then
+ from="y_tab.h"
+ fi
+ fi
+ fi
+ if test -f "$from"; then
+ # If $2 is an absolute path name, then just use that,
+ # otherwise prepend `../'.
+ case "$2" in
+ [\\/]* | ?:[\\/]*) target="$2";;
+ *) target="../$2";;
+ esac
+
+ # Edit out `#line' or `#' directives. We don't want the
+ # resulting debug information to point at an absolute srcdir;
+ # it is better for it to just mention the .y file with no
+ # path.
+ sed -e "/^#/ s,$input_rx,," "$from" > "$target" || status=$?
+ else
+ # A missing file is only an error for the first file. This
+ # is a blatant hack to let us support using "yacc -d". If -d
+ # is not specified, we don't want an error when the header
+ # file is "missing".
+ if test $first = yes; then
+ status=1
+ fi
+ fi
+ shift
+ shift
+ first=no
+ done
+else
+ status=$?
+fi
+
+# Remove the directory.
+cd ..
+rm -rf $dirname
+
+exit $status