diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..d3dc39b --- /dev/null +++ b/AUTHORS @@ -0,0 +1,44 @@ +AUTHORS OF SIEGE +---------------- + +Jeffrey Fulmer +Designed and implemented Siege in his position as +Webmaster for Armstrong World Industries; he is the +primary author and maintainer of the application. +http://www.joedog.org/ + + + +Major contributors: +------------------- +Albert Chin-A-Young +Submitted several patches which contributed to the +portability of the application. thewrittenword.com +redistributes siege for several platforms in binary +form. + +Peter J. Hutnick: +Designed and authored bombardment and siege2csv.pl, +auxiliary tools distributed with siege. He is the +webmaster of joedog.org, the primary source of siege +information. + +Kai S. Juse +Incorporated the programmatic logic to handle cookie +exprirations, re-architected the client thread entry +functions and submitted bug fixes and insight. + +Oliver Teuber +Made numerous feature contributions and bug fixes. + +Larry D. Weiner +Wrote most of the code to support the HTTP POST +method and keep-alive directives. + + + +---------------------------------------------------- +Other contributions are attributed in the ChangeLog. + + + diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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. + + 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.) + +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. + + 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. + + 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 + + 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. + + + Copyright (C) + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. + + , 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 Lesser General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..20ee6ac --- /dev/null +++ b/ChangeLog @@ -0,0 +1,189 @@ +To email a contributor remove "DELETE" from the email address. +(The DELETEs are necessary as this list is published online.) + +2014/09/05 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-8_SEP_05-2014 + * src/http.c Added :port to the host header on condition + * src/log.c Added logfile location to error messages + * src/version.c Version increment: 3.0.8 + +2014/08/20 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-7_AUG_20-2014 + * src/url.c Handle localhost from a Location header + * src/version.c Version increment: 3.0.7 + +2014/07/18 Jeffrey Fulmer + * src/ssl.c SSL_initialise return TRUE if C->ssl not null + +2014/01/08 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-6_JAN_08-2014 + * doc/siegerc.in Updated to include proxy directives + +2013/10/31 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-6-beta2_OCT-31-2013 + * src/client.c Added support for HTTP-303 + * src/version.c Version increment: 3.0.6-beta2 + +2013/10/27 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-6-beta1_OCT-27-2013 + * src/main.c Added new logic for --reps=once + * src/client.c Moved __normalize to url.c; Change logic for -r once + * src/url.c Added url_normalize(URL U, location); + * src/version.c Version increment: 3.0.6-beta1 + +2013/10/17 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-5_OCT-17-2013 + * src/version.c Version increment: 3.0.5 + +2013/10/15 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-5-beta3_OCT-15-2013 + * src/url.c trim'd path and file so they have no extra space + * src/url.c Assigned my.conttype to this->conntype if it's defined + * src/http.c free'd the request in post, made protocol and keepalive static + * src/version.c Version increment: 3.0.5-beta3 + +2013/09/18 Guillaume Quintard + * SIEGE RELEASE RELEASE_3-0-5-beta2_OCT-13-2013 + * utils/bombardment.in Fixed logic; made behavior consistent with docs + * src/version.c Version increment: 3.0.5-beta2 + +2013/09/18 Jeffrey Fulmer + * src/http.c Removed port from host in the Host header + * src/version.c Version increment: 3.0.5-beta1 + +2013/09/17 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-4_SEP-17-2013 + * src/version.c Version increment: 3.0.4 + +2013/09/11 Jeffrey Fulmer + * SIEGE BETA RELEASE_3-0-4-beta1_SEP-11-2013 + * configure.ac Added PLATFORM to joepath.h to build user-agent + * src/init.d Changed default user-agent to comply with RFC2616 + * src/client.c Added __normalize(URL U, char *location); + * src/version.c Version increment: 3.0.4-beta1 + +2013/08/01 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-3_AUG-18-2013 + * ChangeLog Truncated to 3.x.x entries + * src/version.c Version increment: 3.0.3 + * siege/* Updated FSF address information + +2013/07/29 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-3-beta3_JUL-30-2013 + * src/init.c trimmed the line coming from read function + * src/version.c Version increment: 3.0.3-beta3 + +2013/07/22 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-3-beta2_JUL-23-2013 + * src/http.c Made Accept-Encoding dynamic; and + if my.get is true, use HTTP/1.0 + * siegerc.in Added url-escaping to turn on/off + * src/setup.h Added my.escape turn escaping on/off + * src/init.c Parse for url-escaping true | false + * src/url.c Added url escaping for get requests + * src/version.c Version increment: 3.0.3-beta2 + +2013/07/20 Jeffrey Fulmer + * SIEGE BETA RELEASE_3-0-3-beta1_JUL-20-2013 + +2013/07/20 Evgeny Stepanischev + * src/cfg.c Improved is_variable_line(char *line) + * src/version.c Version increment: 3.0.3-beta1 + +2013/07/19 Jeffrey Fulmer + * src/url.h Added NAUGHT to METHOD enum + +2013/07/18 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-2_JUL-18-2013 + * src/url.c Added encoding methods from wget + * src/http.c Used url_get_request instead of piecing it + * src/version.c Version increment: 3.0.2 + +2013/06/30 Jamie Couture + * SIEGE BETA RELEASE_3-0-2-beta2_JUN-30-2013 + * doc/Makefile.am Ensure the existence of $(sysconfdir); + * src/http.c Corrected bounds checking on line 352 + * src/url.c Added char * url_get_display(URL this); + * src/url.h Added char * url_get_display(URL this); + * src/client.c Changed display to use url_get_display + * src/version.c Version increment: beta2 + +2013/05/28 Jeffrey Fulmer + * SIEGE BETA RELEASE_3-0-2-beta1_MAY-28-2013 + * src/autoconf.ac Added type checks for int types + * src/hash.c Conditionally added #include + * src/version.c Version incrment: beta1 + +2013/05/14 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-1_MAY-14-2013 + +2013/05/08 Michael Hudson-Doyle + * SIEGE BETA RELEASE_3-0-1-beta4_MAY-08-2013 + * doc/siegerc.in Added documentation for cookies + * src/cookies.c Code format change by JDF + * src/version.c Version increment: beta4 + +2013/05/06 Michael Hudson-Doyle + * SIEGE BETA RELEASE_3-0-1-beta3_MAY-06-2013 + * src/sock.c Fixed called to gethostbyname_r + * src/version.c Version increment: beta3 + +2013/04/18 Jeffrey Fulmer + * SIEGE BETA RELEASE_3-0-1-beta2_APR-18-2013 + * src/version.c Version increment: beta2 + * utils/config.guess Updated + * utils/config.sub Updated + +2013/04/16 Jeffrey Fulmer + * SIEGE BETA RELEASE_3-0-1-beta1_APR-16-2013 + * src/http.c request buffer is dynmaic in _get and _post + * src/version.c Version increment: beta1 + +2013/04/16 Mike Jones + * src/client.c Iteration loop changed so that each client + starts at a different spot in the file + +2013/04/05 Jeffrey Fulmer + * SIEGE RELEASE RELEASE_3-0-0_APR-05-2013 + +2013/03/24 Jeffrey Fulmer + * SIEGE BETA RELEASE_3-0-0-beta3_MAR-24-2013 + * configure.ac Added -Wunused-value + * src/eval.c Uses new hash API + * src/hash.c Replaced homegrown algorithm with FNV + * src/init.c Uses new hash API + * src/main.c Cleaned up remnants from 2.xx architecture + * src/version.c Version increment: beta3 + * doc/siegerc.in Added documentation for ftp-unique + * lib/util.c Removed deference * in for loops; + recalculated len if end is longer + than the parameter string. + + +2013/03/20 Jeffrey Fulmer + * SIEGE BETA RELEASE_3-0-0-beta2_MAR-21-2013 + * src/ftp.c Reworked __response to accomode server messages + * src/main.c Added condition for PUT in usecase --get + * src/http.c Null'd some memsets rather than zero'ing them + * src/url.c Added logic to add a / if the url is simply a host + +2013/03/18 Jeffrey Fulmer + * src/ftp.c xfree'd file (D'oh!) + * src/client.c xfree'd D on failure TODO: Free in socket_close? + * src/version.c Version increment: beta2 + +2013/03/17 Jeffrey Fulmer + * SIEGE BETA RELEASE_3-0-0-beta1_MAR-19-2013 + * src/auth.c Completely reworked as an object + * src/auth.h Completely reworked as an object + * src/cookie.c Updated with new API calls + * src/creds.c Added to the distribution + * src/creds.h Added to the distribution + * src/ftp.c Added to the distribution + * src/ftp.h Added to the distribution + * src/http.c Updated with new API calls + * src/setup.h Added values for FTP + * src/sock.c Updated with new API calls + * src/url.c Completely reworked as an object + * src/url.h Completely reworked as an object + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..e26ca44 --- /dev/null +++ b/INSTALL @@ -0,0 +1,208 @@ + + INSTALLATION PROCEDURE & PLATFORM INFORMATION + + +Siege was originally built and tested on GNU/Linux. It has been ported +to other platforms. See the MACHINES document for more details. + +This program was built using the GNU autoconf mechanism. If you are +familiar with GNU applications, then siege should present few problems +especially on the above mentioned platforms. For best results, use gcc. + +IMPORTANT: If you are upgrading from an earlier version, you MUST delete +the older version before installing this one. The simplest way to remove +the older version to run "make uninstall" in the old source directory. +If you no longer have the old source, you can configure the new version +to be installed in the same place as the old version. Then BEFORE you +run "make install", run "make uninstall" first. + +"Hey! I'm impatient, I only read these things when things go wrong!" +If that is the case, then follow the steps in item #1 below... + +1. In a nutshell, to install the application in the default directory, + ( /usr/local ), run the following commands: + $ ./configure (IMPORTANT: see step 2 for enabling https support) + $ make + $ make uninstall (if you have an older version installed in PREFIX) + $ make install + + This will install the application ( siege ) in the default directory + /usr/local/bin. If that directory is in your PATH, then to run siege + and view the online help type: + $ siege --help + + To learn more about siege, make sure /usr/local/man is in your MANPATH + and type: + $ man siege + + For more detailed information about running siege and stress testing + HTTP servers, type: + $ man layingsiege + + For more details, read on. Especially if you want to install siege + in a directory other that /usr/local/bin + +2. Configuration + The configure script attempts to guess the values which are set + on your platform. If all goes well, you should only have to run it + with some preferred arguments. The more notable ones are listed + below: + --help prints the configure script's help section + --prefix=/some/dir installs the files in /some/dir + --bindir=/some/bin installs the executable in /some/bin + --mandir=/some/man installs the man page in /some/man + --with-ssl=/some/dir where dir is where you installed ssl, this + flag is used to enable https protocol. + + + Since siege is a pretty esoteric program, I prefer to install it in my + home directory. Really, how many people are laying siege to http servers + and do you really want them running it by accident? For this reason, I + run configure with my home directory as the prefix. + + $ ./configure --prefix=/export/home/jdfulmer + + If you don't already, make sure $HOME/bin and $HOME/man are set appropriately + in your .profile. In my case, I set them like this: + + # jdfulmer's profile + PATH=/export/home/jdfulmer/bin:$PATH + MANPATH=/export/home/jdfulmer/man:$MANPATH + + export PATH MANPATH + ~ + ~ + + To reload your profile without logging out, do this: + + $ . .profile + + If it runs successfully, the configure script creates the Makefiles which + lets you build the program. After you configure your environment, the next + step is to build siege. If that next step fails, you may have to return to + this step. Reasons for reconfiguring are mentioned below. If configure + failed to create Makefiles, then you have problems which may be beyond the + scope of this document, such as no compiler ( you'll have to get one ), no + libraries ( again, an acquisition on your part ). + + HTTPS support + To enable https, you must have ssl installed on your system. Get the latest + version from http://www.openssl.org. AFTER ssl is installed, then you have + to configure siege to use it: + $ ./configure --prefix=/some/dir --with-ssl=/ssl/install/dir + + The openssl default installation is /usr/local/ssl. So if you configured + openssl with the default directory, then you would configure siege like this: + $ ./configure --prefix=/some/dir --with-ssl=/usr/local/ssl + $ make + $ make uninstall ( if you have a previous version already installed ) + $ make install + +3. Compilation + To compile the program, execute the second step of the nutshell version + mentioned in item #1: type "make" and hope for the best. If your environment + was configured without errors, then configure should have generated the Makefiles + that will enable this step to work. + + The make command will invoke your compiler and build siege. If you are using + gcc on any of the platforms mentioned above, then you should not have problems. + In general, any ANSI C compiler should work. Siege does not currently support + K&R compilers and older versions of the operating systems mentioned in MACHINES. + + Some systems may require options that were not set by the configure script. You + can set them using the configure step mentioned above: + $ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + + You can also set them by editing the Makefiles that were created as a result of + running configure, but this is not preferred. + +4. Installation + If the program compiled successfully, follow the third nutshell step + and type "make install" This will install the package in the directories + that you've selected in the configuration step. If they are not already, + make sure PREFIX/bin and PREFIX/man are in your PATH and MANPATH + respectively. This process is described in detail in item #2. + + Files installed: + siege --> SIEGE_HOME/bin/siege + bombardment --> SIEGE_HOME/bin/bombardment + siege2csv --> SIEGE_HOME/bin/siege2csv + .siegerc --> $HOME/.siegerc + siege.1 --> SIEGE_HOME/man/man1/siege.1 + bombardment.1 --> SIEGE_HOME/man/man1/bombardment.1 + siege2csv.1 --> SIEGE_HOME/man/man1/siege2csv.1 + layingsiege.1 --> SIEGE_HOME/man/man1/layingsiege.1 + urls_text.1 --> SIEGE_HOME/man/man1/urls_txt.1 + urls.txt --> SIEGE_HOME/etc/urls.txt + +5. Uninstall + To remove the package, type "make uninstall" To make the source + directory completely clean, type "make distclean". There are differences + of opinion regarding this option. Some people claim that it should not + be available as it depends the original Makefiles from the source + directory. Since I tend to hoard all source code, I like this feature. + + The point is, if you've installed one version of siege in /usr/local and + another version in $HOME, then make uninstall is obviously not going to + work in both locations. The safest thing to do is manually remove the + files which were installed by make install. The files and their locations + are described in item #4. + +6. Read the documentation + The online help is pretty straight forward ( siege --help ): + Usage: siege [options] + Options: + -V, --version VERSION, prints version number to screen. + -h, --help HELP, prints this section. + -v, --verbose VERBOSE, prints notification to screen. + -c, --concurrent=NUM CONCURRENT users, default is 10 + -u, --url="URL" URL, a single user defined URL for stress testing. + -i, --internet INTERNET user simulation, hits the URLs randomly. + -b, --benchmark BENCHMARK, signifies no delay for time testing. + -t, --times=NUM TIMES, number of times to run the test, default is 25 + -t, --time=NUMm TIME based testing where "m" is the modifier S, M, or H + no space between NUM and "m", ex: --time=1H, 1 hour test. + -f, --file=FILE FILE, change the configuration file to file. + -l, --log LOG, logs the transaction to PREFIX/var/siege.log + -m, --mark="text" MARK, mark the log file with a string separator. + -d, --delay=NUM Time DELAY, random delay between 1 and num designed + to simulate human activity. Default value is 3 + + For more detailed information, consult the man pages: + $ man siege + $ man layingsiege + $ man siege.config + + All the siege man pages are also available online: + http://www.joedog.org/siege/docs/man/index.html + + OR, read the html manual, doc/manual.html The manual is also available online: + http://www.joedog.org/siege/docs/manual.html + +7. Edit the .siegerc file in your home directory. This file contains runtime + directives for siege. Each directive is well documented with comments. Some + directives exist ONLY in this file; they don't have a command line option. + If you are upgrading from an earlier version, your original version is kept + and a new resource file is installed as .siegerc.new. In order to take + advantage of any new directives, you might want to use this new file instead. + +8. Tell me about it + If you like/dislike siege please let me know. See name and email below: + +-- + +Please consult the file, COPYING for complete license information. + +Copyright (C)2000-2007 Jeffrey Fulmer , et al. + +Permission is granted to anyone to make or distribute verbatim +copies of this document as received, in any medium, provided that +the copyright notice and this permission notice are preserved, thus +giving the recipient permission to redistribute in turn. + +Permission is granted to distribute modified versions of this +document, or of portions of it, under the above conditions, +provided also that they carry prominent notices stating who last +changed them. + + diff --git a/KNOWNBUGS b/KNOWNBUGS new file mode 100644 index 0000000..eabe2f3 --- /dev/null +++ b/KNOWNBUGS @@ -0,0 +1,35 @@ +------------------------------------ +KNOWN BUGS, AND OTHER SQUISHY THINGS +------------------------------------ +Updated Wed Jul 22 16:00:00 EDT 2009 +Updated Wed Jul 9 16:16:22 EDT 2003 +Updated Fri Mar 28 11:55:21 EST 2003 +Updated Thu Mar 6 11:10:32 EST 2003 +Updated Thu Nov 7 15:34:22 EST 2002 +Updated Wed Jun 26 15:04:01 EDT 2002 +Updated Tue Mar 19 15:48:16 EST 2002 +Updated Thu Feb 21 16:27:27 EST 2002 +Updated Sun Feb 3 16:34:46 EST 2002 +Created Tue Nov 27 23:23:08 EST 2001 + +*** FIXED: siege doesn't return cookies with leading . in the domain + +*** HP-UX: the connection keep-alive directive does not work well + +*** Solaris: the connection keep-alive directive does not work well + on this platform at this time; also note: on solaris you MUST + edit include/joedog/joepath.h BEFORE compiling siege. + +*** Siege returns *ALL* cookies regardless of their path; it doesn't + store path information. + +*** Siege https does not work with proxies; + +*** On AIX, the native compiler is supported. It currently doesn't + work with gcc, appears to be a linking issue. + +*** Support for clients > 1000 is limited on most platforms without + OS tweaking on the part of the end user. Start with a smaller + number (100) and work your way up.... + + diff --git a/MACHINES b/MACHINES new file mode 100644 index 0000000..3686f15 --- /dev/null +++ b/MACHINES @@ -0,0 +1,70 @@ + +-------------------------------------- +MACHINE / PLATFORM RELATED INFORMATION +-------------------------------------- + +This file contains information and known issues about the various +machines and platforms on which siege has been ported. Please send +information about any platform issues currently NOT discussed in +this file to Jeffrey Fulmer . Include your platform +information located in the PLATFORM file in this directory + +Siege 2.50+ (threaded) has been successfully compiled and installed +on the following machines: + +Apple + i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367) + +AIX( powerpc-ibm-aix4.2.1.0 ) + * Native compiler only. Siege has had little luck with gcc on AIX. + +GNU/Linux( i[56]86-pc-linux-gnu ) + * Siege was originally developed on SuSE GNU/Linux with gcc, there + are no known issues on this platform. + +HP-UX( hp-hppa2.0w-hpux11.00 ) + * Siege was built with both aCC and gcc. + +OpenBSD( i[345]86-openbsd2.5 ) + * Siege was built and tested with gcc + +Solaris( sparc-sun-solaris2.[5678]; pc-i386-solaris2.8 ) + * Siege has been built successfully using gcc. + +Windows( pc-i686-cygwin ) + * Siege was built and tested with gcc on cygwin 1.5.x + + +--- + +Earlier versions(forked) have been successfully built and installed +on the following platforms: + +AIX( powerpc-ibm-aix4.2.1.0 ) + * Siege has been built successfully using gcc and GNU make + * Siege has been built successfully using xlc version 5 + * The protocol bug on AIX 4.x has been fixed. + +GNU/Linux( i[56]86-pc-linux-gnu ) + * Siege was originally developed on SuSE GNU/Linux with gcc, there + are no known issues on this platform. + +HP-UX ( hppa2.0w-hp-hpux11.00 ) + * Siege has been built successfully using HP ANSI C compiler + * Siege has been built successfully using gcc + * There are no known issues at this time. + +Solaris( sparc-sun-solaris2.[678] ) + * Siege has been built successfully using gcc. + * The protocol bug on Solaris 2.x has been fixed. + +OpenBSD( i[345]86-openbsd2.5 ) + * Siege has been built successfully using gcc. + * Currently the compiler complains about struct descrepancies and + BSD doesn't like mktemp. These problems should be remedied soon. + +Tru64 UNIX( 4.0D, 5.0A ) + * Siege has been built and tested successfully. + +Earlier versions of siege are still available for download via FTP: +ftp://sid.joedog.org/pub/siege/ diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..f91ca1f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,37 @@ +## +## Makefile.am +## +## Copyright (C) 2000-2014 by +## Jeffrey Fulmer - , et al. +## This file is distributed as part of Siege +## +## 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., +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +## + +AUTOMAKE_OPTIONS = foreign no-dependencies + +WARN_CFLAGS = @WARN_CFLAGS@ + +AM_CFLAGS = $(WARN_CFLAGS) + +SUBDIRS = . include lib src utils doc html + +DIST_SUBDIRS = $(SUBDIRS) + +EXTRA_DIST = KNOWNBUGS MACHINES README.md README.https README.solaris \ + acspecific.m4 aclocal.m4 acinclude.m4 + +DISTCLEANFILES = libtool config.status PLATFORM + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..629a094 --- /dev/null +++ b/NEWS @@ -0,0 +1,4 @@ +NEWS AND RELEASE INFORMATION + +http://www.joedog.org/ + diff --git a/README.https b/README.https new file mode 100644 index 0000000..8a1dd09 --- /dev/null +++ b/README.https @@ -0,0 +1,63 @@ + + Siege HTTPS README + +Siege 1.10 introduced https protocol support. To enable HTTPS +you will have to download OpenSSL < http://www.openssl.org > +to enable Secure Socket Layers and install it on your system. +Please consult the OpenSSL documentation for configuration and +installation instructions. Once it is installed, you are ready to +build siege with https support. + + +----------------------------IMPORTANT---------------------------- +ATTENTION: If you already have siege installed on your system +and you want to enable https support, you will have to remove the +previous version before continuing. If you have the original +source directory, the simplest way to remove siege is: + + $ make uninstall + +If not then you will have to remove it manually. It is important +that you removed the siege binary as well as the libraries. To +remove siege: + + $ cd PREFIX/bin + +[ by default /usr/local/bin ] and remove siege: + + $ rm siege + +Next you will have to remove the libraries: + + $ cd PREFIX/lib + +[ by default /usr/local/lib ] and remove the libraries: + + $ rm libsiege* + $ rm libjoedog* + +To build siege with HTTPS protocol support consult the document +INSTALL in this directory. For the impatient: + + $ ./configure --prefix=/some/dir --with-ssl=/dir/with/ssl + $ make + $ make install + +If you've installed openssl in the default directory, then the +directory parameter is /usr/local/ssl. The configure script is +designed to scan several common installation paths if it does +not find ssl in the directory that you've indicated. + +NO SSL? +To build siege without ssl support, especially if you have ssl +installed on your system, build siege as follows: + + $ ./configure --prefix=/some/dir --with-ssl=no + $ make + $ make install + + +BUG ALERT: Several problems have been reported with the openssl +version which ships with Red Hat 9.x. We recommend you compile +your own ssl rather than use the Red Hat version. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..5025053 --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ + + Siege README + +WHAT IS IT? +----------- +Siege is an open source regression test and benchmark utility. +It can stress test a single URL with a user defined number of +simulated users, or it can read many URLs into memory and +stress them simultaneously. The program reports the total +number of hits recorded, bytes transferred, response time, +concurrency, and return status. Siege supports HTTP/1.0 and 1.1 +protocols, the GET and POST directives, cookies, transaction +logging, and basic authentication. Its features are configurable +on a per user basis. + +Most features are configurable with command line options which +also include default values to minimize the complexity of the +program's invocation. Siege allows you to stress a web server +with n number of users t number of times, where n and t are +defined by the user. It records the duration time of the test +as well as the duration of each single transaction. It reports +the number of transactions, elapsed time, bytes transferred, +response time, transaction rate, concurrency and the number of +times the server responded OK, that is status code 200. + +Siege was designed and implemented by Jeffrey Fulmer in his +position as Webmaster for Armstrong World Industries. It was +modeled in part after Lincoln Stein's torture.pl and it's data +reporting is almost identical. But torture.pl does not allow +one to stress many URLs simultaneously; out of that need siege +was born.... + +When a HTTP server is being hit by the program, it is said to be +"under siege." + + +WHY DO I NEED IT? +----------------- +Siege was written for both web developers and web systems admin- +istrators. It allows those individuals to test their programs +and their systems under duress. As a web professional, you are +responsible for the intregrity of your product, yet you have no +control over who accesses it. Traffic spikes can occur at any +moment. How do you know if you're prepared? + +Siege will allow you to place those programs under duress, to +allow you to better understand the load that they can with +stand. You'll sleep better knowing your site can withstand the +weight of 400 simultaneous transactions if your site currently +peaks at 250. + +A transaction is characterized by the server opening a socket +for the client, handling a request, serving data over the wire +and closing the socket upon completion. It is important to note +that HUMAN internet users take time to digest the data which +comes back to them. Siege users do not. In practice I've found +that 400 simultaneous siege users translates to at least five +times that amount in real internet sessions. This is why siege +allows you to set a delay ( --delay=NUM ). When set, each siege +user sleeps for a random number of seconds between 1 and NUM. +Through your server logs you should be able to get the average +amount of time spent on a page. It is recommended that you use +that number for your delay when simulating internet activity. + + +WHERE IS IT? +------------ +The latest version of siege can be obtained via anonymous FTP: +ftp://sid.joedog.org/pub/siege/siege-latest.tar.gz + +Siege is mirrored at nerf-herder: +http://nerf-herder.net/siege + +Updates and announcements are distributed via freshmeat: +http://freshmeat.net/projects/siege + + +INSTALLATION +------------ +Siege was built with GNU autoconf. If you are familiar with +GNU software, then you should be comfortable installing siege +Please consult the file INSTALL for more details. + +PREREQUISITES +------------- +To enable HTTPS support, you will need openssl installed on +your system. http://www.openssl.org. For complete installation +instructions, see section 2 of INSTALL. + + +DOCUMENTATION +------------- +Documentation is available in man pages siege(1) layingsiege(1) +An html manual is included with this distribution: manual.html + +Complete documentation for siege can be found at www.joedog.org + + +LICENSE +------- +Consult the file COPYING for complete license information. + +Copyright (C) 2000-2009 by Jeffrey Fulmer + +Permission is granted to anyone to make or distribute verbatim +copies of this document as received, in any medium, provided +that the copyright notice and this permission notice are +preserved, thus giving the recipient permission to redistribute +in turn. + +Permission is granted to distribute modified versions of this +document, or of portions of it, under the above conditions, +provided also that they carry prominent notices stating who last +changed them. + +In addition, as a special exception, the copyright holders give +permission to link the code of portions of this program with the +OpenSSL library under certain conditions as described in each +individual source file, and distribute linked combinations +including the two. + +You must obey the GNU General Public License in all respects +for all of the code used other than OpenSSL. If you modify +file(s) with this exception, you may extend this exception to +your version of the file(s), but you are not obligated to do so. +If you do not wish to do so, delete this exception statement +from your version. If you delete this exception statement from +all source files in the program, then also delete it here. + + diff --git a/README.solaris b/README.solaris new file mode 100644 index 0000000..151e1b2 --- /dev/null +++ b/README.solaris @@ -0,0 +1,7 @@ +You'll have to set your log file location in $HOME/.siegerc +Look for the "logfile = " directive in that file... + +You should check and edit include/joedog/joepath.h before you +compile siege on Solaris. Newer versions >= 9.0 seem to work +without problems, but should check your path just to be safe. + diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..864388b --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,6880 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## 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. + +# serial 48 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])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_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)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 +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +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 + +# 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'] + +# 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' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_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 MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +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 "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +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 "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# 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="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +_LT_CC_BASENAME([$compiler]) + +# 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_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--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 + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +AC_DEFUN([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +AC_DEFUN([_LT_COMPILER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +AC_DEFUN([_LT_LINKER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_LINKER_BOILERPLATE + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE([AC_LANG_PROGRAM],[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _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], +[_LT_AC_SHELL_INIT([ +# 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 </dev/null 2>&1 && unset CDPATH + +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. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + 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="$lt_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) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--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 +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + 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 + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + 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_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + 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 + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +AC_PROVIDE_IFELSE([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) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# ------------------ +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _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], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#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); */ + } + else + puts (dlerror ()); + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|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], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +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 + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + 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" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl 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 + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + 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_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && 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 + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = 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 +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != 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 "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = 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 +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[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 +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +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" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + 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.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + 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}${shared_ext}$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}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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" + # 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 + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $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 + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + 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}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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 + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # 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' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU 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}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + 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 + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + 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" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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}${shared_ext}$versuffix ${libname}${shared_ext}$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.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=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 + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +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_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 DLLs +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# 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], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [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. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# 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_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# 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], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [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. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# 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_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# 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], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [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. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# 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_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# 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_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +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_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +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 + IFS="$lt_save_ifs" + 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 <&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="$lt_save_ifs" + MAGIC_CMD="$lt_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_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$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_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--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([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])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 $CC]) + 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. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname 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 + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + 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 variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /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|DragonFly)/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_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + 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_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + 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 + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + 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 + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_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 + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + 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 + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_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* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# 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 +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY 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_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# 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 +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY 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 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, lt_dlinit, + [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" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + +# _LT_AC_PROG_CXXCPP +# ------------------ +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# ------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF + +# Report which library types will actually be built +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* | aix5*) + 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]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + 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 + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + 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. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=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 + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-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 does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=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. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + ;; + *) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $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 + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $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' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $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' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | 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, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# 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=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# 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=$lt_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_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# 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_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# 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_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +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_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_[]_LT_AC_TAGVAR(predep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_[]_LT_AC_TAGVAR(postdep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# 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_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# 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_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_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=$_LT_AC_TAGVAR(hardcode_action, $1) + +# 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_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# 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=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# 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="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# 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_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# 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 + + # 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" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +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. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# 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 from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# 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 an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_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 + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_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. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # 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 < $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 grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + 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 +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + 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_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # 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_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + 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_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + 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_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + 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_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_cv_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$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 + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp 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'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_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= + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) + 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 + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&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 + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$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)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II 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't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&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 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$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. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=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 + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + 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. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=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 + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-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 does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=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. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$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)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + 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. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$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. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=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*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$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' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$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 + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$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' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$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 + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$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 + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$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' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$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' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$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 ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$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' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=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. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) 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]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #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 +# 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 */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# 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]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +]) +## ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- +## Copyright (C) 1999-2000 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. + +# serial 7 AC_LIB_LTDL + +# AC_WITH_LTDL +# ------------ +# Clients of libltdl can use this macro to allow the installer to +# choose between a shipped copy of the ltdl sources or a preinstalled +# version of the library. +AC_DEFUN([AC_WITH_LTDL], +[AC_REQUIRE([AC_LIB_LTDL]) +AC_SUBST([LIBLTDL]) +AC_SUBST([INCLTDL]) + +# Unless the user asks us to check, assume no installed ltdl exists. +use_installed_libltdl=no + +AC_ARG_WITH([included_ltdl], + [ --with-included-ltdl use the GNU ltdl sources included here]) + +if test "x$with_included_ltdl" != xyes; then + # We are not being forced to use the included libltdl sources, so + # decide whether there is a useful installed version we can use. + AC_CHECK_HEADER([ltdl.h], + [AC_CHECK_LIB([ltdl], [lt_dlcaller_register], + [with_included_ltdl=no], + [with_included_ltdl=yes]) + ]) +fi + +if test "x$enable_ltdl_install" != xyes; then + # If the user did not specify an installable libltdl, then default + # to a convenience lib. + AC_LIBLTDL_CONVENIENCE +fi + +if test "x$with_included_ltdl" = xno; then + # If the included ltdl is not to be used. then Use the + # preinstalled libltdl we found. + AC_DEFINE([HAVE_LTDL], [1], + [Define this if a modern libltdl is already installed]) + LIBLTDL=-lltdl +fi + +# Report our decision... +AC_MSG_CHECKING([whether to use included libltdl]) +AC_MSG_RESULT([$with_included_ltdl]) + +AC_CONFIG_SUBDIRS([libltdl]) +])# AC_WITH_LTDL + + +# AC_LIB_LTDL +# ----------- +# Perform all the checks necessary for compilation of the ltdl objects +# -- including compiler checks and header checks. +AC_DEFUN([AC_LIB_LTDL], +[AC_PREREQ(2.50) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_C_CONST]) +AC_REQUIRE([AC_HEADER_STDC]) +AC_REQUIRE([AC_HEADER_DIRENT]) +AC_REQUIRE([_LT_AC_CHECK_DLFCN]) +AC_REQUIRE([AC_LTDL_ENABLE_INSTALL]) +AC_REQUIRE([AC_LTDL_SHLIBEXT]) +AC_REQUIRE([AC_LTDL_SHLIBPATH]) +AC_REQUIRE([AC_LTDL_SYSSEARCHPATH]) +AC_REQUIRE([AC_LTDL_OBJDIR]) +AC_REQUIRE([AC_LTDL_DLPREOPEN]) +AC_REQUIRE([AC_LTDL_DLLIB]) +AC_REQUIRE([AC_LTDL_SYMBOL_USCORE]) +AC_REQUIRE([AC_LTDL_DLSYM_USCORE]) +AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS]) +AC_REQUIRE([AC_LTDL_FUNC_ARGZ]) + +AC_CHECK_HEADERS([assert.h ctype.h errno.h malloc.h memory.h stdlib.h \ + stdio.h unistd.h]) +AC_CHECK_HEADERS([dl.h sys/dl.h dld.h mach-o/dyld.h]) +AC_CHECK_HEADERS([string.h strings.h], [break]) + +AC_CHECK_FUNCS([strchr index], [break]) +AC_CHECK_FUNCS([strrchr rindex], [break]) +AC_CHECK_FUNCS([memcpy bcopy], [break]) +AC_CHECK_FUNCS([memmove strcmp]) +AC_CHECK_FUNCS([closedir opendir readdir]) +])# AC_LIB_LTDL + + +# AC_LTDL_ENABLE_INSTALL +# ---------------------- +AC_DEFUN([AC_LTDL_ENABLE_INSTALL], +[AC_ARG_ENABLE([ltdl-install], + [AC_HELP_STRING([--enable-ltdl-install], [install libltdl])]) + +AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno) +AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno) +])# AC_LTDL_ENABLE_INSTALL + + +# AC_LTDL_SYS_DLOPEN_DEPLIBS +# -------------------------- +AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_CACHE_CHECK([whether deplibs are loaded by dlopen], + [libltdl_cv_sys_dlopen_deplibs], + [# PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + libltdl_cv_sys_dlopen_deplibs=unknown + case "$host_os" in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this `case' here to explicitly catch those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + aix[[45]]*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + darwin*) + # Assuming the user has installed a libdl from somewhere, this is true + # If you are looking for one http://www.opendarwin.org/projects/dlcompat + libltdl_cv_sys_dlopen_deplibs=yes + ;; + gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu) + # GNU and its variants, using gnu ld.so (Glibc) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + hpux10*|hpux11*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + interix*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + irix[[12345]]*|irix6.[[01]]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + netbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + osf[[1234]]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explictly say `no'. + libltdl_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to `yes'. Without it, it would be `no'. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say `yes'. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + ]) +if test "$libltdl_cv_sys_dlopen_deplibs" != yes; then + AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], + [Define if the OS needs help to load dependent libraries for dlopen().]) +fi +])# AC_LTDL_SYS_DLOPEN_DEPLIBS + + +# AC_LTDL_SHLIBEXT +# ---------------- +AC_DEFUN([AC_LTDL_SHLIBEXT], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([which extension is used for loadable modules], + [libltdl_cv_shlibext], +[ +module=yes +eval libltdl_cv_shlibext=$shrext_cmds + ]) +if test -n "$libltdl_cv_shlibext"; then + AC_DEFINE_UNQUOTED([LTDL_SHLIB_EXT], ["$libltdl_cv_shlibext"], + [Define to the extension used for shared libraries, say, ".so".]) +fi +])# AC_LTDL_SHLIBEXT + + +# AC_LTDL_SHLIBPATH +# ----------------- +AC_DEFUN([AC_LTDL_SHLIBPATH], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([which variable specifies run-time library path], + [libltdl_cv_shlibpath_var], [libltdl_cv_shlibpath_var="$shlibpath_var"]) +if test -n "$libltdl_cv_shlibpath_var"; then + AC_DEFINE_UNQUOTED([LTDL_SHLIBPATH_VAR], ["$libltdl_cv_shlibpath_var"], + [Define to the name of the environment variable that determines the dynamic library search path.]) +fi +])# AC_LTDL_SHLIBPATH + + +# AC_LTDL_SYSSEARCHPATH +# --------------------- +AC_DEFUN([AC_LTDL_SYSSEARCHPATH], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([for the default library search path], + [libltdl_cv_sys_search_path], + [libltdl_cv_sys_search_path="$sys_lib_dlsearch_path_spec"]) +if test -n "$libltdl_cv_sys_search_path"; then + sys_search_path= + for dir in $libltdl_cv_sys_search_path; do + if test -z "$sys_search_path"; then + sys_search_path="$dir" + else + sys_search_path="$sys_search_path$PATH_SEPARATOR$dir" + fi + done + AC_DEFINE_UNQUOTED([LTDL_SYSSEARCHPATH], ["$sys_search_path"], + [Define to the system default library search path.]) +fi +])# AC_LTDL_SYSSEARCHPATH + + +# AC_LTDL_OBJDIR +# -------------- +AC_DEFUN([AC_LTDL_OBJDIR], +[AC_CACHE_CHECK([for objdir], + [libltdl_cv_objdir], + [libltdl_cv_objdir="$objdir" + if test -n "$objdir"; then + : + else + rm -f .libs 2>/dev/null + mkdir .libs 2>/dev/null + if test -d .libs; then + libltdl_cv_objdir=.libs + else + # MS-DOS does not allow filenames that begin with a dot. + libltdl_cv_objdir=_libs + fi + rmdir .libs 2>/dev/null + fi + ]) +AC_DEFINE_UNQUOTED([LTDL_OBJDIR], ["$libltdl_cv_objdir/"], + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# AC_LTDL_OBJDIR + + +# AC_LTDL_DLPREOPEN +# ----------------- +AC_DEFUN([AC_LTDL_DLPREOPEN], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) +AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], + [libltdl_cv_preloaded_symbols], + [if test -n "$lt_cv_sys_global_symbol_pipe"; then + libltdl_cv_preloaded_symbols=yes + else + libltdl_cv_preloaded_symbols=no + fi + ]) +if test x"$libltdl_cv_preloaded_symbols" = xyes; then + AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1], + [Define if libtool can extract symbol lists from object files.]) +fi +])# AC_LTDL_DLPREOPEN + + +# AC_LTDL_DLLIB +# ------------- +AC_DEFUN([AC_LTDL_DLLIB], +[LIBADD_DL= +AC_SUBST(LIBADD_DL) +AC_LANG_PUSH([C]) + +AC_CHECK_FUNC([shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.])], + [AC_CHECK_LIB([dld], [shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LIBADD_DL="$LIBADD_DL -ldld"], + [AC_CHECK_LIB([dl], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DL="-ldl" libltdl_cv_lib_dl_dlopen="yes"], + [AC_TRY_LINK([#if HAVE_DLFCN_H +# include +#endif + ], + [dlopen(0, 0);], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) libltdl_cv_func_dlopen="yes"], + [AC_CHECK_LIB([svld], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DL="-lsvld" libltdl_cv_func_dlopen="yes"], + [AC_CHECK_LIB([dld], [dld_link], + [AC_DEFINE([HAVE_DLD], [1], + [Define if you have the GNU dld library.]) + LIBADD_DL="$LIBADD_DL -ldld"], + [AC_CHECK_FUNC([_dyld_func_lookup], + [AC_DEFINE([HAVE_DYLD], [1], + [Define if you have the _dyld_func_lookup function.])]) + ]) + ]) + ]) + ]) + ]) +]) + +if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes +then + lt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + AC_CHECK_FUNCS([dlerror]) + LIBS="$lt_save_LIBS" +fi +AC_LANG_POP +])# AC_LTDL_DLLIB + + +# AC_LTDL_SYMBOL_USCORE +# --------------------- +# does the compiler prefix global symbols with an underscore? +AC_DEFUN([AC_LTDL_SYMBOL_USCORE], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) +AC_CACHE_CHECK([for _ prefix in compiled symbols], + [ac_cv_sys_symbol_underscore], + [ac_cv_sys_symbol_underscore=no + cat > conftest.$ac_ext < $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + ac_cv_sys_symbol_underscore=yes + else + if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + fi + fi + else + echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC + fi + rm -rf conftest* + ]) +])# AC_LTDL_SYMBOL_USCORE + + +# AC_LTDL_DLSYM_USCORE +# -------------------- +AC_DEFUN([AC_LTDL_DLSYM_USCORE], +[AC_REQUIRE([AC_LTDL_SYMBOL_USCORE]) +if test x"$ac_cv_sys_symbol_underscore" = xyes; then + if test x"$libltdl_cv_func_dlopen" = xyes || + test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then + AC_CACHE_CHECK([whether we have to add an underscore for dlsym], + [libltdl_cv_need_uscore], + [libltdl_cv_need_uscore=unknown + save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + _LT_AC_TRY_DLOPEN_SELF( + [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], + [], [libltdl_cv_need_uscore=cross]) + LIBS="$save_LIBS" + ]) + fi +fi + +if test x"$libltdl_cv_need_uscore" = xyes; then + AC_DEFINE([NEED_USCORE], [1], + [Define if dlsym() requires a leading underscore in symbol names.]) +fi +])# AC_LTDL_DLSYM_USCORE + +# AC_LTDL_FUNC_ARGZ +# ----------------- +AC_DEFUN([AC_LTDL_FUNC_ARGZ], +[AC_CHECK_HEADERS([argz.h]) + +AC_CHECK_TYPES([error_t], + [], + [AC_DEFINE([error_t], [int], + [Define to a type to use for `error_t' if it is not otherwise available.])], + [#if HAVE_ARGZ_H +# include +#endif]) + +AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next argz_stringify]) +])# AC_LTDL_FUNC_ARGZ + +AC_DEFUN([AC_PROG_SHELL], + [AC_MSG_CHECKING(for a POSIX-compliant shell) + AC_CACHE_VAL(ac_cv_path_shell, + [ac_cv_path_shell=no + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy=/bin:/usr/bin:/usr/bin/posix:/usr/xpg4/bin:$PATH + for ac_dir in $ac_dummy; do + for ac_base in sh bash ksh sh5; do + case "$ac_dir" in + /*) + if ("$ac_dir/$ac_base" -c ' + + # Test the noclobber option, + # using the portable POSIX.2 syntax. + set -C + rm -f conftest.c || exit + >conftest.c || exit + >|conftest.c || exit + !>conftest.c || exit + + ') 2>/dev/null; then + ac_cv_path_shell="$ac_dir/$ac_base" + break + fi + ;; + esac + done + if test "$ac_cv_path_shell" != no; then + break + fi + done + IFS="$ac_save_ifs"]) + AC_MSG_RESULT($ac_cv_path_shell) + SHELL=$ac_cv_path_shell + if test "$SHELL" = no; then + SHELL=/bin/sh + AC_MSG_WARN(Using $SHELL, even though it is not POSIX-compliant) + fi + AC_SUBST(SHELL)]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..40593d9 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,851 @@ +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 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. + +# Copyright (C) 2002, 2003, 2005 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. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.6])]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 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. + +# 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], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# 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. + +# serial 7 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# 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. + +# serial 8 + +# 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", "GCJ", 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 + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + 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 + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # 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. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/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=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --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]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# 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. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. 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 " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/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=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# 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_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# 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. + +# serial 12 + +# 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. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# 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_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[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 +]) +]) + + +# 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. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 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. + +# 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)]) + +# Copyright (C) 2003, 2005 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. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 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. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +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 | grep -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 +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# 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. + +# serial 4 + +# 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= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005 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. + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 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. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# 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. + +# serial 4 + +# 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)]) + +# Copyright (C) 2001, 2003, 2005 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. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# 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 +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 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. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff --git a/acspecific.m4 b/acspecific.m4 new file mode 100644 index 0000000..0071304 --- /dev/null +++ b/acspecific.m4 @@ -0,0 +1,1050 @@ +# This file is part of Autoconf. -*- Autoconf -*- +# Macros that test for specific features. +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +# 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, the Free Software Foundation gives unlimited +# permission to copy, distribute and modify the configure scripts that +# are the output of Autoconf. You need not follow the terms of the GNU +# General Public License when using or distributing such scripts, even +# though portions of the text of Autoconf appear in them. The GNU +# General Public License (GPL) does govern all other use of the material +# that constitutes the Autoconf program. +# +# Certain portions of the Autoconf source text are designed to be copied +# (in certain cases, depending on the input) into the output of +# Autoconf. We call these the "data" portions. The rest of the Autoconf +# source text consists of comments plus executable code that decides which +# of the data portions to output in any given case. We call these +# comments and executable code the "non-data" portions. Autoconf never +# copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of Autoconf +# released by the Free Software Foundation. When you make and +# distribute a modified version of Autoconf, you may extend this special +# exception to the GPL to apply to your modified version as well, *unless* +# your modified version has the potential to copy into its output some +# of the text that was the non-data portion of the version that you started +# with. (In other words, unless your change moves or copies text from +# the non-data portions to the data portions.) If your modification has +# such potential, you must delete any notice of this special exception +# to the GPL from your modified version. +# +# Written by David MacKenzie, with help from +# Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor, +# Roland McGrath, Noah Friedman, david d zuhn, and many others. + + +## --------------------- ## +## Checks for programs. ## +## --------------------- ## + + +# _AC_PROG_ECHO +# ------------- +# Check whether to use -n, \c, or newline-tab to separate +# checking messages from result messages. +# Don't try to cache, since the results of this macro are needed to +# display the checking message. In addition, caching something used once +# has little interest. +# Idea borrowed from dist 3.0. Use `*c*,', not `*c,' because if `\c' +# failed there is also a new-line to match. +m4_define([_AC_PROG_ECHO], +[case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac +AC_SUBST(ECHO_C)dnl +AC_SUBST(ECHO_N)dnl +AC_SUBST(ECHO_T)dnl +])# _AC_PROG_ECHO + + +# AC_PROG_MAKE_SET +# ---------------- +# Define SET_MAKE to set ${MAKE} if make doesn't. +AC_DEFUN([AC_PROG_MAKE_SET], +[AC_MSG_CHECKING([whether ${MAKE-make} sets \${MAKE}]) +set dummy ${MAKE-make}; ac_make=`echo "$[2]" | sed 'y,./+-,__p_,'` +AC_CACHE_VAL(ac_cv_prog_make_${ac_make}_set, +[cat >conftest.make <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 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 conftest.make])dnl +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + AC_MSG_RESULT([yes]) + SET_MAKE= +else + AC_MSG_RESULT([no]) + SET_MAKE="MAKE=${MAKE-make}" +fi +AC_SUBST([SET_MAKE])dnl +])# AC_PROG_MAKE_SET + + +# AC_PROG_RANLIB +# -------------- +AC_DEFUN([AC_PROG_RANLIB], +[AC_CHECK_TOOL(RANLIB, ranlib, :)]) + + +# Check for mawk first since it's generally faster. +AC_DEFUN([AC_PROG_AWK], +[AC_CHECK_PROGS(AWK, mawk gawk nawk awk, )]) + + +# AC_PROG_YACC +# ------------ +AC_DEFUN([AC_PROG_YACC], +[AC_CHECK_PROGS(YACC, 'bison -y' byacc, yacc)]) + + +# AC_PROG_LEX +# ----------- +# Look for flex or lex. Set its associated library to LEXLIB. +# Check if lex declares yytext as a char * by default, not a char[]. +AC_DEFUN_ONCE([AC_PROG_LEX], +[AC_CHECK_PROGS(LEX, flex lex, :) +if test -z "$LEXLIB" +then + AC_CHECK_LIB(fl, yywrap, LEXLIB="-lfl", + [AC_CHECK_LIB(l, yywrap, LEXLIB="-ll")]) +fi +AC_SUBST(LEXLIB) +if test "x$LEX" != "x:"; then + _AC_DECL_YYTEXT +fi]) + + +# _AC_DECL_YYTEXT +# --------------- +# Check if lex declares yytext as a char * by default, not a char[]. +m4_define([_AC_DECL_YYTEXT], +[AC_CACHE_CHECK(lex output file root, ac_cv_prog_lex_root, +[# 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 + AC_MSG_ERROR([cannot find output from $LEX; giving up]) +fi]) +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root +AC_SUBST(LEX_OUTPUT_ROOT)dnl + +AC_CACHE_CHECK(whether yytext is a pointer, ac_cv_prog_lex_yytext_pointer, +[# 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" +AC_LINK_IFELSE([`cat $LEX_OUTPUT_ROOT.c`], ac_cv_prog_lex_yytext_pointer=yes) +LIBS=$ac_save_LIBS +rm -f "${LEX_OUTPUT_ROOT}.c" +]) +dnl +if test $ac_cv_prog_lex_yytext_pointer = yes; then + AC_DEFINE(YYTEXT_POINTER, 1, + [Define if `lex' declares `yytext' as a `char *' by default, + not a `char[]'.]) +fi +])# _AC_DECL_YYTEXT + + +# Require AC_PROG_LEX in case some people were just calling this macro. +AU_DEFUN([AC_DECL_YYTEXT], +[AC_PROG_LEX]) + + +# AC_PROG_INSTALL +# --------------- +AC_DEFUN([AC_PROG_INSTALL], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# 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 +# AmigaOS /C/install, which installs bootblocks on floppy discs +# 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. +AC_MSG_CHECKING([for a BSD compatible install]) +if test -z "$INSTALL"; then +AC_CACHE_VAL(ac_cv_path_install, +[ ac_save_IFS=$IFS; IFS=$ac_path_separator + for ac_dir in $PATH; do + IFS=$ac_save_IFS + # Account for people who put trailing slashes in PATH elements. + case $ac_dir/ in + / | ./ | .// | /[cC]/* \ + | /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 AS_EXECUTABLE_P(["$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. + : + elif test $ac_prog = install && + grep pwplus "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done +])dnl + 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 +dnl We do special magic for INSTALL instead of AC_SUBST, to get +dnl relative paths right. +AC_MSG_RESULT([$INSTALL]) + +# 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}' +AC_SUBST(INSTALL_PROGRAM)dnl + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' +AC_SUBST(INSTALL_SCRIPT)dnl + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +AC_SUBST(INSTALL_DATA)dnl +])# AC_PROG_INSTALL + + +# AC_PROG_LN_S +# ------------ +AC_DEFUN([AC_PROG_LN_S], +[AC_MSG_CHECKING([whether ln -s works]) +AC_SUBST([LN_S], [$as_ln_s])dnl +if test "$LN_S" = "ln -s"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no, using $LN_S]) +fi +])# AC_PROG_LN_S + + +# AC_RSH +# ------ +# I don't know what it used to do, but it no longer does. +AU_DEFUN([AC_RSH], +[AC_DIAGNOSE([obsolete], [$0: is no longer supported. +Remove this warning when you adjust the code.])]) + + + +## ------------------------- ## +## Checks for declarations. ## +## ------------------------- ## + + +# AC_DECL_SYS_SIGLIST +# ------------------- +AC_DEFUN([AC_DECL_SYS_SIGLIST], +[AC_CACHE_CHECK([for sys_siglist declaration in signal.h or unistd.h], + ac_cv_decl_sys_siglist, +[AC_COMPILE_IFELSE( +[AC_LANG_PROGRAM([#include +#include +/* NetBSD declares sys_siglist in unistd.h. */ +#if HAVE_UNISTD_H +# include +#endif +], [char *msg = *(sys_siglist + 1);])], + [ac_cv_decl_sys_siglist=yes], + [ac_cv_decl_sys_siglist=no])]) +if test $ac_cv_decl_sys_siglist = yes; then + AC_DEFINE(SYS_SIGLIST_DECLARED, 1, + [Define if `sys_siglist' is declared by or .]) +fi +])# AC_DECL_SYS_SIGLIST + + + + +## -------------------------------------- ## +## Checks for operating system services. ## +## -------------------------------------- ## + + +# AC_SYS_INTERPRETER +# ------------------ +AC_DEFUN([AC_SYS_INTERPRETER], +[AC_CACHE_CHECK(whether @%:@! works in shell scripts, ac_cv_sys_interpreter, +[echo '#! /bin/cat +exit 69 +' >conftest +chmod u+x conftest +(SHELL=/bin/sh; export SHELL; ./conftest >/dev/null) +if test $? -ne 69; then + ac_cv_sys_interpreter=yes +else + ac_cv_sys_interpreter=no +fi +rm -f conftest]) +interpval=$ac_cv_sys_interpreter +]) + + +AU_DEFUN([AC_HAVE_POUNDBANG], +[AC_SYS_INTERPRETER +AC_DIAGNOSE([obsolete], +[$0: Remove this warning when you adjust your code to use + `AC_SYS_INTERPRETER'.])]) + + +AU_DEFUN([AC_ARG_ARRAY], +[AC_DIAGNOSE([obsolete], +[$0: no longer implemented: don't do unportable things +with arguments. Remove this warning when you adjust your code.])]) + + +# _AC_SYS_LARGEFILE_TEST_INCLUDES +# ------------------------------- +m4_define([_AC_SYS_LARGEFILE_TEST_INCLUDES], +[@%:@include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +@%:@define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]];[]dnl +]) + + +# _AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, +# CACHE-VAR, +# DESCRIPTION, +# [INCLUDES], [FUNCTION-BODY]) +# ---------------------------------------------------------- +m4_define([_AC_SYS_LARGEFILE_MACRO_VALUE], +[AC_CACHE_CHECK([for $1 value needed for large files], [$3], +[while :; do + $3=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$5], [$6])], + [break]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@define $1 $2 +$5], [$6])], + [$3=$2; break]) + break +done]) +if test "$$3" != no; then + AC_DEFINE_UNQUOTED([$1], [$$3], [$4]) +fi +rm -f conftest*[]dnl +])# _AC_SYS_LARGEFILE_MACRO_VALUE + + +# AC_SYS_LARGEFILE +# ---------------- +# By default, many hosts won't let programs access large files; +# one must use special compiler options to get large-file access to work. +# For more details about this brain damage please see: +# http://www.sas.com/standards/large.file/x_open.20Mar96.html +AC_DEFUN([AC_SYS_LARGEFILE], +[AC_ARG_ENABLE(largefile, + [ --disable-largefile omit support for large files]) +if test "$enable_largefile" != no; then + + AC_CACHE_CHECK([for special C compiler options needed for large files], + ac_cv_sys_largefile_CC, + [ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + AC_LANG_CONFTEST([AC_LANG_PROGRAM([_AC_SYS_LARGEFILE_TEST_INCLUDES])]) + AC_COMPILE_IFELSE([], [break]) + CC="$CC -n32" + AC_COMPILE_IFELSE([], [ac_cv_sys_largefile_CC=' -n32'; break]) + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi]) + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + _AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64, + ac_cv_sys_file_offset_bits, + [Number of bits in a file offset, on hosts where this is settable.], + [_AC_SYS_LARGEFILE_TEST_INCLUDES]) + _AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1, + ac_cv_sys_large_files, + [Define for large files, on AIX-style hosts.], + [_AC_SYS_LARGEFILE_TEST_INCLUDES]) +fi +])# AC_SYS_LARGEFILE + + +# AC_SYS_LONG_FILE_NAMES +# ---------------------- +# Security: use a temporary directory as the most portable way of +# creating files in /tmp securely. Removing them leaves a race +# condition, set -C is not portably guaranteed to use O_EXCL, so still +# leaves a race, and not all systems have the `mktemp' utility. We +# still test for existence first in case of broken systems where the +# mkdir succeeds even when the directory exists. Broken systems may +# retain a race, but they probably have other security problems +# anyway; this should be secure on well-behaved systems. In any case, +# use of `mktemp' is probably inappropriate here since it would fail in +# attempting to create different file names differing after the 14th +# character on file systems without long file names. +AC_DEFUN([AC_SYS_LONG_FILE_NAMES], +[AC_CACHE_CHECK(for long file names, ac_cv_sys_long_file_names, +[ac_cv_sys_long_file_names=yes +# Test for long file names in all the places we know might matter: +# . the current directory, where building will happen +# $prefix/lib where we will be installing things +# $exec_prefix/lib likewise +# eval it to expand exec_prefix. +# $TMPDIR if set, where it might want to write temporary files +# if $TMPDIR is not set: +# /tmp where it might want to write temporary files +# /var/tmp likewise +# /usr/tmp likewise +if test -n "$TMPDIR" && test -d "$TMPDIR" && test -w "$TMPDIR"; then + ac_tmpdirs=$TMPDIR +else + ac_tmpdirs='/tmp /var/tmp /usr/tmp' +fi +for ac_dir in . $ac_tmpdirs `eval echo $prefix/lib $exec_prefix/lib` ; do + test -d $ac_dir || continue + test -w $ac_dir || continue # It is less confusing to not echo anything here. + ac_xdir=$ac_dir/cf$$ + (umask 077 && mkdir $ac_xdir 2>/dev/null) || continue + ac_tf1=$ac_xdir/conftest9012345 + ac_tf2=$ac_xdir/conftest9012346 + (echo 1 >$ac_tf1) 2>/dev/null + (echo 2 >$ac_tf2) 2>/dev/null + ac_val=`cat $ac_tf1 2>/dev/null` + if test ! -f $ac_tf1 || test "$ac_val" != 1; then + ac_cv_sys_long_file_names=no + rm -rf $ac_xdir 2>/dev/null + break + fi + rm -rf $ac_xdir 2>/dev/null +done]) +if test $ac_cv_sys_long_file_names = yes; then + AC_DEFINE(HAVE_LONG_FILE_NAMES, 1, + [Define if you support file names longer than 14 characters.]) +fi +]) + + +# AC_SYS_RESTARTABLE_SYSCALLS +# --------------------------- +# If the system automatically restarts a system call that is +# interrupted by a signal, define `HAVE_RESTARTABLE_SYSCALLS'. +AC_DEFUN([AC_SYS_RESTARTABLE_SYSCALLS], +[AC_DIAGNOSE([obsolete], +[$0: System call restartability is now typically set at runtime. +Remove this `AC_SYS_RESTARTABLE_SYSCALLS' +and adjust your code to use `sigaction' with `SA_RESTART' instead.])dnl +AC_REQUIRE([AC_HEADER_SYS_WAIT])dnl +AC_CHECK_HEADERS(unistd.h) +AC_CACHE_CHECK(for restartable system calls, ac_cv_sys_restartable_syscalls, +[AC_RUN_IFELSE([AC_LANG_SOURCE( +[/* Exit 0 (true) if wait returns something other than -1, + i.e. the pid of the child, which means that wait was restarted + after getting the signal. */ + +#include +#include +#if HAVE_UNISTD_H +# include +#endif +#if HAVE_SYS_WAIT_H +# include +#endif + +/* Some platforms explicitly require an extern "C" signal handler + when using C++. */ +#ifdef __cplusplus +extern "C" void ucatch (int dummy) { } +#else +void ucatch (dummy) int dummy; { } +#endif + +int +main () +{ + int i = fork (), status; + + if (i == 0) + { + sleep (3); + kill (getppid (), SIGINT); + sleep (3); + exit (0); + } + + signal (SIGINT, ucatch); + + status = wait (&i); + if (status == -1) + wait (&i); + + exit (status == -1); +}])], + [ac_cv_sys_restartable_syscalls=yes], + [ac_cv_sys_restartable_syscalls=no])]) +if test $ac_cv_sys_restartable_syscalls = yes; then + AC_DEFINE(HAVE_RESTARTABLE_SYSCALLS, 1, + [Define if system calls automatically restart after interruption + by a signal.]) +fi +])# AC_SYS_RESTARTABLE_SYSCALLS + + +# AC_SYS_POSIX_TERMIOS +# -------------------- +AC_DEFUN([AC_SYS_POSIX_TERMIOS], +[AC_CACHE_CHECK([POSIX termios], ac_cv_sys_posix_termios, +[AC_TRY_LINK([#include +#include +@%:@include ], + [/* SunOS 4.0.3 has termios.h but not the library calls. */ + tcgetattr(0, 0);], + ac_cv_sys_posix_termios=yes, + ac_cv_sys_posix_termios=no)]) +])# AC_SYS_POSIX_TERMIOS + + + +## --------------------- ## +## Checks for X window. ## +## --------------------- ## + + +# _AC_PATH_X_XMKMF +# ---------------- +# Internal subroutine of _AC_PATH_X. +# Set ac_x_includes and/or ac_x_libraries. +m4_define([_AC_PATH_X_XMKMF], +[rm -fr conftest.dir +if mkdir conftest.dir; then + cd conftest.dir + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat >Imakefile <<'EOF' +acfindx: + @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' +EOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which would confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl; do + if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && + test -f $ac_im_libdir/libX11.$ac_extension; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case $ac_im_incroot in + /usr/include) ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; + esac + case $ac_im_usrlibdir in + /usr/lib | /lib) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; + esac + fi + cd .. + rm -fr conftest.dir +fi +])# _AC_PATH_X_XMKMF + + +# _AC_PATH_X_DIRECT +# ----------------- +# Internal subroutine of _AC_PATH_X. +# Set ac_x_includes and/or ac_x_libraries. +m4_define([_AC_PATH_X_DIRECT], +[# Standard set of common directories for X headers. +# Check X11 before X11Rn because it is often a symlink to the current release. +ac_x_header_dirs=' +/usr/X11/include +/usr/X11R6/include +/usr/X11R5/include +/usr/X11R4/include + +/usr/include/X11 +/usr/include/X11R6 +/usr/include/X11R5 +/usr/include/X11R4 + +/usr/local/X11/include +/usr/local/X11R6/include +/usr/local/X11R5/include +/usr/local/X11R4/include + +/usr/local/include/X11 +/usr/local/include/X11R6 +/usr/local/include/X11R5 +/usr/local/include/X11R4 + +/usr/X386/include +/usr/x386/include +/usr/XFree86/include/X11 + +/usr/include +/usr/local/include +/usr/unsupported/include +/usr/athena/include +/usr/local/x11r5/include +/usr/lpp/Xamples/include + +/usr/openwin/include +/usr/openwin/share/include' + +if test "$ac_x_includes" = no; then + # Guess where to find include files, by looking for Intrinsic.h. + # First, try using that file with no special directory specified. + AC_PREPROC_IFELSE([AC_LANG_SOURCE([@%:@include ])], +[# We can compile using X headers with no special include directory. +ac_x_includes=], +[for ac_dir in $ac_x_header_dirs; do + if test -r "$ac_dir/X11/Intrinsic.h"; then + ac_x_includes=$ac_dir + break + fi +done]) +fi # $ac_x_includes = no + +if test "$ac_x_libraries" = no; then + # Check for the libraries. + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS=$LIBS + LIBS="-lXt $LIBS" + AC_TRY_LINK([@%:@include ], [XtMalloc (0)], +[LIBS=$ac_save_LIBS +# We can link X programs with no special library path. +ac_x_libraries=], +[LIBS=$ac_save_LIBS +for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +do + # Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl; do + if test -r $ac_dir/libXt.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done]) +fi # $ac_x_libraries = no +])# _AC_PATH_X_DIRECT + + +# _AC_PATH_X +# ---------- +# Compute ac_cv_have_x. +AC_DEFUN([_AC_PATH_X], +[AC_CACHE_VAL(ac_cv_have_x, +[# One or both of the vars are not set, and there is no cached value. +ac_x_includes=no ac_x_libraries=no +_AC_PATH_X_XMKMF +_AC_PATH_X_DIRECT +if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then + # Didn't find X anywhere. Cache the known absence of X. + ac_cv_have_x="have_x=no" +else + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" +fi])dnl +]) + + +# AC_PATH_X +# --------- +# If we find X, set shell vars x_includes and x_libraries to the +# paths, otherwise set no_x=yes. +# Uses ac_ vars as temps to allow command line to override cache and checks. +# --without-x overrides everything else, but does not touch the cache. +AC_DEFUN([AC_PATH_X], +[dnl Document the X abnormal options inherited from history. +m4_divert_once([HELP_BEGIN], [ +X features: + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR])dnl +AC_MSG_CHECKING([for X]) + +AC_ARG_WITH(x, [ --with-x use the X Window System]) +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then + # Both variables are already set. + have_x=yes + else + _AC_PATH_X + fi + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + AC_MSG_RESULT([$have_x]) + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$x_includes ac_x_libraries=$x_libraries" + AC_MSG_RESULT([libraries $x_libraries, headers $x_includes]) +fi +])# AC_PATH_X + + + +# AC_PATH_XTRA +# ------------ +# Find additional X libraries, magic flags, etc. +AC_DEFUN([AC_PATH_XTRA], +[AC_REQUIRE([AC_PATH_X])dnl +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + AC_DEFINE([X_DISPLAY_MISSING], 1, + [Define if the X Window System is missing or not being used.]) + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" +dnl FIXME: banish uname from this macro! + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + case `(uname -sr) 2>/dev/null` in + "SunOS 5"*) + AC_MSG_CHECKING([whether -R must be followed by a space]) + ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" + AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_R_nospace=yes, ac_R_nospace=no) + if test $ac_R_nospace = yes; then + AC_MSG_RESULT([no]) + X_LIBS="$X_LIBS -R$x_libraries" + else + LIBS="$ac_xsave_LIBS -R $x_libraries" + AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_R_space=yes, ac_R_space=no) + if test $ac_R_space = yes; then + AC_MSG_RESULT([yes]) + X_LIBS="$X_LIBS -R $x_libraries" + else + AC_MSG_RESULT([neither works]) + fi + fi + LIBS=$ac_xsave_LIBS + esac + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn Johnson says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And Karl Berry says + # the Alpha needs dnet_stub (dnet does not exist). + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" + AC_TRY_LINK_FUNC(XOpenDisplay, , + [AC_CHECK_LIB(dnet, dnet_ntoa, [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"]) + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + AC_CHECK_LIB(dnet_stub, dnet_ntoa, + [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"]) + fi]) + LIBS="$ac_xsave_LIBS" + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to T.E. Dickey. + # The functions gethostbyname, getservbyname, and inet_addr are + # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. + AC_CHECK_FUNC(gethostbyname) + if test $ac_cv_func_gethostbyname = no; then + AC_CHECK_LIB(nsl, gethostbyname, X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl") + if test $ac_cv_lib_nsl_gethostbyname = no; then + AC_CHECK_LIB(bsd, gethostbyname, X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd") + fi + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says Simon Leinen: it contains gethostby* + # variants that don't use the nameserver (or something). -lsocket + # must be given before -lnsl if both are needed. We assume that + # if connect needs -lnsl, so does gethostbyname. + AC_CHECK_FUNC(connect) + if test $ac_cv_func_connect = no; then + AC_CHECK_LIB(socket, connect, X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS", , + $X_EXTRA_LIBS) + fi + + # Guillermo Gomez says -lposix is necessary on A/UX. + AC_CHECK_FUNC(remove) + if test $ac_cv_func_remove = no; then + AC_CHECK_LIB(posix, remove, X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix") + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + AC_CHECK_FUNC(shmat) + if test $ac_cv_func_shmat = no; then + AC_CHECK_LIB(ipc, shmat, X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc") + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS=$LDFLAGS + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # John Interrante, Karl Berry + AC_CHECK_LIB(ICE, IceConnectionNumber, + [X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"], , $X_EXTRA_LIBS) + LDFLAGS=$ac_save_LDFLAGS + +fi +AC_SUBST(X_CFLAGS)dnl +AC_SUBST(X_PRE_LIBS)dnl +AC_SUBST(X_LIBS)dnl +AC_SUBST(X_EXTRA_LIBS)dnl +])# AC_PATH_XTRA + + + +## ------------------------------------ ## +## Checks for not-quite-Unix variants. ## +## ------------------------------------ ## + + +# AC_CYGWIN +# --------- +# Check for Cygwin. This is a way to set the right value for +# EXEEXT. +AU_DEFUN([AC_CYGWIN], +[AC_REQUIRE([AC_CANONICAL_HOST])[]dnl +AC_DIAGNOSE([obsolete], + [$0 is obsolete: use AC_CANONICAL_HOST and $host_os])dnl +case $host_os in + *cygwin* ) CYGWIN=yes;; + * ) CYGWIN=no;; +esac +])# AC_CYGWIN + + +# AC_EMXOS2 +# --------- +# Check for EMX on OS/2. This is another way to set the right value +# for EXEEXT. +AU_DEFUN([AC_EMXOS2], +[AC_REQUIRE([AC_CANONICAL_HOST])[]dnl +AC_DIAGNOSE([obsolete], + [$0 is obsolete: use AC_CANONICAL_HOST and $host_os])dnl +case $host_os in + *emx* ) EMXOS2=yes;; + * ) EMXOS2=no;; +esac +])# AC_EMXOS2 + + +# AC_MINGW32 +# ---------- +# Check for mingw32. This is another way to set the right value for +# EXEEXT. +AU_DEFUN([AC_MINGW32], +[AC_REQUIRE([AC_CANONICAL_HOST])[]dnl +AC_DIAGNOSE([obsolete], + [$0 is obsolete: use AC_CANONICAL_HOST and $host_os])dnl +case $host_os in + *mingw32* ) MINGW32=yes;; + * ) MINGW32=no;; +esac +])# AC_MINGW32 + + + + +## -------------------------- ## +## Checks for UNIX variants. ## +## -------------------------- ## + + +# These are kludges which should be replaced by a single POSIX check. +# They aren't cached, to discourage their use. + +# AC_AIX +# ------ +AC_DEFUN([AC_AIX], +[AH_VERBATIM([_ALL_SOURCE], +[/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +@%:@ifndef _ALL_SOURCE +@%:@ undef _ALL_SOURCE +@%:@endif])dnl +AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +AC_BEFORE([$0], [AC_RUN_IFELSE])dnl +AC_MSG_CHECKING([for AIX]) +AC_EGREP_CPP(yes, +[#ifdef _AIX + yes +#endif +], +[AC_MSG_RESULT([yes]) +AC_DEFINE(_ALL_SOURCE)], +[AC_MSG_RESULT([no])]) +])# AC_AIX + + +# AC_MINIX +# -------- +AC_DEFUN([AC_MINIX], +[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +AC_BEFORE([$0], [AC_RUN_IFELSE])dnl +AC_CHECK_HEADER(minix/config.h, MINIX=yes, MINIX=) +if test "$MINIX" = yes; then + AC_DEFINE(_POSIX_SOURCE, 1, + [Define if you need to in order for `stat' and other things to + work.]) + AC_DEFINE(_POSIX_1_SOURCE, 2, + [Define if the system does not provide POSIX.1 features except + with this defined.]) + AC_DEFINE(_MINIX, 1, + [Define if on MINIX.]) +fi +])# AC_MINIX + + +# AC_ISC_POSIX +# ------------ +AC_DEFUN([AC_ISC_POSIX], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +AC_BEFORE([$0], [AC_RUN_IFELSE])dnl +AC_MSG_CHECKING([for POSIXized ISC]) +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION [/usr/include/sys/unistd.h] >/dev/null 2>&1 +then + AC_MSG_RESULT([yes]) + ISC=yes # If later tests want to check for ISC. + AC_DEFINE(_POSIX_SOURCE, 1, + [Define if you need to in order for stat and other things to + work.]) + if test "$GCC" = yes; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +else + AC_MSG_RESULT([no]) + ISC= +fi +])# AC_ISC_POSIX + + +# AC_XENIX_DIR +# ------------ +AU_DEFUN(AC_XENIX_DIR, +[# You shouldn't need to depend upon XENIX. Remove this test if useless. +AC_MSG_CHECKING([for Xenix]) +AC_EGREP_CPP(yes, +[#if defined(M_XENIX) && !defined(M_UNIX) + yes +@%:@endif], + [AC_MSG_RESULT([yes]); XENIX=yes], + [AC_MSG_RESULT([no]); XENIX=]) + +AC_HEADER_DIRENT[]dnl +]) + + +# AC_DYNIX_SEQ +# ------------ +AU_DEFUN([AC_DYNIX_SEQ], [AC_FUNC_GETMNTENT]) + + +# AC_IRIX_SUN +# ----------- +AU_DEFUN([AC_IRIX_SUN], +[AC_FUNC_GETMNTENT +AC_CHECK_LIB(sun, getpwnam)]) + + +# AC_SCO_INTL +# ----------- +AU_DEFUN([AC_SCO_INTL], [AC_FUNC_STRFTIME]) diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..262bc17 --- /dev/null +++ b/configure.ac @@ -0,0 +1,465 @@ +dnl REQUIRE AUTOCONF 2.50 OR HIGHER... +AC_PREREQ(2.50) + +dnl +dnl Process this file with autoconf to produce a configure script. +dnl +AC_INIT +AC_CONFIG_SRCDIR([src/setup.h]) +AC_CONFIG_HEADERS(include/config.h) + +dnl +dnl Define the utils directory +dnl +AC_CONFIG_AUX_DIR(utils) + +dnl VERSION=`sed -e 's/^.*"\(.*\)";$/\1/' ${srcdir}/src/version.c` +VERSION=`sed -ne 's/.*version_string.*"\(.*\)"\;/\1/p' ${srcdir}/src/version.c` +PROGRAM=`sed -ne 's/.*program_name.*"\(.*\)"\;/\1/p' ${srcdir}/src/version.c` +AUTHOR=`sed -ne 's/.*author_name.*"\(.*\)"\;/\1/p' ${srcdir}/src/version.c` +EMAIL=`sed -ne 's/.*email_address.*"\(.*\)"\;/\1/p' ${srcdir}/src/version.c` +AM_INIT_AUTOMAKE($PROGRAM, $VERSION) +DATE=`${CONFIG_SHELL} ${srcdir}/utils/mkstamp` +AC_SUBST(DATE) +AC_SUBST(PROGRAM) +AC_SUBST(AUTHOR) +AC_SUBST(EMAIL) + +dnl +dnl canonicalize the host +dnl +AC_CANONICAL_HOST +PLATFORM="${host_vendor}-${host_cpu}-${host_os}" +AC_SUBST(PLATFORM) + +dnl Check for AIX weirdos +AC_AIX + +dnl Checks for programs. +AC_PROG_CC + +AM_PROG_LIBTOOL + +dnl +dnl Program support +dnl +AC_PATH_PROG( PERL, perl, false ) +AC_PROG_SHELL +AC_PROG_MAKE_SET +AC_PROG_INSTALL +case "$host_os" in + *aix*) + if test -n "${CC}" ; then + AC_CHECK_PROGS(CC_R, xlc_r cc_r cc) + if test "$CC_R" = cc ; then + AC_MSG_ERROR([pthread support requires cc_r (or other suitable compiler) on AIX]) + else + CC=$CC_R + AC_SUBST(CC) + fi + fi + ;; +esac + +if test -n "$GCC"; then + oldCFLAGS=$CFLAGS + CFLAGS="$CFLAGS -W -Wall -Werror -Wunused-value" + AC_MSG_CHECKING(for buggy pthread mutex initializers) + + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([#include ], + [pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&m); ])], + [buggy_init="no"], [buggy_init="yes"]) + + if test $buggy_init = "no" ; then + WARN_CFLAGS="-W -Wall -Wunused-value" + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + WARN_CFLAGS="-W -Wall -Wno-missing-braces -Wunused-value" + fi +fi +CFLAGS=$oldCFLAGS +AC_SUBST(WARN_CFLAGS) + +AC_MSG_CHECKING([for dlopen() in -ldld]) +olibs=$LIBS +LIBS="$LIBS -ldld" +AC_TRY_LINK(, + [ extern void* dlopen(); dlopen(); ], + AC_MSG_RESULT(yes); + LIBS=$olibs; + LDL=-ldld + AC_DEFINE(HAVE_SHL_LOAD, 1, [ Define if we have shl_load() ]), + AC_MSG_RESULT(no); + LDL= + LIBS=$olibs) + +AC_MSG_CHECKING([for dlopen() in -ldl]) +olibs=$LIBS +LIBS="$LIBS -ldl" +AC_TRY_LINK(, + [ extern void* dlopen(); dlopen(); ], + AC_MSG_RESULT(yes); + LIBS=$olibs; + LDL=-ldl, + AC_MSG_RESULT(no); + LDL= + LIBS=$olibs) + +AC_SUBST(LDL) + +dnl +dnl check for random device +dnl +AC_CACHE_CHECK(for random device, ac_cv_have_dev_random, +[if test -r "/dev/random" && test -r "/dev/urandom" ; then + ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi]) +if test "$ac_cv_have_dev_random" = yes; then + AC_DEFINE([HAVE_DEV_RANDOM], 1, [Discovered a random device]) +fi + +dnl +dnl with SSL support +dnl +MYSSL=off +sslfound=locate +SSL_INCLUDE= +SSL_LDFLAGS= +SSL_LIBS= +AC_ARG_WITH(ssl,dnl +[ --with-ssl=ARG where ARG is the ssl directory or "no" ], +[ MYSSL="$withval" ]) +AC_ARG_WITH(nossl,dnl +[ --without-ssl do NOT use SSL (same as --with-ssl=no) ], +[ MYSSL="no" ]) +if test "$MYSSL" = "no" +then + AC_MSG_RESULT(checking for ssl support... no) +else + AC_MSG_RESULT(checking for ssl support... yes) +fi + +dnl +dnl Check for ssl libraries +dnl +if test "$MYSSL" = "no" +then + AC_MSG_RESULT(HTTPS/ssl support disabled) +else + AC_CHECK_HEADERS($MYSSL/include/openssl/opensslv.h, sslfound=yes, sslfound=locate) + if test $sslfound = "locate"; then + dnl the user probably misunderstood the option.... + for dir in /usr /usr/local /usr/local/ssl /usr/pkg /usr/lib/ssl /usr/include/ssl /usr/include; do + AC_CHECK_HEADERS($dir/include/openssl/opensslv.h, sslfound=yes, sslfound=no) + if test $sslfound = "yes" ; then + SSL_CFLAGS="-DOPENSSL_NO_KRB5" + SSL_LDFLAGS="-L$dir/lib" + SSL_INCLUDE="-I$dir/include/openssl -I$dir/include" + SSL_LIBS="-lssl -lcrypto" + AC_MSG_CHECKING([for OpenSSL version]) + CPPFLAGS="$SSL_INCLUDE" + AC_EGREP_CPP(yes,[ + #include + #if OPENSSL_VERSION_NUMBER >= 0x0090800fL + yes + #endif + ],[ + SSL_LIBS="$LDL $SSL_LIBS" + AC_MSG_RESULT([>= 0.9.8 (appropriate flag set)]) + ],[ + AC_MSG_RESULT([< 0.9.8]) + ]) + AC_SUBST(SSL_CFLAGS) + AC_SUBST(SSL_INCLUDE) + AC_SUBST(SSL_LDFLAGS) + AC_SUBST(SSL_LIBS) + AC_DEFINE([HAVE_SSL], 1, [Discovered OpenSSL library for HTTPS]) + break + fi + done + else + echo "found ssl in $MYSSL" + SSL_CFLAGS="-DOPENSSL_NO_KRB5" + SSL_LDFLAGS="-L$MYSSL/lib" + SSL_INCLUDE="-I$MYSSL/include/openssl -I$MYSSL/include" + SSL_LIBS="-lssl -lcrypto" + AC_MSG_CHECKING([for OpenSSL version]) + CPPFLAGS="$SSL_INCLUDE" + AC_EGREP_CPP(yes,[ + #include + #if OPENSSL_VERSION_NUMBER >= 0x0090800fL + yes + #endif + ],[ + SSL_LIBS="$LDL $SSL_LIBS" + AC_MSG_RESULT([>= 0.9.8 (appropriate flag set)]) + ],[ + AC_MSG_RESULT([< 0.9.8]) + ]) + AC_SUBST(SSL_CFLAGS) + AC_SUBST(SSL_INCLUDE) + AC_SUBST(SSL_LDFLAGS) + AC_SUBST(SSL_LIBS) + AC_DEFINE(HAVE_SSL) + fi +fi + +AC_C_INLINE +AC_CHECK_TYPE(int8_t, char) +AC_CHECK_TYPE(int16_t, short) +AC_CHECK_TYPE(int32_t, int) +AC_CHECK_TYPE(int64_t, long long) +AC_CHECK_TYPE(uint8_t, unsigned char) +AC_CHECK_TYPE(uint16_t, unsigned short) +AC_CHECK_TYPE(uint32_t, unsigned int) +AC_CHECK_TYPE(uint64_t, unsigned long long) +AC_CHECK_TYPE(u_int32_t,unsigned int) +AC_CHECK_TYPE(ssize_t, int) + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(fcntl.h) +AC_CHECK_HEADERS(limits.h) +AC_CHECK_HEADERS(unistd.h) +AC_CHECK_HEADERS(signal.h) +AC_CHECK_HEADERS(sys/socket.h) +AC_CHECK_HEADERS(sys/select.h) +AC_CHECK_HEADERS(sys/time.h sys/times.h) +AC_CHECK_HEADERS(sys/resource.h) +AC_CHECK_HEADERS(errno.h) +AC_CHECK_HEADERS(arpa/inet.h) +AC_CHECK_HEADERS(netinet/in.h) +AC_CHECK_HEADERS(netdb.h) +AC_CHECK_HEADERS(pthread.h) +AC_CHECK_HEADERS(string.h) +AC_CHECK_HEADERS(strings.h) +AC_CHECK_HEADERS(sched.h) +AC_CHECK_HEADERS(openssl/e_os.h) +AC_CHECK_HEADERS(openssl/e_os2.h) + +dnl +dnl Checks for typedefs, structures, and compiler characteristics. +dnl +AC_C_CONST +AC_TYPE_SIZE_T +AC_HEADER_TIME + +dnl +dnl Return type of signal-handlers +dnl +AC_TYPE_SIGNAL + +dnl +dnl Checks for library functions. +dnl +AC_FUNC_ALLOCA +AC_CHECK_FUNCS(strchr memcpy strncpy strstr strlen) +AC_CHECK_FUNCS(strncasecmp strncmp) +AC_CHECK_FUNCS(socket, , AC_CHECK_LIB(socket, socket)) +AC_CHECK_FUNCS(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname)) +AC_CHECK_FUNCS(snprintf) +AC_CHECK_FUNCS(strdup) +AC_CHECK_FUNCS(rand_r) +AC_CHECK_FUNCS(localtime_r) +AC_CHECK_FUNCS(getipnodebyname) +AC_CHECK_FUNCS(freehostent) +AC_CHECK_FUNCS(getopt_long) + +dnl +dnl Check for socket library +dnl +AC_CHECK_LIB(socket, socket) + +dnl +dnl Check for pthread support +dnl +PTHREAD_CFLAGS=error +PTHREAD_LDFLAGS=error + +dnl If it's error, then the user didn't +dnl define it. +if test "x$PTHREAD_LDFLAGS" = xerror; then + AC_CHECK_LIB(pthread, pthread_attr_init, [ + PTHREAD_CFLAGS="-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS" + PTHREAD_LDFLAGS="-lpthread" ]) +fi + +if test "x$PTHREAD_LDFLAGS" = xerror; then + AC_CHECK_LIB(pthreads, pthread_attr_init, [ + PTHREAD_CFLAGS="-D_THREAD_SAFE" + PTHREAD_LDFLAGS="-lpthreads" ]) +fi + +if test "x$PTHREAD_LDFLAGS" = xerror; then + AC_CHECK_LIB(c_r, pthread_attr_init, [ + PTHREAD_CFLAGS="-D_THREAD_SAFE -pthread" + PTHREAD_LDFLAGS="-pthread" ]) +fi + +if test "x$PTHREAD_LDFLAGS" = xerror; then + AC_CHECK_FUNC(pthread_attr_init, [ + PTHREAD_CFLAGS="-D_REENTRANT" + PTHREAD_LDFLAGS="-lpthread" ]) +fi + +if test $PTHREAD_LDFLAGS = "error"; then + AC_MSG_WARN(pthread library NOT found: guessing and hoping for the best....) + PTHREAD_CFLAGS="-D_REENTRANT" + PTHREAD_LDFLAGS="-lpthread" +fi + +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_LDFLAGS) + +dnl +dnl On some platforms, notably Solaris, these +dnl variables are assigned literally by the user +dnl and not implied. (don't know why...) +case "$host_os" in + *solaris*) + if test -z "$ac_given_sysconfdir" ; + then + sysconfdir="$prefix/etc" + fi + + if test -z "$ac_given_localstatedir" ; + then + localstatedir="$prefix/var" + fi + ;; + *) ;; +esac + +dnl +dnl Create header file +dnl +AC_OUTPUT_COMMANDS([ + outfile=include/joedog/joepath.h + tmpfile=${outfile} + cat > $tmpfile << _EOF_ +/** + * Path Header + * + * Copyright (C) 2000-2013 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef JOEPATH_H +#define JOEPATH_H + +#define SIEGE_HOME "$prefix" +#define URL_FILE "$sysconfdir/urls.txt" +#define CNF_FILE "$sysconfdir/siegerc" +#define LOG_FILE "$localstatedir/siege.log" +#define PLATFORM "$platform" + +#endif/*JOEPATH_H*/ +_EOF_ +], [ prefix=$prefix sysconfdir=$sysconfdir localstatedir=$localstatedir platform=$PLATFORM ]) + +echo "PLATFORM: $PLATFORM" +dnl +dnl update dates and versioning in doc +dnl +AC_OUTPUT_COMMANDS([ + for file in doc/bombardment.1 doc/layingsiege.7 doc/siege.1 doc/siege.config.1 \ + doc/siege2csv.1 doc/siegerc doc/urls_txt.5; + do + rm -f $file + sed -e "s|%_VERSION%|$VERSION|" \ + -e "s|%_PROGRAM%|$PROGRAM|" \ + -e "s|%_DATE%|$DATE|" \ + -e "s|%_AUTHOR%|$AUTHOR|" \ + -e "s|%_EMAIL%|$EMAIL|" \ + < $file.in > $file + done +], [ VERSION=$VERSION DATE="$DATE" PROGRAM="$PROGRAM" AUTHOR="$AUTHOR" EMAIL="$EMAIL" ]) + +dnl +dnl create siege.config utility +dnl +AC_OUTPUT_COMMANDS([ + infile=utils/siege.config.in + outfile=utils/siege.config + rm -f $outfile + sed -e "s|%_PREFIX%|$bindir|" \ + -e "s|%_SHELL%|$sh|" \ + < $infile > $outfile + cat doc/siegerc >> $outfile + echo "_EOF_" >> $outfile + echo "echo \"New configuration template added to \$rcfile\"" >> $outfile + echo "echo \"Run siege -C to view the current settings in that file\"" >> $outfile + echo "exit" >> $outfile + echo "" >> $outfile + +], [ bindir=$exec_prefix$bindir sh=$SHELL ]) + +dnl +dnl create bombardment utility +dnl +AC_OUTPUT_COMMANDS([ + infile=utils/bombardment.in + outfile=utils/bombardment + rm -f $outfile + sed -e "s|%_PREFIX%|$bindir|" \ + -e "s|%_SHELL%|$sh|" \ + < $infile > $outfile + +], [ bindir=$exec_prefix$bindir sh=$SHELL ]) + +dnl +dnl create siege2csv utility +dnl +AC_OUTPUT_COMMANDS([ + infile=utils/siege2csv.in + outfile=utils/siege2csv.pl + rm -f $outfile + sed -e "s|%_PREFIX%|$bindir|" \ + -e "s|%_PERL%|$LREP|" \ + < $infile > $outfile + +], [ bindir=$exec_prefix$bindir LREP=$PERL ]) + +dnl +dnl Write platform to file for support reporting +dnl +AC_OUTPUT_COMMANDS([ + outfile=PLATFORM + tmpfile=${outfile} + cat > $tmpfile << _EOF_ +$PLATFORM +_EOF_ +], [PLATFORM=$PLATFORM]) + +AC_OUTPUT(Makefile src/Makefile doc/Makefile html/Makefile lib/Makefile lib/joedog/Makefile include/Makefile include/joedog/Makefile utils/Makefile) + +echo +echo "--------------------------------------------------------" +echo "Configuration is complete" +echo +echo "Run the following commands to complete the installation:" +echo " make " +echo " make install" +echo +echo "To upgrade an old siegerc file (optional): " +echo " mv ~/.siegerc.new ~/.siegerc" +echo +echo "For complete documentation: http://www.joedog.org" +echo "--------------------------------------------------------" diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..7d9a2df --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,81 @@ +## +## doc/Makefile.am +## +## Copyright (C) 2000-2010 by +## Jeffrey Fulmer - , et al. +## This file is distributed as part of Siege +## +## 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. +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +## + +AUTOMAKE_OPTIONS = foreign no-dependencies + +man_MANS = \ +siege.1 \ +siege.config.1 \ +layingsiege.7 \ +urls_txt.5 \ +bombardment.1 \ +siege2csv.1 + +EXTRA_DIST = \ +siege.1.in \ +siege.config.1.in \ +layingsiege.7.in \ +urls_txt.5.in \ +bombardment.1.in \ +siege2csv.1.in \ +urls.txt \ +siegerc.in + +DISTCLEANFILES = siegerc $(man_MANS) + +SIEGERC = $(sysconfdir)/siegerc + +URLSTXT = $(sysconfdir)/urls.txt + +install-exec-hook: + @if test -f $(DESTDIR)$(SIEGERC); then \ + if cmp -s $(srcdir)/siegerc $(DESTDIR)$(SIEGERC); then echo ""; \ + else \ + echo ' $(INSTALL_DATA) $(srcdir)/siegerc $(DESTDIR)$(SIEGERC).new'; \ + $(INSTALL_DATA) $(srcdir)/siegerc $(DESTDIR)$(SIEGERC).new; \ + echo "#####################################################"; \ + echo "WARNING: File $(SIEGERC) already exists."; \ + echo " A new resource file has been installed as"; \ + echo " $(SIEGERC).new. You may want to"; \ + echo " consider using the newer version in order to"; \ + echo " take advantage of any new features."; \ + echo "#####################################################"; \ + fi; \ + else \ + $(mkinstalldirs) $(DESTDIR)$(sysconfdir); \ + $(INSTALL_DATA) $(srcdir)/siegerc $(DESTDIR)$(SIEGERC); \ + fi + @if test -f $(DESTDIR)$(URLSTXT); then \ + if cmp -s $(srcdir)/siegerc $(DESTDIR)$(URLSTXT); then echo ""; \ + else \ + echo "WARNING: File $(DESTDIR)$(URLSTXT) already exists."; \ + echo " It was NOT replaced with this installation."; \ + fi; \ + else \ + $(mkinstalldirs) $(DESTDIR)$(sysconfdir); \ + $(INSTALL_DATA) $(srcdir)/urls.txt $(DESTDIR)$(URLSTXT); \ + fi + + +uninstall: + rm -f $(DESTDIR)$(SIEGERC) + diff --git a/doc/bombardment.1.in b/doc/bombardment.1.in new file mode 100644 index 0000000..23a846a --- /dev/null +++ b/doc/bombardment.1.in @@ -0,0 +1,49 @@ +.\" Copyright 2001, 2002 Peter J. Hutnick (phutnick@aperian.com) +.\" May be distributed under the GNU General Public License +.TH BOMBARDMENT 1 "%_DATE%" "Siege Utility" "bombardment v%_VERSION%" +.SH NAME +bombardment \- Run Siege with an ever-increasing number of users +.SH SYNOPSIS +.BR "bombardment" " [urlfile] [initial number of clients] [increment value] +[number of increments] [delay]" +.br +.B "bombardment urlfile.txt 5 10 20 1" +.SH DESCRIPTION +.B bombardment +is part of the Siege package. It calls siege with an initial number of +clients. When that run finishes, it immediately calls siege again with +that number of clients plus the increment. It does this the number of +times specified in the fourth argument. +.SH OPTIONS +.TP +.BR "urlfile" +The name of the file containing one or more URLs for siege to test. +.TP +.BR "initial number of clients" +The number of clients to be used on the first Siege run. +.TP +.BR "increment value" +The number of clients to add from run to run. +.TP +.BR "number of increments" +The number of times to run siege. +.TP +.BR "delay" +The is the amount of time, in seconds, that each client will wait between +requests. The Siege default of 3 is overridden by +.B bombardment +and is 15. +.SH NOTES +.B bombardment +can very easily overcome process and filehandle limits. Siege DOES give a +warning if it is going to exceed 600 concurrent processes. See your +system documentation (or try ulimit \-a) for information on the limits of +your system before using a high number of concurrent users. +.SH "SEE ALSO" +.BR siege (1), +.BR urls_txt (5), +.BR layingsiege (7), +.BR siege2csv (1) +.SH AUTHOR +Written by Peter Hutnick + diff --git a/doc/layingsiege.7.in b/doc/layingsiege.7.in new file mode 100644 index 0000000..09ab711 --- /dev/null +++ b/doc/layingsiege.7.in @@ -0,0 +1,70 @@ +.ig \"-*- Siege -*- +Copyright (C) 2000-2007 %_AUTHOR% + +Siege is distributed under the terms of the GNU GPL. + +.. +.TH LAYINGSIEGE 7 "%_DATE%" "Siege v%_VERSION%" +.SH NAME +.B Siege +\- An HTTP/HTTPS stress tester +was designed orignally as a internet usage simulator. In short, its role was to simulate the activity of many simultaneous users hitting a HTTP server. We were debugging some java code and during that process we arrived at a point where the code could withstand an acceptable number of users hitting a single URL but it could not withstand the seemingly random activity that characterizes many users hitting many URLs on a webserver. + +In order to debug the problem in a lab environment, I developed a program that simply read a bunch of URLs ( we used images, scripts, static html, jsps, etc. ) into memory and hit them randomly. The result was a success. We were able to break the code in the lab, an occurance which ultimately allowed us to fix it and put it into production. As the developers code improved, siege improved until we ultimately had good java code and a pretty decent regression tool. It was helpful for us, I hope it is helpful to you. + +In order to feel comfortable putting code into production, you need a way to measure its performance and to determine its threshold for failure. If you break your database pool at 250 simultaneous users and you average less then one-hundred simultaneous users and the code performs favorably, you can feel good about putting it into production. At the same time, if you should monitor trends in your site's activity and prepare for the moment when your traffic starts to near your threshold for failure. + +As a webdeveloper or websystems administrator you have little to no control over your user group. They can visit your site anytime day or night. Your domain name could resemble a popular site, yoohoo.com? And when was the last time marketing informed you about an approaching advertising blitz? You must be prepared for anything. That is why stress and performance testing is so important. I would not recommend putting anything into production until you have a good feel for how it will perform under duress. + +.SH LAYING SIEGE +.LP +Whenever we add new code to a webserver, we place the server "under siege." First we stressthe new URL(s) and then we pound the server with regression testing with the new URLs added to the configuration file. We want to see if the new code will stand on its own, plus we want to see if it will break anything else. + +The following statistics were gleaned when I laid siege to a single URL on a http server: + +.br +Transactions: 1000 hits +.br +Elapsed time: 617.99 secs +.br +Data transferred: 4848000 bytes +.br +Response time: 59.41 secs +.br +Transaction rate: 1.62 trans/sec +.br +Throughput: 7844.79 bytes/sec +.br +Concurrency: 96.14 +.br +Status code 200: 1000 + +In the above example, we simulated 100 users hitting the same URL 10 times, a total of 1000 transactions. The elapsed time is measured from the first transaction to the last, in this case it took 617.99 seconds to hit the http server 1000 times. During that run, siege recieved a total of 4848000 bytes including headers. The response time is measured by the duration of each transaction divided by the number of transactions. The transaction rate is number of transactions divided by elapsed time. Throughput is the measure of bytes recieved divided by elapsed time. And the concurrency is the time of each transaction divided by the elapsed time. The final statistic is Status code 200. This is the number of pages that were effectively delivered without server errors. + +To create this example, I ran siege on my Sun workstation and I pounded a GNU/Linux Intel box, essentially a workstation. The performance leaves a lot to be desired. One indication that the server is struggling is the high concurrency. The longer the transaction, the higher the concurrency. This server is taking a while to complete the transaction and it continues to open new sockets to handle all the additional requests. In truth the Linux box is suffering from a lack of RAM, it has about 200MB, hardly enough to be handling one hundred concurrent users. :-) + +Now that we've stressed the URL(s) singly, we can add them to our main configuration file and stress them with the rest of the site. The default URLs file is SIEGE_HOME/etc/urls.txt. + +Siege can allow websystems administrators a chance to see how their servers perform under duress. I recommend running server performance monitoring tools while it is under siege to gage your hardware / software configurations. The results can be surprising... + +.B Siege +was originally based on Lincoln Stein's torture.pl and if you cannot it on your architecture, it is recommended that you run that excellent perl script instead. I intentionally modeled my statistics output after his in order to maintain similar reference. + +.SH COPYRIGHT +Copyright \(co 2000 2001 2004 %_AUTHOR% <%_EMAIL%> +.LP +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 Fo +undation; 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., 675 Mass Ave, +Cambridge, MA 02139, USA. +.LP +.SH AVAILABILITY +The most recent released version of siege is available by +anonymous FTP from sid.joedog.org in the directory pub/siege. +.LP +.SH SEE ALSO +siege(1) siege.config(1) urls_txt(5) + diff --git a/doc/siege.1.in b/doc/siege.1.in new file mode 100644 index 0000000..77b2277 --- /dev/null +++ b/doc/siege.1.in @@ -0,0 +1,250 @@ +.ig \"-*- Siege -*- +Copyright (C) 2000-2010 by %_AUTHOR% + +Siege is distributed under the terms of the GNU GPL. + +.. +.de TQ +.br +.ns +.TP \\$1 +.. +.\" Like TP, but if specified indent is more than half +.\" the current line-length - indent, use the default indent. +.de Tp +.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP +.el .TP "\\$1" +.. +.TH SIEGE 1 "%_DATE%" "Siege v%_VERSION%" +.SH NAME +.B %_PROGRAM% +\- An HTTP/HTTPS stress tester +.SH INTRODUCTION +Siege is a multi-threaded http load testing and benchmarking utility. It was designed to let web developers measure the performance of their code under duress. It allows one to hit a web server with a configurable number of concurrent simulated users. Those users place the webserver "under siege." +\fR\fR +Performance measures include elapsed time, total data transferred, server response time, its transaction rate, its throughput, its concurrency and the number of times it returned OK. These measures are quantified and reported at the end of each run. Their meaning and significance is discussed below. +\fR\fR +Siege has essentially three modes of operation: regression (when invoked by bombardment), internet simulation and brute force. +.SH INVOCATION +The format for invoking siege is: siege [options] \fR + siege [options] [url]\fR + siege \-g [url]\fR + +Siege supports the following command line options:\fR\fR +.TP +\fB\-V\fR, \fB\-\-version\fR +VERSION, prints the version number +.TP +\fB\-h\fR, \fB\-\-help\fR +HELP, prints the help section which includes a summary of all the command line options. +.TP +\fB\-C\fR, \fB\-\-config\fR +CONFIGURATION, prints the current configuration in the $HOME/.siegerc file. Edit that file to set flag values for EVERY siege run, a feature which eases runtime invocation. You set an alternative resource file with the SIEGERC environment variable: export SIEGERC=/home/jeff/haha +.TP +\fB\-v\fR, \fB\-\-verbose\fR +VERBOSE, prints the HTTP return status and the GET request to the screen. Useful when reading a series of URLs from a configuration file. This flag allows you to witness the progress of the test. +.TP +\fB\-q\fR, \fB\-\-quiet\fR +QUIET turns off verbose and suppresses most output. This option was added primarily for scripting with \-g/\-\-get. If you run a full siege in quiet mode, you'll still get the opening introduction and the final stats. +.TP +\fB\-g\fR, \fB\-\-get\fR +GET HTTP headers and display the transaction. Siege exits 1 if the transaction doesn't contain at least one HTTP 200 response, otherwise it exits 0. You can limit the transaction to just the headers by setting gmethod=HEAD in $HOME/.siegerc +.TP +\fB\-c NUM\fR, \fB\-\-concurrent=NUM\fR +CONCURRENT, allows you to set the concurrent number of simulated users to num. The number of simulated users is limited to the resources on the computer running siege. +.TP +\fB\-i\fR, \fB\-\-internet\fR +INTERNET, generates user simulation by randomly hitting the URLs read from the urls.txt file. This option is viable only with the urls.txt file. +.TP +\fB\-d NUM\fR, \fB\-\-delay=NUM\fR +DELAY, each siege simulated users sleeps for a random interval in seconds between 0 and NUM. +.TP +\fB\-b\fR, \fB\-\-benchmark\fR +BENCHMARK, runs the test with NO DELAY for throughput benchmarking. By default each simulated user is invoked with at least a one second delay. This option removes that delay. It is not recommended that you use this option while load testing. +.TP +\fB\-r NUM\fR, \fB\-\-reps=NUM\fR, \fB\-\-reps=once\fR +REPS, allows you to run the siege for NUM repetitions. If \-\-reps=once, then siege will run through the urls.txt file and hit each URL in the file exactly once. The list will be divided among each simulated user. So if you run --reps=once -c10 on a file which contains 30 URLs, then each user will run three times. NOTE: \-t/\-\-time takes precedent over \-r/\-\-reps. If you want to use this option, make sure time = x is commented out in your $HOME/.siegerc file. +.TP +\fB\-t NUMm\fR, \fB\-\-time=NUMm\fR +TIME, allows you to run the test for a selected period of time. The format is "NUMm", where NUM is a time unit and the "m" modifier is either S, M, or H for seconds, minutes and hours. To run siege for an hour, you could select any one of the following combinations: \-t3600S, \-t60M, \-t1H. The modifier is not case sensitive, but it does require no space between the number and itself. +.TP +\fB\-l [FILE]\fR, \fB\-\-log[=FILE]\fR +LOG transaction stats to FILE. The argument is optional. If FILE is not specified, then siege logs the transaction to SIEGE_HOME/var/siege.log. If siege is installed in /usr/local, then the default siege.log is /usr/local/var/siege.log. This option logs the final statistics reported when siege successfully completes its test. You can edit $HOME/.siegerc to change the location of the siege.log file. +.TP +\fB\-m MESSAGE\fR, \fB\-\-mark=MESSAGE\fR +MARK, mark the log file with a separator. This option will allow you to separate your log file entries with header information. This is especially useful when testing two different servers. It is not necessary to use both the \-m option and the \-l option. \-m assumes \-l so it marks and logs the transaction. If the MESSAGE has spaces in it, make sure that you put it in quotes. +.TP +\fB\-H HEADER\fR, \fB\-\-header=HEADER\fR +HEADER, this option allows you to add additional header information. +.TP +\fB\-R SIEGERC\fR, \fB\-\-rc=SIEGERC\fR +RC, sets the siegerc file for the run. This option overrides the environment variable SIEGERC and the default resource file, $HOME/.siegerc +.TP +\fB\-f FILE\fR, \fB\-\-file=FILE\fR +FILE, the default URL file is SIEGE_HOME/etc/urls.txt. To select a different URL file, use this option, i.e., siege \-f myurls.txt +.TP +\fB\-A "User Agent"\fR, \fB\-\-user\-agent="User Agent"\fR +AGENT, use this option to set the User-Agent in the request. +.SH URL FORMAT +Siege understands the following URL formats: \fR +.br +(brackets indicate the directive is optional)\fR +.br + \fR +.br +[protocol://] host.domain.xxx [:port] [/path/file] \fR +.br + \fR +.br +host.domain.xxx/file POST field=value&field2=value2 \fR +.br + \fR +.br +Or you can POST the contents of a file using the line input operator, the "<" character: \fR +.br + \fR +.br +host/file POST = 400 plus the sum of all failed socket transactions which includes socket timeouts. +.TP +.B Longest transaction +The greatest amount of time that any single transaction took, out of all transactions. +.TP +.B Shortest transaction +The smallest amount of time that any single transaction took, out of all transactions. + +.SH AUTHOR +%_AUTHOR% <%_EMAIL%> +.SH BUGS +Report bugs to %_EMAIL%. +Give a detailed description of the problem +and report the version of siege that +you are using. +.SH COPYRIGHT +Copyright \(co 2000 2001 2004 %_AUTHOR% +.LP +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., 675 Mass Ave, Cambridge, MA 02139, USA. +.LP +.SH AVAILABILITY +The most recent released version of siege is available by +anonymous FTP from ftp.joedog.org in the directory pub/siege. +.LP +.SH SEE ALSO +siege.config(1) urls_txt(5) layingsiege(7) diff --git a/doc/siege.config.1.in b/doc/siege.config.1.in new file mode 100644 index 0000000..8d71077 --- /dev/null +++ b/doc/siege.config.1.in @@ -0,0 +1,54 @@ +.ig \"-*- Siege -*- +Copyright (C) 2013 %_AUTHOR% + +Siege is distributed under the terms of the GNU GPL. + +.. +.de TQ +.br +.ns +.TP \\$1 +.. +.\" Like TP, but if specified indent is more than half +.\" the current line-length - indent, use the default indent. +.de Tp +.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP +.el .TP "\\$1" +.. +.TH SIEGE.CONFIG 1 "%_DATE%" "Siege v%_VERSION%" +.SH NAME +.B siege.config +\- builds a .siegerc template in the user's home directory. +.SH INTRODUCTION +.LP +With the release of version 2.00, siege supports a settings configuration file to permanently store runtime variables. The settings in this file are the default values for every siege invocation. They are superceded by command line options, so if the configuration file has a default "times = 10" and the user invokes siege with \-t1000, then siege will run 1000 times and not 10. +.LP +When siege is installed on a system, a .siegerc file is installed in the installing user's home directory. This means that only the user who installed siege has a configuration file. The siege.config utility was designed to install a .siegerc file in the home directory of the user who invoked it. This makes it possible to have customized siege configuration on a per user basis. +.SH INVOCATION +.LP +The format for invoking siege.config is this:\fR +.br +siege.config [no arguments]\fR + +.SH AUTHOR +%_AUTHOR% <%_EMAIL%> +.SH BUGS +Report bugs to %_EMAIL%. +Give a detailed description of the problem +and report the version of %_PROGRAM% that +you are using. +.SH COPYRIGHT +Copyright \(co 2000 2001 2004 %_AUTHOR% +.LP +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., 675 Mass Ave, Cambridge, MA 02139, USA. +.LP +.SH AVAILABILITY +The most recent released version of siege is available by +anonymous FTP from sid.joedog.org in the directory pub/siege. +.LP +.SH SEE ALSO +siege(1) layingsiege(1) diff --git a/doc/siege2csv.1.in b/doc/siege2csv.1.in new file mode 100644 index 0000000..6dc5d2a --- /dev/null +++ b/doc/siege2csv.1.in @@ -0,0 +1,30 @@ +.\" Copyright 2001, 2002 Peter J. Hutnick (phutnick@aperian.com) +.\" May be distributed under the GNU General Public License +.TH SIEGE2CSV 1 "%_DATE%" "Siege Utility" "siege2csv.pl v%_VERSION%" +.SH NAME +siege2csv.pl \- Convert output from +.B "bombardment(1)" +to Comma Separated Values (CSV) +.SH SYNOPSIS +.BR "siege2csv.pl" " [filename] " +.br +.SH DESCRIPTION +.B siege2csv.pl +is part of the Siege package. It converts the output of +.B "bombardment(1)" +to CSV for easy use with spreadsheets. +.SH OPTIONS +.TP +.BR "filename" +The name of the file containing the output from +.B "bombardment(1)" +or from +.B "siege(1)" +.SH "SEE ALSO" +.BR siege (1), +.BR urls_txt (5), +.BR layingsiege (7), +.BR bombardment (1) +.SH AUTHOR +Written by Peter Hutnick + diff --git a/doc/siegerc.in b/doc/siegerc.in new file mode 100644 index 0000000..2bdafd2 --- /dev/null +++ b/doc/siegerc.in @@ -0,0 +1,477 @@ +# Updated by Siege %_VERSION%, %_DATE% +# Copyright 2000-2013 by %_AUTHOR% +# +# Siege configuration file -- edit as necessary +# For more information about configuring and running +# this program, visit: http://www.joedog.org/ + +# +# Variable declarations. You can set variables here +# for use in the directives below. Example: +# PROXY = proxy.joedog.org +# Reference variables inside ${} or $(), example: +# proxy-host = ${PROXY} +# You can also reference ENVIRONMENT variables without +# actually declaring them, example: +# logfile = $(HOME)/var/siege.log + +# +# Verbose mode +# +# Signify verbose mode, true turns on verbose output +# ex: verbose = true|false +# +verbose = true + +# +# Quiet mode +# +# When true, this turns off verbose and standard output. +# You'll still see the opening announcement and the final +# stats if you're running a siege but -g/--get will be +# extremely quiet. This was added primarily for scripting +# ex: quiet = true|false +# +quiet = false + +# +# Get method - select an HTTP method to use when siege +# is set to get mode, siege -g/--get URL. You may select +# GET or HEAD. The default method is HEAD. As expected +# HEAD prints just the headers and GET prints the entire +# page. +# +# NOTE: This only applies when siege is invoked with +# -g/--get. All other requests methods will be made +# on the basis of the URL. +# +# example: gmethod = GET +# +gmethod = HEAD + + +# +# CSV Verbose format: with this option, you can choose +# to format verbose output in traditional siege format +# or comma separated format. The latter will allow you +# to redirect output to a file for import into a spread +# sheet, i.e., siege > file.csv +# ex: csv = true|false (default false) +# +# csv = true + +# +# Timestamp format: with this option, you can choose to +# print a timestamp each line of output +# example: timestamp = true|false (default false) +# +# sample: [Sat, 2010-11-20 10:39:13] HTTP/1.1 200 0.12 secs: 4003 bytes ==> / +# +# timestamp = true + +# +# Full URL verbose format: By default siege displays +# the URL path and not the full URL. With this option, +# you # can instruct siege to show the complete URL. +# ex: fullurl = true|false (default false) +# +# fullurl = true + +# +# Display id: in verbose mode, display the siege user +# id associated with the HTTP transaction information +# ex: display-id = true|false +# +# display-id = + +# +# Show logfile location. By default, siege displays the +# logfile location at the end of every run when logging +# You can turn this message off with this directive. +# ex: show-logfile = false +# +show-logfile = true + +# +# Default logging status, true turns logging on. +# ex: logging = true|false +# +logging = true + +# +# Logfile, the default siege logfile is $PREFIX/var/siege.log +# This directive allows you to choose an alternative log file. +# Environment variables may be used as shown in the examples: +# ex: logfile = /home/jeff/var/log/siege.log +# logfile = ${HOME}/var/log/siege.log +# logfile = ${LOGFILE} +# +# logfile = + +# +# HTTP protocol. Options HTTP/1.1 and HTTP/1.0. +# Some webservers have broken implementation of the +# 1.1 protocol which skews throughput evaluations. +# If you notice some siege clients hanging for +# extended periods of time, change this to HTTP/1.0 +# ex: protocol = HTTP/1.1 +# protocol = HTTP/1.0 +# +protocol = HTTP/1.1 + +# +# Chunked encoding is required by HTTP/1.1 protocol +# but siege allows you to turn it off as desired. +# +# ex: chunked = true +# +chunked = true + +# +# Cache revalidation. +# Siege supports cache revalidation for both ETag and +# Last-modified headers. If a copy is still fresh, the +# server responds with 304. +# HTTP/1.1 200 0.00 secs: 2326 bytes ==> /apache_pb.gif +# HTTP/1.1 304 0.00 secs: 0 bytes ==> /apache_pb.gif +# HTTP/1.1 304 0.00 secs: 0 bytes ==> /apache_pb.gif +# +# ex: cache = true +# +cache = false + +# +# Connection directive. Options "close" and "keep-alive" +# Starting with release 2.57b3, siege implements persistent +# connections in accordance to RFC 2068 using both chunked +# encoding and content-length directives to determine the +# page size. To run siege with persistent connections set +# the connection directive to keep-alive. (Default close) +# CAUTION: use the keep-alive directive with care. +# DOUBLE CAUTION: this directive does not work well on HPUX +# TRIPLE CAUTION: don't use keep-alives until further notice +# ex: connection = close +# connection = keep-alive +# +connection = close + +# +# Default number of simulated concurrent users +# ex: concurrent = 25 +# +concurrent = 15 + +# +# Default duration of the siege. The right hand argument has +# a modifier which specifies the time units, H=hours, M=minutes, +# and S=seconds. If a modifier is not specified, then minutes +# are assumed. +# ex: time = 50M +# +# time = + +# +# Repetitions. The length of siege may be specified in client +# reps rather then a time duration. Instead of specifying a time +# span, you can tell each siege instance to hit the server X number +# of times. So if you chose 'reps = 20' and you've selected 10 +# concurrent users, then siege will hit the server 200 times. +# ex: reps = 20 +# +# reps = + +# +# Default URLs file, set at configuration time, the default +# file is PREFIX/etc/urls.txt. So if you configured siege +# with --prefix=/usr/local then the urls.txt file is installed +# int /usr/local/etc/urls.txt. Use the "file = " directive to +# configure an alternative URLs file. You may use environment +# variables as shown in the examples below: +# ex: file = /export/home/jdfulmer/MYURLS.txt +# file = $HOME/etc/urls.txt +# file = $URLSFILE +# +# file = + +# +# Default URL, this is a single URL that you want to test. This +# is usually set at the command line with the -u option. When +# used, this option overrides the urls.txt (-f FILE/--file=FILE) +# option. You will HAVE to comment this out for in order to use +# the urls.txt file option. +# +# NOTE: you may do the same thing by passing a URL to siege at +# the command line: siege -c10 -r10 "www.joedog.org/" +# Generally, it's a good idea to wrap a command line URL in quotes +# +# ex: url = https://shemp.whoohoo.com/docs/index.jsp +# +# url = + +# +# Default delay value, see the siege(1) man page. +# This value is used for load testing, it is not used +# for benchmarking. +# ex: delay = 3 +# +delay = 1 + +# +# Connection timeout value. Set the value in seconds for +# socket connection timeouts. The default value is 30 seconds. +# ex: timeout = 30 +# +# timeout = + +# +# Session expiration: This directive allows you to delete all +# cookies after you pass through the URLs. This means siege will +# grab a new session with each run through its URLs. The default +# value is false. +# ex: expire-session = true +# +# expire-session = + +# +# Cookie support: by default siege accepts cookies. This directive +# is available to disable that support. Set cookies to 'false' to +# refuse cookies. Set it to 'true' to accept them. The default value +# is true. +# ex: cookies = false +# +# cookies = + +# +# Failures: This is the number of total connection failures allowed +# before siege aborts. Connection failures (timeouts, socket failures, +# etc.) are combined with 400 and 500 level errors in the final stats, +# but those errors do not count against the abort total. If you set +# this total to 10, then siege will abort after ten socket timeouts, +# but it will NOT abort after ten 404s. This is designed to prevent +# a run-away mess on an unattended siege. The default value is 1024 +# ex: failures = 50 +# +# failures = + +# +# Internet simulation. If true, siege clients will hit +# the URLs in the urls.txt file randomly, thereby simulating +# internet usage. If false, siege will run through the +# urls.txt file in order from first to last and back again. +# ex: internet = true +# +internet = false + +# +# Default benchmarking value, If true, there is NO delay +# between server requests, siege runs as fast as the web +# server and the network will let it. Set this to false +# for load testing. +# ex: benchmark = true +# +benchmark = false + +# +# Set the siege User-Agent to identify yourself at the +# host, the default is: JoeDog/1.00 [en] (X11; I; Siege #.##) +# But that wreaks of corporate techno speak. Feel free +# to make it more interesting :-) Since Limey is recovering +# from minor surgery as I write this, I'll dedicate the +# example to him... +# +# ex: user-agent = Limey The Bulldog +# +# user-agent = + +# +# Accept-encoding. This option allows you to specify +# acceptable encodings returned by the server. Use this +# directive to turn on compression. By default we accept +# gzip compression. +# +# ex: accept-encoding = * +# accept-encoding = gzip +# accept-encoding = compress;q=0.5;gzip;q=1 +accept-encoding = gzip + +# +# URL escaping was added in version 3.0.3. You may use this +# directive to turn off this experimental feature. By default +# this feature is active by default starting with v3.0.3 +# +# http://www.joedog.org/jukebox.php?band=the days of new +# becomes: +# http://www.joedog.org/jukebox.php?band=the%20days%20of%20the%20new +# +# ex: url-escaping = false +# +url-escaping = true + +# +# TURN OFF THAT ANNOYING SPINNER! +# Siege spawns a thread and runs a spinner to entertain you +# as it collects and computes its stats. If you don't like +# this feature, you may turn it off here. +# ex: spinner = false +# +spinner = true + +# +# WWW-Authenticate login. When siege hits a webpage +# that requires basic authentication, it will search its +# logins for authentication which matches the specific realm +# requested by the server. If it finds a match, it will send +# that login information. If it fails to match the realm, it +# will send the default login information. (Default is "all"). +# You may configure siege with several logins as long as no +# two realms match. The format for logins is: +# username:password[:realm] where "realm" is optional. +# If you do not supply a realm, then it will default to "all" +# ex: login = jdfulmer:topsecret:Admin +# login = jeff:supersecret +# +# login = + +# +# Login URL. This is the first URL to be hit by every siege +# client. This feature was designed to allow you to login to +# a server and establish a session. It will only be hit once +# so if you need to hit this URL more then once, make sure it +# also appears in your urls.txt file. +# +# ex: login-url = http://eos.haha.com/login.jsp POST name=jeff&pass=foo +# +# Siege versions after 2.69 support multi logins; you can configure +# them with multiple login-url directives. Place each one on a separate +# line. Siege loops through each login then starts again at the beginning +# after it uses the last one. If you have more users than login-urls, then +# siege starts reassigning ones that have already been used. +# +# ex: login-url = http://www.haha.com/login.php?name=homer&pass=whoohoo +# login-url = http://www.haha.com/login.php?name=marge&pass=ohhomie +# login-url = http://www.haha.com/login.php?name=bart&pass=eatMyShorts +# +# login-url = + +# +# FTP login - This directive provides one of two ways +# to login to an ftp server. You may also set credentials +# in RFC-1738 format: ftp://user:pass@host.com/ink.jpg +# +# The format is USER:PASS:HOST separated by colon ':' +# The host field is optional. If you don't set a host, +# then siege will send the same user:pass to every FTP +# server. You may use this directive MULTIPLE times. +# Siege will store each instance in memory and send the +# appropriate credentials at login time depending on the +# hostname in the URL. +# +# ex: ftp-login: jdfulmer:whoohoo:ftp.joedog.org +# ftp-login: jdfulmer:password +# +# ftp-login = + +# +# FTP unique - This directive determines whether siege +# will upload files with the same name (and therefore +# overwrite whatever is on disk) or upload files each with a +# unique name. If true, siege will rewrite the file name with +# a timestamp in its name, i.e., p.jpg => p-3086060432.jpg +# The default value is true. +# +# ex: unique = false +# +unique = true + +# +# ssl-cert +# This optional feature allows you to specify a path to a client +# certificate. It is not neccessary to specify a certificate in +# order to use https. If you don't know why you would want one, +# then you probably don't need this feature. Use openssl to +# generate a certificate and key with the following command: +# $ openssl req -nodes -new -days 365 -newkey rsa:1024 \ +# -keyout key.pem -out cert.pem +# Specify a path to cert.pem as follows: +# ex: ssl-cert = /home/jeff/.certs/cert.pem +# +# ssl-cert = + +# +# ssl-key +# Use this option to specify the key you generated with the command +# above. ex: ssl-key = /home/jeff/.certs/key.pem +# You may actually skip this option and combine both your cert and +# your key in a single file: +# $ cat key.pem > client.pem +# $ cat cert.pem >> client.pem +# Now set the path for ssl-cert: +# ex: ssl-cert = /home/jeff/.certs/client.pem +# (in this scenario, you comment out ssl-key) +# +# ssl-key = + +# +# ssl-timeout +# This option sets a connection timeout for the ssl library +# ex: ssl-timeout = 30 +# +# ssl-timeout = + +# +# ssl-ciphers +# You can use this feature to select a specific ssl cipher +# for HTTPs. To view the ones available with your library run +# the following command: openssl ciphers +# ex: ssl-ciphers = EXP-RC4-MD5 +# +# ssl-ciphers = + +# +# Proxy Host. You can use siege to test a proxy server but +# you need to configure it to use one. You'll need to name +# a proxy host and the port it's listening one. The settings +# are proxy-host and proxy-port. The following example shows +# how to use them. +# ex: proxy-host = proxy.joedog.org +# proxy-port = 3123 +# +# proxy-host = +# proxy-port = + +# +# Proxy-Authenticate. When scout hits a proxy server which +# requires username and password authentication, it will this +# username and password to the server. The format is username, +# password and optional realm each separated by a colon. You +# may enter more than one proxy-login as long as each one has +# a different realm. If you do not enter a realm, then scout +# will send that login information to all proxy challenges. If +# you have more than one proxy-login, then scout will attempt +# to match the login to the realm. +# ex: proxy-login: jeff:secret:corporate +# proxy-login: jeff:whoohoo +# +# proxy-login = + +# +# Redirection support. This option allows to to control +# whether a Location: hint will be followed. Most users +# will want to follow redirection information, but sometimes +# it's desired to just get the Location information. +# +# ex: follow-location = false +# +# follow-location = + +# Zero-length data. siege can be configured to disregard +# results in which zero bytes are read after the headers. +# Alternatively, such results can be counted in the final +# tally of outcomes. +# +# ex: zero-data-ok = false +# +# zero-data-ok = + +# +# end of siegerc diff --git a/doc/urls.txt b/doc/urls.txt new file mode 100644 index 0000000..c726cb0 --- /dev/null +++ b/doc/urls.txt @@ -0,0 +1,16 @@ +# URLS file for siege +# -- +# Format the url entries in any of the following formats: +# http://www.whoohoo.com/index.html +# http://www/index.html +# www/index.html +# http://www.whoohoo.com/cgi-bin/howto/display.cgi?1013 +# Use the POST directive for pages that require it: +# http://www.whoohoo.com/cgi-bin/haha.cgi POST ha=1&ho=2 +# or POST content from a file: +# http://www.whoohoo.com/melvin.jsp POST (\\n(.lu-\\n(.iu)) .TP +.el .TP "\\$1" +.. +.TH URLS.TXT 5 "%_DATE%" "Siege v%_VERSION%" +.SH NAME +.B urls.txt +\- URL database for regression testing +.SH INTRODUCTION +.LP +The urls.txt file is installed by default in SIEGE_HOME/etc/urls.txt. When siege is invoked without a command line reference to a URL, then by default it looks for urls in that file. The advantage of using the urls.txt file is two-fold: One, it frees you free retyping a url with every invocation. And two, it allows you to conduct full site regression testing. + +When the urls.txt file is used, siege reads all the urls in that file into memory and runs through the list in one of two ways, sequentially or randomly. The default run is sequential from start to finish and back again until the \-\-reps or the \-\-time option has been satisfied. With the \-i/\-\-internet option selected, siege runs through the file randomly simulating the stress applied by a community of internet users. \fR +.br + \fR +The \-f/\-\-file option allows you to select a file other then the default urls.txt file. You may also instruct siege to use a different file with the "file" directive in .siegerc, i.e., "file = /usr/local/etc/urls.txt"\fR +.br +\fR +You may set and reference variables inside the urls.txt file. All variables must be declared BEFORE they are referenced. Variables are declared with the "=" operator, VARIABLE = VALUE. They are then referenced inside $() or ${}, example: $(HOST), ${HOST}\fR +.br +\fR +HOST=joey.joedog.org\fR +.br +http://${HOST}/browse.jsp?size=5\fR +.br +http://${HOST}/admin.jsp?name=ralph\fR +.br + +.SH EXAMPLE FILE +This is an exmple urls.txt file. Lines beginning with a hash (#) are comments and ignored by siege.\fR +.br + \fR +.br +# \fR +.br +# Example urls.txt file \fR +.br +# URLs database for siege\fR +.br +# \fR +.br +http://www.haha.com/index.html \fR +.br +http://www.haha.com/howto/index.html \fR +.br +http://www.haha.com/cgi-bin/howto/display.cgi?1013\fR +.br +www.haha.com/cgi-bin/fm.cgi?first=j.&last=fulmer \fR +.br +https://www.haha.com/index.shtml\fR +.br +https://www.whoohoo.com/my_whoohoo.jsp\fR +.br +# POST data requires a POST directive\fR +.br +www.haha.com/cgi-bin/foo.cgi POST first=bart&last=simpson\fR +.br +www.haha.com/hoho.jsp POST name=jeff&pass=secret\fR +.br +# POST the contents of a file using the\fR +.br +# line input character "<"\fR +.br +http://www.haha.com/my.jsp POST , et al. +.SH BUGS +Report bugs to jeff@joedog.org. +Give a detailed description of the problem +and report the version of siege that +you are using. +.SH COPYRIGHT +Copyright \(co 2007 %_AUTHOR% +.LP +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., 675 Mass Ave, Cambridge, MA 02139, USA. +.LP +.SH AVAILABILITY +The most recent released version of siege is available by +anonymous FTP from ftp.joedog.org in the directory pub/siege. +.LP +.SH SEE ALSO +siege(1) siege.config(1) layingsiege(7) diff --git a/html/Makefile.am b/html/Makefile.am new file mode 100644 index 0000000..a43dc98 --- /dev/null +++ b/html/Makefile.am @@ -0,0 +1,35 @@ +## +## html/Makefile.am +## +## Copyright (C) 2007 by +## Jeffrey Fulmer - , et al. +## This file is distributed as part of Siege +## +## 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., 675 Mass Ave, Cambridge, MA 02139, USA. +## + +AUTOMAKE_OPTIONS = foreign no-dependencies + +EXTRA_DIST = \ +README \ +basic.php \ +cache-control.php \ +cookie-test.php \ +etag.php \ +login.php + +install-exec-hook: + @echo "HTML pages not installed" + diff --git a/html/README b/html/README new file mode 100644 index 0000000..bb5fcd4 --- /dev/null +++ b/html/README @@ -0,0 +1,15 @@ +---------------- +SIEGE TEST PAGES +---------------- + +These pages are available to siege developers and users to test its +functionality. Each test is explained individually on the page itself. +Each application is self-contained, i.e., no dependencies. To install, +simply drop them inside your webserver's document root. Make sure the +server supports the associated language. + +Please send language ports of these pages to jeff@joedog.org + + + + diff --git a/html/basic.php b/html/basic.php new file mode 100644 index 0000000..ea296d7 --- /dev/null +++ b/html/basic.php @@ -0,0 +1,26 @@ + + + SIEGE: Successful login + +

Logged in as "siege"

+ Congratulations. You are able to penetrate our defenses by entering the
username and password combination that we provided you on the login page. + + +Authorization required!"; + echo "You can log into this page with the following credentials:
"; + echo "Username: $user
"; + echo "Password: $pass
"; + echo "Realm (optional): $realm
"; + exit; +} +?> diff --git a/html/cache-control.php b/html/cache-control.php new file mode 100644 index 0000000..bf85de2 --- /dev/null +++ b/html/cache-control.php @@ -0,0 +1,16 @@ + + +SIEGE: Cache control + +

Siege Cache-Control

+This page sets a max-age cache control for seconds. The header looks like this:
+ +Cache-Control: s-maxage=, max-age=, must-revalidate, proxy-revalidate + + + + + diff --git a/html/cookie-test.php b/html/cookie-test.php new file mode 100644 index 0000000..3e00875 --- /dev/null +++ b/html/cookie-test.php @@ -0,0 +1,46 @@ +" . + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
" . + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
" . + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
" . + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
"; + + if(!isset($_COOKIE['nelson'])){ + setcookie("nelson", 'HAHA!', time()+$secs); + setcookie("number", 'X'); + } else { + setcookie("number", $x); + } +?> + +SIEGE: Cookie Test + +

Siege Cookie Test

+In verbose mode, you see siege pull down consistently more data each time it downloads
+the page. This pattern will continue for seconds until the nelson cookie expires. The
+number of bytes downloaded will drop to its original size and then stair-step back up again.

+ +Hardy: $ siege -c1 -r100 http://hardy/cookie-test.php
+** SIEGE 2.66
+** Preparing 1 concurrent users for battle.
+The server is now under siege...
+HTTP/1.1 200 0.00 secs: 652 bytes ==> /cookie-test.php
+HTTP/1.1 200 0.00 secs: 653 bytes ==> /cookie-test.php
+HTTP/1.1 200 0.01 secs: 933 bytes ==> /cookie-test.php
+HTTP/1.1 200 0.01 secs: 1213 bytes ==> /cookie-test.php
+HTTP/1.1 200 0.01 secs: 1493 bytes ==> /cookie-test.php
+HTTP/1.1 200 0.02 secs: 1773 bytes ==> /cookie-test.php
+HTTP/1.1 200 0.01 secs: 2053 bytes ==> /cookie-test.php
+HTTP/1.1 200 0.01 secs: 2333 bytes ==> /cookie-test.php
+HTTP/1.1 200 0.02 secs: 2613 bytes ==> /cookie-test.php
+[...]
+HTTP/1.1 200 0.00 secs: 652 bytes ==> /cookie-test.php +
+

+Eventually, bytes will top out at page size plus MAX_COOKIE_SIZE. You can test this
+page manually with the reload button in your web browser.

+ + + diff --git a/html/echo.php b/html/echo.php new file mode 100644 index 0000000..7ef5e55 --- /dev/null +++ b/html/echo.php @@ -0,0 +1,14 @@ +"; + foreach (getallheaders() as $name => $value) { + echo "$name: $value
"; + } + + echo "

"; + ob_end_flush(); + flush(); + foreach (apache_response_headers() as $name => $value) { + echo "$name: $value
"; + } + +?> diff --git a/html/etag.php b/html/etag.php new file mode 100644 index 0000000..6a9ed10 --- /dev/null +++ b/html/etag.php @@ -0,0 +1,30 @@ +"; + echo "SIEGE: Etity Tag Test"; + echo ""; + echo "

Siege Entity Tags

"; + echo "This page sets a entity tag every minute. The header looks like this:
"; + echo ""; + echo "$etag"; + echo "

"; + echo "To test ETags response, you should enable them in your apache webserver. To do this
"; + echo "on apache, you should add the following directive at the server, virtual host, directory
"; + echo "or .htaccess level:

"; + echo ""; + echo "FileETag INode MTime Size"; + echo ""; + echo ""; + echo ""; + } +?> diff --git a/html/login.php b/html/login.php new file mode 100644 index 0000000..b9e6e2e --- /dev/null +++ b/html/login.php @@ -0,0 +1,92 @@ + $val){ + $arr[$key] = $vay; + switch($key){ + case "username": + $username = $val; + break; + case "password": + $password = $val; + break; + } + } + if(empty($username) && empty($password)){ + login(); + return; + } + if($username == "siege" && $password == "haha"){ + success(); + return; + } else { + header('HTTP/1.1 403 Forbidden', true, 403); + print << +SIEGE: Access denied + +

Access denied

+Seriously. We provided you with login credentials. How did you mess that up? + + +END; + exit; + } + } + + function success(){ + print << + SIEGE: Successful login + +

Logged in as "siege"

+ Congratulations. You are able to penetrate our defenses by entering the
username and password combination that we provided you on the login page. + + +END; + } + + function login(){ + print << + SIEGE: Login Page + +

Restricted area

+
+ + + + + + + + + + + + +
Welcome to the top-secret siege login page. To login, user the following credentials:

+ + username: siege
+ password: haha +
+

+ This page accepts both GET and POST requests. You may construct siege URLs in either manner:

+ + siege -c1 -r1 "http://my.server.com/login.php?username=siege&password=haha"
+
OR
+ + siege -c1 -r1 "http://my.server.com/login.php POST username=siege&password=haha" + +

+
Username:
Password:
+
+ + +END; + } + +?> diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..ac58f9b --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,30 @@ +## +## include/Makefile.am +## +## Copyright (C) 2000-2007 by +## Jeffrey Fulmer - , et al. +## This file is distributed as part of Siege +## +## 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. +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +## + +SUBDIRS = joedog + +WARN_CFLAGS = @WARN_CFLAGS@ +AM_CFLAGS = $(WARN_CFLAGS) + +AUTOMAKE_OPTIONS = foreign no-dependencies + +DISTCLEANFILES = config.h stamp-h stamp-h.in diff --git a/include/joedog/Makefile.am b/include/joedog/Makefile.am new file mode 100644 index 0000000..12bd5b1 --- /dev/null +++ b/include/joedog/Makefile.am @@ -0,0 +1,26 @@ +## +## include/joedog/Makefile.am +## +## Copyright (C) 2000, 2001, 2002 by +## Jeffrey Fulmer - , et al +## This file is distributed as part of Siege +## +## 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. +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +## + +noinst_HEADERS = joedog.h getopt.h boolean.h defs.h + +DISTCLEANFILES = joepath.h + diff --git a/include/joedog/boolean.h b/include/joedog/boolean.h new file mode 100644 index 0000000..5a6d809 --- /dev/null +++ b/include/joedog/boolean.h @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2002-2013 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef BOOLEAN_H +#define BOOLEAN_H + +typedef enum {boolean_false=0,boolean_true=1} BOOLEAN; +typedef enum {toolean_false=0,toolean_true=1,toolean_undefined=-1} TOOLEAN; + +#ifndef FALSE +# define FALSE boolean_false +#endif /*FALSE*/ + +#ifndef TRUE +# define TRUE boolean_true +#endif /*TRUE*/ + +#ifndef UNDEFINED +# define UNDEFINED toolean_undefined +#endif /*UNDEFINED*/ + +#endif/*BOOLEAN_H*/ diff --git a/include/joedog/defs.h b/include/joedog/defs.h new file mode 100644 index 0000000..ad86fbd --- /dev/null +++ b/include/joedog/defs.h @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2002-2013 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef JOEDOG_DEFS_H +#define JOEDOG_DEFS_H +#define private static +#define public + +#define ISSEPARATOR(x) (('='==(x))||(':'==(x))) +#define ISSPACE(x) isspace((unsigned char)(x)) +#define ISOPERAND(x) ('<'==(x)||'>'==(x)||'='==(x)) +#define ISDIGIT(x) isdigit ((unsigned char)(x)) +#define ISXDIGIT(c) (((((((((c) - 48U) & 255) * 18 / 17 * 52 / 51 * 58 / 114 \ + * 13 / 11 * 14 / 13 * 35 + 35) / 36 * 35 / 33 * 34 / 33 * 35 / 170 ^ 4) \ + - 3) & 255) ^ 1) <= 2U) +/** + * Lifted from wget: Convert a sequence of ASCII hex digits X and Y + * to a number between 0 and 255. Uses XDIGIT_TO_NUM for conversion + * of individual digits. + */ +#define XDIGIT_TO_NUM(x) ((x) < 'A' ? (x) - '0' : TOUPPER (x) - 'A' + 10) +#define XNUM_TO_DIGIT(x) ("0123456789ABCDEF"[x]) +#define XNUM_TO_digit(x) ("0123456789abcdef"[x]) +#define X2DIGITS_TO_NUM(h1, h2) ((XDIGIT_TO_NUM (h1) << 4) + XDIGIT_TO_NUM (h2)) + +#define ISNUMBER(v) (((v) > (char)0x2f) && ((v) < (char)0x3a)) +#define ISQUOTE(x) (x == '"' || x == '\'') +#if STDC_HEADERS +# define TOLOWER(Ch) tolower (Ch) +# define TOUPPER(Ch) toupper (Ch) +#else +# define TOLOWER(Ch) (ISUPPER (Ch) ? tolower (Ch) : (Ch)) +# define TOUPPER(Ch) (ISLOWER (Ch) ? toupper (Ch) : (Ch)) +#endif + +#ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +#endif /*EXIT_SUCESS*/ +#ifndef EXIT_FAILURE +# define EXIT_FAILURE 1 +#endif /*EXIT_FAILURE*/ + +#endif/*JOEDOG_DEFS_H*/ diff --git a/include/joedog/getopt.h b/include/joedog/getopt.h new file mode 100644 index 0000000..e081fd1 --- /dev/null +++ b/include/joedog/getopt.h @@ -0,0 +1,171 @@ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library 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. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + $Id: getopt.h,v 1.2 2013/08/19 14:07:45 jdfulmer Exp $ +*/ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if defined __STDC__ && __STDC__ + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if defined __STDC__ && __STDC__ +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int __argc, char *const *__argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/include/joedog/joedog.h b/include/joedog/joedog.h new file mode 100644 index 0000000..b29d8fe --- /dev/null +++ b/include/joedog/joedog.h @@ -0,0 +1,150 @@ +#ifndef JOEDOG_H +#define JOEDOG_H +/** + * JOEDOG HEADER + * + * Copyright (C) 2000-2006 Jeffrey Fulmer + * This file is part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * -- + */ +#include +#include +#include + +#define BLACK 0 +#define RED 1 +#define GREEN 2 +#define YELLOW 3 +#define BLUE 4 +#define MAGENTA 5 +#define CYAN 6 +#define WHITE 7 + +/** + * Error notification + */ +typedef enum { + DEBUG = 0, + WARNING = 1, + ERROR = 2, + FATAL = 3 +} LEVEL; + +void OPENLOG(char *program_name); +void CLOSELOG(void); +void SYSLOG(LEVEL L, const char *fmt, ...); +void NOTIFY(LEVEL L, const char *fmt, ...); +void DISPLAY(int color, const char *fmt, ...); + +/** + * Memory management + */ +void * xrealloc(void *, size_t); +void * xmalloc (size_t); +void * xcalloc (size_t, size_t); +char * xstrdup(const char *str); +char * xstrcat(const char *arg1, ...); +void xfree(void *ptr); + +/** + * Utility functions + */ +void itoa(int, char []); +void reverse(char []); +int my_random(int, int); +char *substring(char *, int, int); +float elapsed_time(clock_t); + +/** + * snprintf functions + */ +#define PORTABLE_SNPRINTF_VERSION_MAJOR 2 +#define PORTABLE_SNPRINTF_VERSION_MINOR 2 + +#ifdef HAVE_SNPRINTF +#include +#else +extern int snprintf(char *, size_t, const char *, /*args*/ ...); +extern int vsnprintf(char *, size_t, const char *, va_list); +#endif + +#if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF) +extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); +extern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); +#define snprintf portable_snprintf +#define vsnprintf portable_vsnprintf +#endif + +#ifndef __CYGWIN__ +extern int asprintf (char **ptr, const char *fmt, /*args*/ ...); +extern int vasprintf (char **ptr, const char *fmt, va_list ap); +extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); +extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap); +#endif/*__CYGWIN__*/ + +/** + * chomps the newline character off + * the end of a string. + */ +char *chomp(char *str); + +/** + * trims the white space from the right + * of a string. + */ +char *rtrim(char *str); + +/** + * trims the white space from the left + * of a string. + */ +char *ltrim(char *str); + +/** + * trims the white space from the left + * and the right sides of a string. + */ +char * trim(char *str); + +/** + * split string *s on pattern pattern pointer + * n_words holds the size of ** + */ +char **split(char pattern, char *s, int *n_words); + +/** + * free memory allocated by split + */ +void split_free(char **split, int length); + + +/** + * tests for empty string; warns if invalid + */ +int empty(const char *s); + +/** + * portable strsep + */ +char *xstrsep(char **stringp, const char *delim); + +/** + * string allocation + */ +char *stralloc(char *); + +#endif/* JOEDOG_H */ diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..0ae12c0 --- /dev/null +++ b/install-sh @@ -0,0 +1,401 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-11-07.23 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# 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}" + +posix_glob= +posix_mkdir= + +# Symbolic mode for testing mkdir with directories. +# It is the same as 755, but also tests that "u+" works. +test_mode=u=rwx,g=rx,o=rx,u+wx + +# Desired mode of installed file. +mode=0755 + +# Desired mode of newly created intermediate directories. +# It is empty if not known yet. +intermediate_mode= + +chmodcmd=$chmodprog +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +test -n "$dir_arg" || trap '(exit $?); exit' 1 2 13 15 + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + posix_mkdir=false + if $mkdirprog -m $test_mode -p -- / >/dev/null 2>&1; then + posix_mkdir=true + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./-m "$test_mode" ./-p ./-- 2>/dev/null + fi ;; + esac + + if + $posix_mkdir && { + + # With -d, create the new directory with the user-specified mode. + # Otherwise, create it using the same intermediate mode that + # mkdir -p would use when creating intermediate directories. + # POSIX says that this mode is "$(umask -S),u+wx", so use that + # if umask -S works. + + if test -n "$dir_arg"; then + mkdir_mode=$mode + else + case $intermediate_mode in + '') + if umask_S=`(umask -S) 2>/dev/null`; then + intermediate_mode=$umask_S,u+wx + else + intermediate_mode=$test_mode + fi ;; + esac + mkdir_mode=$intermediate_mode + fi + + $mkdirprog -m "$mkdir_mode" -p -- "$dstdir" + } + then : + else + + # mkdir does not conform to POSIX, or it failed possibly due to + # a race condition. Create the directory the slow way, step by + # step, checking for races as we go. + + case $dstdir in + /*) pathcomp=/ ;; + -*) pathcomp=./ ;; + *) pathcomp= ;; + esac + + case $posix_glob in + '') + if (set -f) 2>/dev/null; then + posix_glob=true + else + posix_glob=false + fi ;; + esac + + oIFS=$IFS + IFS=/ + $posix_glob && set -f + set fnord $dstdir + shift + $posix_glob && set +f + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + pathcomp=$pathcomp$d + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # Don't fail if two instances are running concurrently. + test -d "$pathcomp" || exit 1 + fi + pathcomp=$pathcomp/ + done + obsolete_mkdir_used=true + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # 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 $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dst"; then + $doit $rmcmd -f "$dst" 2>/dev/null \ + || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ + && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ + || { + echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + } || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..4733059 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,29 @@ +## +## lib/Makefile.am +## +## Copyright (C) 2000-2007 by +## Jeffrey Fulmer - , et al. +## This file is distributed as part of Siege +## +## 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. +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +## + +SUBDIRS = joedog + +AUTOMAKE_OPTIONS = foreign no-dependencies + +WARN_CFLAGS = @WARN_CFLAGS@ +AM_CFLAGS = $(WARN_CFLAGS) + diff --git a/lib/joedog/Makefile.am b/lib/joedog/Makefile.am new file mode 100644 index 0000000..d641a18 --- /dev/null +++ b/lib/joedog/Makefile.am @@ -0,0 +1,39 @@ +## +## lib/joedog/Makefile.am +## +## Copyright (C) 2000-2007 by +## Jeffrey Fulmer - , et al. +## This file is distributed as part of Siege +## +## 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. +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +## + +AUTOMAKE_OPTIONS = foreign no-dependencies + +WARN_CFLAGS = @WARN_CFLAGS@ +AM_CFLAGS = $(WARN_CFLAGS) + +noinst_LTLIBRARIES = libjoedog.la + +libjoedog_la_LDFLAGS = -version-info 1:0:1 + +libjoedog_la_SOURCES = \ +memory.c memory.h \ +notify.c notify.h \ +perl.c perl.h \ +util.c util.h \ +snprintf.c snprintf.h \ +stralloc.c stralloc.h + diff --git a/lib/joedog/memory.c b/lib/joedog/memory.c new file mode 100644 index 0000000..5f9509b --- /dev/null +++ b/lib/joedog/memory.c @@ -0,0 +1,143 @@ +/** + * Memory handling + * Library: joedog + * + * Copyright (C) 2000-2013 by + * Jeffrey Fulmer - + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * -- + * + */ +#include +#include +#include +#include +#include + +char * +xstrdup(const char *str) +{ + register char *ret; +#ifndef HAVE_STRDUP + register size_t len; +#endif/*HAVE_STRDUP*/ + + if(!str){ + NOTIFY(ERROR, "string has no value!"); + return NULL; + } +#ifdef HAVE_STRDUP + ret = strdup(str); + if(ret==NULL) NOTIFY(FATAL, "xstrdup: unable to allocate additional memory"); +#else + len = strlen(str)+1; + ret = malloc(len); + if (ret==NULL) { + NOTIFY(FATAL, "xstrdup: unable to allocate additional memory"); + } + memcpy(ret, str, len); +#endif + return ret; +} + +char * +xstrcat(const char *arg1, ...) +{ + const char *argptr; + char *resptr, *result; + int nargs = 0; + size_t len = 0; + va_list valist; + + va_start(valist, arg1); + + for(argptr = arg1; argptr != NULL; argptr = va_arg(valist, char *)) + len += strlen(argptr); + + va_end(valist); + + result = xmalloc(len + 1); + resptr = result; + + va_start(valist, arg1); + + nargs = 0; + for(argptr = arg1; argptr != NULL; argptr = va_arg(valist, char *)) { + len = strlen(argptr); + memcpy(resptr, argptr, len); + resptr += len; + } + + va_end(valist); + + *resptr = '\0'; + + return result; +} + +/** + * xrealloc: value added realloc + */ +void * +xrealloc(void *ptr, size_t size) +{ + void *tmp; + if (ptr) { + tmp = realloc(ptr, size); + } else { + tmp = malloc(size); + } + if (tmp==NULL) NOTIFY(FATAL, "Memory exhausted; unable to continue."); + return tmp; +} + +/** + * xmalloc: value-added malloc + */ +void * +xmalloc(size_t size) +{ + void *tmp = malloc(size); + if(tmp==NULL) NOTIFY(FATAL, "Unable to allocate additional memory."); + return tmp; +} + +/** + * xcalloc replaces calloc + */ +void * +xcalloc(size_t num, size_t size) +{ + void *tmp = xmalloc(num * size); + memset(tmp, 0, (num * size)); + return tmp; +} + + +/** + * free() wrapper: + * free it and NULL it to ensure we + * don't free it a second time... + */ +void +xfree(void *ptr) +{ + if(ptr!=(void *)NULL){ + free(ptr); ptr=(void *)NULL; + } +} + diff --git a/lib/joedog/memory.h b/lib/joedog/memory.h new file mode 100644 index 0000000..4725951 --- /dev/null +++ b/lib/joedog/memory.h @@ -0,0 +1,53 @@ +/** + * Memory handling + * Library: joedog + * + * Copyright (C) 2000-2007 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef MEMORY_H +#define MEMORY_H + +#include + +/** + * a controlled strdup + */ +char * xstrdup(const char *str); + +/** + * a controlled realloc + */ +void * xrealloc(void *, size_t); + +/** + * a controlled malloc + */ +void * xmalloc (size_t); + +/** + * a controlled calloc + */ +void * xcalloc (size_t, size_t); + +/** + * a controlled free + */ +void xfree(void *ptr); + +#endif /* MEMORY_H */ diff --git a/lib/joedog/notify.c b/lib/joedog/notify.c new file mode 100644 index 0000000..9e43d49 --- /dev/null +++ b/lib/joedog/notify.c @@ -0,0 +1,173 @@ +/** + * Error notification + * Library: joedog + * + * Copyright (C) 2000-2013 by + * Jeffrey Fulmer - , et. al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 40000 + +#define RESET 0 +#define BRIGHT 1 +#define DIM 2 +#define UNDERLINE 3 +#define BLINK 4 +#define REVERSE 7 +#define HIDDEN 8 + +#define BLACK 0 +#define RED 1 +#define GREEN 2 +#define YELLOW 3 +#define BLUE 4 +#define MAGENTA 5 +#define CYAN 6 +#define WHITE 7 + +typedef enum { + __LOG = 1, + __OUT = 2, +} METHOD; + +static void __message(METHOD M, LEVEL L, const char *fmt, va_list ap); + +void +OPENLOG(char *program) +{ + openlog(program, LOG_PID, LOG_DAEMON); + return; +} + +void +CLOSELOG(void) +{ + closelog(); + return; +} + +static void +__message(METHOD M, LEVEL L, const char *fmt, va_list ap) +{ + char buf[BUFSIZE]; + char msg[BUFSIZE+1024]; + LEVEL level = WARNING; + char pmode[64]; + char lmode[64]; + memset(lmode, '\0', 64); + memset(pmode, '\0', 64); + + vsprintf(buf, fmt, ap); + if (errno == 0 || errno == ENOSYS || L == DEBUG) { + snprintf(msg, sizeof msg, "%s\n", buf); + } else { + snprintf(msg, sizeof msg, "%s: %s\n", buf, strerror(errno)); + } + + switch (L) { + case DEBUG: + sprintf(pmode, "[%c[%d;%dmdebug%c[%dm]", 0x1B, BRIGHT, BLUE+30, 0x1B, RESET); + strcpy(lmode, "[debug]"); + level = LOG_WARNING; + break; + case WARNING: + sprintf(pmode, "[%c[%d;%dmalert%c[%dm]", 0x1B, BRIGHT, GREEN+30, 0x1B, RESET); + strcpy(lmode, "[alert] "); + level = LOG_WARNING; + break; + case ERROR: + sprintf(pmode, "[%c[%d;%dmerror%c[%dm]", 0x1B, BRIGHT, YELLOW+30, 0x1B, RESET); + strcpy(lmode, "[error]"); + level = LOG_ERR; + break; + case FATAL: + sprintf(pmode, "[%c[%d;%dmfatal%c[%dm]", 0x1B, BRIGHT, RED+30, 0x1B, RESET); + strcpy(lmode, "[fatal]"); + level = LOG_CRIT; + break; + } + + if (M == __LOG) { + syslog(level, "%s %s", lmode, msg); + } else { + fflush(stdout); + fprintf(stderr, "%s %s", pmode, msg); + } + if (L==FATAL) { exit(1); } + return; +} + +void +SYSLOG(LEVEL L, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + __message(__LOG, L, fmt, ap); + va_end(ap); + + return; +} + +void +NOTIFY(LEVEL L, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + __message(__OUT, L, fmt, ap); + va_end(ap); + + return; +} + +void +__display(int color, const char *fmt, va_list ap) +{ + char buf[BUFSIZE]; + char msg[BUFSIZE+1024]; + + vsprintf(buf, fmt, ap); + snprintf(msg, sizeof msg, "%c[%d;%dm%s%c[%dm\n", 0x1B, RESET, color+30, buf, 0x1B, RESET); + printf("%s", msg); + return; +} + +void +DISPLAY(int color, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + __display(color, fmt, ap); + va_end(ap); + return; +} + diff --git a/lib/joedog/notify.h b/lib/joedog/notify.h new file mode 100644 index 0000000..e6d2842 --- /dev/null +++ b/lib/joedog/notify.h @@ -0,0 +1,39 @@ +/** + * Error notification + * Library: joedog + * + * Copyright (C) 2000-2009 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef NOTIFY_H +#define NOTIFY_H + +typedef enum { + DEBUG = 0, + WARNING = 1, + ERROR = 2, + FATAL = 3 +} LEVEL; + +void OPENLOG(char *program_name); +void CLOSELOG(void); +void SYSLOG(LEVEL L, const char *fmt, ...); +void NOTIFY(LEVEL L, const char *fmt, ...); + + +#endif/*NOTIFY_H*/ diff --git a/lib/joedog/perl.c b/lib/joedog/perl.c new file mode 100644 index 0000000..17408ba --- /dev/null +++ b/lib/joedog/perl.c @@ -0,0 +1,211 @@ +/** + * Perly functions + * Library: joedog + * + * Copyright (C) 2000-2007 by + * Jeffrey Fulmer - + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#include +#include +#include +#include +#include + +#define SPLITSZ 256 + +/** + * not quite perl chomp, this function + * hacks the newline off the end of a + * string. + */ +char * +chomp(char *str) +{ + if(*str && str[strlen(str)-1]=='\n') str[strlen(str)-1] = 0; + return str; +} + +/** + * rtrim + */ +char * +rtrim(char *str) +{ + char *ptr; + int len; + + len = strlen(str); + for(ptr = str + len - 1; ptr >= str && isspace((int)*ptr ); --ptr); + + ptr[1] = '\0'; + + return str; +} + +/** + * ltrim: trim white space off left of str + */ +char * +ltrim(char *str) +{ + char *ptr; + int len; + + for(ptr = str; *ptr && isspace((int)*ptr); ++ptr); + + len = strlen(ptr); + memmove(str, ptr, len + 1); + + return str; +} + +/** + * trim: calls ltrim and rtrim + */ +char * +trim(char *str) +{ + char *ptr; + ptr = rtrim(str); + str = ltrim(ptr); + return str; +} + +int +valid(const char *s) +{ + int flag=0; + int i = 0; + + for(i = 0; i <= 255; i++){ + flag = flag || s[i]=='\0'; + } + + if(flag){ + return 1; + } else { + return 0; + } +} + +int +empty(const char *s) +{ + if(!s) return 1; + if(strlen(s) < 1) return 1; + + while ((ISSPACE(*s))) + s++; + return (*s == '\0'); +} + + +int +word_count(char pattern, char *s) +{ + int in_word_flag = 0; + int count = 0; + char *ptr; + + ptr = s; + while(*ptr){ + if((*ptr) != pattern){ + if(in_word_flag == 0) + count++; + in_word_flag = 1; + } else { + in_word_flag = 0; + } + ptr++; + } + return count; +} + +char ** +split(char pattern, char *s, int *n_words) +{ + char **words; + char *str0, *str1; + int i; + + *n_words = word_count(pattern, s); + if( *n_words == 0 ) + return NULL; + + words = xmalloc(*n_words * sizeof (*words)); + if(!words) + return NULL; + + str0 = s; + i = 0; + while(*str0){ + size_t len; + str1 = strchr(str0, pattern); + if(str1 != NULL){ + len = str1 - str0; + } else { + len = strlen(str0); + } + + /** + * if len is 0 then str0 and str1 match + * which means the string begins with a + * separator. we don't want to allocate + * memory for an empty string, we just want + * to increment the pointer. on 0 we decrement + * i since it will be incremented below... + */ + if(len == 0){ + i--; + } else { + words[i] = (char*)xmalloc(SPLITSZ); + memset(words[i], '\0', SPLITSZ ); + memcpy(words[i], (char*)str0, SPLITSZ); + words[i][len] = '\0'; + } + + if(str1 != NULL){ + str0 = ++str1; + } else { + break; + } + i++; + } + return words; +} + +void +split_free(char **split, int length) +{ + int x; + for(x = 0; x < length; x ++){ + if( split[x] != NULL ){ + char *tmp = split[x]; + xfree(tmp); + } + } + free(split); + + return; +} diff --git a/lib/joedog/perl.h b/lib/joedog/perl.h new file mode 100644 index 0000000..5ebf788 --- /dev/null +++ b/lib/joedog/perl.h @@ -0,0 +1,78 @@ +/** + * Perly functions + * Library: joedog + * + * Copyright (C) 2000-2007 by + * Jeffrey Fulmer - + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef PERL_H +#define PERL_H + +#include +#include + +/** + * not quite perl chomp, this function + * hacks the newline off the end of + * string str. + */ +char *chomp( char *str ); + +/** + * trims the white space from the right + * of a string. + */ +char *rtrim(char *str); + +/** + * trims the white space from the left + * of a string. + */ +char *ltrim(char *str); + +/** + * trims the white space from the left + * and the right sides of a string. + */ +char * trim(char *str); + +/** + * local library function prototyped here + * for split. + */ +int word_count( char pattern, char *s ); + +/** + * split string *s on pattern pattern pointer + * n_words holds the size of ** + */ +char **split( char pattern, char *s, int *n_words ); + +/** + * free memory allocated by split + */ +void split_free( char **split, int length ); + +/** + * tests for empty string; warns if invalid + */ +int empty(const char *s); + +#endif diff --git a/lib/joedog/snprintf.c b/lib/joedog/snprintf.c new file mode 100644 index 0000000..e623e04 --- /dev/null +++ b/lib/joedog/snprintf.c @@ -0,0 +1,1027 @@ +/* + * snprintf.c - a portable implementation of snprintf + * + * AUTHOR + * Mark Martinec , April 1999. + * + * Copyright 1999, Mark Martinec. All rights reserved. + * + * TERMS AND CONDITIONS + * This program is free software; you can redistribute it and/or modify + * it under the terms of the "Frontier Artistic License" which comes + * with this Kit. + * + * 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 Frontier Artistic License for more details. + * + * You should have received a copy of the Frontier Artistic License + * with this Kit in the file named LICENSE.txt . + * If not, I'll be glad to provide one. + * + * FEATURES + * - careful adherence to specs regarding flags, field width and precision; + * - good performance for large string handling (large format, large + * argument or large paddings). Performance is similar to system's sprintf + * and in several cases significantly better (make sure you compile with + * optimizations turned on, tell the compiler the code is strict ANSI + * if necessary to give it more freedom for optimizations); + * - return value semantics per ISO/IEC 9899:1999 ("ISO C99"); + * - written in standard ISO/ANSI C - requires an ANSI C compiler. + * + * SUPPORTED CONVERSION SPECIFIERS AND DATA TYPES + * + * This snprintf only supports the following conversion specifiers: + * s, c, d, u, o, x, X, p (and synonyms: i, D, U, O - see below) + * with flags: '-', '+', ' ', '0' and '#'. + * An asterisk is supported for field width as well as precision. + * + * Length modifiers 'h' (short int), 'l' (long int), + * and 'll' (long long int) are supported. + * NOTE: + * If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default) the + * length modifier 'll' is recognized but treated the same as 'l', + * which may cause argument value truncation! Defining + * SNPRINTF_LONGLONG_SUPPORT requires that your system's sprintf also + * handles length modifier 'll'. long long int is a language extension + * which may not be portable. + * + * Conversion of numeric data (conversion specifiers d, u, o, x, X, p) + * with length modifiers (none or h, l, ll) is left to the system routine + * sprintf, but all handling of flags, field width and precision as well as + * c and s conversions is done very carefully by this portable routine. + * If a string precision (truncation) is specified (e.g. %.8s) it is + * guaranteed the string beyond the specified precision will not be referenced. + * + * Length modifiers h, l and ll are ignored for c and s conversions (data + * types wint_t and wchar_t are not supported). + * + * The following common synonyms for conversion characters are supported: + * - i is a synonym for d + * - D is a synonym for ld, explicit length modifiers are ignored + * - U is a synonym for lu, explicit length modifiers are ignored + * - O is a synonym for lo, explicit length modifiers are ignored + * The D, O and U conversion characters are nonstandard, they are supported + * for backward compatibility only, and should not be used for new code. + * + * The following is specifically NOT supported: + * - flag ' (thousands' grouping character) is recognized but ignored + * - numeric conversion specifiers: f, e, E, g, G and synonym F, + * as well as the new a and A conversion specifiers + * - length modifier 'L' (long double) and 'q' (quad - use 'll' instead) + * - wide character/string conversions: lc, ls, and nonstandard + * synonyms C and S + * - writeback of converted string length: conversion character n + * - the n$ specification for direct reference to n-th argument + * - locales + * + * It is permitted for str_m to be zero, and it is permitted to specify NULL + * pointer for resulting string argument if str_m is zero (as per ISO C99). + * + * The return value is the number of characters which would be generated + * for the given input, excluding the trailing null. If this value + * is greater or equal to str_m, not all characters from the result + * have been stored in str, output bytes beyond the (str_m-1) -th character + * are discarded. If str_m is greater than zero it is guaranteed + * the resulting string will be null-terminated. + * + * NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1, + * but is different from some older and vendor implementations, + * and is also different from XPG, XSH5, SUSv2 specifications. + * For historical discussion on changes in the semantics and standards + * of snprintf see printf(3) man page in the Linux programmers manual. + * + * Routines asprintf and vasprintf return a pointer (in the ptr argument) + * to a buffer sufficiently large to hold the resulting string. This pointer + * should be passed to free(3) to release the allocated storage when it is + * no longer needed. If sufficient space cannot be allocated, these functions + * will return -1 and set ptr to be a NULL pointer. These two routines are a + * GNU C library extensions (glibc). + * + * Routines asnprintf and vasnprintf are similar to asprintf and vasprintf, + * yet, like snprintf and vsnprintf counterparts, will write at most str_m-1 + * characters into the allocated output string, the last character in the + * allocated buffer then gets the terminating null. If the formatted string + * length (the return value) is greater than or equal to the str_m argument, + * the resulting string was truncated and some of the formatted characters + * were discarded. These routines present a handy way to limit the amount + * of allocated memory to some sane value. + * + * AVAILABILITY + * http://www.ijs.si/software/snprintf/ + * + * REVISION HISTORY + * 1999-04 V0.9 Mark Martinec + * - initial version, some modifications after comparing printf + * man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10, + * and checking how Perl handles sprintf (differently!); + * 1999-04-09 V1.0 Mark Martinec + * - added main test program, fixed remaining inconsistencies, + * added optional (long long int) support; + * 1999-04-12 V1.1 Mark Martinec + * - support the 'p' conversion (pointer to void); + * - if a string precision is specified + * make sure the string beyond the specified precision + * will not be referenced (e.g. by strlen); + * 1999-04-13 V1.2 Mark Martinec + * - support synonyms %D=%ld, %U=%lu, %O=%lo; + * - speed up the case of long format string with few conversions; + * 1999-06-30 V1.3 Mark Martinec + * - fixed runaway loop (eventually crashing when str_l wraps + * beyond 2^31) while copying format string without + * conversion specifiers to a buffer that is too short + * (thanks to Edwin Young for + * spotting the problem); + * - added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) + * to snprintf.h + * 2000-02-14 V2.0 (never released) Mark Martinec + * - relaxed license terms: The Artistic License now applies. + * You may still apply the GNU GENERAL PUBLIC LICENSE + * as was distributed with previous versions, if you prefer; + * - changed REVISION HISTORY dates to use ISO 8601 date format; + * - added vsnprintf (patch also independently proposed by + * Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01) + * 2000-06-27 V2.1 Mark Martinec + * - removed POSIX check for str_m<1; value 0 for str_m is + * allowed by ISO C99 (and GNU C library 2.1) - (pointed out + * on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie). + * Besides relaxed license this change in standards adherence + * is the main reason to bump up the major version number; + * - added nonstandard routines asnprintf, vasnprintf, asprintf, + * vasprintf that dynamically allocate storage for the + * resulting string; these routines are not compiled by default, + * see comments where NEED_V?ASN?PRINTF macros are defined; + * - autoconf contributed by Caolan McNamara + * 2000-10-06 V2.2 Mark Martinec + * - BUG FIX: the %c conversion used a temporary variable + * that was no longer in scope when referenced, + * possibly causing incorrect resulting character; + * - BUG FIX: make precision and minimal field width unsigned + * to handle huge values (2^31 <= n < 2^32) correctly; + * also be more careful in the use of signed/unsigned/size_t + * internal variables - probably more careful than many + * vendor implementations, but there may still be a case + * where huge values of str_m, precision or minimal field + * could cause incorrect behaviour; + * - use separate variables for signed/unsigned arguments, + * and for short/int, long, and long long argument lengths + * to avoid possible incompatibilities on certain + * computer architectures. Also use separate variable + * arg_sign to hold sign of a numeric argument, + * to make code more transparent; + * - some fiddling with zero padding and "0x" to make it + * Linux compatible; + * - systematically use macros fast_memcpy and fast_memset + * instead of case-by-case hand optimization; determine some + * breakeven string lengths for different architectures; + * - terminology change: 'format' -> 'conversion specifier', + * 'C9x' -> 'ISO/IEC 9899:1999 ("ISO C99")', + * 'alternative form' -> 'alternate form', + * 'data type modifier' -> 'length modifier'; + * - several comments rephrased and new ones added; + * - make compiler not complain about 'credits' defined but + * not used; + */ + + +/* Define HAVE_SNPRINTF if your system already has snprintf and vsnprintf. + * + * If HAVE_SNPRINTF is defined this module will not produce code for + * snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well, + * causing this portable version of snprintf to be called portable_snprintf + * (and portable_vsnprintf). + */ +/* #define HAVE_SNPRINTF */ + +/* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and + * vsnprintf but you would prefer to use the portable routine(s) instead. + * In this case the portable routine is declared as portable_snprintf + * (and portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf') + * is defined to expand to 'portable_v?snprintf' - see file snprintf.h . + * Defining this macro is only useful if HAVE_SNPRINTF is also defined, + * but does does no harm if defined nevertheless. + */ +/* #define PREFER_PORTABLE_SNPRINTF */ + +/* Define SNPRINTF_LONGLONG_SUPPORT if you want to support + * data type (long long int) and length modifier 'll' (e.g. %lld). + * If undefined, 'll' is recognized but treated as a single 'l'. + * + * If the system's sprintf does not handle 'll' + * the SNPRINTF_LONGLONG_SUPPORT must not be defined! + * + * This is off by default as (long long int) is a language extension. + */ +/* #define SNPRINTF_LONGLONG_SUPPORT */ + +/* Define NEED_SNPRINTF_ONLY if you only need snprintf, and not vsnprintf. + * If NEED_SNPRINTF_ONLY is defined, the snprintf will be defined directly, + * otherwise both snprintf and vsnprintf routines will be defined + * and snprintf will be a simple wrapper around vsnprintf, at the expense + * of an extra procedure call. + */ +/* #define NEED_SNPRINTF_ONLY */ + +/* Define NEED_V?ASN?PRINTF macros if you need library extension + * routines asprintf, vasprintf, asnprintf, vasnprintf respectively, + * and your system library does not provide them. They are all small + * wrapper routines around portable_vsnprintf. Defining any of the four + * NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY + * and turns on PREFER_PORTABLE_SNPRINTF. + * + * Watch for name conflicts with the system library if these routines + * are already present there. + * + * NOTE: vasprintf and vasnprintf routines need va_copy() from stdarg.h, as + * specified by C99, to be able to traverse the same list of arguments twice. + * I don't know of any other standard and portable way of achieving the same. + * With some versions of gcc you may use __va_copy(). You might even get away + * with "ap2 = ap", in this case you must not call va_end(ap2) ! + * #define va_copy(ap2,ap) ap2 = ap + */ +/* #define NEED_ASPRINTF */ +/* #define NEED_ASNPRINTF */ +/* #define NEED_VASPRINTF */ +/* #define NEED_VASNPRINTF */ + + +/* Define the following macros if desired: + * SOLARIS_COMPATIBLE, SOLARIS_BUG_COMPATIBLE, + * HPUX_COMPATIBLE, HPUX_BUG_COMPATIBLE, LINUX_COMPATIBLE, + * DIGITAL_UNIX_COMPATIBLE, DIGITAL_UNIX_BUG_COMPATIBLE, + * PERL_COMPATIBLE, PERL_BUG_COMPATIBLE, + * + * - For portable applications it is best not to rely on peculiarities + * of a given implementation so it may be best not to define any + * of the macros that select compatibility and to avoid features + * that vary among the systems. + * + * - Selecting compatibility with more than one operating system + * is not strictly forbidden but is not recommended. + * + * - 'x'_BUG_COMPATIBLE implies 'x'_COMPATIBLE . + * + * - 'x'_COMPATIBLE refers to (and enables) a behaviour that is + * documented in a sprintf man page on a given operating system + * and actually adhered to by the system's sprintf (but not on + * most other operating systems). It may also refer to and enable + * a behaviour that is declared 'undefined' or 'implementation specific' + * in the man page but a given implementation behaves predictably + * in a certain way. + * + * - 'x'_BUG_COMPATIBLE refers to (and enables) a behaviour of system's sprintf + * that contradicts the sprintf man page on the same operating system. + * + * - I do not claim that the 'x'_COMPATIBLE and 'x'_BUG_COMPATIBLE + * conditionals take into account all idiosyncrasies of a particular + * implementation, there may be other incompatibilities. + */ + + + +/* ============================================= */ +/* NO USER SERVICABLE PARTS FOLLOWING THIS POINT */ +/* ============================================= */ + +#define PORTABLE_SNPRINTF_VERSION_MAJOR 2 +#define PORTABLE_SNPRINTF_VERSION_MINOR 2 + +#if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF) +# if defined(NEED_SNPRINTF_ONLY) +# undef NEED_SNPRINTF_ONLY +# endif +# if !defined(PREFER_PORTABLE_SNPRINTF) +# define PREFER_PORTABLE_SNPRINTF +# endif +#endif + +#if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE) +#define SOLARIS_COMPATIBLE +#endif + +#if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE) +#define HPUX_COMPATIBLE +#endif + +#if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE) +#define DIGITAL_UNIX_COMPATIBLE +#endif + +#if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE) +#define PERL_COMPATIBLE +#endif + +#if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE) +#define LINUX_COMPATIBLE +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef isdigit +#undef isdigit +#endif +#define isdigit(c) ((c) >= '0' && (c) <= '9') + +/* For copying strings longer or equal to 'breakeven_point' + * it is more efficient to call memcpy() than to do it inline. + * The value depends mostly on the processor architecture, + * but also on the compiler and its optimization capabilities. + * The value is not critical, some small value greater than zero + * will be just fine if you don't care to squeeze every drop + * of performance out of the code. + * + * Small values favor memcpy, large values favor inline code. + */ +#if defined(__alpha__) || defined(__alpha) +# define breakeven_point 2 /* AXP (DEC Alpha) - gcc or cc or egcs */ +#endif +#if defined(__i386__) || defined(__i386) +# define breakeven_point 12 /* Intel Pentium/Linux - gcc 2.96 */ +#endif +#if defined(__hppa) +# define breakeven_point 10 /* HP-PA - gcc */ +#endif +#if defined(__sparc__) || defined(__sparc) +# define breakeven_point 33 /* Sun Sparc 5 - gcc 2.8.1 */ +#endif + +/* some other values of possible interest: */ +/* #define breakeven_point 8 */ /* VAX 4000 - vaxc */ +/* #define breakeven_point 19 */ /* VAX 4000 - gcc 2.7.0 */ + +#ifndef breakeven_point +# define breakeven_point 6 /* some reasonable one-size-fits-all value */ +#endif + +#define fast_memcpy(d,s,n) \ + { register size_t nn = (size_t)(n); \ + if (nn >= breakeven_point) memcpy((d), (s), nn); \ + else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ + register char *dd; register const char *ss; \ + for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } } + +#define fast_memset(d,c,n) \ + { register size_t nn = (size_t)(n); \ + if (nn >= breakeven_point) memset((d), (int)(c), nn); \ + else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ + register char *dd; register const int cc=(int)(c); \ + for (dd=(d); nn>0; nn--) *dd++ = cc; } } + +/* prototypes */ + +#if defined(NEED_ASPRINTF) +int asprintf (char **ptr, const char *fmt, /*args*/ ...); +#endif +#if defined(NEED_VASPRINTF) +int vasprintf (char **ptr, const char *fmt, va_list ap); +#endif +#if defined(NEED_ASNPRINTF) +int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); +#endif +#if defined(NEED_VASNPRINTF) +int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap); +#endif + +#if defined(HAVE_SNPRINTF) +/* declare our portable snprintf routine under name portable_snprintf */ +/* declare our portable vsnprintf routine under name portable_vsnprintf */ +#else +/* declare our portable routines under names snprintf and vsnprintf */ +#define portable_snprintf snprintf +#if !defined(NEED_SNPRINTF_ONLY) +#define portable_vsnprintf vsnprintf +#endif +#endif + +#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) +int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); +#if !defined(NEED_SNPRINTF_ONLY) +int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); +#endif +#endif + +/* declarations */ +#if 0 +static char credits[] = "\n\ +@(#)snprintf.c, v2.2: Mark Martinec, \n\ +@(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\ +@(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n"; +#endif /* silence the compiler */ + +#if defined(NEED_ASPRINTF) +int asprintf(char **ptr, const char *fmt, /*args*/ ...) { + va_list ap; + size_t str_m; + int str_l; + + *ptr = NULL; + va_start(ap, fmt); /* measure the required size */ + str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); + va_end(ap); + assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ + *ptr = (char *) malloc(str_m = (size_t)str_l + 1); + if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } + else { + int str_l2; + va_start(ap, fmt); + str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); + va_end(ap); + assert(str_l2 == str_l); + } + return str_l; +} +#endif + +#if defined(NEED_VASPRINTF) +int vasprintf(char **ptr, const char *fmt, va_list ap) { + size_t str_m; + int str_l; + + *ptr = NULL; + { va_list ap2; + va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ + str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ + va_end(ap2); + } + assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ + *ptr = (char *) malloc(str_m = (size_t)str_l + 1); + if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } + else { + int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); + assert(str_l2 == str_l); + } + return str_l; +} +#endif + +#if defined(NEED_ASNPRINTF) +int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) { + va_list ap; + int str_l; + + *ptr = NULL; + va_start(ap, fmt); /* measure the required size */ + str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); + va_end(ap); + assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ + if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ + /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ + if (str_m == 0) { /* not interested in resulting string, just return size */ + } else { + *ptr = (char *) malloc(str_m); + if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } + else { + int str_l2; + va_start(ap, fmt); + str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); + va_end(ap); + assert(str_l2 == str_l); + } + } + return str_l; +} +#endif + +#if defined(NEED_VASNPRINTF) +int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) { + int str_l; + + *ptr = NULL; + { va_list ap2; + va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ + str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ + va_end(ap2); + } + assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ + if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ + /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ + if (str_m == 0) { /* not interested in resulting string, just return size */ + } else { + *ptr = (char *) malloc(str_m); + if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } + else { + int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); + assert(str_l2 == str_l); + } + } + return str_l; +} +#endif + +/* + * If the system does have snprintf and the portable routine is not + * specifically required, this module produces no code for snprintf/vsnprintf. + */ +#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) + +#if !defined(NEED_SNPRINTF_ONLY) +int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { + va_list ap; + int str_l; + + va_start(ap, fmt); + str_l = portable_vsnprintf(str, str_m, fmt, ap); + va_end(ap); + return str_l; +} +#endif + +#if defined(NEED_SNPRINTF_ONLY) +int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { +#else +int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { +#endif + +#if defined(NEED_SNPRINTF_ONLY) + va_list ap; +#endif + size_t str_l = 0; + const char *p = fmt; + +/* In contrast with POSIX, the ISO C99 now says + * that str can be NULL and str_m can be 0. + * This is more useful than the old: if (str_m < 1) return -1; */ + +#if defined(NEED_SNPRINTF_ONLY) + va_start(ap, fmt); +#endif + if (!p) p = ""; + while (*p) { + if (*p != '%') { + /* if (str_l < str_m) str[str_l++] = *p++; -- this would be sufficient */ + /* but the following code achieves better performance for cases + * where format string is long and contains few conversions */ + const char *q = strchr(p+1,'%'); + size_t n = !q ? strlen(p) : (q-p); + if (str_l < str_m) { + size_t avail = str_m-str_l; + fast_memcpy(str+str_l, p, (n>avail?avail:n)); + } + p += n; str_l += n; + } else { + const char *starting_p; + size_t min_field_width = 0, precision = 0; + int zero_padding = 0, precision_specified = 0, justify_left = 0; + int alternate_form = 0, force_sign = 0; + int space_for_positive = 1; /* If both the ' ' and '+' flags appear, + the ' ' flag should be ignored. */ + char length_modifier = '\0'; /* allowed values: \0, h, l, L */ + char tmp[32];/* temporary buffer for simple numeric->string conversion */ + + const char *str_arg; /* string address in case of string argument */ + size_t str_arg_l; /* natural field width of arg without padding + and sign */ + unsigned char uchar_arg; + /* unsigned char argument value - only defined for c conversion. + N.B. standard explicitly states the char argument for + the c conversion is unsigned */ + + size_t number_of_zeros_to_pad = 0; + /* number of zeros to be inserted for numeric conversions + as required by the precision or minimal field width */ + + size_t zero_padding_insertion_ind = 0; + /* index into tmp where zero padding is to be inserted */ + + char fmt_spec = '\0'; + /* current conversion specifier character */ + + /* str_arg = credits; just to make compiler happy (defined but not used)*/ + str_arg = NULL; + starting_p = p; p++; /* skip '%' */ + /* parse flags */ + while (*p == '0' || *p == '-' || *p == '+' || + *p == ' ' || *p == '#' || *p == '\'') { + switch (*p) { + case '0': zero_padding = 1; break; + case '-': justify_left = 1; break; + case '+': force_sign = 1; space_for_positive = 0; break; + case ' ': force_sign = 1; + /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */ +#ifdef PERL_COMPATIBLE + /* ... but in Perl the last of ' ' and '+' applies */ + space_for_positive = 1; +#endif + break; + case '#': alternate_form = 1; break; + case '\'': break; + } + p++; + } + /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */ + + /* parse field width */ + if (*p == '*') { + int j; + p++; j = va_arg(ap, int); + if (j >= 0) min_field_width = j; + else { min_field_width = -j; justify_left = 1; } + } else if (isdigit((int)(*p))) { + /* size_t could be wider than unsigned int; + make sure we treat argument like common implementations do */ + unsigned int uj = *p++ - '0'; + while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); + min_field_width = uj; + } + /* parse precision */ + if (*p == '.') { + p++; precision_specified = 1; + if (*p == '*') { + int j = va_arg(ap, int); + p++; + if (j >= 0) precision = j; + else { + precision_specified = 0; precision = 0; + /* NOTE: + * Solaris 2.6 man page claims that in this case the precision + * should be set to 0. Digital Unix 4.0, HPUX 10 and BSD man page + * claim that this case should be treated as unspecified precision, + * which is what we do here. + */ + } + } else if (isdigit((int)(*p))) { + /* size_t could be wider than unsigned int; + make sure we treat argument like common implementations do */ + unsigned int uj = *p++ - '0'; + while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); + precision = uj; + } + } + /* parse 'h', 'l' and 'll' length modifiers */ + if (*p == 'h' || *p == 'l') { + length_modifier = *p; p++; + if (length_modifier == 'l' && *p == 'l') { /* double l = long long */ +#ifdef SNPRINTF_LONGLONG_SUPPORT + length_modifier = '2'; /* double l encoded as '2' */ +#else + length_modifier = 'l'; /* treat it as a single 'l' */ +#endif + p++; + } + } + fmt_spec = *p; + /* common synonyms: */ + switch (fmt_spec) { + case 'i': fmt_spec = 'd'; break; + case 'D': fmt_spec = 'd'; length_modifier = 'l'; break; + case 'U': fmt_spec = 'u'; length_modifier = 'l'; break; + case 'O': fmt_spec = 'o'; length_modifier = 'l'; break; + default: break; + } + /* get parameter value, do initial processing */ + switch (fmt_spec) { + case '%': /* % behaves similar to 's' regarding flags and field widths */ + case 'c': /* c behaves similar to 's' regarding flags and field widths */ + case 's': + length_modifier = '\0'; /* wint_t and wchar_t not supported */ + /* the result of zero padding flag with non-numeric conversion specifier*/ + /* is undefined. Solaris and HPUX 10 does zero padding in this case, */ + /* Digital Unix and Linux does not. */ +#if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE) + zero_padding = 0; /* turn zero padding off for string conversions */ +#endif + str_arg_l = 1; + switch (fmt_spec) { + case '%': + str_arg = p; break; + case 'c': { + int j = va_arg(ap, int); + uchar_arg = (unsigned char) j; /* standard demands unsigned char */ + str_arg = (const char *) &uchar_arg; + break; + } + case 's': + str_arg = va_arg(ap, const char *); + if (!str_arg) str_arg_l = 0; + /* make sure not to address string beyond the specified precision !!! */ + else if (!precision_specified) str_arg_l = strlen(str_arg); + /* truncate string if necessary as requested by precision */ + else if (precision == 0) str_arg_l = 0; + else { + /* memchr on HP does not like n > 2^31 !!! */ + const char *q = (char*)memchr(str_arg, '\0', + precision <= 0x7fffffff ? precision : 0x7fffffff); + str_arg_l = !q ? precision : (q-str_arg); + } + break; + default: break; + } + break; + case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': { + /* NOTE: the u, o, x, X and p conversion specifiers imply + the value is unsigned; d implies a signed value */ + + int arg_sign = 0; + /* 0 if numeric argument is zero (or if pointer is NULL for 'p'), + +1 if greater than zero (or nonzero for unsigned arguments), + -1 if negative (unsigned argument is never negative) */ + + int int_arg = 0; unsigned int uint_arg = 0; + /* only defined for length modifier h, or for no length modifiers */ + + long int long_arg = 0; unsigned long int ulong_arg = 0; + /* only defined for length modifier l */ + + void *ptr_arg = NULL; + /* pointer argument value -only defined for p conversion */ + +#ifdef SNPRINTF_LONGLONG_SUPPORT + long long int long_long_arg = 0; + unsigned long long int ulong_long_arg = 0; + /* only defined for length modifier ll */ +#endif + if (fmt_spec == 'p') { + /* HPUX 10: An l, h, ll or L before any other conversion character + * (other than d, i, u, o, x, or X) is ignored. + * Digital Unix: + * not specified, but seems to behave as HPUX does. + * Solaris: If an h, l, or L appears before any other conversion + * specifier (other than d, i, u, o, x, or X), the behavior + * is undefined. (Actually %hp converts only 16-bits of address + * and %llp treats address as 64-bit data which is incompatible + * with (void *) argument on a 32-bit system). + */ +#ifdef SOLARIS_COMPATIBLE +# ifdef SOLARIS_BUG_COMPATIBLE + /* keep length modifiers even if it represents 'll' */ +# else + if (length_modifier == '2') length_modifier = '\0'; +# endif +#else + length_modifier = '\0'; +#endif + ptr_arg = va_arg(ap, void *); + if (ptr_arg != NULL) arg_sign = 1; + } else if (fmt_spec == 'd') { /* signed */ + switch (length_modifier) { + case '\0': + case 'h': + /* It is non-portable to specify a second argument of char or short + * to va_arg, because arguments seen by the called function + * are not char or short. C converts char and short arguments + * to int before passing them to a function. + */ + int_arg = va_arg(ap, int); + if (int_arg > 0) arg_sign = 1; + else if (int_arg < 0) arg_sign = -1; + break; + case 'l': + long_arg = va_arg(ap, long int); + if (long_arg > 0) arg_sign = 1; + else if (long_arg < 0) arg_sign = -1; + break; +#ifdef SNPRINTF_LONGLONG_SUPPORT + case '2': + long_long_arg = va_arg(ap, long long int); + if (long_long_arg > 0) arg_sign = 1; + else if (long_long_arg < 0) arg_sign = -1; + break; +#endif + } + } else { /* unsigned */ + switch (length_modifier) { + case '\0': + case 'h': + uint_arg = va_arg(ap, unsigned int); + if (uint_arg) arg_sign = 1; + break; + case 'l': + ulong_arg = va_arg(ap, unsigned long int); + if (ulong_arg) arg_sign = 1; + break; +#ifdef SNPRINTF_LONGLONG_SUPPORT + case '2': + ulong_long_arg = va_arg(ap, unsigned long long int); + if (ulong_long_arg) arg_sign = 1; + break; +#endif + } + } + str_arg = tmp; str_arg_l = 0; + /* NOTE: + * For d, i, u, o, x, and X conversions, if precision is specified, + * the '0' flag should be ignored. This is so with Solaris 2.6, + * Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. + */ +#ifndef PERL_COMPATIBLE + if (precision_specified) zero_padding = 0; +#endif + if (fmt_spec == 'd') { + if (force_sign && arg_sign >= 0) + tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; + /* leave negative numbers for sprintf to handle, + to avoid handling tricky cases like (short int)(-32768) */ +#ifdef LINUX_COMPATIBLE + } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) { + tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; +#endif + } else if (alternate_form) { + if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') ) + { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; } + /* alternate form should have no effect for p conversion, but ... */ +#ifdef HPUX_COMPATIBLE + else if (fmt_spec == 'p' + /* HPUX 10: for an alternate form of p conversion, + * a nonzero result is prefixed by 0x. */ +#ifndef HPUX_BUG_COMPATIBLE + /* Actually it uses 0x prefix even for a zero value. */ + && arg_sign != 0 +#endif + ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; } +#endif + } + zero_padding_insertion_ind = str_arg_l; + if (!precision_specified) precision = 1; /* default precision is 1 */ + if (precision == 0 && arg_sign == 0 +#if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE) + && fmt_spec != 'p' + /* HPUX 10 man page claims: With conversion character p the result of + * converting a zero value with a precision of zero is a null string. + * Actually HP returns all zeroes, and Linux returns "(nil)". */ +#endif + ) { + /* converted to null string */ + /* When zero value is formatted with an explicit precision 0, + the resulting formatted string is empty (d, i, u, o, x, X, p). */ + } else { + char f[5]; int f_l = 0; + f[f_l++] = '%'; /* construct a simple format string for sprintf */ + if (!length_modifier) { } + else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; } + else f[f_l++] = length_modifier; + f[f_l++] = fmt_spec; f[f_l++] = '\0'; + if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg); + else if (fmt_spec == 'd') { /* signed */ + switch (length_modifier) { + case '\0': + case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg); break; + case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break; +#ifdef SNPRINTF_LONGLONG_SUPPORT + case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break; +#endif + } + } else { /* unsigned */ + switch (length_modifier) { + case '\0': + case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg); break; + case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break; +#ifdef SNPRINTF_LONGLONG_SUPPORT + case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break; +#endif + } + } + /* include the optional minus sign and possible "0x" + in the region before the zero padding insertion point */ + if (zero_padding_insertion_ind < str_arg_l && + tmp[zero_padding_insertion_ind] == '-') { + zero_padding_insertion_ind++; + } + if (zero_padding_insertion_ind+1 < str_arg_l && + tmp[zero_padding_insertion_ind] == '0' && + (tmp[zero_padding_insertion_ind+1] == 'x' || + tmp[zero_padding_insertion_ind+1] == 'X') ) { + zero_padding_insertion_ind += 2; + } + } + { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; + if (alternate_form && fmt_spec == 'o' +#ifdef HPUX_COMPATIBLE /* ("%#.o",0) -> "" */ + && (str_arg_l > 0) +#endif +#ifdef DIGITAL_UNIX_BUG_COMPATIBLE /* ("%#o",0) -> "00" */ +#else + /* unless zero is already the first character */ + && !(zero_padding_insertion_ind < str_arg_l + && tmp[zero_padding_insertion_ind] == '0') +#endif + ) { /* assure leading zero for alternate-form octal numbers */ + if (!precision_specified || precision < num_of_digits+1) { + /* precision is increased to force the first character to be zero, + except if a zero value is formatted with an explicit precision + of zero */ + precision = num_of_digits+1; precision_specified = 1; + } + } + /* zero padding to specified precision? */ + if (num_of_digits < precision) + number_of_zeros_to_pad = precision - num_of_digits; + } + /* zero padding to specified minimal field width? */ + if (!justify_left && zero_padding) { + int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); + if (n > 0) number_of_zeros_to_pad += n; + } + break; + } + default: /* unrecognized conversion specifier, keep format string as-is*/ + zero_padding = 0; /* turn zero padding off for non-numeric convers. */ +#ifndef DIGITAL_UNIX_COMPATIBLE + justify_left = 1; min_field_width = 0; /* reset flags */ +#endif +#if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE) + /* keep the entire format string unchanged */ + str_arg = starting_p; str_arg_l = p - starting_p; + /* well, not exactly so for Linux, which does something inbetween, + * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y" */ +#else + /* discard the unrecognized conversion, just keep * + * the unrecognized conversion character */ + str_arg = p; str_arg_l = 0; +#endif + if (*p) str_arg_l++; /* include invalid conversion specifier unchanged + if not at end-of-string */ + break; + } + if (*p) p++; /* step over the just processed conversion specifier */ + /* insert padding to the left as requested by min_field_width; + this does not include the zero padding in case of numerical conversions*/ + if (!justify_left) { /* left padding with blank or zero */ + int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); + if (n > 0) { + if (str_l < str_m) { + size_t avail = str_m-str_l; + fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n)); + } + str_l += n; + } + } + /* zero padding as requested by the precision or by the minimal field width + * for numeric conversions required? */ + if (number_of_zeros_to_pad <= 0) { + /* will not copy first part of numeric right now, * + * force it to be copied later in its entirety */ + zero_padding_insertion_ind = 0; + } else { + /* insert first part of numerics (sign or '0x') before zero padding */ + int n = zero_padding_insertion_ind; + if (n > 0) { + if (str_l < str_m) { + size_t avail = str_m-str_l; + fast_memcpy(str+str_l, str_arg, (n>avail?avail:n)); + } + str_l += n; + } + /* insert zero padding as requested by the precision or min field width */ + n = number_of_zeros_to_pad; + if (n > 0) { + if (str_l < str_m) { + size_t avail = str_m-str_l; + fast_memset(str+str_l, '0', (n>avail?avail:n)); + } + str_l += n; + } + } + /* insert formatted string + * (or as-is conversion specifier for unknown conversions) */ + { int n = str_arg_l - zero_padding_insertion_ind; + if (n > 0) { + if (str_l < str_m) { + size_t avail = str_m-str_l; + fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind, + (n>avail?avail:n)); + } + str_l += n; + } + } + /* insert right padding */ + if (justify_left) { /* right blank padding to the field width */ + int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); + if (n > 0) { + if (str_l < str_m) { + size_t avail = str_m-str_l; + fast_memset(str+str_l, ' ', (n>avail?avail:n)); + } + str_l += n; + } + } + } + } +#if defined(NEED_SNPRINTF_ONLY) + va_end(ap); +#endif + if (str_m > 0) { /* make sure the string is null-terminated + even at the expense of overwriting the last character + (shouldn't happen, but just in case) */ + str[str_l <= str_m-1 ? str_l : str_m-1] = '\0'; + } + /* Return the number of characters formatted (excluding trailing null + * character), that is, the number of characters that would have been + * written to the buffer if it were large enough. + * + * The value of str_l should be returned, but str_l is of unsigned type + * size_t, and snprintf is int, possibly leading to an undetected + * integer overflow, resulting in a negative return value, which is illegal. + * Both XSH5 and ISO C99 (at least the draft) are silent on this issue. + * Should errno be set to EOVERFLOW and EOF returned in this case??? + */ + return (int) str_l; +} +#endif diff --git a/lib/joedog/snprintf.h b/lib/joedog/snprintf.h new file mode 100644 index 0000000..70ec841 --- /dev/null +++ b/lib/joedog/snprintf.h @@ -0,0 +1,26 @@ +#ifndef _PORTABLE_SNPRINTF_H_ +#define _PORTABLE_SNPRINTF_H_ + +#define PORTABLE_SNPRINTF_VERSION_MAJOR 2 +#define PORTABLE_SNPRINTF_VERSION_MINOR 2 + +#ifdef HAVE_SNPRINTF +#include +#else +extern int snprintf(char *, size_t, const char *, /*args*/ ...); +extern int vsnprintf(char *, size_t, const char *, va_list); +#endif + +#if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF) +extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); +extern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); +#define snprintf portable_snprintf +#define vsnprintf portable_vsnprintf +#endif + +extern int asprintf (char **ptr, const char *fmt, /*args*/ ...); +extern int vasprintf (char **ptr, const char *fmt, va_list ap); +extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); +extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap); + +#endif diff --git a/lib/joedog/stralloc.c b/lib/joedog/stralloc.c new file mode 100644 index 0000000..6268e04 --- /dev/null +++ b/lib/joedog/stralloc.c @@ -0,0 +1,51 @@ +/** + * Stralloc + * Library: joedog + * + * Copyright (C) 2000-2009 by + * Jeffrey Fulmer - + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#ifdef HAVE_STRING_H +# include +#endif/*HAVE_STRING_H*/ + +#ifdef HAVE_STRINGS_H +# include +#endif/*HAVE_STRINGS_H*/ + +#include +#include + +char *stralloc(char *str) +{ + char *retval; + + retval=calloc(strlen(str)+1, 1); + if(!retval) { + NOTIFY(FATAL, "Fatal memory allocation error"); + } + strcpy(retval, str); + return retval; +} + diff --git a/lib/joedog/stralloc.h b/lib/joedog/stralloc.h new file mode 100644 index 0000000..1e56cc2 --- /dev/null +++ b/lib/joedog/stralloc.h @@ -0,0 +1,29 @@ +/** + * Stralloc + * Library: joedog + * + * Copyright (C) 2000-2007 by + * Jeffrey Fulmer - + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef STRALLOC_H +#define STRALLOC_H + +char *stralloc(char *); + +#endif/*STRALLOC_H*/ diff --git a/lib/joedog/util.c b/lib/joedog/util.c new file mode 100644 index 0000000..8c13e77 --- /dev/null +++ b/lib/joedog/util.c @@ -0,0 +1,110 @@ +/** + * Utility functions + * Library: joedog + * + * Copyright (C) 2000-2009 by + * Jeffrey Fulmer - + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include + +/** + * substring returns a char pointer from + * start to start + length in a + * larger char pointer (buffer). + */ +char * +substring(char *str, int start, int len) +{ + int i; + char *ret; + char *res; + char *ptr; + char *end; + +// if ((len < 1) || (start < 0) || (start > (int)strlen (str)) || start+len > (int)strlen(str)) +// return NULL; + + if ((len < 1) || (start < 0) || (start > (int)strlen (str))) + return NULL; + + if (start+len > (int)strlen(str)) + len = strlen(str) - start; + + ret = xmalloc(len+1); + res = ret; + ptr = str; + end = str; + + for (i = 0; i < start; i++, ptr++) ; + for (i = 0; i < start+len; i++, end++) ; + while (ptr < end) + *res++ = *ptr++; + + *res = 0; + return ret; +} + +/** + * my_random returns a random int + */ +int +my_random( int max, int seed ) +{ + srand( (unsigned)time( NULL ) * seed ); + return (int)((double)rand() / ((double)RAND_MAX + 1) * max ); +} + +void +itoa( int n, char s[] ) +{ + int i, sign; + if(( sign = n ) < 0 ) + n = -n; + i = 0; + do{ + s[i++] = n % 10 + '0'; + } while(( n /= 10 ) > 0 ); + if( sign < 0 ) + s[i++] = '-'; + s[i] = '\0'; + + reverse( s ); +} + +void +reverse( char s[] ) +{ + int c, i, j; + for( i = 0, j = strlen( s )-1; i < j; i++, j-- ){ + c = s[i]; + s[i] = s[j]; + s[j] = c; + } /** end of for **/ +} /** end of reverse **/ + +float +elapsed_time( clock_t time ) +{ + long tps = sysconf( _SC_CLK_TCK ); + return (float)time/tps; +} + + diff --git a/lib/joedog/util.h b/lib/joedog/util.h new file mode 100644 index 0000000..cb63ae2 --- /dev/null +++ b/lib/joedog/util.h @@ -0,0 +1,73 @@ +/** + * Utility functions + * Library: joedog + * + * Copyright (C) 2000-2007 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef UTIL_H +#define UTIL_H + +#ifdef HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +#ifdef STDC_HEADERS +# include +#else +# ifndef HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif /* HAVE_STRCHR */ +char *strchr (), *strrchr (); +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# define memmove(d, s, n) bcopy ((s), (d), (n)) +# endif /* HAVE_MEMCPY */ +#endif /* STDC_HEADERS */ + +#ifdef HAVE_SYS_TIMES_H +# include +#endif /* HAVE_SYS_TIMES_H */ + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif /* HAVE_SYS_TIME_H */ +#endif /* TIME_WITH_SYS_TIME */ + +#include +#include +#include +#include +#include +#include "memory.h" + +void itoa(int, char []); +void reverse(char []); +int my_random(int, int); +char *substring(char *, int, int); +float elapsed_time(clock_t); + +#endif /* UTIL_H */ + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..3506c07 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,69 @@ +## +## src/Makefile.am +## +## Copyright (C) 2000-2010 by +## Jeffrey Fulmer - , et al. +## This file is distributed as part of Siege +## +## 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., 675 Mass Ave, Cambridge, MA 02139, USA. +## + +bin_PROGRAMS = siege + +INCLUDES = $(SSL_INCLUDE) + +WARN_CFLAGS = @WARN_CFLAGS@ + +AM_CFLAGS = $(PTHREAD_CFLAGS) $(WARN_CFLAGS) $(SSL_CFLAGS) + +AM_LDFLAGS = $(SSL_LDFLAGS) $(PTHREAD_LDFLAGS) + +LIBS = $(SSL_LIBS) + +siege_LDADD = $(top_srcdir)/lib/joedog/libjoedog.la + +siege_DEPENDENCIES = $(top_srcdir)/lib/joedog/libjoedog.la + +siege_SOURCES = \ +array.c array.h \ +auth.c auth.h \ +base64.c base64.h \ +client.c client.h \ +cookie.c cookie.h \ +cfg.c cfg.h \ +creds.c creds.h \ +crew.c crew.h \ +data.c data.h \ +date.c date.h \ +eval.c eval.h \ +ftp.c ftp.h \ +getopt.c getopt1.c \ +handler.c handler.h \ +hash.c hash.h \ +http.c http.h \ +init.c init.h \ +load.c load.h \ +log.c log.h \ +main.c setup.h \ +md5.c md5.h \ +sock.c sock.h \ +ssl.c ssl.h \ +timer.c timer.h \ +url.c url.h \ +util.c util.h \ +version.c version.h + +AUTOMAKE_OPTIONS = foreign no-dependencies + diff --git a/src/array.c b/src/array.c new file mode 100644 index 0000000..d4938b4 --- /dev/null +++ b/src/array.c @@ -0,0 +1,148 @@ +/** + * Dynamic Array + * + * Copyright (C) 2006-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include +#include + +typedef void *array; + +struct ARRAY_T +{ + int index; + int length; + array *data; +}; + +size_t ARRAYSIZE = sizeof(struct ARRAY_T); + + +ARRAY +new_array(){ + ARRAY this; + + this = xcalloc(sizeof(struct ARRAY_T), 1); + this->index = -1; + this->length = 0; + return this; +} + +ARRAY +array_destroy(ARRAY this) +{ + int i; + + for (i = 0; i < this->length; i++) { + xfree(this->data[i]); + } + xfree(this->data); + this = NULL; + return this; +} + +void +array_push(ARRAY this, void *thing) +{ + int len = 0; + + if (thing==NULL) return; + + len = strlen(thing)+1; + array_npush(this, (void*)thing, len); + return; +} + +void +array_npush(ARRAY this, void *thing, size_t len) +{ + array arr; + if (thing==NULL) return; + if (this->length == 0) { + this->data = xmalloc(sizeof(array)); + } else { + this->data = realloc(this->data,(this->length+1)*sizeof(array)); + } + arr = xmalloc(len+1); + memset(arr, 0, len); + memcpy(arr, thing, len); + this->data[this->length] = arr; + this->length += 1; + return; +} + +void * +array_get(ARRAY this, int index) +{ + if (index > this->length) return NULL; + + return this->data[index]; +} + +void * +array_next(ARRAY this) +{ + this->index++; + return this->data[(this->index) % this->length]; +} + +void * +array_prev(ARRAY this) +{ + this->index--; + return this->data[((this->index) + (this->length - 1)) % this->length] ; +} + +size_t +array_length(ARRAY this) +{ + return this->length; +} + +#if 0 +int +main (int argc, char *argv[]) +{ + int x; + ARRAY A = new_array(30); + + if (argc > 1) { + for (x = 1; x < argc; x++) + array_npush(A, new_url(argv[x]), sizeof(struct _URL)); + } else { + printf("usage: %s [...]\n", argv[0]); + return 0; + } + + for (x = 0; x < 10; x++) { + URL U = (URL)array_next(A); + printf("|%s|\n", U->iface->getParameters(U) ); + } + //for (x = 0; x < 10; x++) { + // printf("|%s|\n", ((char*)array_prev(A))); + //} + + return 0; +} +#endif diff --git a/src/array.h b/src/array.h new file mode 100644 index 0000000..e2d0abc --- /dev/null +++ b/src/array.h @@ -0,0 +1,42 @@ +/** + * Dynamic Array + * + * Copyright (C) 2006-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef ARRAY_H +#define ARRAY_H + +/** + * ARRAY object + */ +typedef struct ARRAY_T *ARRAY; +extern size_t ARRAYSIZE; + +ARRAY new_array(); +ARRAY array_destroy(ARRAY this); +void array_push(ARRAY this, void *thing); +void array_npush(ARRAY this, void *thing, size_t len); +void * array_get(ARRAY this, int index); +void * array_next(ARRAY this); +void * array_prev(ARRAY this); +size_t array_length(ARRAY this); + +#endif/*ARRAY_H*/ + diff --git a/src/auth.c b/src/auth.c new file mode 100644 index 0000000..d7f044f --- /dev/null +++ b/src/auth.c @@ -0,0 +1,678 @@ +/** + * HTTP Authentication + * + * Copyright (C) 2002-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct AUTH_T { + ARRAY creds; + BOOLEAN okay; + struct { + char *encode; + } basic; + struct { + char *encode; + } digest; + struct { + BOOLEAN required; /* boolean, TRUE == use a proxy server. */ + char *hostname; /* hostname for the proxy server. */ + int port; /* port number for proxysrv */ + char *encode; /* base64 encoded username and password */ + } proxy; + pthread_mutex_t lock; +}; + +struct DIGEST_CRED { + char *username; + char *password; + char *cnonce_value; + char *h_a1; + char nc[9]; + unsigned int nc_value; +}; + +struct DIGEST_CHLG { + char *realm; + char *domain; + char *nonce; + char *opaque; + char *stale; + char *algorithm; + char *qop; +}; + +typedef enum { + REALM, + DOMAIN, + NONCE, + OPAQUE, + STALE, + ALGORITHM, + QOP, + UNKNOWN +} KEY_HEADER_E; + +size_t AUTHSIZE = sizeof(struct AUTH_T); + +private BOOLEAN __basic_header(AUTH this, SCHEME scheme, CREDS creds); +private DCHLG * __digest_challenge(const char *challenge); +private DCRED * __digest_credentials(CREDS creds, size_t *randseed); +private KEY_HEADER_E __get_keyval(const char *key); +private char * __get_random_string(size_t length, unsigned int *randseed); +private char * __get_h_a1(const DCHLG *chlg, DCRED *cred, const char *nonce_value); +private char * __get_md5_str(const char *buf); +private BOOLEAN __str_list_contains(const char *str, const char *pattern, size_t pattern_len); + +AUTH +new_auth() +{ + AUTH this; + + this = calloc(AUTHSIZE, 1); + this->creds = new_array(); + this->basic.encode = xstrdup(""); + this->digest.encode = xstrdup(""); + this->proxy.encode = xstrdup(""); + return this; +} + +AUTH +auth_destroy(AUTH this) +{ + this->creds = array_destroy(this->creds); + xfree(this); + return NULL; +} + +void +auth_add(AUTH this, CREDS creds) +{ + array_npush(this->creds, creds, CREDSIZE); + return; +} + +void +auth_display(AUTH this, SCHEME scheme) +{ + size_t i; + //XXX: Needs to be reformatted for siege -C + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (creds_get_scheme(tmp) == scheme) { + printf("credentials: %s:%s:%s\n", creds_get_username(tmp), creds_get_password(tmp), creds_get_realm(tmp)); + } + } +} + +char * +auth_get_basic_header(AUTH this, SCHEME scheme) +{ + if (scheme == PROXY) { + return this->proxy.encode; + } else { + return this->basic.encode; + } +} + +BOOLEAN +auth_set_basic_header(AUTH this, SCHEME scheme, char *realm) +{ + size_t i; + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (strmatch(creds_get_realm(tmp), realm)) { + if (creds_get_scheme(tmp) == HTTP || creds_get_scheme(tmp) == HTTPS) { + return __basic_header(this, scheme, tmp); + } + } + } + /** + * didn't match a realm, trying 'any' + */ + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (strmatch(creds_get_realm(tmp), "any")) { + if (creds_get_scheme(tmp) == HTTP || creds_get_scheme(tmp) == HTTPS) { + return __basic_header(this, scheme, tmp); + } + } + } + return FALSE; +} + +//digest_generate_authorization(C->auth.wwwchlg, C->auth.wwwcred, "GET", fullpath); +char * +auth_get_digest_header(AUTH this, SCHEME scheme, DCHLG *chlg, DCRED *cred, const char *method, const char *uri) +{ + size_t len; + char *cnonce = NULL; + char *nonce_count = NULL; + char *qop = NULL; + char *response = NULL; + char *request_digest = NULL; + char *h_a1 = NULL; + char *h_a2 = NULL; + char *opaque = NULL; + char *result, *tmp; + + if (NULL != chlg->qop) { + nonce_count = xstrcat(", nc=", cred->nc, NULL); + cnonce = xstrcat(", cnonce=\"", cred->cnonce_value, "\"", NULL); + + if (NULL == (h_a1 = __get_h_a1(chlg, cred, chlg->nonce))) { + fprintf(stderr, "error calling __get_h_a1\n"); + return NULL; + } + + if (__str_list_contains(chlg->qop, "auth", 4)) { + qop = xstrdup(", qop=auth"); + tmp = xstrcat(method, ":", uri, NULL); + h_a2 = __get_md5_str(tmp); + xfree(tmp); + + tmp = xstrcat(h_a1,":",chlg->nonce,":",cred->nc,":",cred->cnonce_value,":auth:",h_a2,NULL); + request_digest = __get_md5_str(tmp); + xfree(tmp); + response = xstrcat(", response=\"", request_digest, "\"", NULL); + } else { + fprintf(stderr, "error quality of protection not supported: %s\n", chlg->qop); + return NULL; + } + } else { + if (NULL == (h_a1 = __get_h_a1(chlg, cred, ""))) { + NOTIFY(ERROR, "__get_h_a1\n"); + return NULL; + } + tmp = xstrcat(method, ":", uri, NULL); + h_a2 = __get_md5_str(tmp); + xfree(tmp); + tmp = xstrcat(h_a1, ":", chlg->nonce, ":", h_a2, NULL); + request_digest = __get_md5_str(tmp); + xfree(tmp); + response = xstrcat(" response=\"", request_digest, "\"", NULL); + } + if (NULL != chlg->opaque) + opaque = xstrcat(", opaque=\"", chlg->opaque, "\"", NULL); + + result = xstrcat ( + "Digest username=\"", cred->username, "\", realm=\"", chlg->realm, "\", nonce=\"", chlg->nonce, + "\", uri=\"", uri, "\", algorithm=", chlg->algorithm, response, opaque ? opaque : "", qop ? qop : "", + nonce_count ? nonce_count : "", cnonce ? cnonce : "", NULL + ); + + (cred->nc_value)++; + snprintf(cred->nc, sizeof(cred->nc), "%.8x", cred->nc_value); + + if (0 == strcasecmp("MD5", chlg->algorithm)) + xfree(h_a1); + + xfree(nonce_count); + xfree(cnonce); + xfree(qop); + xfree(response); + xfree(request_digest); + xfree(h_a2); + xfree(opaque); + + len = strlen(result)+32; + + if (scheme == PROXY) { + this->proxy.encode = xmalloc(len); + memset(this->proxy.encode, '\0', len); + snprintf(this->proxy.encode, len, "Proxy-Authorization: %s\015\012", result); + xfree(result); + return this->proxy.encode; + } else { + this->digest.encode = xmalloc(len); + memset(this->digest.encode, '\0', len); + snprintf(this->digest.encode, len, "Authorization: %s\015\012", result); + xfree(result); + return this->digest.encode; + } +} + +BOOLEAN +auth_set_digest_header(AUTH this, DCHLG **chlg, DCRED **cred, size_t *rand, char *realm, char *str) { + size_t i; + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (strmatch(creds_get_realm(tmp), realm)) { + *chlg = __digest_challenge(str); + *cred = __digest_credentials(tmp, rand); + if (*cred == NULL || *chlg == NULL) return FALSE; + return TRUE; + } + } + /** + * didn't match a realm, trying 'any' + */ + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (strmatch(creds_get_realm(tmp), "any")) { + *chlg = __digest_challenge(str); + *cred = __digest_credentials(tmp, rand); + if (*cred == NULL || *chlg == NULL) return FALSE; + return TRUE; + } + } + return FALSE; +} + +BOOLEAN +auth_get_proxy_required(AUTH this) +{ + return this->proxy.required; +} + +char * +auth_get_proxy_host(AUTH this) +{ + return this->proxy.hostname; +} + +int +auth_get_proxy_port(AUTH this) +{ + return this->proxy.port; +} + +void +auth_set_proxy_required(AUTH this, BOOLEAN required) +{ + this->proxy.required = required; +} + +void +auth_set_proxy_host(AUTH this, char *host) +{ + this->proxy.hostname = xstrdup(host); + this->proxy.required = TRUE; +} + +void +auth_set_proxy_port(AUTH this, int port) +{ + this->proxy.port = port; +} + +char * +auth_get_ftp_username(AUTH this, char *realm) +{ + size_t i; + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (strmatch(creds_get_realm(tmp), realm)) { + if (creds_get_scheme(tmp) == FTP) { + return creds_get_username(tmp); + } + } + } + /** + * didn't match a realm, trying 'any' + */ + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (strmatch(creds_get_realm(tmp), "any")) { + if (creds_get_scheme(tmp) == FTP) { + return creds_get_username(tmp); + } + } + } + return ""; +} + +char * +auth_get_ftp_password(AUTH this, char *realm) +{ + size_t i; + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (strmatch(creds_get_realm(tmp), realm)) { + if (creds_get_scheme(tmp) == FTP) { + return creds_get_password(tmp); + } + } + } + /** + * didn't match a realm, trying 'any' + */ + for (i = 0; i < array_length(this->creds); i++) { + CREDS tmp = array_get(this->creds, i); + if (strmatch(creds_get_realm(tmp), "any")) { + if (creds_get_scheme(tmp) == FTP) { + return creds_get_password(tmp); + } + } + } + return ""; +} + +private BOOLEAN +__basic_header(AUTH this, SCHEME scheme, CREDS creds) +{ + char buf[256]; + char *hdr; + size_t len; + BOOLEAN ret = TRUE; + + memset(buf, '\0', sizeof(buf)); + pthread_mutex_lock(&(this->lock)); + snprintf(buf, sizeof buf,"%s:%s",creds_get_username(creds), creds_get_password(creds)); + if (scheme==PROXY) { + xfree(this->proxy.encode); + if ((base64_encode(buf, strlen(buf), &hdr) < 0)) { + ret = FALSE; + } else { + len = strlen(hdr)+32; + this->proxy.encode = xmalloc(len); + memset(this->proxy.encode, '\0', len); + snprintf(this->proxy.encode, len, "Proxy-Authorization: Basic %s\015\012", hdr); + } + } else { + xfree(this->basic.encode); + if ((base64_encode(buf, strlen(buf), &hdr) < 0 )) { + ret = FALSE; + } else { + len = strlen(hdr)+32; + this->basic.encode = xmalloc(len); + memset(this->basic.encode, '\0', len); + snprintf(this->basic.encode, len, "Authorization: Basic %s\015\012", hdr); + } + } + pthread_mutex_unlock(&(this->lock)); + return ret; +} + +typedef struct +{ + const char *keyname; + KEY_HEADER_E keyval; +} KEYPARSER; + +static const KEYPARSER keyparser[] = +{ + { "realm", REALM }, + { "domain", DOMAIN }, + { "nonce", NONCE }, + { "opaque", OPAQUE }, + { "stale", STALE }, + { "algorithm", ALGORITHM }, + { "qop", QOP }, + { NULL, UNKNOWN } +}; + + +private KEY_HEADER_E +__get_keyval(const char *key) +{ + int i; + + for (i = 0; keyparser[i].keyname; i++) { + if (!strcasecmp(key, keyparser[i].keyname)) { + return keyparser[i].keyval; + } + } + return UNKNOWN; +} + +private char * +__get_random_string(size_t length, unsigned int *randseed) +{ + const unsigned char b64_alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./"; + unsigned char *result; + size_t i; + + result = xmalloc(sizeof(unsigned char) * (length + 1)); + + for(i = 0; i < length; i++) + result[i] = (int) (255.0 * (pthread_rand_np(randseed) / (RAND_MAX + 1.0))); + for (i = 0; i < length; i++) + result[i] = b64_alphabet[(result[i] % ((sizeof(b64_alphabet) - 1) / sizeof(unsigned char)))]; + + result[length] = '\0'; + + return (char *) result; +} + + +#define DIGEST_CNONCE_SIZE 16 + +private DCRED * +__digest_credentials(CREDS creds, size_t *randseed) +{ + DCRED *result; + + result = xcalloc(1, sizeof(struct DIGEST_CRED)); + result->username = xstrdup(creds_get_username(creds)); + result->password = xstrdup(creds_get_password(creds)); + /* Generate a pseudo random cnonce */ + result->cnonce_value = __get_random_string(DIGEST_CNONCE_SIZE, randseed); + result->nc_value = 1U; + snprintf(result->nc, sizeof(result->nc), "%.8x", result->nc_value); + result->h_a1 = NULL; + + return result; +} + +private DCHLG * +__digest_challenge(const char *challenge) +{ + DCHLG *result; + char *key; + char *val; + const char *beg; + const char *end; + KEY_HEADER_E keyval; + + result = xcalloc(1, sizeof(struct DIGEST_CHLG)); + + for (beg = end = challenge; !isspace(*end) && *end; ++end); + + if (strncasecmp("Digest", beg, end - beg)) { + fprintf(stderr, "no Digest keyword in challenge [%s]\n", challenge); + return NULL; + } + + for (beg = end; isspace(*beg); ++beg); + + while (*beg != '\0') { + + /* find key */ + while (isspace(*beg)) + beg++; + + end = beg; + while (*end != '=' && *end != ',' && *end != '\0' && !isspace(*end)) + end++; + + key = xmalloc((1 + end - beg) * sizeof(char)); + memcpy(key, beg, end - beg); + key[end - beg] = '\0'; + + beg = end; + while (isspace(*beg)) + beg++; + + /* find value */ + val = NULL; + if (*beg == '=') { + beg++; + while (isspace(*beg)) + beg++; + + if (*beg == '\"') { /* quoted string */ + beg++; + end = beg; + while (*end != '\"' && *end != '\0') { + if (*end == '\\' && end[1] != '\0') { + end++; /* escaped char */ + } + end++; + } + val = xmalloc((1 + end - beg) * sizeof(char)); + memcpy(val, beg, end - beg); + val[end - beg] = '\0'; + beg = end; + if (*beg != '\0') { + beg++; + } + } + else { /* token */ + end = beg; + while (*end != ',' && *end != '\0' && !isspace(*end)) + end++; + + val = xmalloc((1 + end - beg) * sizeof(char)); + memcpy(val, beg, end - beg); + val[end - beg] = '\0'; + beg = end; + } + } + + while (*beg != ',' && *beg != '\0') + beg++; + + if (*beg != '\0') { + beg++; + } + + keyval = __get_keyval(key); + switch (keyval) { + case REALM: + result->realm = val; + break; + case DOMAIN: + result->domain = val; + break; + case NONCE: + result->nonce = val; + break; + case OPAQUE: + result->opaque = val; + break; + case STALE: + result->stale = val; + break; + case ALGORITHM: + result->algorithm = val; + break; + case QOP: + result->qop = val; + break; + default: + fprintf(stderr, "unknown key [%s]\n", key); + xfree(val); + break; + } + xfree(key); + } + + return result; +} + +private char * +__get_md5_str(const char *buf) +{ + const char *hex = "0123456789abcdef"; + struct md5_ctx ctx; + unsigned char hash[16]; + char *r, *result; + size_t length; + int i; + + length = strlen(buf); + result = xmalloc(33 * sizeof(char)); + md5_init_ctx(&ctx); + md5_process_bytes(buf, length, &ctx); + md5_finish_ctx(&ctx, hash); + + for (i = 0, r = result; i < 16; i++) { + *r++ = hex[hash[i] >> 4]; + *r++ = hex[hash[i] & 0xF]; + } + *r = '\0'; + + return result; +} + + +private char * +__get_h_a1(const DCHLG *chlg, DCRED *cred, const char *nonce_value) +{ + char *h_usrepa, *result, *tmp; + + if (0 == strcasecmp("MD5", chlg->algorithm)) { + tmp = xstrcat(cred->username, ":", chlg->realm, ":", cred->password, NULL); + h_usrepa = __get_md5_str(tmp); + xfree(tmp); + result = h_usrepa; + } + else if (0 == strcasecmp("MD5-sess", chlg->algorithm)) { + if ((NULL == cred->h_a1)) { + tmp = xstrcat(cred->username, ":", chlg->realm, ":", cred->password, NULL); + h_usrepa = __get_md5_str(tmp); + xfree(tmp); + tmp = xstrcat(h_usrepa, ":", nonce_value, ":", cred->cnonce_value, NULL); + result = __get_md5_str(tmp); + xfree(tmp); + cred->h_a1 = result; + } + else { + return cred->h_a1; + } + } + else { + fprintf(stderr, "invalid call to %s algorithm is [%s]\n", __FUNCTION__, chlg->algorithm); + return NULL; + } + + return result; +} + +private BOOLEAN +__str_list_contains(const char *str, const char *pattern, size_t pattern_len) +{ + const char *ptr; + + ptr = str; + do { + if (0 == strncmp(ptr, pattern, pattern_len) + && ((',' == ptr[pattern_len]) || ('\0' == ptr[pattern_len]))) { + return TRUE; + } + + if (NULL != (ptr = strchr(ptr, ','))) ptr++; + } + while (NULL != ptr); + + return FALSE; +} + diff --git a/src/auth.h b/src/auth.h new file mode 100644 index 0000000..a0a552a --- /dev/null +++ b/src/auth.h @@ -0,0 +1,55 @@ +/** + * HTTP Authentication + * + * Copyright (C) 2002-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef __AUTH_H +#define __AUTH_H + +#include +#include +#include + +typedef struct AUTH_T *AUTH; +extern size_t AUTHSIZE; + +typedef struct DIGEST_CRED DCRED; +typedef struct DIGEST_CHLG DCHLG; +typedef enum { BASIC, DIGEST } TYPE; + +AUTH new_auth(); +AUTH auth_destroy(AUTH this); +void auth_add(AUTH this, CREDS creds); +void auth_display(AUTH this, SCHEME scheme); +char * auth_get_basic_header(AUTH this, SCHEME scheme); +BOOLEAN auth_set_basic_header(AUTH this, SCHEME scheme, char *realm); +char * auth_get_digest_header(AUTH this, SCHEME scheme, DCHLG *chlg, DCRED *cred, const char *meth, const char *uri); +BOOLEAN auth_set_digest_header(AUTH this, DCHLG **ch, DCRED **cr, size_t *rand, char *realm, char *str); +BOOLEAN auth_get_proxy_required(AUTH this); +void auth_set_proxy_required(AUTH this, BOOLEAN required); +char * auth_get_proxy_host(AUTH this); +void auth_set_proxy_host(AUTH this, char *host); +int auth_get_proxy_port(AUTH this); +void auth_set_proxy_port(AUTH this, int port); +char * auth_get_ftp_username(AUTH this, char *realm); +char * auth_get_ftp_password(AUTH this, char *realm); + + +#endif/*__AUTH_H*/ diff --git a/src/base64.c b/src/base64.c new file mode 100644 index 0000000..16423e6 --- /dev/null +++ b/src/base64.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include "base64.h" + +/* The last #include file should be: */ +#ifdef MALLOCDEBUG +#include "memdebug.h" +#endif + +static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static int pos(char c) +{ + char *p; + for(p = base64; *p; p++) + if(*p == c) + return p - base64; + return -1; +} + +#if 1 +int base64_encode(const void *data, int size, char **str) +{ + char *s, *p; + int i; + int c; + const unsigned char *q; + + p = s = (char*)malloc(size*4/3+4); + if (p == NULL) + return -1; + q = (const unsigned char*)data; + i=0; + for(i = 0; i < size;){ + c=q[i++]; + c*=256; + if(i < size) + c+=q[i]; + i++; + c*=256; + if(i < size) + c+=q[i]; + i++; + p[0]=base64[(c&0x00fc0000) >> 18]; + p[1]=base64[(c&0x0003f000) >> 12]; + p[2]=base64[(c&0x00000fc0) >> 6]; + p[3]=base64[(c&0x0000003f) >> 0]; + if(i > size) + p[3]='='; + if(i > size+1) + p[2]='='; + p+=4; + } + *p=0; + *str = s; + return strlen(s); +} +#endif + +int base64_decode(const char *str, void *data) +{ + const char *p; + unsigned char *q; + int c; + int x; + int done = 0; + q=(unsigned char*)data; + for(p=str; *p && !done; p+=4){ + x = pos(p[0]); + if(x >= 0) + c = x; + else{ + done = 3; + break; + } + c*=64; + + x = pos(p[1]); + if(x >= 0) + c += x; + else + return -1; + c*=64; + + if(p[2] == '=') + done++; + else{ + x = pos(p[2]); + if(x >= 0) + c += x; + else + return -1; + } + c*=64; + + if(p[3] == '=') + done++; + else{ + if(done) + return -1; + x = pos(p[3]); + if(x >= 0) + c += x; + else + return -1; + } + if(done < 3) + *q++=(c&0x00ff0000)>>16; + + if(done < 2) + *q++=(c&0x0000ff00)>>8; + if(done < 1) + *q++=(c&0x000000ff)>>0; + } + return q - (unsigned char*)data; +} diff --git a/src/base64.h b/src/base64.h new file mode 100644 index 0000000..8ca2946 --- /dev/null +++ b/src/base64.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __BASE64_H +#define __BASE64_H + +int base64_encode(const void *data, int size, char **str); + +#endif/*__BASE64_H*/ diff --git a/src/cfg.c b/src/cfg.c new file mode 100644 index 0000000..c4044ef --- /dev/null +++ b/src/cfg.c @@ -0,0 +1,198 @@ +/** + * Configuration file support + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * -- + * + */ +#include +#include +#include +#include +#include + +BOOLEAN is_variable_line(char *line); + +/** + * Ignores comment lines beginning with + * '#' empty lines beginning with \n + * Takes a char* as an argument + */ +void +parse(char *str) +{ + char *ch; + ch = (char *)strstr(str, "#"); + if ( ch ){ *ch = 0; } + ch = (char *)strstr(str, "\n"); + if ( ch ){ *ch = 0; } +} + +/** + * Reads filename into memory and populates + * the config_t struct with the result. Uses + * parse to ignore comments and empty lines. + */ +int +read_cfg_file(LINES *l, char *filename) +{ + /* file pointer */ + FILE *file; + HASH H; + char *line; + char *option; + char *value; + + /* char array to hold contents */ + + /* make sure LINES has been initialized. */ + if(!l){ + printf("Structure not initialized!\n"); + return -1; + } + + if((file = fopen(filename, "r")) == NULL) { + /* this is a fatal problem, but we want + to enlighten the user before dying */ + NOTIFY(WARNING, "unable to open file: %s", filename); + display_help(); + exit(EXIT_FAILURE); + } + + line = xmalloc(BUFSIZE); + H = new_hash(); + + l->index = 0; + memset(line, 0, sizeof(line)); + while(fgets(line, BUFSIZE, file) != NULL){ + int num; char *p = strchr(line, '\n'); + /** + * if the line is longer than our buffer, we're + * just going to chuck it rather then fsck with it. + */ + if(p) { + *p = '\0'; + } else { + /** + * Small fix by Gargoyle - 19/07/2006 + * Check to see if we are at the end of the file. If so + * keep the line, otherwise throw it away! + */ + if((num = fgetc(file)) != EOF) { + while((num = fgetc(file)) != EOF && num != '\n'); + line[0]='\0'; + } + } + parse(line); + chomp(line); + if(strlen(line) == 0); + else if(is_variable_line(line)){ + char *tmp = line; + option = tmp; + while(*tmp && !ISSPACE((int)*tmp) && !ISSEPARATOR(*tmp)) + tmp++; + *tmp++=0; + while(ISSPACE((int)*tmp) || ISSEPARATOR(*tmp)) + tmp++; + value = tmp; + while(*tmp) + tmp++; + *tmp++=0; + hash_add(H, option, value); + } + else{ + char *tmp = xstrdup(line); + while(strstr(tmp, "$")){ + tmp = evaluate(H, tmp); + } + l->line = (char**)realloc(l->line, sizeof(char *) * (l->index + 1)); + l->line[l->index] = (char *)strdup(tmp); + l->index++; + + free(tmp); + } + memset(line, 0, sizeof(line)); + } + + fclose(file); + xfree(line); + hash_destroy(H); + return l->index; +} + +int +read_cmd_line(LINES *l, char *url) +{ + int x = 0; + /* char array to hold contents */ + char head[BUFSIZE]; + + /* make sure config_t has been initialized. */ + if(!l){ + printf("Structure not initialized!\n"); + return -1; + } + + l->index = 0; + while(x < 4){ + snprintf(head, sizeof(head), "%s", url); + parse(head); + chomp(head); + if(strlen(head) == 0); + else{ + l->line = (char**)realloc(l->line, sizeof(char *) * (l->index + 1)); + l->line[l->index] = (char *)strdup(head); + l->index++; + } + x++; + } + return l->index; +} + +BOOLEAN +is_variable_line(char *line) +{ + char *pos, *x; + char c; + + /** + * check for variable assignment; make sure that on the left side + * of the = is nothing but letters, numbers, and/or underscores. + */ + pos = strstr(line, "="); + if (pos != NULL) { + for (x = line; x < pos; x++) { + c = *x; + /* c must be A-Z, a-z, 0-9, or underscore. */ + if ((c < 'a' || c > 'z') && + (c < 'A' || c > 'Z') && + (c < '0' || c > '9') && + (c != '_')){ + return FALSE; + } + } + } else { + /** + * if it has no '=' then it can't be a variable line + */ + return FALSE; + } + return TRUE; +} + diff --git a/src/cfg.h b/src/cfg.h new file mode 100644 index 0000000..392d941 --- /dev/null +++ b/src/cfg.h @@ -0,0 +1,31 @@ +/** + * Configuration file support + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * -- + * + */ +#ifndef CFG_H +#define CFG_H +#include + +int read_cfg_file( LINES *l, char *filename ); +int read_cmd_line( LINES *l, char *url ); + +#endif/*CFG_H*/ diff --git a/src/client.c b/src/client.c new file mode 100644 index 0000000..680f03e --- /dev/null +++ b/src/client.c @@ -0,0 +1,759 @@ +/** + * HTTP/HTTPS client support + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(hpux) || defined(__hpux) || defined(WINDOWS) +#define SIGNAL_CLIENT_PLATFORM +#endif + +/** + * local prototypes + */ +private BOOLEAN __request(CONN *C, URL U, CLIENT *c); +private BOOLEAN __http(CONN *C, URL U, CLIENT *c); +private BOOLEAN __ftp (CONN *C, URL U, CLIENT *c); +private BOOLEAN __init_connection(CONN *C, URL U, CLIENT *c); +private void __increment_failures(); +private int __select_color(int code); + +#ifdef SIGNAL_CLIENT_PLATFORM +static void signal_handler( int i ); +static void signal_init(); +#else /*CANCEL_CLIENT_PLATFORM*/ +void clean_up(); +#endif/*SIGNAL_CLIENT_PLATFORM*/ + +/** + * local variables + */ +#ifdef SIGNAL_CLIENT_PLATFORM +static pthread_once_t once = PTHREAD_ONCE_INIT; +#endif/*SIGNAL_CLIENT_PLATFORM*/ +float himark = 0; +float lomark = -1; + +/** + * The thread entry point for clients. + * + * #ifdef SIGNAL_CLIENT_PLATFORM + * the thread entry point for signal friendly clients. + * (currently only HP-UX and Windows) + * + * #ifndef SIGNAL_CLIENT_PLATFORM + * assume cancel client. + * thread entry point for cancellable friendly operating systems like + * aix, GNU/linux, solaris, bsd, etc. + */ +void * +start_routine(CLIENT *client) +{ + int x, y; // loop counters, indices + int ret; //function return value + int len; // main loop length + CONN *C = NULL; // connection data (sock.h) + +#ifdef SIGNAL_CLIENT_PLATFORM + sigset_t sigs; +#else + int type, state; +#endif + + C = xcalloc(sizeof(CONN), 1); + C->sock = -1; + +#ifdef SIGNAL_CLIENT_PLATFORM + pthread_once(&once, signal_init); + sigemptyset(&sigs); + sigaddset(&sigs, SIGUSR1); + pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); +#else + #if defined(_AIX) + pthread_cleanup_push((void(*)(void*))clean_up, NULL); + #else + pthread_cleanup_push((void*)clean_up, C); + #endif +#endif /*SIGNAL_CLIENT_PLATFORM*/ + +#ifdef SIGNAL_CLIENT_PLATFORM +#else/*CANCEL_CLIENT_PLATFORM*/ + #if defined(sun) + pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type); + #elif defined(_AIX) + pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type); + #elif defined(hpux) || defined(__hpux) + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &type); + #else + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &type); + #endif + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &state); +#endif/*SIGNAL_CLIENT_PLATFORM*/ + if (my.login == TRUE) { + URL tmp = new_url(array_next(my.lurl)); + url_set_ID(tmp, 0); + __request(C, tmp, client); + } + + len = (my.reps == -1) ? (int)array_length(client->urls) : my.reps; + y = (my.reps == -1) ? 0 : client->id * (my.length / my.cusers); + for (x = 0; x < len; x++, y++) { + x = ((my.secs > 0) && ((my.reps <= 0)||(my.reps == MAXREPS))) ? 0 : x; + if (my.internet == TRUE) { + y = (unsigned int) (((double)pthread_rand_np(&(client->rand_r_SEED)) / + ((double)RAND_MAX + 1) * my.length ) + .5); + y = (y >= my.length)?my.length-1:y; + y = (y < 0)?0:y; + } else { + /** + * URLs accessed sequentially; when reaching the end, start over + * with clean slate, ie. reset (delete) cookies (eg. to let a new + * session start) + */ + if (y >= my.length) { + y = 0; + if (my.expire) { + delete_all_cookies(pthread_self()); + } + } + } + if (y >= my.length || y < 0) { + y = 0; + } + URL tmp = array_get(client->urls, y); + if (tmp != NULL && url_get_hostname(tmp) != NULL) { + client->auth.bids.www = 0; /* reset */ + if ((ret = __request(C, tmp, client))==FALSE) { + __increment_failures(); + } + } + + if (my.failures > 0 && my.failed >= my.failures) { + break; + } + } + + #ifdef SIGNAL_CLIENT_PLATFORM + #else/*CANCEL_CLIENT_PLATFORM*/ + /** + * every cleanup must have a pop + */ + pthread_cleanup_pop(0); + #endif/*SIGNAL_CLIENT_PLATFORM*/ + if (C->sock >= 0){ + C->connection.reuse = 0; + socket_close(C); + } + xfree(C); + C = NULL; + + return(NULL); +} + +private BOOLEAN +__request(CONN *C, URL U, CLIENT *client) { + C->scheme = url_get_scheme(U); + + switch (C->scheme) { + case FTP: + return __ftp(C, U, client); + case HTTP: + case HTTPS: + default: + return __http(C, U, client); + } +} + +/** + * HTTP client request. + * The protocol is executed in http.c + * This function invoked functions inside that module + * and it gathers statistics about the request. + */ +private BOOLEAN +__http(CONN *C, URL U, CLIENT *client) +{ + unsigned long bytes = 0; + int code, fail; + float etime; + clock_t start, stop; + struct tms t_start, t_stop; + HEADERS *head; +#ifdef HAVE_LOCALTIME_R + struct tm keepsake; +#endif/*HAVE_LOCALTIME_R*/ + time_t now; + struct tm *tmp; + size_t len; + char fmtime[65]; + URL redirect_url = NULL; + + if (my.csv) { + now = time(NULL); +#ifdef HAVE_LOCALTIME_R + tmp = (struct tm *)localtime_r(&now, &keepsake); +#else + tmp = localtime(&now); +#endif/*HAVE_LOCALTIME_R*/ + if (tmp) len = strftime(fmtime, 64, "%Y-%m-%d %H:%M:%S", tmp); + else snprintf(fmtime, 64, "n/a"); + } + + if (url_get_scheme(U) == UNSUPPORTED) { + if (my.verbose && !my.get) { + NOTIFY ( + ERROR, + "%s %d %6.2f secs: %7d bytes ==> %s\n", + "UNSPPRTD", 501, 0.00, 0, "PROTOCOL NOT SUPPORTED BY SIEGE" + ); + } /* end if my.verbose */ + return FALSE; + } + + if (my.delay) { + pthread_sleep_np( + (unsigned int) (((double)pthread_rand_np(&(client->rand_r_SEED)) / + ((double)RAND_MAX + 1) * my.delay ) + .5) + ); + } + + /* record transaction start time */ + start = times(&t_start); + + if (! __init_connection(C, U, client)) return FALSE; + + /** + * write to socket with a GET/POST/PUT/DELETE/HEAD + */ + if (url_get_method(U) == GET || url_get_method(U) == HEAD) { + if ((http_get(C, U)) == FALSE) { + C->connection.reuse = 0; + socket_close(C); + return FALSE; + } + } else { + if ((http_post(C, U)) == FALSE) { + C->connection.reuse = 0; + socket_close(C); + return FALSE; + } + } + + /** + * read from socket and collect statistics. + */ + if ((head = http_read_headers(C, U))==NULL) { + C->connection.reuse = 0; + socket_close(C); + echo ("%s:%d NULL headers", __FILE__, __LINE__); + return FALSE; + } + + bytes = http_read(C); + + if (!my.zero_ok && (bytes < 1)) { + C->connection.reuse = 0; + socket_close(C); + http_free_headers(head); + echo ("%s:%d zero bytes back from server", __FILE__, __LINE__); + return FALSE; + } + stop = times(&t_stop); + etime = elapsed_time(stop - start); + code = (head->code < 400 || head->code == 401 || head->code == 407) ? 1 : 0; + fail = (head->code >= 400 && head->code != 401 && head->code != 407) ? 1 : 0; + /** + * quantify the statistics for this client. + */ + client->bytes += bytes; + client->time += etime; + client->code += code; + client->fail += fail; + if (head->code == 200) { + client->ok200++; + } + + /** + * check to see if this transaction is the longest or shortest + */ + if (etime > himark) { + himark = etime; + } + if ((lomark < 0) || (etime < lomark)) { + lomark = etime; + } + client->himark = himark; + client->lomark = lomark; + + /** + * verbose output, print statistics to stdout + */ + if ((my.verbose && !my.get) && (!my.debug)) { + int color = __select_color(head->code); + char *time_str = (my.timestamp==TRUE)?timestamp():""; + if (my.csv) { + if (my.display) + DISPLAY(color, "%s%s%s%4d,%s,%d,%6.2f,%7lu,%s,%d,%s", + time_str, (my.mark)?my.markstr:"", (my.mark)?",":"", client->id, head->head, head->code, + etime, bytes, url_get_display(U), url_get_ID(U), fmtime + ); + else + DISPLAY(color, "%s%s%s%s,%d,%6.2f,%7lu,%s,%d,%s", + time_str, (my.mark)?my.markstr:"", (my.mark)?",":"", head->head, head->code, + etime, bytes, url_get_display(U), url_get_ID(U), fmtime + ); + } else { + if (my.display) + DISPLAY( + color, "%s%4d: %s %d %6.2f secs: %7lu bytes ==> %-4s %s", client->id, + time_str, head->head, head->code, etime, bytes, url_get_method_name(U), + url_get_display(U) + ); + else + DISPLAY ( + color, "%s%s %d %6.2f secs: %7lu bytes ==> %-4s %s", + time_str, head->head, head->code, etime, bytes, url_get_method_name(U), + url_get_display(U) + ); + } /* else not my.csv */ + if (my.timestamp) xfree(time_str); + } + + /** + * close the socket and free memory. + */ + if (!my.keepalive) { + socket_close(C); + } + + /** + * deal with HTTP > 300 + */ + switch (head->code) { + case 301: + case 302: + case 303: + case 307: + if (my.follow && head->redirect[0]) { + /** + * XXX: What if the server sends us + * Location: path/file.htm + * OR + * Location: /path/file.htm + */ + redirect_url = url_normalize(U, head->redirect); //new_url(head->redirect); + + if (empty(url_get_hostname(redirect_url))) { + url_set_hostname(redirect_url, url_get_hostname(U)); + } + if (head->code == 307) { + url_set_conttype(redirect_url,url_get_conttype(U)); + url_set_method(redirect_url, url_get_method(U)); + + if (url_get_method(redirect_url) == POST) { + url_set_postdata(redirect_url, url_get_postdata(U), url_get_postlen(U)); + } + } + if ((__request(C, redirect_url, client)) == FALSE) { + redirect_url = url_destroy(redirect_url); + return FALSE; + } + } + redirect_url = url_destroy(redirect_url); + break; + case 401: + /** + * WWW-Authenticate challenge from the WWW server + */ + client->auth.www = (client->auth.www==0)?1:client->auth.www; + if ((client->auth.bids.www++) < my.bids - 1) { + BOOLEAN b; + if (head->auth.type.www == DIGEST) { + client->auth.type.www = DIGEST; + b = auth_set_digest_header( + my.auth, &(client->auth.wchlg), &(client->auth.wcred), &(client->rand_r_SEED), + head->auth.realm.www, head->auth.challenge.www + ); + if (b == FALSE) { + NOTIFY(ERROR, "unable to set digest header"); + return FALSE; + } + } + if (head->auth.type.www == BASIC) { + client->auth.type.www = BASIC; + auth_set_basic_header(my.auth, HTTP, head->auth.realm.www); + } + if ((__request(C, U, client)) == FALSE) { + fprintf(stderr, "ERROR from http_request\n"); + return FALSE; + } + } + break; + case 407: + /** + * Proxy-Authenticate challenge from the proxy server. + */ + client->auth.proxy = (client->auth.proxy==0)?1:client->auth.proxy; + if ((client->auth.bids.proxy++) < my.bids - 1) { + if (head->auth.type.proxy == DIGEST) { + BOOLEAN b; + client->auth.type.proxy = DIGEST; + b = auth_set_digest_header( + my.auth, &(client->auth.pchlg), &(client->auth.pcred), &(client->rand_r_SEED), + head->auth.realm.proxy, head->auth.challenge.proxy + ); + if (b == FALSE) { + NOTIFY(ERROR, "unable to set digest header"); + return FALSE; + } + } + if (head->auth.type.proxy == BASIC) { + client->auth.type.proxy = BASIC; + auth_set_basic_header(my.auth, PROXY, head->auth.realm.proxy); + } + if ((__request(C, U, client)) == FALSE) + return FALSE; + } + break; + case 408: + case 500: + case 501: + case 502: + case 503: + case 504: + case 505: + case 506: + case 507: + case 508: + case 509: + return FALSE; + default: + break; + } + + client->hits ++; + http_free_headers(head); + + return TRUE; +} + +/** + * HTTP client request. + * The protocol is executed in http.c + * This function invoked functions inside that module + * and it gathers statistics about the request. + */ +private BOOLEAN +__ftp(CONN *C, URL U, CLIENT *client) +{ + int pass; + int fail; + int code = 0; // capture the relevent return code + float etime; // elapsed time + CONN *D = NULL; // FTP data connection + size_t bytes = 0; // bytes from server + clock_t start, stop; + struct tms t_start, t_stop; + + D = xcalloc(sizeof(CONN), 1); + D->sock = -1; + + if (! __init_connection(C, U, client)) { + NOTIFY ( + ERROR, "%s:%d connection failed %s:%d", + __FILE__, __LINE__, url_get_hostname(U), url_get_port(U) + ); + xfree(D); + return FALSE; + } + + start = times(&t_start); + if (C->sock < 0) { + NOTIFY ( + ERROR, "%s:%d connection failed %s:%d", + __FILE__, __LINE__, url_get_hostname(U), url_get_port(U) + ); + socket_close(C); + xfree(D); + return FALSE; + } + + if (url_get_username(U) == NULL || strlen(url_get_username(U)) < 1) { + url_set_username(U, auth_get_ftp_username(my.auth, url_get_hostname(U))); + } + + if (url_get_password(U) == NULL || strlen(url_get_password(U)) < 1) { + url_set_password(U, auth_get_ftp_password(my.auth, url_get_hostname(U))); + } + + if (ftp_login(C, U) == FALSE) { + if (my.verbose) { + int color = __select_color(C->ftp.code); + DISPLAY ( + color, "FTP/%d %6.2f secs: %7lu bytes ==> %-6s %s", + C->ftp.code, 0.0, bytes, url_get_method_name(U), url_get_request(U) + ); + } + xfree(D); + client->fail += 1; + return FALSE; + } + + ftp_pasv(C); + if (C->ftp.pasv == TRUE) { + debug("Connecting to: %s:%d", C->ftp.host, C->ftp.port); + D->sock = new_socket(D, C->ftp.host, C->ftp.port); + if (D->sock < 0) { + debug ( + "%s:%d connection failed. error %d(%s)",__FILE__, __LINE__, errno,strerror(errno) + ); + client->fail += 1; + socket_close(D); + xfree(D); + return FALSE; + } + } + if (url_get_method(U) == POST || url_get_method(U) == PUT) { + ftp_stor(C, U); + bytes = ftp_put(D, U); + code = C->ftp.code; + } else { + if (ftp_size(C, U) == TRUE) { + if (ftp_retr(C, U) == TRUE) { + bytes = ftp_get(D, U, C->ftp.size); + } + } + code = C->ftp.code; + } + socket_close(D); + ftp_quit(C); + + pass = (bytes == C->ftp.size) ? 1 : 0; + fail = (pass == 0) ? 1 : 0; + stop = times(&t_stop); + etime = elapsed_time(stop - start); + client->bytes += bytes; + client->time += etime; + client->code += pass; + client->fail += fail; + + /** + * check to see if this transaction is the longest or shortest + */ + if (etime > himark) { + himark = etime; + } + if ((lomark < 0) || (etime < lomark)) { + lomark = etime; + } + client->himark = himark; + client->lomark = lomark; + + if (my.verbose) { + int color = __select_color(code); + DISPLAY ( + color, "FTP/%d %6.2f secs: %7lu bytes ==> %-6s %s", + code, etime, bytes, url_get_method_name(U), url_get_request(U) + ); + } + client->hits++; + xfree(D); + return TRUE; +} + +#ifdef SIGNAL_CLIENT_PLATFORM +private void +signal_handler(int sig) +{ + pthread_exit(&sig); +} + +private void +signal_init() +{ + struct sigaction sa; + + sa.sa_handler = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGUSR1, &sa, NULL); +} +#else/*CANCEL_CLIENT_PLATFORM*/ + +void +clean_up() +{ + return; +} +#endif + +private BOOLEAN +__init_connection(CONN *C, URL U, CLIENT *client) +{ + C->pos_ini = 0; + C->inbuffer = 0; + C->content.transfer = NONE; + C->content.length = 0; + C->connection.keepalive = (C->connection.max==1)?0:my.keepalive; + C->connection.reuse = (C->connection.max==1)?0:my.keepalive; + C->connection.tested = (C->connection.tested==0)?1:C->connection.tested; + C->auth.www = client->auth.www; + C->auth.wchlg = client->auth.wchlg; + C->auth.wcred = client->auth.wcred; + C->auth.proxy = client->auth.proxy; + C->auth.pchlg = client->auth.pchlg; + C->auth.pcred = client->auth.pcred; + C->auth.type.www = client->auth.type.www; + C->auth.type.proxy = client->auth.type.proxy; + memset(C->buffer, 0, sizeof(C->buffer)); + + debug ( + "%s:%d attempting connection to %s:%d", + __FILE__, __LINE__, + (auth_get_proxy_required(my.auth))?auth_get_proxy_host(my.auth):url_get_hostname(U), + (auth_get_proxy_required(my.auth))?auth_get_proxy_port(my.auth):url_get_port(U) + ); + + if (!C->connection.reuse || C->connection.status == 0) { + if (auth_get_proxy_required(my.auth)) { + debug ( + "%s:%d creating new socket: %s:%d", + __FILE__, __LINE__, auth_get_proxy_host(my.auth), auth_get_proxy_port(my.auth) + ); + C->sock = new_socket(C, auth_get_proxy_host(my.auth), auth_get_proxy_port(my.auth)); + } else { + debug ( + "%s:%d creating new socket: %s:%d", + __FILE__, __LINE__, url_get_hostname(U), url_get_port(U) + ); + C->sock = new_socket(C, url_get_hostname(U), url_get_port(U)); + } + } + + if (my.keepalive) { + C->connection.reuse = TRUE; + } + + if (C->sock < 0) { + debug ( + "%s:%d connection failed. error %d(%s)",__FILE__, __LINE__, errno,strerror(errno) + ); + socket_close(C); + return FALSE; + } + + debug ( + "%s:%d good socket connection: %s:%d", + __FILE__, __LINE__, + (auth_get_proxy_required(my.auth))?auth_get_proxy_host(my.auth):url_get_hostname(U), + (auth_get_proxy_required(my.auth))?auth_get_proxy_port(my.auth):url_get_port(U) + ); + + if (C->encrypt == TRUE) { + if (auth_get_proxy_required(my.auth)) { + https_tunnel_request(C, url_get_hostname(U), url_get_port(U)); + https_tunnel_response(C); + } + C->encrypt = TRUE; + if (SSL_initialize(C)==FALSE) { + return FALSE; + } + } + return TRUE; +} + +private void +__increment_failures() +{ + pthread_mutex_lock(&(my.lock)); + my.failed++; + pthread_mutex_unlock(&(my.lock)); + pthread_testcancel(); +} + + +private int +__select_color(int code) +{ + switch(code) { + case 150: + case 200: + case 201: + case 202: + case 203: + case 204: + case 205: + case 206: + case 226: + return BLUE; + case 300: + case 301: + case 302: + case 303: + case 304: + case 305: + case 306: + case 307: + return CYAN; + case 400: + case 401: + case 402: + case 403: + case 404: + case 405: + case 406: + case 407: + case 408: + case 409: + case 410: + case 411: + case 412: + case 413: + case 414: + case 415: + case 416: + case 417: + return MAGENTA; + case 500: + case 501: + case 502: + case 503: + case 504: + case 505: + default: // WTF? + return RED; + } + return RED; +} + diff --git a/src/client.h b/src/client.h new file mode 100644 index 0000000..2e40e90 --- /dev/null +++ b/src/client.h @@ -0,0 +1,85 @@ +/** + * Client Header + * + * Copyright (C) 2013-2014 by + * Jeffrey Fulmer, et al - + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef CLIENT_H +#define CLIENT_H + +#ifdef HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ +#include +#include +#include +#include +#include +#ifdef HAVE_SSL +# include +# include +#endif /* HAVE_SSL */ + +#include + +struct trans +{ + int bytes; + int code; + float time; +}; + +/** + * client data + */ +typedef struct +{ + int id; + unsigned long hits; + unsigned long bytes; + unsigned int code; + unsigned int fail; + unsigned int ok200; + ARRAY urls; + struct { + DCHLG *wchlg; + DCRED *wcred; + int www; + DCHLG *pchlg; + DCRED *pcred; + int proxy; + struct { + int www; + int proxy; + } bids; + struct { + TYPE www; + TYPE proxy; + } type; + } auth; + int status; + float time; + unsigned int rand_r_SEED; + float himark; + float lomark; +} CLIENT; + +void * start_routine(CLIENT *client); + +#endif/*CLIENT_H */ diff --git a/src/cookie.c b/src/cookie.c new file mode 100644 index 0000000..846e98c --- /dev/null +++ b/src/cookie.c @@ -0,0 +1,344 @@ +/** + * Cookies Support + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * Copyright (C) 2002 the University of Kansas + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * -- + */ +#include +#include +#include +#include + +typedef struct +{ + char* name; + char* value; + char* domain; + char* path; + time_t expires; + int secure; +} PARSED_COOKIE; + +void +free_cookie(PARSED_COOKIE* ck) +{ + xfree(ck->name); + xfree(ck->value); + xfree(ck->domain); + xfree(ck->path); +} + +COOKIE *cookie; + +void +parse_cookie(char *cookiestr, PARSED_COOKIE* ck) +{ + char *lval, *rval; + if (cookiestr==NULL || ck==NULL) return; + + ck->name = ck->value = ck->domain = ck->path = NULL; + ck->expires = ck->secure = 0; + + lval = cookiestr; + + while (*cookiestr && *cookiestr != '=') + cookiestr++; + + if (!*cookiestr) /*WTF?*/ return; + + *cookiestr++ = 0; /* NULL-terminate lval (replace '=') and position at start of rval */ + + rval = cookiestr; + while (*cookiestr && *cookiestr != ';') + cookiestr++; + + *cookiestr++ = 0; + + if (lval != NULL) debug ("%s:%d accepting cookie name: %s", __FILE__, __LINE__, lval); + if (rval != NULL) debug ("%s:%d accepting cookie value: %s", __FILE__, __LINE__, rval); + ck->name = (lval != NULL) ? xstrdup(lval) : NULL; + ck->value = (rval != NULL) ? xstrdup(rval) : NULL; + /* get the biggest possible positive value */ + ck->expires = 0; + ck->expires = ~ck->expires; + if (ck->expires < 0) { + ck->expires = ~(1UL << ((sizeof(ck->expires) * 8) - 1)); + } + if(ck->expires < 0) { + ck->expires = (ck->expires >> 1) * -1; + } + + if (!*cookiestr) { + /** + revert to defaults + XXX: assumes at least one key value pair + */ + return; + } + + while (*cookiestr) { + while (isspace((unsigned char)*cookiestr)) + cookiestr++; + + if (!*cookiestr) break; + + lval = cookiestr; + while (*cookiestr && *cookiestr != '=' ) + cookiestr++; + + if (!strcasecmp (lval, "secure")) { + ck->secure = 1; + rval = NULL; + } else { + if (!*cookiestr) return; + + *cookiestr++ = 0; + + rval = cookiestr; + while (*cookiestr && *cookiestr != ';') + cookiestr++; + *cookiestr++ = 0; + } + + if (!strcasecmp(lval, "domain")) { + ck->domain = (rval != NULL) ? xstrdup( rval ) : NULL; + } else if (!strcasecmp (lval, "expires")) { + ck->expires = strtotime(rval); + } else if (!strcasecmp (lval, "path")) { + ck->path = (rval != NULL) ? xstrdup( rval ) : NULL; + } + } + return; +} + +/** + * insert values into list + */ +int +add_cookie(pthread_t id, char *host, char *cookiestr) +{ + char *name, *value; + int found = FALSE; + CNODE *cur, *pre, *fresh = NULL; + PARSED_COOKIE ck; + + parse_cookie(cookiestr, &ck); + name = ck.name; + value = ck.value; + + if ((name == NULL || value == NULL)) return -1; + + pthread_mutex_lock(&(cookie->mutex)); + for (cur=pre=cookie->first; cur != NULL; pre=cur, cur=cur->next) { + if ((cur->threadID == id )&&(!strcasecmp(cur->name, name))) { + xfree(cur->value); + cur->value = xstrdup(value); + /** + XXX: I need to read the RFC in order to + understand the required behavior + xfree(cur->name); + xfree(cur->domain); + cur->name = xstrdup(name); + cur->expires = ck.expires; + if(!ck.domain) + cur->domain = xstrdup(host); + else + cur->domain = xstrdup(ck.domain); + */ + found = TRUE; + break; + } + } + if (!found) { + fresh = (CNODE*)xmalloc(sizeof(CNODE)); + if (!fresh) NOTIFY(FATAL, "out of memory!"); + fresh->threadID = id; + fresh->name = xstrdup(name); + fresh->value = xstrdup(value); + fresh->expires = ck.expires; + if (!ck.domain) + fresh->domain = xstrdup(host); + else + fresh->domain = xstrdup(ck.domain); + fresh->next = cur; + if (cur==cookie->first) + cookie->first = fresh; + else + pre->next = fresh; + } + if (name != NULL) xfree(name); + if (value != NULL) xfree(value); + + pthread_mutex_unlock(&(cookie->mutex)); + + return 0; +} + +BOOLEAN +delete_cookie(pthread_t id, char *name) +{ + CNODE *cur, *pre; + BOOLEAN res = FALSE; + + for (cur=pre=cookie->first; cur != NULL; pre=cur, cur=cur->next) { + if (cur->threadID == id) { + if (!strcasecmp(cur->name, name)) { + pre->next = cur->next; + /* ksjuse: XXX: this breaks when the cookie to remove comes first */ + /* JDF: XXX: I believe this will fix the problem: */ + if(cur == cookie->first){ + /* deleting the first */ + cookie->first = cur->next; + pre = cookie->first; + } else { + /* deleting inner */ + pre->next = cur->next; + } + res = TRUE; + echo ("%s:%d cookie deleted: %ld => %s\n",__FILE__, __LINE__, (long)id,name); + break; + } + } else { + continue; + } + } + return res; +} + + +/* + Delete all cookies associated with the given id. + return 0 (as delete_cookie does)? +*/ +int +delete_all_cookies(pthread_t id) +{ + CNODE *cur, *pre; + + pthread_mutex_lock(&(cookie->mutex)); + for (pre=NULL, cur=cookie->first; cur != NULL; pre=cur, cur=cur->next) { + if (cur->threadID == id) { + echo ("%s:%d cookie deleted: %ld => %s\n",__FILE__, __LINE__, (long)id,cur->name); + /* delete this cookie */ + if (cur == cookie->first) { + /* deleting the first */ + cookie->first = cur->next; + pre = cookie->first; + } else { + /* deleting inner */ + pre->next = cur->next; + } + xfree(cur->name); + xfree(cur->value); + xfree(cur->domain); + xfree(cur); + cur = pre; + /* cur is NULL now when we deleted the last cookie; + * cur was cookie->first and first->next was NULL. + * check that before incremeting (cur=cur->next). + */ + if (cur == NULL) + break; + } + } + pthread_mutex_unlock(&(cookie->mutex)); + return 0; +} + +/** + * get_cookie returns a char * with a compete value of the Cookie: header + * It does NOT return the actual Cookie struct. + */ +char * +get_cookie_header(pthread_t id, char *host, char *newton) +{ + int dlen, hlen; + CNODE *pre, *cur; + time_t now; + char oreo[MAX_COOKIE_SIZE]; + + memset(oreo, '\0', sizeof oreo); + hlen = strlen(host); + + pthread_mutex_lock(&(cookie->mutex)); + now = time(NULL); + + for (cur=pre=cookie->first; cur != NULL; pre=cur, cur=cur->next) { + /** + * for the purpose of matching, we'll ignore the leading '.' + */ + const char *domainptr = cur->domain; + if (*domainptr == '.') ++domainptr; + dlen = domainptr ? strlen(domainptr) : 0; + if (cur->threadID == id) { + if (!strcasecmp(domainptr, host)) { + if (cur->expires <= now) { + delete_cookie(cur->threadID, cur->name); + continue; + } + if (strlen(oreo) > 0) + strncat(oreo, ";", sizeof(oreo) - 10 - strlen(oreo)); + strncat(oreo, cur->name, sizeof(oreo) - 10 - strlen(oreo)); + strncat(oreo, "=", sizeof(oreo) - 10 - strlen(oreo)); + strncat(oreo, cur->value, sizeof(oreo) - 10 - strlen(oreo)); + } + if ((dlen < hlen) && (!strcasecmp(host + (hlen - dlen), domainptr))) { + if (cur->expires <= now) { + delete_cookie(cur->threadID, cur->name); + continue; + } + if (strlen(oreo) > 0) + strncat(oreo, ";", sizeof(oreo) - 10 - strlen(oreo)); + strncat(oreo, cur->name, sizeof(oreo) - 10 - strlen(oreo)); + strncat(oreo, "=", sizeof(oreo) - 10 - strlen(oreo)); + strncat(oreo, cur->value, sizeof(oreo) - 10 - strlen(oreo)); + } + } + } + if (strlen(oreo) > 0) { + strncpy(newton, "Cookie: ", 8); + strncat(newton, oreo, MAX_COOKIE_SIZE); + strncat(newton, "\015\012", 2); + } + pthread_mutex_unlock(&(cookie->mutex)); + + return newton; +} + +/* + Helper util, displays the contents of Cookie +*/ +void +display_cookies() +{ + CNODE *cur; + + pthread_mutex_lock(&(cookie->mutex)); + + printf ("Linked list contains:\n"); + for (cur=cookie->first; cur != NULL; cur=cur->next) { + printf ("Index: %ld\tName: %s Value: %s\n", (long)cur->threadID, cur->name, cur->value); + } + + pthread_mutex_unlock(&(cookie->mutex)); + + return; +} + diff --git a/src/cookie.h b/src/cookie.h new file mode 100644 index 0000000..68ebdd3 --- /dev/null +++ b/src/cookie.h @@ -0,0 +1,70 @@ +/** + * Cookie support + * + * Copyright (C) 2001-2014 Jeffrey Fulmer , et al + * This file is part of Siege + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + *-- + */ +#ifndef COOKIES_H +#define COOKIES_H + +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#include +#include +#include + +#define MAX_COOKIE_SIZE 8192 + +/** + * cookie node + */ +typedef struct CNODE +{ + int index; + pthread_t threadID; + char *name; + char *value; + char *path; + char *domain; + time_t expires; + char *expirestr; + char *version; + char *max; + int secure; + struct CNODE *next; +} CNODE; + +typedef struct +{ + CNODE *first; + pthread_mutex_t mutex; +} COOKIE; + +int add_cookie(pthread_t id, char *host, char *value); +BOOLEAN delete_cookie(pthread_t id, char *name); +int delete_all_cookies(pthread_t id); +int check_cookie(char *domain, char *value); +char *get_cookie_header(pthread_t id, char *domain, char *cookie); +void display_cookies(); + +extern COOKIE *cookie; + +#endif/*COOKIES_H*/ + diff --git a/src/creds.c b/src/creds.c new file mode 100644 index 0000000..b741825 --- /dev/null +++ b/src/creds.c @@ -0,0 +1,150 @@ +/** + * HTTP authentication credentials + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include +#include + +struct CREDS_T { + SCHEME scheme; + char *username; + char *password; + char *realm; +}; + +size_t CREDSIZE = sizeof(struct CREDS_T); + +private void __parse_input(CREDS this, char *str); + + +CREDS +new_creds(SCHEME scheme, char *str) +{ + CREDS this; + + this = calloc(sizeof(struct CREDS_T), 1); + this->scheme = scheme; + __parse_input(this, str); + return this; +} + +CREDS +creds_destroy(CREDS this) +{ + free(this->username); + free(this->password); + free(this->realm); + free(this); + return NULL; +} + +SCHEME +creds_get_scheme(CREDS this) +{ + return this->scheme; +} + +char * +creds_get_username(CREDS this) +{ + return this->username; +} + +char * +creds_get_password(CREDS this) +{ + return this->password; +} + +char * +creds_get_realm(CREDS this) +{ + return this->realm; +} + +void +creds_set_username(CREDS this, char *username) +{ + size_t len = strlen(username); + + this->username = malloc(len+1); + memset(this->username, '\0', len+1); + memcpy(this->username, username, len); + return; +} + +void +creds_set_password(CREDS this, char *password) +{ + size_t len = strlen(password); + + this->password = malloc(len+1); + memset(this->password, '\0', len+1); + memcpy(this->password, password, len); + return; +} + +void +creds_set_realm(CREDS this, char *realm) +{ + size_t len = strlen(realm); + + this->realm = malloc(len+1); + memset(this->realm, '\0', len+1); + memcpy(this->realm, realm, len); + return; +} + + +private void +__parse_input(CREDS this, char *str) +{ + char *usr; + char *pwd; + char *rlm; + char *tmp; + char any[] = "any\0"; + + usr = tmp = str; + while (*tmp && *tmp != ':' && *tmp != '\0') + tmp++; + + *tmp++=0; + pwd = tmp; + while (*tmp && *tmp != ':' && *tmp != '\0') + tmp++; + + if ('\0' != *tmp) { + *tmp++=0; + rlm = tmp; + } else { + rlm = NULL; + } + + creds_set_username(this, usr); + creds_set_password(this, pwd); + creds_set_realm(this, (rlm==NULL)?any:rlm); +} + diff --git a/src/creds.h b/src/creds.h new file mode 100644 index 0000000..e84f447 --- /dev/null +++ b/src/creds.h @@ -0,0 +1,42 @@ +/** + * HTTP authentication credentials + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef __CREDS_H +#define __CREDS_H + +#include + +typedef struct CREDS_T *CREDS; +extern size_t CREDSIZE; + +CREDS new_creds(SCHEME scheme, char *str); +CREDS creds_destroy(CREDS this); +SCHEME creds_get_scheme(CREDS this); +char *creds_get_username(CREDS this); +char *creds_get_password(CREDS this); +char *creds_get_realm(CREDS this); +void creds_set_username(CREDS this, char *username); +void creds_set_password(CREDS this, char *password); +void creds_set_realm(CREDS this, char *realm); + +#endif/*__CREDS*/ + diff --git a/src/crew.c b/src/crew.c new file mode 100644 index 0000000..bc3adf5 --- /dev/null +++ b/src/crew.c @@ -0,0 +1,328 @@ +/** + * Thread pool + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include +#include + +private void *crew_thread(void *); + +struct CREW_T +{ + int size; + int maxsize; + int cursize; + int total; + WORK *head; + WORK *tail; + BOOLEAN block; + BOOLEAN closed; + BOOLEAN shutdown; + pthread_t *threads; + pthread_mutex_t lock; + pthread_cond_t not_empty; + pthread_cond_t not_full; + pthread_cond_t empty; +}; + +CREW +new_crew(int size, int maxsize, BOOLEAN block) +{ + int x; + int c; + CREW this; + + if((this = calloc(sizeof(*this),1)) == NULL) + return NULL; + + if((this->threads = (pthread_t *)malloc(sizeof(pthread_t)*size)) == NULL) + return NULL; + + this->size = size; + this->maxsize = maxsize; + this->cursize = 0; + this->total = 0; + this->block = block; + this->head = NULL; + this->tail = NULL; + this->closed = FALSE; + this->shutdown = FALSE; + + if((c = pthread_mutex_init(&(this->lock), NULL)) != 0) + return NULL; + if((c = pthread_cond_init(&(this->not_empty), NULL )) != 0) + return NULL; + if((c = pthread_cond_init(&(this->not_full), NULL )) != 0) + return NULL; + if((c = pthread_cond_init(&(this->empty), NULL)) != 0) + return NULL; + + for(x = 0; x != size; x++){ + if((c = pthread_create(&(this->threads[x]), NULL, crew_thread, (void *)this)) != 0) + return NULL; + } + + return this; +} + +private void +*crew_thread(void *crew) +{ + int c; + WORK *workptr; + CREW this = (CREW)crew; + + while(TRUE){ + if((c = pthread_mutex_lock(&(this->lock))) != 0){ + NOTIFY(FATAL, "mutex lock"); + } + while((this->cursize == 0) && (!this->shutdown)){ + if((c = pthread_cond_wait(&(this->not_empty), &(this->lock))) != 0) + NOTIFY(FATAL, "pthread wait"); + } + + if(this->shutdown == TRUE){ + if((c = pthread_mutex_unlock(&(this->lock))) != 0){ + NOTIFY(FATAL, "mutex unlock"); + } + pthread_exit(NULL); + } + workptr = this->head; + this->cursize--; + if(this->cursize == 0){ + this->head = this->tail = NULL; + } + else{ + this->head = workptr->next; + } + if((this->block) && (this->cursize == (this->maxsize - 1))){ + if((c = pthread_cond_broadcast(&(this->not_full))) != 0){ + NOTIFY(FATAL, "pthread broadcast"); + } + } + if(this->cursize == 0){ + if((c = pthread_cond_signal(&(this->empty))) != 0){ + NOTIFY(FATAL, "pthread signal"); + } + } + if((c = pthread_mutex_unlock(&(this->lock))) != 0){ + NOTIFY(FATAL, "pthread unlock"); + } + + (*(workptr->routine))(workptr->arg); + + xfree(workptr); + } + + return(NULL); +} + +BOOLEAN +crew_add(CREW crew, void (*routine)(), void *arg) +{ + int c; + WORK *workptr; + + if((c = pthread_mutex_lock(&(crew->lock))) != 0){ + NOTIFY(FATAL, "pthread lock"); + } + if((crew->cursize == crew->maxsize) && !crew->block ){ + if((c = pthread_mutex_unlock(&(crew->lock))) != 0){ + NOTIFY(FATAL, "pthread unlock"); + } + return FALSE; + } + + while((crew->cursize == crew->maxsize ) && (!(crew->shutdown || crew->closed))){ + if((c = pthread_cond_wait(&(crew->not_full), &(crew->lock))) != 0){ + NOTIFY(FATAL, "pthread wait"); + } + } + if(crew->shutdown || crew->closed){ + if((c = pthread_mutex_unlock(&(crew->lock))) != 0){ + NOTIFY(FATAL, "pthread unlock"); + } + return FALSE; + } + if((workptr = (WORK *)malloc(sizeof(WORK))) == NULL){ + NOTIFY(FATAL, "out of memory"); + } + workptr->routine = routine; + workptr->arg = arg; + workptr->next = NULL; + + if(crew->cursize == 0){ + crew->tail = crew->head = workptr; + if((c = pthread_cond_broadcast(&(crew->not_empty))) != 0){ + NOTIFY(FATAL, "pthread signal"); + } + } else { + crew->tail->next = workptr; + crew->tail = workptr; + } + + crew->cursize++; + crew->total ++; + if((c = pthread_mutex_unlock(&(crew->lock))) != 0){ + NOTIFY(FATAL, "pthread unlock"); + } + + return TRUE; +} + +BOOLEAN +crew_cancel(CREW this) +{ + int x; + int size; + + /* XXX we store the size in a local + variable because crew->size gets + whacked when we cancel threads */ + size = this->size; + + crew_set_shutdown(this, TRUE); + for(x = 0; x < size; x++){ +#if defined(hpux) || defined(__hpux) + pthread_kill(this->threads[x], SIGUSR1); +#else + pthread_cancel(this->threads[x]); +#endif + } + return TRUE; +} + +BOOLEAN +crew_join(CREW crew, BOOLEAN finish, void **payload) +{ + int x; + int c; + + if((c = pthread_mutex_lock(&(crew->lock))) != 0){ + NOTIFY(FATAL, "pthread lock"); + } + + if(crew->closed || crew->shutdown){ + if((c = pthread_mutex_unlock(&(crew->lock))) != 0){ + NOTIFY(FATAL, "pthread unlock"); + } + return FALSE; + } + + crew->closed = TRUE; + + if(finish == TRUE){ + while((crew->cursize != 0) && (!crew->shutdown)){ + int rc; + struct timespec ts; + struct timeval tp; + + rc = gettimeofday(&tp,NULL); + if( rc != 0 ) + perror("gettimeofday"); + ts.tv_sec = tp.tv_sec+60; + ts.tv_nsec = tp.tv_usec*1000; + rc = pthread_cond_timedwait(&(crew->empty), &(crew->lock), &ts ); + if(rc==ETIMEDOUT) { + pthread_mutex_unlock(&crew->lock); + } + + if( rc != 0){ + NOTIFY(FATAL, "pthread wait"); + } + } + } + + crew->shutdown = TRUE; + + if((c = pthread_mutex_unlock(&(crew->lock))) != 0){ + NOTIFY(FATAL, "pthread_mutex_unlock"); + } + + if((c = pthread_cond_broadcast(&(crew->not_empty))) != 0){ + NOTIFY(FATAL, "pthread broadcast"); + } + + if((c = pthread_cond_broadcast(&(crew->not_full))) != 0){ + NOTIFY(FATAL, "pthread broadcast"); + } + + for(x = 0; x < crew->size; x++){ + if((c = pthread_join(crew->threads[x], payload)) != 0){ + NOTIFY(FATAL, "pthread_join"); + } + } + + return TRUE; +} + +void crew_destroy(CREW crew) { + WORK *workptr; + + xfree(crew->threads); + while(crew->head != NULL){ + workptr = crew->head; + crew->head = crew->head->next; + xfree(workptr); + } + + xfree(crew); +} + +/** + * getters and setters + */ +public void +crew_set_shutdown(CREW this, BOOLEAN shutdown) +{ +// pthread_mutex_lock(&this->lock); + this->shutdown = shutdown; +// pthread_mutex_unlock(&this->lock); + + pthread_cond_broadcast(&this->not_empty); + pthread_cond_broadcast(&this->not_full); + pthread_cond_broadcast(&this->empty); + return; +} + +public int +crew_get_size(CREW this) +{ + return this->size; +} + +public int +crew_get_total(CREW this) +{ + return this->total; +} + +public BOOLEAN +crew_get_shutdown(CREW this) +{ + return this->shutdown; +} + + diff --git a/src/crew.h b/src/crew.h new file mode 100644 index 0000000..5bfafe6 --- /dev/null +++ b/src/crew.h @@ -0,0 +1,51 @@ +/** + * Thread pool + * + * Copyright (C) 2003-2013 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef __CREW_H +#define __CREW_H + +#include +#include +#include + +typedef struct work +{ + void (*routine)(); + void *arg; + struct work *next; +} WORK; + +typedef struct CREW_T *CREW; + +CREW new_crew(int size, int maxsize, BOOLEAN block); +BOOLEAN crew_add(CREW this, void (*routine)(), void *arg); +BOOLEAN crew_cancel(CREW this); +BOOLEAN crew_join(CREW this, BOOLEAN finish, void **payload); +void crew_destroy(CREW this); + +void crew_set_shutdown(CREW this, BOOLEAN shutdown); + +int crew_get_size(CREW this); +int crew_get_total(CREW this); +BOOLEAN crew_get_shutdown(CREW this); + +#endif/*__CREW_H*/ diff --git a/src/data.c b/src/data.c new file mode 100644 index 0000000..0eb0dfb --- /dev/null +++ b/src/data.c @@ -0,0 +1,271 @@ +/** + * Storage for siege data + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include + +#ifdef HAVE_SYS_TIMES_H +# include +#endif/*HAVE_SYS_TIMES_H*/ + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif/*HAVE_SYS_TIME_H */ +#endif /*TIME_WITH_SYS_TIME*/ + + +struct DATA_T +{ + float total; /*ttime*/ + float available; + float failed; + float lowest; + float highest; + float elapsed; + clock_t start; + clock_t stop; + struct tms t_start; + struct tms t_stop; + unsigned int code; + unsigned int count; + unsigned int ok200; + unsigned int fail; + unsigned long long bytes; +}; + +DATA +new_data() +{ + DATA this; + + this = calloc(sizeof(*this),1); + this->total = 0.0; + this->available = 0.0; + this->count = 0.0; + this->ok200 = 0; + this->failed = 0.0; + this->lowest = -1; + this->highest = 0.0; + this->elapsed = 0.0; + this->bytes = 0.0; + return this; +} + +void +data_destroy(DATA this) +{ + xfree(this); + return; +} + +void +data_increment_bytes(DATA this, unsigned long bytes) +{ + this->bytes += bytes; + return; +} + +void +data_increment_count(DATA this, unsigned long count) +{ + this->count += count; + return; +} + +void +data_increment_total(DATA this, float total) +{ + this->total += total; + return; +} + +void +data_increment_code(DATA this, int code) +{ + this->code += code; + return; +} + +void +data_increment_fail(DATA this, int fail) +{ + this->fail += fail; + return; +} + +void +data_increment_ok200(DATA this, int ok200) +{ + this->ok200 += ok200; + return; +} + +void +data_set_start(DATA this) +{ + this->start = times(&this->t_start); + return; +} + +void +data_set_stop(DATA this) +{ + this->stop = times(&this->t_stop); + return; +} + +void +data_set_highest(DATA this, float highest) +{ + if(this->highest < highest){ + this->highest = highest; + } + return; +} + +void +data_set_lowest(DATA this, float lowest) +{ + if((this->lowest <= 0)||(this->lowest > lowest)){ + this->lowest = lowest; + } + return; +} + +unsigned int +data_get_count(DATA this) +{ + return this->count; +} + +unsigned int +data_get_code(DATA this) +{ + return this->code; +} + +unsigned int +data_get_fail(DATA this) +{ + return this->fail; +} + +unsigned int +data_get_ok200(DATA this) +{ + return this->ok200; +} + +float +data_get_total(DATA this) +{ + return this->total; +} + +float +data_get_bytes(DATA this) +{ + return (float)this->bytes; +} + +float +data_get_highest(DATA this) +{ + return this->highest; +} + +float +data_get_lowest(DATA this) +{ + if(this->code){ + return this->lowest; + } else { + return this->code; + } +} + +float +data_get_megabytes(DATA this) +{ + return (float)this->bytes/(1024.0*1024.0); +} + +float +data_get_elapsed(DATA this) +{ + long tps; + clock_t time; + + time = this->stop - this->start; + tps = sysconf(_SC_CLK_TCK); + this->elapsed = (float)time/tps; + return this->elapsed; +} + +float +data_get_availability(DATA this) +{ + this->available = (this->count==0)?0:((this->count/(this->count+this->failed))*100); + return this->available; +} + +float +data_get_response_time(DATA this) +{ + if((this->total==0)||(this->count==0)) + return 0; + return (this->total / this->count); +} + +float +data_get_transaction_rate(DATA this) +{ + if((this->count==0)||(this->elapsed==0)) + return 0; + return (this->count / this->elapsed); +} + +float +data_get_throughput(DATA this) +{ + if(this->elapsed==0) + return 0; + return this->bytes / (this->elapsed * 1024.0*1024.0); +} + +float +data_get_concurrency(DATA this) +{ + if(this->elapsed==0) + return 0; + /* total transaction time / elapsed time */ + return (this->total / this->elapsed); +} + diff --git a/src/data.h b/src/data.h new file mode 100644 index 0000000..6154c30 --- /dev/null +++ b/src/data.h @@ -0,0 +1,79 @@ +/** + * Storage for siege data + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef __DATA_H +#define __DATA_H + +#include +#include + +#ifdef HAVE_SYS_TIMES_H +# include +#endif/*HAVE_SYS_TIMES_H*/ + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif/*HAVE_SYS_TIME_H */ +#endif /*TIME_WITH_SYS_TIME*/ + +typedef struct DATA_T *DATA; + +/* constructor */ +DATA new_data(); +void data_destroy(DATA this); + +/* setters */ +void data_set_start (DATA this); +void data_set_stop (DATA this); +void data_set_highest (DATA this, float highest); +void data_set_lowest (DATA this, float lowest); +void data_increment_bytes(DATA this, unsigned long bytes); +void data_increment_count(DATA this, unsigned long count); +void data_increment_total(DATA this, float total); +void data_increment_code (DATA this, int code); +void data_increment_fail (DATA this, int fail); +void data_increment_ok200 (DATA this, int ok200); + +/* getters */ +float data_get_total(DATA this); +float data_get_bytes(DATA this); +float data_get_megabytes(DATA this); +float data_get_highest(DATA this); +float data_get_lowest(DATA this); +float data_get_elapsed(DATA this); +float data_get_availability(DATA this); +float data_get_response_time(DATA this); +float data_get_transaction_rate(DATA this); +float data_get_throughput(DATA this); +float data_get_concurrency(DATA this); +unsigned int data_get_count(DATA this); +unsigned int data_get_code (DATA this); +unsigned int data_get_fail (DATA this); +unsigned int data_get_ok200(DATA this); + +#endif/*__DATA_H*/ diff --git a/src/date.c b/src/date.c new file mode 100644 index 0000000..153c083 --- /dev/null +++ b/src/date.c @@ -0,0 +1,458 @@ +/** + * Date calculations for siege + * + * Copyright (C) 2007-2014 by + * Jeffrey Fulmer - , et al. + * + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * (modified - use the original: http://curl.haxx.se/) + * + * This file is distributed as part of Siege + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif/*TIME_WITH_SYS_TIME*/ + +#include +#include + +#define MAX_TIME_LEN 64 + +enum assume { + DATE_MDAY, + DATE_YEAR, + DATE_TIME +}; + +const char * const wday[] = { + "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" +}; + +const char * const weekday[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", +}; + +const char * const month[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", +}; + +struct tzinfo { + const char *name; + int offset; /* +/- in minutes */ +}; + +#define tDAYZONE -60 /* offset for daylight savings time */ +static const struct tzinfo tz[]= { + {"GMT", 0}, /* Greenwich Mean */ + {"UTC", 0}, /* Universal (Coordinated) */ + {"WET", 0}, /* Western European */ + {"BST", 0 tDAYZONE}, /* British Summer */ + {"WAT", 60}, /* West Africa */ + {"AST", 240}, /* Atlantic Standard */ + {"ADT", 240 tDAYZONE}, /* Atlantic Daylight */ + {"EST", 300}, /* Eastern Standard */ + {"EDT", 300 tDAYZONE}, /* Eastern Daylight */ + {"CST", 360}, /* Central Standard */ + {"CDT", 360 tDAYZONE}, /* Central Daylight */ + {"MST", 420}, /* Mountain Standard */ + {"MDT", 420 tDAYZONE}, /* Mountain Daylight */ + {"PST", 480}, /* Pacific Standard */ + {"PDT", 480 tDAYZONE}, /* Pacific Daylight */ + {"YST", 540}, /* Yukon Standard */ + {"YDT", 540 tDAYZONE}, /* Yukon Daylight */ + {"HST", 600}, /* Hawaii Standard */ + {"HDT", 600 tDAYZONE}, /* Hawaii Daylight */ + {"CAT", 600}, /* Central Alaska */ + {"AHST", 600}, /* Alaska-Hawaii Standard */ + {"NT", 660}, /* Nome */ + {"IDLW", 720}, /* International Date Line West */ + {"CET", -60}, /* Central European */ + {"MET", -60}, /* Middle European */ + {"MEWT", -60}, /* Middle European Winter */ + {"MEST", -60 tDAYZONE}, /* Middle European Summer */ + {"CEST", -60 tDAYZONE}, /* Central European Summer */ + {"MESZ", -60 tDAYZONE}, /* Middle European Summer */ + {"FWT", -60}, /* French Winter */ + {"FST", -60 tDAYZONE}, /* French Summer */ + {"EET", -120}, /* Eastern Europe, USSR Zone 1 */ + {"WAST", -420}, /* West Australian Standard */ + {"WADT", -420 tDAYZONE}, /* West Australian Daylight */ + {"CCT", -480}, /* China Coast, USSR Zone 7 */ + {"JST", -540}, /* Japan Standard, USSR Zone 8 */ + {"EAST", -600}, /* Eastern Australian Standard */ + {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */ + {"GST", -600}, /* Guam Standard, USSR Zone 9 */ + {"NZT", -720}, /* New Zealand */ + {"NZST", -720}, /* New Zealand Standard */ + {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */ + {"IDLE", -720}, /* International Date Line East */ +}; + +char * +timetostr(const time_t *T) +{ + char *line; + struct tm *tm; + + tm = gmtime(T); + line = xmalloc(MAX_TIME_LEN); + + snprintf( + line, MAX_TIME_LEN, + "If-Modified-Since: %s, %d %s %d %d:%d:%d GMT\015\012", + wday[tm->tm_wday], + tm->tm_mday, + month[tm->tm_mon], + tm->tm_year, + tm->tm_hour, + tm->tm_min, + tm->tm_sec + ); + + return line; +} + +char * +timestamp() +{ + char *line; + time_t ltime; + struct tm *tm; + + ltime = time(NULL); + tm = localtime(<ime); + line = xmalloc(MAX_TIME_LEN); + + strftime(line, 64, "[%a, %F %T] ", tm); + return line; +} + +time_t +adjust(time_t tvalue, int secs) +{ + struct tm *tp; + time_t ret; + + if((ret = (tvalue != (time_t)-1))){ + tp = localtime(&tvalue); + if(secs > INT_MAX - tp->tm_sec){ + ret = (time_t)-1; + } else { + tp->tm_sec += secs; + ret = mktime(tp); + } + } + return ret; +} + +/** + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * (modified - use the original: http://curl.haxx.se/) + */ +static int checkday(char *check, size_t len) +{ + int i; + const char * const *what; + BOOLEAN found = FALSE; + if(len > 3) + what = &weekday[0]; + else + what = &wday[0]; + for(i=0; i<7; i++) { + if(strmatch(check, (char*)what[0])) { + found=TRUE; + break; + } + what++; + } + return found?i:-1; +} + +/** + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * (modified - use the original: http://curl.haxx.se/) + */ +static int checkmonth(char *check) +{ + int i; + const char * const *what; + BOOLEAN found = FALSE; + + what = &month[0]; + for(i = 0; i < 12; i++){ + if(strmatch(check, (char*)what[0])) { + found=TRUE; + break; + } + what++; + } + return found ? i : -1; /* return the offset or -1, no real offset is -1 */ +} + +/** + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * (modified - use the original: http://curl.haxx.se/) + */ +static int checktz(char *check) +{ + unsigned int i; + const struct tzinfo *what; + BOOLEAN found = FALSE; + + what = tz; + for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) { + if(strmatch(check, (char*)what->name)) { + found=TRUE; + break; + } + what++; + } + return found ? what->offset*60 : -1; +} + +/** + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + */ +static void skip(const char **date) { + /* skip everything that aren't letters or digits */ + while(**date && !isalnum((unsigned char)**date)) + (*date)++; +} + +time_t +strtotime(const char *string){ + int sec = -1; /* seconds */ + int min = -1; /* minutes */ + int hour = -1; /* hours */ + int mday = -1; /* day of the month */ + int mon = -1; /* month */ + int year = -1; /* year */ + int wday = -1; /* day of the week */ + int tzoff = -1; /* time zone offset */ + int part = 0; + time_t t = 0; + time_t now = 0; + struct tm tm; + const char *date; + const char *indate = string; /* original pointer */ + enum assume dignext = DATE_MDAY; + BOOLEAN found = FALSE; + + /* + * Make sure we have a string to parse. + */ + if(!(string && *string)) + return(0); + + date = string; + + /** + * this parser was more or less stolen form libcurl. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * http://curl.haxx.se/ + */ + + while(*date && (part < 6)) { + found=FALSE; + + skip(&date); + + if(isalpha((unsigned char)*date)) { + /* a name coming up */ + char buf[32]=""; + size_t len; + sscanf(date, "%31[A-Za-z]", buf); + len = strlen(buf); + + if(wday == -1) { + wday = checkday(buf, len); + if(wday != -1) + found = TRUE; + } + if(!found && (mon == -1)) { + mon = checkmonth(buf); + if(mon != -1) + found = TRUE; + } + + if(!found && (tzoff == -1)) { + /* this just must be a time zone string */ + tzoff = checktz(buf); + if(tzoff != -1) + found = TRUE; + } + + if(!found) + return -1; /* bad string */ + + date += len; + } else if(isdigit((unsigned char)*date)) { + /* a digit */ + int val; + char *end; + if((sec == -1) && + (3 == sscanf(date, "%02d:%02d:%02d", &hour, &min, &sec))) { + /* time stamp! */ + date += 8; + found = TRUE; + } + else { + val = (int)strtol(date, &end, 10); + + if((tzoff == -1) && + ((end - date) == 4) && + (val < 1300) && + (indate< date) && + ((date[-1] == '+' || date[-1] == '-'))) { + /* four digits and a value less than 1300 and it is preceeded with + a plus or minus. This is a time zone indication. */ + found = TRUE; + tzoff = (val/100 * 60 + val%100)*60; + + /* the + and - prefix indicates the local time compared to GMT, + this we need ther reversed math to get what we want */ + tzoff = date[-1]=='+'?-tzoff:tzoff; + } + + if(((end - date) == 8) && (year == -1) && (mon == -1) && (mday == -1)) { + /* 8 digits, no year, month or day yet. This is YYYYMMDD */ + found = TRUE; + year = val/10000; + mon = (val%10000)/100-1; /* month is 0 - 11 */ + mday = val%100; + } + + if(!found && (dignext == DATE_MDAY) && (mday == -1)) { + if((val > 0) && (val<32)) { + mday = val; + found = TRUE; + } + dignext = DATE_YEAR; + } + + if(!found && (dignext == DATE_YEAR) && (year == -1)) { + year = val; + found = TRUE; + if(year < 1900) { + if (year > 70) + year += 1900; + else + year += 2000; + } + if(mday == -1) + dignext = DATE_MDAY; + } + + if(!found) + return -1; + + date = end; + } + } + part++; + } + + if(-1 == sec) + sec = min = hour = 0; /* no time, make it zero */ + + if((-1 == mday) || + (-1 == mon) || + (-1 == year)) + /* lacks vital info, fail */ + return -1; + + /* Y238 'bug' */ + if(year > 2037) + return 0x7fffffff; + + tm.tm_sec = sec; + tm.tm_min = min; + tm.tm_hour = hour; + tm.tm_mday = mday; + tm.tm_mon = mon; + tm.tm_year = year - 1900; + tm.tm_wday = 0; + tm.tm_yday = 0; + tm.tm_isdst = 0; + + t = mktime(&tm); + + /* time zone adjust (cast t to int to compare to negative one) */ + if(-1 != (int)t) { + struct tm *gmt; + long delta; + time_t t2; + +#ifdef HAVE_GMTIME_R + /* thread-safe version */ + struct tm keeptime2; + gmt = (struct tm *)gmtime_r(&t, &keeptime2); + if(!gmt) + return -1; /* illegal date/time */ + t2 = mktime(gmt); +#else + /* It seems that at least the MSVC version of mktime() doesn't work + properly if it gets the 'gmt' pointer passed in (which is a pointer + returned from gmtime() pointing to static memory), so instead we copy + the tm struct to a local struct and pass a pointer to that struct as + input to mktime(). */ + struct tm gmt2; + gmt = gmtime(&t); /* use gmtime_r() if available */ + if(!gmt) + return -1; /* illegal date/time */ + gmt2 = *gmt; + t2 = mktime(&gmt2); +#endif + + /* Add the time zone diff (between the given timezone and GMT) + and the diff between the local time zone and GMT. */ + delta = (long)((tzoff!=-1?tzoff:0) + (t - t2)); + + if((delta>0) && (t + delta < t)) + return -1; /* time_t overflow */ + + t += delta; + } + now = time(NULL); + return t; +} + +#if 0 +int main() +{ + const char date[] = "Tue, 20-Mar-2007 14:31:38 GMT"; + time_t t = strtotime(date); + time_t n = time(NULL); + + printf("%ld => %ld\n", t, n); + return 0; +} +#endif diff --git a/src/date.h b/src/date.h new file mode 100644 index 0000000..f962f45 --- /dev/null +++ b/src/date.h @@ -0,0 +1,33 @@ +/** + * Date Header - date calculations for Siege + * + * Copyright (C) 2007-2013 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#ifndef DATE_H +#define DATE_H + +#include + +time_t adjust(time_t tvalue, int secs); +time_t strtotime(const char *string); +char * timetostr(const time_t *T); +char * timestamp(); + +#endif/*DATE_H*/ diff --git a/src/eval.c b/src/eval.c new file mode 100644 index 0000000..6b1641c --- /dev/null +++ b/src/eval.c @@ -0,0 +1,85 @@ +/** + * Variable evaluation + * + * Copyright (C) 2003-2014 by + * Jeffrey Fulmer - , et al. + * This file is part of siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + * + */ +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ +#include +#include +#include +#include +#include +#include + +char * +evaluate(HASH hash_table, char *buf) +{ + int x = 0; + int ENV = 0; + int len = 0; + char final[BUFSIZE]; + char *ptr; + char *string; + const char *scan; + + char *result = xrealloc(buf, BUFSIZE * sizeof(char)); + if(result != NULL) + buf = result; + + scan = strchr(buf, '$') + 1; + len = (strlen(buf) - strlen(scan)) -1; + + if(scan[0] == '{' || scan[0] == '(') + scan++; + + ptr = (char*)scan; + + while(*scan && *scan != '}' && *scan != ')' && *scan != '/'){ + scan++; + x++; + } + + if(scan[0] == '}' || scan[0] == ')') + scan++; + + string = substring(ptr, 0, x); + if (hash_lookup(hash_table, string) == 0) { + if (getenv(string) != NULL) { + ENV = 1; + } else { + string = '\0'; /* user botched his config file */ + } + } + + memset(final, 0, sizeof final); + strncpy( final, buf, len); + if(string != NULL) + strcat(final, ENV==0?hash_get(hash_table, string):getenv(string)); + strcat(final, scan ); + memset(result, 0, BUFSIZE * sizeof(char)); + strncpy(result, final, strlen(final)); + + xfree(string); + return result; +} + diff --git a/src/eval.h b/src/eval.h new file mode 100644 index 0000000..439a3ba --- /dev/null +++ b/src/eval.h @@ -0,0 +1,33 @@ +/** + * Variable evaluation + * + * Copyright (C) 2003-2014 by + * Jeffrey Fulmer - , et al. + * This file is part of siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + * + */ +#ifndef EVAL_H +#define EVAL_H + +#include + +#define BUFSIZE 40000 + +char *evaluate(HASH hash_table, char *buf); + +#endif/*EVAL_H*/ diff --git a/src/ftp.c b/src/ftp.c new file mode 100644 index 0000000..936fad5 --- /dev/null +++ b/src/ftp.c @@ -0,0 +1,361 @@ +/** + * FTP protocol support + * + * Copyright (C) 2013-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include +#include +#include + +private int __request(CONN *C, char *fmt, ...); +private int __response(CONN *C); +private int __response_code(const char *buf); +private BOOLEAN __in_range(int code, int lower, int upper); + +BOOLEAN +ftp_login(CONN *C, URL U) +{ + int code = 120; + char tmp[128]; + + code = __response(C); + if (! okay(code)) { + NOTIFY(ERROR, "FTP: Server responded: %d", code); + return FALSE; + } + + snprintf(tmp, sizeof(tmp), "%s", (url_get_username(U)==NULL)?"anonymous":url_get_username(U)); + code = __request(C, "USER %s", tmp); + if (code != 331) { + if (okay(code)) return TRUE; + } + + memset(tmp, '\0', sizeof(tmp)); + snprintf(tmp, sizeof(tmp), "%s", (url_get_password(U)==NULL)?"siege@joedog.org":url_get_password(U)); + code = __request(C, "PASS %s", tmp); + return __in_range(code, 200, 299); +} + +BOOLEAN +ftp_pasv(CONN *C) +{ + int i, code; + char *ptr; + unsigned char addr[6]; + + code = __request(C, "PASV"); + if (!okay(code)) return FALSE; + + ptr = (char *) C->chkbuf; + for (ptr += 4; *ptr && !isdigit(*ptr); ptr++); + + if (!*ptr) return FALSE; + + for (i = 0; i < 6; i++) { + addr[i] = 0; + for (; isdigit(*ptr); ptr++) + addr[i] = (*ptr - '0') + 10 * addr[i]; + + if (*ptr == ',') ptr++; + else if (i < 5) return FALSE; + } + snprintf(C->ftp.host, sizeof(C->ftp.host), "%d.%d.%d.%d", addr[0],addr[1],addr[2],addr[3]); + C->ftp.port = (addr[4] << 8) + addr[5]; + + return TRUE; +} + +BOOLEAN +ftp_cwd(CONN *C, URL U) +{ + int code; + + code = __request(C, "CWD %s", url_get_path(U)); + return okay(code); +} + +BOOLEAN +ftp_ascii(CONN *C) +{ + C->ftp.code = __request(C, "TYPE A"); + return okay(C->ftp.code); +} + +BOOLEAN +ftp_binary(CONN *C) +{ + C->ftp.code = __request(C, "TYPE I"); + return okay(C->ftp.code); +} + +BOOLEAN +ftp_quit(CONN *C) +{ + C->ftp.code = __request(C, "QUIT"); + return okay(C->ftp.code); +} + +BOOLEAN +ftp_size(CONN *C, URL U) +{ + int size; + int resp; + + if (ftp_binary(C) != TRUE) return FALSE; + + C->ftp.code = __request(C, "SIZE %s%s", url_get_path(U), url_get_file(U)); + if (!okay(C->ftp.code)) { + return FALSE; + } else { + if (sscanf(C->chkbuf, "%d %d", &resp, &size) == 2) { + C->ftp.size = size; + return TRUE; + } else { + return FALSE; + } + } + return TRUE; +} + +BOOLEAN +ftp_stor(CONN *C, URL U) +{ + size_t len; + char *file; + size_t id = pthread_self(); + int num = 2; + char **parts; + + if (id < 0.0) { + id = -id; + } + + len = strlen(url_get_file(U))+16; + parts = split('.', url_get_file(U), &num); + + file = xmalloc(len); + memset(file, '\0', len); + snprintf(file, len, "%s-%u.%s", parts[0], id, (parts[1]==NULL)?"":parts[1]); + if (my.unique) { + C->ftp.code = __request(C, "STOR %s", file); + } else { + C->ftp.code = __request(C, "STOR %s", url_get_file(U)); + } + xfree(file); + split_free(parts, num); + return (okay(C->ftp.code)); +} + + +BOOLEAN +ftp_retr(CONN *C, URL U) +{ + C->ftp.code = __request(C, "RETR %s%s", url_get_path(U), url_get_file(U)); + return (okay(C->ftp.code)); +} + +size_t +ftp_put(CONN *D, URL U) +{ + size_t n; + if ((n = socket_write(D, url_get_postdata(U), url_get_postlen(U))) != url_get_postlen(U)){ + NOTIFY(ERROR, "HTTP: unable to write to socket." ); + return -1; + } + + return url_get_postlen(U); +} + +size_t +ftp_get(CONN *D, URL U, size_t size) +{ + int n; + char c; + size_t bytes = 0; + char *file; + + file = xmalloc(size); + memset(file, '\0', size); + + do { + if ((n = socket_read(D, &c, 1)) == 0) + break; + file[bytes] = c; + bytes += n; + } while (bytes < size); + + if (my.get) { + write_file(U, file, size); + } + xfree(file); + + return bytes; +} + +BOOLEAN +ftp_list(CONN *C, CONN *D, URL U) +{ + int n; + char c; + int bytes; + + C->ftp.code = __request(C, "LIST %s", (url_get_file(U)==NULL)?url_get_path(U):url_get_file(U)); + + if (C->ftp.code == 150) { + if (D->sock < 1) { + NOTIFY(ERROR, "unable to read from socket: %s:%d", C->ftp.host, C->ftp.port); + return FALSE; + } + do { + if ((n = socket_read(D, &c, 1)) == 0) + break; + if (my.verbose) printf("%c", c); + bytes += n; + } while (TRUE); + } + return TRUE; +} + +int +__request(CONN *C, char *fmt, ...) +{ + int code = 0; + char buf[1024]; + char cmd[1024+8]; + size_t len, n; + va_list ap; + + memset(buf, '\0', sizeof(buf)); + memset(cmd, '\0', sizeof(cmd)); + + va_start(ap, fmt); + vsnprintf(buf, sizeof buf, fmt, ap); + len = snprintf(cmd, sizeof(cmd), "%s\015\012", buf); + + if ((n = socket_write(C, cmd, len)) != len) { + NOTIFY(ERROR, "FTP: unable to write to socket."); + code = 500; + } + va_end(ap); + debug(chomp(cmd)); + + if (code == 500) { + C->ftp.code = 500; + return C->ftp.code; + } else { + C->ftp.code = __response(C); + return C->ftp.code; + } +} + + +private int +__response(CONN *C) +{ + int n; + char c; + int code = 120; + BOOLEAN cont = TRUE; + + while (cont) { + int x; + + while (TRUE) { + x = 0; + memset(C->chkbuf, '\0', sizeof(C->chkbuf)); + while ((n = socket_read(C, &c, 1)) == 1) { + echo("%c", c); + C->chkbuf[x] = c; + if (C->chkbuf[x] == '\n') break; + x++; + } + if (isdigit(C->chkbuf[0]) && (C->chkbuf[3] != '-')) break; + } + code = __response_code(C->chkbuf); + if (C->chkbuf[3] == ' ') { + cont = FALSE; + } + } + if (code > 499 && !my.quiet) { + printf("%s\n", chomp(C->chkbuf)); + } + return code; +} + +private int +__response_code(const char *buf) +{ + int ret; + char code[4]; + memset(code, '\0', sizeof(code)); + strncpy(code, buf, 3); + code[3] = '\0'; + ret = atoi(code); + return ret; +} + +private BOOLEAN +__in_range(int code, int lower, int upper) +{ + return (code >= lower && code <= upper); +} + +/** + From RFC 959 + 200 Command okay. + 202 Command not implemented, superfluous at this site. + 211 System status, or system help reply. + 212 Directory status. + 213 File status. + 214 Help message. + 215 NAME system type. + 220 Service ready for new user. + 221 Service closing control connection. + 225 Data connection open; no transfer in progress. + 226 Closing data connection. + 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). + 230 User logged in, proceed. + 250 Requested file action okay, completed. + 257 "PATHNAME" created. + 331 User name okay, need password. + 332 Need account for login. + 350 Requested file action pending further information. + 421 Service not available, closing control connection. + 425 Can't open data connection. + 426 Connection closed; transfer aborted. + 450 Requested file action not taken. + 451 Requested action aborted: local error in processing. + 452 Requested action not taken. + 500 Syntax error, command unrecognized. + 501 Syntax error in parameters or arguments. + 502 Command not implemented. + 503 Bad sequence of commands. + 504 Command not implemented for that parameter. + 530 Not logged in. + 532 Need account for storing files. + 550 Requested action not taken. + 551 Requested action aborted: page type unknown. + 552 Requested file action aborted. + 553 Requested action not taken. +*/ diff --git a/src/ftp.h b/src/ftp.h new file mode 100644 index 0000000..026bf63 --- /dev/null +++ b/src/ftp.h @@ -0,0 +1,42 @@ +/** + * FTP protocol support + * + * Copyright (C) 2013-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef __FTP_H +#define __FTP_H + +#include +#include + +BOOLEAN ftp_login(CONN *C, URL U); +BOOLEAN ftp_ascii(CONN *C); +BOOLEAN ftp_binary(CONN *C); +BOOLEAN ftp_size(CONN *C, URL U); +BOOLEAN ftp_cwd(CONN *C, URL U); +BOOLEAN ftp_pasv(CONN *C); +BOOLEAN ftp_list(CONN *C, CONN *D, URL U); +BOOLEAN ftp_stor(CONN *C, URL U); +BOOLEAN ftp_retr(CONN *C, URL U); +size_t ftp_get(CONN *D, URL U, size_t size); +size_t ftp_put(CONN *D, URL U); +BOOLEAN ftp_quit(CONN *C); + +#endif/*__FTP_H*/ diff --git a/src/getopt.c b/src/getopt.c new file mode 100644 index 0000000..9c6fa0d --- /dev/null +++ b/src/getopt.c @@ -0,0 +1,1060 @@ +#include + +#ifndef HAVE_GETOPT_LONG +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# ifdef HAVE_LIBINTL_H +# include +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# include +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + + /* Kill compiler warnings */ + (void) argc; + (void) argv; + + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ +#endif /* HAVE_GETOPT_LONG */ diff --git a/src/getopt1.c b/src/getopt1.c new file mode 100644 index 0000000..84b7811 --- /dev/null +++ b/src/getopt1.c @@ -0,0 +1,191 @@ +#include +#ifndef HAVE_GETOPT_LONG +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ +#endif /* HAVE_GETOPT_LONG */ diff --git a/src/handler.c b/src/handler.c new file mode 100644 index 0000000..4e7f792 --- /dev/null +++ b/src/handler.c @@ -0,0 +1,106 @@ +/** + * Signal Handling + * + * Copyright (C) 2013-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#ifdef HAVE_PTHREAD_H +# include +#endif/*HAVE_PTHREAD_H*/ + +#include +#include +#include +#include +#include + +void +spin_doctor(CREW crew) +{ + long x; + char h[4] = {'-','\\','|','/'}; + + if(my.spinner==FALSE){ + return; + } + + for(x = 0; crew_get_total(crew) > 1 || x < 55; x++){ + fflush(stderr); + fprintf(stderr,"%c", h[x%4]); + pthread_usleep_np(20000); + fprintf(stderr, "\b"); + } + return; +} + +void +sig_handler(CREW crew) +{ + int gotsig = 0; + sigset_t sigs; +#if defined (hpux) || defined(__hpux) +#else + int result; + pthread_t spinner; +#endif + + sigemptyset(&sigs); + sigaddset(&sigs, SIGHUP); + sigaddset(&sigs, SIGINT); + sigaddset(&sigs, SIGTERM); + sigprocmask(SIG_BLOCK, &sigs, NULL); + + /** + * Now wait around for something to happen ... + */ + sigwait(&sigs, &gotsig); + my.verbose = FALSE; + fprintf(stderr, "\nLifting the server siege..."); +// crew_set_shutdown(crew, TRUE); + crew_cancel(crew); + + +#if defined (hpux) || defined(__hpux) +#else + if((result = pthread_create(&spinner, NULL, (void*)spin_doctor, crew)) < 0){ + NOTIFY(ERROR, "failed to create handler: %d\n", result); + } +#endif + + /** + * The signal consistently arrives early, + * so we artificially extend the life of + * the siege to make up the discrepancy. + */ + pthread_usleep_np(501125); + +// crew_cancel(crew); + +#if defined(hpux) || defined(__hpux) +#else + pthread_join(spinner, NULL); +#endif + + pthread_exit(NULL); +} + diff --git a/src/handler.h b/src/handler.h new file mode 100644 index 0000000..42df64b --- /dev/null +++ b/src/handler.h @@ -0,0 +1,32 @@ +/** + * Signal Handling + * + * Copyright (C) 2013-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef HANDLER_H +#define HANDLER_H + +#include +#include + +void spin_doctor(); +void sig_handler(CREW crew); + +#endif/*HANDLER_H*/ diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..6a866fa --- /dev/null +++ b/src/hash.c @@ -0,0 +1,362 @@ +/** + * Hash Table + * + * Copyright (C) 2003-2014 by + * Jeffrey Fulmer - , et al. + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#include +#include +#include +#include +#include +#include + +typedef struct NODE +{ + char *key; + char *value; + struct NODE *next; +} NODE; + +struct HASH_T +{ + int size; + int entries; + int index; + NODE **table; +}; + +#define xfree(x) free(x) +#define xmalloc(x) malloc(x) + +/** + * local prototypes + */ +private BOOLEAN __lookup(HASH this, char *key); +private void __resize(HASH this); +private unsigned int __genkey(int size, char *str); +private u_int32_t fnv_32_buf(void *buf, size_t len, u_int32_t hval); + +/** + * allocs size and space for the + * hash table. + */ +HASH +new_hash() +{ + HASH this; + int size = 10240; + + this = calloc(sizeof(*this),1); + this->size = size; + this->entries = 0; + this->index = 0; + while (this->size < size) { + this->size <<= 1; + } + this->table = (NODE**)calloc(this->size * sizeof(NODE*), 1); + return this; +} + +void +hash_reset(HASH this, ssize_t size) +{ + this->size = 2; + this->entries = 0; + + while (this->size < size) { + this->size <<= 1; + } + + this->table = (NODE**)calloc(this->size * sizeof(NODE*), 1); + return; +} + +/** + * redoubles the size of the hash table. + * This is a local function called by hash_add + * which dynamically resizes the table as + * necessary. + */ +private void +__resize(HASH this) +{ + NODE *tmp; + NODE *last_node; + NODE **last_table; + int x, hash, size; + + size = this->size; + last_table = this->table; + + hash_reset(this, size*2); + + x = 0; + while (x < size) { + last_node = last_table[x]; + while (last_node != NULL) { + tmp = last_node; + last_node = last_node->next; + hash = __genkey(this->size, (char*)tmp->key); + tmp->next = this->table[hash]; + this->table[hash] = tmp; + this->entries++; + } + x++; + } + return; +} + +/** + * add a key value pair to the hash table. + * This function tests the size of the table + * and dynamically resizes it as necessary. + * len is the size of void pointer. + */ +void +hash_add(HASH this, char *key, char *value) +{ + int x; + NODE *node; + + if (__lookup(this, key) == TRUE) + return; + + if (this->entries >= this->size/4) + __resize(this); + + x = __genkey(this->size, key); + node = xmalloc(sizeof(NODE)); + node->key = strdup(key); + node->value = strdup(value); + node->next = this->table[x]; + this->table[x] = node; + this->entries++; + return; +} + +/** + * returns a void NODE->value element + * in the table corresponding to key. + */ +char * +hash_get(HASH this, char *key) +{ + int x; + NODE *node; + + x = __genkey(this->size, key); + for (node = this->table[x]; node != NULL; node = node->next) { + if (!strcmp( node->key, key)) { + return(node->value); + } + } + + return NULL; +} + +BOOLEAN +hash_lookup(HASH this, char *key) +{ + return __lookup(this, key); +} + + +char ** +hash_get_keys(HASH this) +{ + int x; + int i = 0; + NODE *node; + char **keys; + + keys = (char**)malloc(sizeof( char*) * this->entries); + for (x = 0; x < this->size; x ++) { + for(node = this->table[x]; node != NULL; node = node->next){ + keys[i] = (char*)malloc(128); + memset(keys[i], 0, sizeof(keys[i])); + memcpy(keys[i], (char*)node->key, strlen(node->key)); + keys[i][strlen(node->key)] = 0; + i++; + } + } + return keys; +} + +void +hash_free_keys(HASH this, char **keys) +{ + int x; + for (x = 0; x < this->entries; x ++) + if (keys[x] != NULL) { + char *tmp = keys[x]; + xfree(tmp); + } + xfree(keys); + + return; +} + +/** + * destroy the hash table and free + * memory which was allocated to it. + */ +void +hash_destroy(HASH this) +{ + int x; + NODE *t1, *t2; + + for (x = 0; x < this->size; x++) { + t1 = this->table[x]; + while (t1 != NULL) { + t2 = t1->next; + if (t1->key != NULL) + xfree(t1->key); + if (t1->value != NULL) + xfree(t1->value); + xfree(t1); + t1 = t2; + } + this->table[x] = NULL; + } + if (this->table != NULL) { + xfree(this->table); + memset(this, 0, sizeof(HASH)); + } + xfree(this); + return; +} + +int +hash_get_entries(HASH this) +{ + return this->entries; +} + +/** + * returns int cache key for the table + */ +private unsigned int +fnv_32_buf(void *buf, size_t len, unsigned int hval) { + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ + unsigned char *be = bp + len; /* beyond end of buffer */ + + /** + * FNV-1a hash each octet in the buffer + */ + while (bp < be) { + hval ^= (u_int32_t)*bp++; + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); + } + return hval; +} + +/** + * returns int hash key for the table + */ +#define FNV1_32_INIT ((unsigned int)2166136261LL) + +private unsigned int +__genkey(int size, char *str) { + unsigned int hash; + void *data = str; + + hash = fnv_32_buf(data, strlen(str), FNV1_32_INIT); + hash %= size; + return hash; +} + + +/** + * returns TRUE if key is present in the table + * and FALSE if it is not. + */ +private BOOLEAN +__lookup(HASH this, char *key) +{ + int x; + NODE *node; + + if (key == NULL) { return FALSE; } + x = __genkey(this->size, key); + for (node = this->table[x]; node != NULL; node = node->next) { + if (!strcmp(node->key, key)) { + return TRUE; + } + } + return FALSE; +} + +#if 0 +int +main() +{ + HASH H = new_hash(); + int i = 0; + int j; + char **keys; + int len = 24; + char *simpsons[][2] = { + {"Homer", "D'oh!!!"}, + {"Homey", "Whoo hoo!"}, + {"Homer J.", "Why, you little!"}, + {"Marge", "Hrrrrmph"}, + {"Bart", "Aye Caramba!"}, + {"Lisa", "I'll be in my room"}, + {"Maggie", "(pacifier suck)"}, + {"Ned", "Okily Dokily!"}, + {"Moe", "WhaaaAAAAT?!"}, + {"Comic Book Guy", "Worst. Episode. Ever!"}, + {"Waylon", "That's Homer Simpson from sector 7G"}, + {"Barnie", "Brrraaarrp!"}, + {"Krusty", "Hey! Hey! Kids!"}, + {"Frink", "Glavin!"}, + {"Burns", "Release the hounds!"}, + {"Nelson", "Hah! Haw!"}, + {"Dr. Nick", "Hi, everybody!"}, + {"Edna", "Hah!"}, + {"Helen", "Think of the children!"}, + {"Snake", "Dude!"}, + {"Chalmers", "SKINNER!"}, + {"Agnes", "SEYMOUR!"}, + {"Sea Cap'n", "Yargh!"}, + {"Sideshow Bob", "Hello, Bart!"}, + }; + + for (i = 0; i < len; i++) { + hash_add(H, simpsons[i][0], simpsons[i][1]); + } + + keys = hash_get_keys(H); + for (j = 0; j < 100000; j++) { + for (i = 0; i < hash_get_entries(H); i ++){ + char *tmp = (char*)hash_get(H, keys[i]); + printf("%16s => %s\n", keys[i], (tmp==NULL)?"NULL":tmp); + } + } + hash_free_keys(H, keys); + hash_destroy(H); + exit(0); +} +#endif + diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 0000000..720049f --- /dev/null +++ b/src/hash.h @@ -0,0 +1,43 @@ +/** + * Hash Table + * + * Copyright (C) 2003-2014 by + * Jeffrey Fulmer - + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef HASH_H +#define HASH_H + +#include +#if defined (__FreeBSD__) +# include +#endif + +#include + +typedef struct HASH_T *HASH; + +HASH new_hash(); +void hash_add(HASH this, char *key, char *value); +char * hash_get(HASH this, char *key); +char ** hash_get_keys(HASH this); +BOOLEAN hash_lookup(HASH this, char *key); +void hash_destroy(HASH this); +void hash_free_keys(HASH this, char **keys); +int hash_get_entries(HASH this); + +#endif/*HASH_H*/ diff --git a/src/http.c b/src/http.c new file mode 100644 index 0000000..de70f0a --- /dev/null +++ b/src/http.c @@ -0,0 +1,810 @@ +/** + * HTTP/HTTPS protocol support + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXFILE 10240 + +private char *__parse_pair(char **str); +private char *__dequote(char *str); + +/** + * HTTPS tunnel; set up a secure tunnel with the + * proxy server. CONNECT server:port HTTP/1.0 + */ +BOOLEAN +https_tunnel_request(CONN *C, char *host, int port) +{ + size_t rlen, n; + char request[256]; + + if (C->encrypt == TRUE && auth_get_proxy_required(my.auth)) { + snprintf( + request, sizeof(request), + "CONNECT %s:%d HTTP/1.0\015\012" + "User-agent: Proxy-User\015\012" + "\015\012", + host, port + ); + rlen = strlen(request); + echo ("%s", request); + if ((n = socket_write(C, request, rlen)) != rlen){ + NOTIFY(ERROR, "HTTP: unable to write to socket." ); + return FALSE; + } + } else { + return FALSE; + } + return TRUE; +} + +int +https_tunnel_response(CONN *C) +{ + int x, n; + char c; + char line[256]; + int code = 100; + + while(TRUE){ + x = 0; + memset( &line, '\0', sizeof( line )); + while ((n = read(C->sock, &c, 1)) == 1) { + line[x] = c; + echo ("%c", c); + if((line[0] == '\n') || (line[1] == '\n')){ + return code; + } + if( line[x] == '\n' ) break; + x ++; + } + line[x]=0; + if( strncasecmp( line, "http", 4 ) == 0 ){ + code = atoi(line + 9); + } + } +} + +BOOLEAN +http_get(CONN *C, URL U) +{ + size_t rlen; + size_t mlen; + char protocol[16]; + char keepalive[16]; + char hoststr[512]; + char authwww[512]; + char authpxy[512]; + char accept[] = "Accept: */*\015\012"; + char encoding[512]; + char *request; + char portstr[16]; + char fullpath[4096]; + char cookie[MAX_COOKIE_SIZE+8]; + time_t now; + char * ifmod = url_get_if_modified_since(U); + char * ifnon = url_get_etag(U); + + now = time(NULL); + + memset(hoststr, '\0', sizeof hoststr); + memset(cookie, '\0', sizeof cookie); + memset(portstr, '\0', sizeof portstr); + + /* Request path based on proxy settings */ + if(auth_get_proxy_required(my.auth)){ + sprintf( + fullpath, "%s://%s:%d%s", C->encrypt == FALSE?"http":"https", + url_get_hostname(U), url_get_port(U), url_get_request(U) + ); + } else { + sprintf(fullpath, "%s", url_get_request(U)); + } + if ((url_get_port(U)==80 && C->encrypt==FALSE) || (url_get_port(U)==443 && C->encrypt==FALSE)){ + portstr[0] = '\0'; + } else { + snprintf(portstr, sizeof portstr, ":%d", url_get_port(U)); + } + + /** + * Set the protocol and keepalive strings + * based on configuration conditions.... + */ + if (my.protocol == FALSE || my.get == TRUE) { + snprintf(protocol, sizeof(protocol), "HTTP/1.0"); + } else { + snprintf(protocol, sizeof(protocol), "HTTP/1.1"); + } + if (C->connection.keepalive == TRUE) { + snprintf(keepalive, sizeof(keepalive), "keep-alive"); + } else { + snprintf(keepalive, sizeof(keepalive), "close"); + } + + get_cookie_header(pthread_self(), url_get_hostname(U), cookie); + if (C->auth.www) { + if (C->auth.type.www==DIGEST) { + snprintf ( + authwww, sizeof(authwww), "%s", + auth_get_digest_header(my.auth, HTTP, C->auth.wchlg, C->auth.wcred, url_get_method_name(U), fullpath) + ); + } else { + snprintf(authwww, sizeof(authwww), "%s", auth_get_basic_header(my.auth, HTTP)); + } + } + if (C->auth.proxy) { + if (C->auth.type.proxy==DIGEST) { + snprintf ( + authwww, sizeof(authwww), "%s", + auth_get_digest_header(my.auth, HTTP, C->auth.wchlg, C->auth.wcred, url_get_method_name(U), fullpath) + ); + } else { + snprintf(authpxy, sizeof(authpxy), "%s", auth_get_basic_header(my.auth, PROXY)); + } + } + + /* Only send the Host header if one wasn't provided by the configuration. */ + if (strncasestr(my.extra, "host:", sizeof(my.extra)) == NULL) { + // as per RFC2616 14.23, send the port if it's not default + if ((url_get_scheme(U) == HTTP && url_get_port(U) != 80) || + (url_get_scheme(U) == HTTPS && url_get_port(U) != 443)) { + rlen = snprintf(hoststr, sizeof(hoststr), "Host: %s:%d\015\012", url_get_hostname(U), url_get_port(U)); + } else { + rlen = snprintf(hoststr, sizeof(hoststr), "Host: %s\015\012", url_get_hostname(U)); + } + } + + mlen = strlen(url_get_method_name(U)) + + strlen(fullpath) + + strlen(protocol) + + strlen(hoststr) + + strlen((C->auth.www==TRUE)?authwww:"") + + strlen((C->auth.proxy==TRUE)?authpxy:"") + + strlen(cookie) + + strlen((ifmod!=NULL)?ifmod:"") + + strlen((ifnon!=NULL)?ifnon:"") + + strlen((strncasecmp(my.extra, "Accept:", 7)==0) ? "" : accept) + + sizeof(encoding) + + strlen(my.uagent) + + strlen(my.extra) + + strlen(keepalive) + + 128; + request = (char*)xmalloc(mlen); + memset(request, '\0', mlen); + memset(encoding, '\0', sizeof(encoding)); + if (! my.get) { + snprintf(encoding, sizeof(encoding), "Accept-Encoding: %s\015\012", my.encoding); + } + + /** + * build a request string to pass to the server + */ + rlen = snprintf ( + request, mlen, + "%s %s %s\015\012" /* operation, fullpath, protocol */ + "%s" /* hoststr */ + "%s" /* authwww or empty str */ + "%s" /* authproxy or empty str */ + "%s" /* cookie or empty str */ + "%s" /* ifmod or empty str */ + "%s" /* ifnon or empty str */ + "%s" /* Conditional Accept: */ + "%s" /* encoding */ + "User-Agent: %s\015\012" /* my uagent */ + "%s" /* my.extra */ + "Connection: %s\015\012\015\012", /* keepalive */ + url_get_method_name(U), fullpath, protocol, hoststr, + (C->auth.www==TRUE)?authwww:"", + (C->auth.proxy==TRUE)?authpxy:"", + (strlen(cookie) > 8)?cookie:"", + (ifmod!=NULL)?ifmod:"", + (ifnon!=NULL)?ifnon:"", + (strncasecmp(my.extra, "Accept:", 7)==0) ? "" : accept, + encoding, my.uagent, my.extra, keepalive + ); + + /** + * XXX: I hate to use a printf here (as opposed to echo) but we + * don't want to preface the headers with [debug] in debug mode + */ + if ((my.debug || my.get) && !my.quiet) { printf("%s\n", request); fflush(stdout); } + + if (rlen == 0 || rlen > mlen) { + NOTIFY(FATAL, "HTTP %s: request buffer overrun!", url_get_method_name(U)); + } + + if ((socket_write(C, request, rlen)) < 0) { + xfree(ifmod); + xfree(ifnon); + return FALSE; + } + + xfree(ifmod); + xfree(ifnon); + xfree(request); + return TRUE; +} + +BOOLEAN +http_post(CONN *C, URL U) +{ + size_t rlen; + size_t mlen; + char hoststr[128]; + char authwww[128]; + char authpxy[128]; + char accept[] = "Accept: */*\015\012"; + char encoding[512]; + char * request; + char portstr[16]; + char protocol[16]; + char keepalive[16]; + char cookie[MAX_COOKIE_SIZE]; + char fullpath[4096]; + + memset(hoststr, '\0', sizeof(hoststr)); + memset(cookie, '\0', sizeof(cookie)); + memset(portstr, '\0', sizeof portstr); + memset(protocol, '\0', sizeof portstr); + memset(keepalive,'\0', sizeof portstr); + + if (auth_get_proxy_required(my.auth)) { + sprintf( + fullpath, + "%s://%s:%d%s", + C->encrypt == FALSE?"http":"https", url_get_hostname(U), url_get_port(U), url_get_request(U) + ); + } else { + sprintf(fullpath, "%s", url_get_request(U)); + } + + if ((url_get_port(U)==80 && C->encrypt==FALSE) || (url_get_port(U)==443 && C->encrypt==TRUE)) { + portstr[0] = '\0'; ; + } else { + snprintf(portstr, sizeof portstr, ":%d", url_get_port(U)); + } + + /** + * Set the protocol and keepalive strings + * based on configuration conditions.... + */ + if (my.protocol == FALSE || my.get == TRUE) { + snprintf(protocol, sizeof(protocol), "HTTP/1.0"); + } else { + snprintf(protocol, sizeof(protocol), "HTTP/1.1"); + } + if (C->connection.keepalive == TRUE) { + snprintf(keepalive, sizeof(keepalive), "keep-alive"); + } else { + snprintf(keepalive, sizeof(keepalive), "close"); + } + + get_cookie_header(pthread_self(), url_get_hostname(U), cookie); + if (C->auth.www) { + if (C->auth.type.www==DIGEST) { + snprintf ( + authwww, sizeof(authwww), "%s", + auth_get_digest_header(my.auth, HTTP, C->auth.wchlg, C->auth.wcred, url_get_method_name(U), fullpath) + ); + } else { + snprintf(authwww, sizeof(authwww), "%s", auth_get_basic_header(my.auth, HTTP)); + } + } + if (C->auth.proxy) { + if (C->auth.type.proxy==DIGEST) { + snprintf ( + authwww, sizeof(authwww), "%s", + auth_get_digest_header(my.auth, HTTP, C->auth.wchlg, C->auth.wcred, url_get_method_name(U), fullpath) + ); + } else { + snprintf(authpxy, sizeof(authpxy), "%s", auth_get_basic_header(my.auth, PROXY)); + } + } + + /* Only send the Host header if one wasn't provided by the configuration. */ + if (strncasestr(my.extra, "host:", sizeof(my.extra)) == NULL) { + // as per RFC2616 14.23, send the port if it's not default + if ((url_get_scheme(U) == HTTP && url_get_port(U) != 80) || + (url_get_scheme(U) == HTTPS && url_get_port(U) != 443)) { + rlen = snprintf(hoststr, sizeof(hoststr), "Host: %s:%d\015\012", url_get_hostname(U), url_get_port(U)); + } else { + rlen = snprintf(hoststr, sizeof(hoststr), "Host: %s\015\012", url_get_hostname(U)); + } + } + + mlen = strlen(url_get_method_name(U)) + + strlen(fullpath) + + strlen(protocol) + + strlen(hoststr) + + strlen((C->auth.www==TRUE)?authwww:"") + + strlen((C->auth.proxy==TRUE)?authpxy:"") + + strlen(cookie) + + strlen((strncasecmp(my.extra, "Accept:", 7)==0) ? "" : accept) + + sizeof(encoding) + + strlen(my.uagent) + + strlen(url_get_conttype(U)) + + strlen(my.extra) + + strlen(keepalive) + + url_get_postlen(U) + + 128; + request = (char*)xmalloc(mlen); + memset(request, '\0', mlen); + memset(encoding, '\0', sizeof(encoding)); + if (! my.get) { + snprintf(encoding, sizeof(encoding), "Accept-Encoding: %s\015\012", my.encoding); + } + + /** + * build a request string to + * post on the web server + */ + rlen = snprintf ( + request, mlen, + "%s %s %s\015\012" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "User-Agent: %s\015\012%s" + "Connection: %s\015\012" + "Content-type: %s\015\012" + "Content-length: %ld\015\012\015\012", + url_get_method_name(U), fullpath, protocol, hoststr, + (C->auth.www==TRUE)?authwww:"", + (C->auth.proxy==TRUE)?authpxy:"", + (strlen(cookie) > 8)?cookie:"", + (strncasecmp(my.extra, "Accept:", 7)==0) ? "" : accept, + encoding, my.uagent, my.extra, keepalive, url_get_conttype(U), (long)url_get_postlen(U) + ); + + if (rlen < mlen) { + memcpy(request + rlen, url_get_postdata(U), url_get_postlen(U)); + request[rlen+url_get_postlen(U)] = 0; + } + rlen += url_get_postlen(U); + + if (my.get || my.debug) printf("%s\n\n", request); + + if (rlen == 0 || rlen > mlen) { + NOTIFY(FATAL, "HTTP %s: request buffer overrun! Unable to continue...", url_get_method_name(U)); + } + + if ((socket_write(C, request, rlen)) < 0) { + return FALSE; + } + + xfree(request); + return TRUE; +} + +void +http_free_headers(HEADERS *h) +{ + xfree(h->redirect); + xfree(h->auth.realm.proxy); + xfree(h->auth.realm.www); + xfree(h); +} + +/** + * returns HEADERS struct + * reads from http/https socket and parses + * header information into the struct. + */ +HEADERS * +http_read_headers(CONN *C, URL U) +{ + int x; /* while loop index */ + int n; /* assign socket_read */ + char c; /* assign char read */ + HEADERS *h; /* struct to hold it all */ + char line[MAX_COOKIE_SIZE]; /* assign chars read */ + + h = xcalloc(sizeof(HEADERS), 1); + + while (TRUE) { + x = 0; + memset(&line, '\0', MAX_COOKIE_SIZE); + while ((n = socket_read(C, &c, 1)) == 1) { + if (x < MAX_COOKIE_SIZE - 1) + line[x] = c; + else + line[x] = '\n'; + echo("%c", c); + if ((line[0] == '\n') || (line[1] == '\n')) { + return h; + } + if (line[x] == '\n') break; + x ++; + } + line[x]=0; + /* strip trailing CR */ + if (x > 0 && line[x-1] == '\r') line[x-1]=0; + if (strncasecmp(line, "http", 4) == 0) { + strncpy( h->head, line, 8); + h->code = atoi(line + 9); + } + if (strncasecmp(line, "content-length: ", 16) == 0) { + C->content.length = atoi(line + 16); + } + if (strncasecmp(line, "set-cookie: ", 12) == 0) { + if (my.cookies) { + memset(h->cookie, '\0', sizeof(h->cookie)); + strncpy(h->cookie, line+12, strlen(line)); + add_cookie(pthread_self(), url_get_hostname(U), h->cookie); + } + } + if (strncasecmp(line, "connection: ", 12 ) == 0) { + if (strncasecmp(line+12, "keep-alive", 10) == 0) { + h->keepalive = 1; + } else if (strncasecmp(line+12, "close", 5) == 0) { + h->keepalive = 0; + } + } + if (strncasecmp(line, "keep-alive: ", 12) == 0) { + char *tmp = ""; + char *option = "", *value = ""; + char *newline = (char*)line; + while ((tmp = __parse_pair(&newline)) != NULL) { + option = tmp; + while (*tmp && !ISSPACE((int)*tmp) && !ISSEPARATOR(*tmp)) + tmp++; + *tmp++=0; + while (ISSPACE((int)*tmp) || ISSEPARATOR(*tmp)) + tmp++; + value = tmp; + while (*tmp) + tmp++; + if (!strncasecmp(option, "timeout", 7)) { + if(value != NULL){ + C->connection.timeout = atoi(value); + } else { + C->connection.timeout = 15; + } + } + if (!strncasecmp(option, "max", 3)) { + if(value != NULL){ + C->connection.max = atoi(value); + } else { + C->connection.max = 0; + } + } + } + } + if (strncasecmp(line, "location: ", 10) == 0) { + size_t len = strlen(line); + h->redirect = xmalloc(len); + memcpy(h->redirect, line+10, len-10); + h->redirect[len-10] = 0; + } + if (strncasecmp(line, "last-modified: ", 15) == 0) { + char *date; + size_t len = strlen(line); + if(my.cache){ + date = xmalloc(len); + memcpy(date, line+15, len-14); + url_set_last_modified(U, date); + xfree(date); + } + } + if (strncasecmp(line, "etag: ", 6) == 0) { + char *etag; + size_t len = strlen(line); + if(my.cache){ + etag = xmalloc(len); + memcpy(etag, line+6, len-5); + etag[len-1] = '\0'; + url_set_etag(U, etag); + xfree(etag); + } + } + if (strncasecmp(line, "www-authenticate: ", 18) == 0) { + char *tmp = ""; + char *option = "", *value = ""; + char *newline = (char*)line; + if (strncasecmp(line+18, "digest", 6) == 0) { + newline += 24; + h->auth.type.www = DIGEST; + h->auth.challenge.www = xstrdup(line+18); + } else { + newline += 23; + h->auth.type.www = BASIC; + } + while ((tmp = __parse_pair(&newline)) != NULL) { + option = tmp; + while (*tmp && !ISSPACE((int)*tmp) && !ISSEPARATOR(*tmp)) + tmp++; + *tmp++=0; + while (ISSPACE((int)*tmp) || ISSEPARATOR(*tmp)) + tmp++; + value = tmp; + while (*tmp) + tmp++; + if (!strncasecmp(option, "realm", 5)) { + if(value != NULL){ + h->auth.realm.www = xstrdup(__dequote(value)); + url_set_realm(U, __dequote(value)); + } else { + h->auth.realm.www = xstrdup(""); + } + } + } /* end of parse pairs */ + } + if (strncasecmp(line, "proxy-authenticate: ", 20) == 0) { + char *tmp = ""; + char *option = "", *value = ""; + char *newline = (char*)line; + if(strncasecmp(line+20, "digest", 6) == 0){ + newline += 26; + h->auth.type.proxy = DIGEST; + h->auth.challenge.proxy = xstrdup(line+20); + } else { + newline += 25; + h->auth.type.proxy = BASIC; + } + while((tmp = __parse_pair(&newline)) != NULL){ + option = tmp; + while(*tmp && !ISSPACE((int)*tmp) && !ISSEPARATOR(*tmp)) + tmp++; + *tmp++=0; + while(ISSPACE((int)*tmp) || ISSEPARATOR(*tmp)) + tmp++; + value = tmp; + while(*tmp) + tmp++; + if (!strncasecmp(option, "realm", 5)) { + if (value != NULL) { + h->auth.realm.proxy = xstrdup(__dequote(value)); + } else { + h->auth.realm.proxy = xstrdup(""); + } + } + } /* end of parse pairs */ + } + if (strncasecmp(line, "transfer-encoding: ", 19) == 0) { + if (strncasecmp(line+20, "chunked", 7)) { + C->content.transfer = CHUNKED; + } else if (strncasecmp(line+20, "trailer", 7)) { + C->content.transfer = TRAILER; + } else { + C->content.transfer = NONE; + } + } + if (strncasecmp(line, "expires: ", 9) == 0) { + /* printf("%s\n", line+10); */ + } + if (strncasecmp(line, "cache-control: ", 15) == 0) { + /* printf("%s\n", line+15); */ + } + if (n <= 0) { + echo ("read error: %s:%d", __FILE__, __LINE__); + http_free_headers(h); + return(NULL); + } /* socket closed */ + } /* end of while TRUE */ + + return h; +} + +int +http_chunk_size(CONN *C) +{ + int n; + char *end; + size_t length; + + memset(C->chkbuf, '\0', sizeof(C->chkbuf)); + if ((n = socket_readline(C, C->chkbuf, sizeof(C->chkbuf))) < 1) { + NOTIFY(WARNING, "HTTP: unable to determine chunk size"); + return -1; + } + + if (((C->chkbuf[0] == '\n')||(strlen(C->chkbuf)==0)||(C->chkbuf[0] == '\r'))) { + return -1; + } + + errno = 0; + if (!isxdigit((unsigned)*C->chkbuf)) + return -1; + length = strtoul(C->chkbuf, &end, 16); + if ((errno == ERANGE) || (end == C->chkbuf)) { + NOTIFY(WARNING, "HTTP: invalid chunk line %s\n", C->chkbuf); + return 0; + } else { + return length; + } + return -1; +} + +/** + * returns ssize_t + */ +ssize_t +http_read(CONN *C) +{ + int n = 0; + char c; + int chunk = 0; + size_t bytes = 0; + size_t length = 0; + static char body[MAXFILE]; + + if (C == NULL) NOTIFY(FATAL, "Connection is NULL! Unable to proceed"); + + if (my.get || my.debug) { + // The is debug / get mode - read a char and print it to stdout + if (C->content.length > 0) { + length = (C->content.length < MAXFILE) ? C->content.length:MAXFILE; + do { + if ((n = socket_read(C, &c, 1)) == 0) + break; + echo ("%c", c); + bytes += n; + length = (C->content.length - bytes < MAXFILE)?C->content.length-bytes:MAXFILE; + } while (bytes < C->content.length); + } else { + do { + /*if (my.chunked && C->content.transfer == CHUNKED) { + chunk = http_chunk_size(C); + } */ + if ((n = socket_read(C, &c, 1)) == 0) + break; + echo ("%c", c); + bytes += n; + } while(TRUE); + } + } else { + // This is non-debug / non-get mode. We'll read into a larger bucket + if (C->content.length > 0) { + length = (C->content.length < MAXFILE) ? C->content.length:MAXFILE; + do { + memset(body, '\0', sizeof(body)); + if ((n = socket_read(C, body, length)) == 0) + break; + bytes += n; + length = (C->content.length - bytes < MAXFILE)?C->content.length-bytes:MAXFILE; + } while (bytes < C->content.length); + } else if (my.chunked && C->content.transfer == CHUNKED) { + int tries = 0; + while (tries < 128) { + chunk = http_chunk_size(C); + if (chunk == 0) + break; + else if (chunk < 0) { + tries ++; + continue; + } + do { + int n; + memset(body, '\0', MAXFILE); + n = socket_read(C, body, (chunk>MAXFILE)?MAXFILE:chunk); + chunk -= n; + bytes += n; + } while(chunk > 0); + } + } else { + do { + memset(body, '\0', sizeof(body)); + if ((n = socket_read(C, body, sizeof(body))) == 0) + break; + bytes += n; + } while(TRUE); + } + } + + //if (my.debug||my.get) { printf("\n"); fflush(stdout); } + echo ("\n"); + + return bytes; +} + + +/** + * parses option=value pairs from an + * http header, see keep-alive: above + * while(( tmp = __parse_pair( &newline )) != NULL ){ + * do_something( tmp ); + * } + */ +private char * +__parse_pair(char **str) +{ + int okay = 0; + char *p = *str; + char *pair = NULL; + + if( !str || !*str ) return NULL; + /** + * strip the header label + */ + while( *p && *p != ' ' ) + p++; + *p++=0; + if( !*p ){ + *str = p; + return NULL; + } + + pair = p; + while( *p && *p != ';' && *p != ',' ){ + if( !*p ){ + *str = p; + return NULL; + } + if( *p == '=' ) okay = 1; + p++; + } + *p++ = 0; + *str = p; + + if( okay ) + return pair; + else + return NULL; +} + +char * +__rquote(char *str) +{ + char *ptr; + int len; + + len = strlen(str); + for(ptr = str + len - 1; ptr >= str && ISQUOTE((int)*ptr ); --ptr); + + ptr[1] = '\0'; + + return str; +} + +char * +__lquote(char *str) +{ + char *ptr; + int len; + + for(ptr = str; *ptr && ISQUOTE((int)*ptr); ++ptr); + + len = strlen(ptr); + memmove(str, ptr, len + 1); + + return str; +} + +char * +__dequote(char *str) +{ + char *ptr; + ptr = __rquote(str); + str = __lquote(ptr); + return str; +} diff --git a/src/http.h b/src/http.h new file mode 100644 index 0000000..3a1555a --- /dev/null +++ b/src/http.h @@ -0,0 +1,86 @@ +/** + * SIEGE http header file + * + * Copyright (C) 2000-2014 by Jeffrey Fulmer , et al + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef HTTP_H +#define HTTP_H + +#ifdef HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef HAVE_SNPRINTF +# define portable_snprintf snprintf +# define portable_vsnprintf vsnprintf +#endif + +#define REQBUF 43008 +#define POSTBUF 63488 + +/** + * HTTP headers structure. + */ +typedef +struct headers +{ + char head[64]; /* http response */ + int code; /* http return code */ + unsigned long int length; + char cookie[MAX_COOKIE_SIZE]; /* set-cookie data */ + char *redirect; /* redirection URL */ + struct{ + int www; /* www auth challenge */ + int proxy; /* proxy auth challenge */ + struct { + char *www; /* www auth realm */ + char *proxy; /* proxy auth realm */ + } realm; + struct { + char *www; /* www auth realm */ + char *proxy; /* proxy auth realm */ + } challenge; /* square peg/round hole */ + struct { + TYPE www; + TYPE proxy; + } type; + } auth; + int keepalive; /* http keep-alive */ +} HEADERS; + +/* http function prototypes */ +BOOLEAN http_get (CONN *C, URL U); +BOOLEAN http_post(CONN *C, URL U); +void http_free_headers(HEADERS *h); +HEADERS *http_read_headers(CONN *C, URL U); +ssize_t http_read(CONN *C); +BOOLEAN https_tunnel_request(CONN *C, char *host, int port); +int https_tunnel_response(CONN *C); + +#endif /* HTTP_H */ + diff --git a/src/init.c b/src/init.c new file mode 100644 index 0000000..ab2ab80 --- /dev/null +++ b/src/init.c @@ -0,0 +1,578 @@ +/** + * Siege environment initialization. + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +init_config( void ) +{ + char *e; + int res; + struct stat buf; + + /* Check if we were passed the -R switch to use a different siegerc file. + * If not, check for the presence of the SIEGERC variable, otherwise + * use default of ~/.siegerc */ + if(strcmp(my.rc, "") == 0){ + if((e = getenv("SIEGERC")) != NULL){ + snprintf(my.rc, sizeof(my.rc), "%s", e); + } else { + snprintf(my.rc, sizeof(my.rc), "%s/.siegerc", getenv("HOME")); + if (stat(my.rc, &buf) < 0 && errno == ENOENT) { + snprintf(my.rc, sizeof(my.rc), CNF_FILE); + } + } + } + + my.debug = FALSE; + my.quiet = FALSE; + my.internet = FALSE; + my.config = FALSE; + my.cookies = TRUE; + my.csv = FALSE; + my.fullurl = FALSE; + my.escape = TRUE; + my.secs = -1; + my.reps = MAXREPS; + my.bids = 5; + my.login = FALSE; + my.failures = 1024; + my.failed = 0; + my.auth = new_auth(); + auth_set_proxy_required(my.auth, FALSE); + auth_set_proxy_port(my.auth, 3128); + my.timeout = 30; + my.timestamp = FALSE; + my.chunked = FALSE; + my.unique = TRUE; + my.extra[0] = 0; + my.follow = TRUE; + my.zero_ok = TRUE; + my.signaled = 0; + my.ssl_timeout = 300; + my.ssl_cert = NULL; + my.ssl_key = NULL; + my.ssl_ciphers = NULL; + my.lurl = new_array(); + + if((res = pthread_mutex_init(&(my.lock), NULL)) != 0) + NOTIFY(FATAL, "unable to initiate lock"); + if((res = pthread_cond_init(&(my.cond), NULL )) != 0) + NOTIFY(FATAL, "unable to initiate condition"); + + if (load_conf(my.rc) < 0) { + fprintf( stderr, "****************************************************\n" ); + fprintf( stderr, "siege: could not open %s\n", my.rc ); + fprintf( stderr, "run \'siege.config\' to generate a new .siegerc file\n" ); + fprintf( stderr, "****************************************************\n" ); + return -1; + } + + if (strlen(my.file) < 1) { + snprintf( + my.file, sizeof( my.file ), + "%s", URL_FILE + ); + } + + if (strlen(my.uagent) < 1) + snprintf( + my.uagent, sizeof(my.uagent), + "Mozilla/5.0 (%s) Siege/%s", PLATFORM, version_string + ); + + if (strlen(my.conttype) < 1) + snprintf( + my.conttype, sizeof(my.conttype), + "application/x-www-form-urlencoded" + ); + + if (strlen(my.encoding) < 1) + snprintf( + my.encoding, sizeof(my.encoding), "*" + ); + + if (strlen(my.logfile) < 1) + snprintf( + my.logfile, sizeof( my.logfile ), + "%s", LOG_FILE + ); + return 0; +} + +int +show_config(int EXIT) +{ + char *method; + switch (my.method) { + case GET: + method = strdup("GET"); + break; + case HEAD: + default: + method = strdup("HEAD"); + break; + } + + printf( "CURRENT SIEGE CONFIGURATION\n" ); + printf( "%s\n", my.uagent ); + printf( "Edit the resource file to change the settings.\n" ); + printf( "----------------------------------------------\n" ); + printf( "version: %s\n", version_string ); + printf( "verbose: %s\n", my.verbose?"true":"false" ); + printf( "quiet: %s\n", my.quiet?"true":"false" ); + printf( "debug: %s\n", my.debug?"true":"false" ); + printf( "protocol: %s\n", my.protocol?"HTTP/1.1":"HTTP/1.0" ); + printf( "get method: %s\n", method); + if (auth_get_proxy_required(my.auth)){ + printf("proxy-host: %s\n", auth_get_proxy_host(my.auth)); + printf("proxy-port: %d\n", auth_get_proxy_port(my.auth)); + } + printf( "connection: %s\n", my.keepalive?"keep-alive":"close" ); + printf( "concurrent users: %d\n", my.cusers ); + if( my.secs > 0 ) + printf( "time to run: %d seconds\n", my.secs ); + else + printf( "time to run: n/a\n" ); + if(( my.reps > 0 )&&( my.reps != MAXREPS )) + printf( "repetitions: %d\n", my.reps ); + else + printf( "repetitions: n/a\n" ); + printf( "socket timeout: %d\n", my.timeout ); + printf( "accept-encoding: %s\n", my.encoding); + printf( "delay: %d sec%s\n", my.delay,my.delay>1?"s":"" ); + printf( "internet simulation: %s\n", my.internet?"true":"false" ); + printf( "benchmark mode: %s\n", my.bench?"true":"false" ); + printf( "failures until abort: %d\n", my.failures ); + printf( "named URL: %s\n", my.url==NULL||strlen(my.url)<2?"none":my.url ); + printf( "URLs file: %s\n", strlen(my.file)>1?my.file:URL_FILE ); + printf( "logging: %s\n", my.logging?"true":"false" ); + printf( "log file: %s\n", my.logfile==NULL?LOG_FILE:my.logfile ); + printf( "resource file: %s\n", my.rc); + printf( "timestamped output: %s\n", my.timestamp?"true":"false"); + printf( "comma separated output: %s\n", my.csv?"true":"false"); + printf( "allow redirects: %s\n", my.follow?"true":"false" ); + printf( "allow zero byte data: %s\n", my.zero_ok?"true":"false" ); + printf( "allow chunked encoding: %s\n", my.chunked?"true":"false" ); + printf( "upload unique files: %s\n", my.unique?"true":"false" ); + //printf( "proxy auth: " ); display_authorization( PROXY );printf( "\n" ); + //printf( "www auth: " ); display_authorization( WWW ); + printf( "\n" ); + xfree(method); + if (EXIT) exit(0); + else return 0; +} + +static char * +get_line(FILE *fp) +{ + char *ptr = NULL; + char *newline; + char tmp[256]; + + memset( tmp, 0, sizeof(tmp)); + do { + if((fgets(tmp, sizeof(tmp), fp)) == NULL) return(NULL); + if(ptr == NULL) { + ptr = xstrdup( tmp ); + } else { + ptr = (char*)xrealloc(ptr, strlen(ptr) + strlen(tmp) + 1); + strcat( ptr, tmp ); + } + newline = strchr(ptr, '\n'); + } while( newline == NULL ); + *newline = '\0'; + + return ptr; +} + +static char * +chomp_line(FILE *fp, char **mystr, int *line_num) +{ + char *ptr; + while(TRUE){ + if((*mystr = get_line( fp )) == NULL) return NULL; + (*line_num)++; + ptr = chomp(*mystr); + /* exclude comments */ + if(*ptr != '#' && *ptr != '\0'){ + return(ptr); + } else { + xfree(ptr); + } + } +} + +int +load_conf(char *filename) +{ + FILE *fp; + HASH H; + int line_num = 0; + char *line; + char *tmp; + char *option; + char *optionptr; + char *value; + + if ((fp = fopen(filename, "r")) == NULL) { + return -1; + } + + H = new_hash(); + + while ((line = chomp_line(fp, &line, &line_num)) != NULL) { + tmp = trim(line); + optionptr = option = xstrdup(line); + while (*optionptr && !ISSPACE((int)*optionptr) && !ISSEPARATOR(*optionptr)) { + optionptr++; + } + *optionptr++=0; + while (ISSPACE((int)*optionptr) || ISSEPARATOR(*optionptr)) { + optionptr++; + } + value = xstrdup(optionptr); + while (*line) + line++; + while (strstr(option, "$")) { + option = evaluate(H, option); + } + while (strstr(value, "$")){ + value = evaluate(H, value); + } + if (strmatch(option, "verbose")) { + if (!strncasecmp(value, "true", 4)) + my.verbose = TRUE; + else + my.verbose = FALSE; + } + else if (strmatch(option, "quiet")) { + if (!strncasecmp(value, "true", 4)) + my.quiet = TRUE; + else + my.quiet = FALSE; + } + else if (strmatch(option, "csv")) { + if (!strncasecmp(value, "true", 4)) + my.csv = TRUE; + else + my.csv = FALSE; + } + else if (strmatch(option, "fullurl")) { + if (!strncasecmp(value, "true", 4)) + my.fullurl = TRUE; + else + my.fullurl = FALSE; + } + else if (strmatch(option, "display-id")) { + if (!strncasecmp(value, "true", 4)) + my.display = TRUE; + else + my.display = FALSE; + } + else if (strmatch( option, "logging")) { + if (!strncasecmp( value, "true", 4)) + my.logging = TRUE; + else + my.logging = FALSE; + } + else if (strmatch(option, "show-logfile")) { + if (!strncasecmp(value, "true", 4)) + my.shlog = TRUE; + else + my.shlog = FALSE; + } + else if (strmatch(option, "logfile")) { + strncpy(my.logfile, value, sizeof(my.logfile)); + } + else if (strmatch(option, "cookies")) { + if (strmatch(value, "true")) + my.cookies = TRUE; + else + my.cookies = FALSE; + } + else if (strmatch(option, "concurrent")) { + if (value != NULL) { + my.cusers = atoi(value); + } else { + my.cusers = 10; + } + } + else if (strmatch(option, "reps")) { + if (value != NULL) { + my.reps = atoi(value); + } else { + my.reps = 5; + } + } + else if (strmatch(option, "time")) { + parse_time(value); + } + else if (strmatch(option, "delay")) { + if (value != NULL) { + my.delay = atoi(value); + } else { + my.delay = 1; + } + } + else if (strmatch(option, "timeout")) { + if (value != NULL) { + my.timeout = atoi(value); + } else { + my.timeout = 15; + } + } + else if (strmatch(option, "timestamp")) { + if (!strncasecmp(value, "true", 4)) + my.timestamp = TRUE; + else + my.timestamp = FALSE; + } + else if (strmatch(option, "internet")) { + if (!strncasecmp(value, "true", 4)) + my.internet = TRUE; + else + my.internet = FALSE; + } + else if (strmatch(option, "benchmark")) { + if (!strncasecmp(value, "true", 4)) + my.bench = TRUE; + else + my.bench = FALSE; + } + else if (strmatch(option, "cache")) { + if (!strncasecmp(value, "true", 4)) + my.cache = TRUE; + else + my.cache = FALSE; + } + else if (strmatch( option, "debug")) { + if (!strncasecmp( value, "true", 4)) + my.debug = TRUE; + else + my.debug = FALSE; + } + else if (strmatch(option, "gmethod")) { + if (strmatch(value, "GET")) { + my.method = GET; + } else { + my.method = HEAD; + } + } + else if (strmatch(option, "file")) { + memset(my.file, 0, sizeof(my.file)); + strncpy(my.file, value, sizeof(my.file)); + } + else if (strmatch(option, "url")) { + my.url = stralloc(value); + } + else if (strmatch(option, "user-agent")) { + strncpy(my.uagent, value, sizeof(my.uagent)); + } + else if (strmatch(option, "accept-encoding")) { + strncpy(my.encoding, value, sizeof(my.encoding)); + } + #if 1 + else if (!strncasecmp(option, "login", 5)) { + if(strmatch(option, "login-url")){ + my.login = TRUE; + array_push(my.lurl, value); + } else { + /* user login info */ + auth_add(my.auth, new_creds(HTTP, value)); + } + } + #endif + else if (strmatch(option, "attempts")) { + if (value != NULL) { + my.bids = atoi(value); + } else { + my.bids = 3; + } + } + else if (strmatch(option, "username")) { + my.username = stralloc(trim(value)); + } + else if (strmatch(option, "password")) { + my.password = stralloc(trim(value)); + } + else if (strmatch(option, "connection")) { + if (!strncasecmp(value, "keep-alive", 10)) + my.keepalive = TRUE; + else + my.keepalive = FALSE; + } + else if (strmatch(option, "protocol")) { + if (!strncasecmp(value, "HTTP/1.1", 8)) + my.protocol = TRUE; + else + my.protocol = FALSE; + } + else if (strmatch(option, "proxy-host")) { + auth_set_proxy_host(my.auth, trim(value)); + } + else if (strmatch(option, "proxy-port")) { + if (value != NULL) { + auth_set_proxy_port(my.auth, atoi(value)); + } else { + auth_set_proxy_port(my.auth, 3128); + } + } + else if (strmatch(option, "ftp-login")) { + auth_add(my.auth, new_creds(FTP, value)); + } + else if (strmatch(option, "proxy-login")) { + auth_add(my.auth, new_creds(PROXY, value)); + } + else if (strmatch(option, "failures")) { + if (value != NULL) { + my.failures = atoi(value); + } else { + my.failures = 30; + } + } + else if (strmatch(option, "chunked")) { + if (!strncasecmp(value, "true", 4)) + my.chunked = TRUE; + else + my.chunked = FALSE; + } + else if (strmatch(option, "unique")) { + if (!strncasecmp(value, "true", 4)) + my.unique = TRUE; + else + my.unique = FALSE; + } + else if (strmatch(option, "header")) { + if (!strchr(value,':')) NOTIFY(FATAL, "no ':' in http-header"); + if ((strlen(value) + strlen(my.extra) + 3) > 512) NOTIFY(FATAL, "too many headers"); + strcat(my.extra,value); + strcat(my.extra,"\015\012"); + } + else if (strmatch(option, "expire-session")) { + if (!strncasecmp(value, "true", 4 )) + my.expire = TRUE; + else + my.expire = FALSE; + } + else if (strmatch(option, "follow-location")) { + if (!strncasecmp(value, "true", 4)) + my.follow = TRUE; + else + my.follow = FALSE; + } + else if (strmatch(option, "url-escaping")) { + if (!strncasecmp(value, "true", 4)) + my.escape = TRUE; + else + my.escape = FALSE; + } + else if (strmatch(option, "zero-data-ok")) { + if (!strncasecmp(value, "true", 4)) + my.zero_ok = TRUE; + else + my.zero_ok = FALSE; + } + else if (strmatch(option, "ssl-cert")) { + my.ssl_cert = stralloc(value); + } + else if (strmatch(option, "ssl-key")) { + my.ssl_key = stralloc(value); + } + else if (strmatch(option, "ssl-timeout")) { + if (value != NULL) { + my.ssl_timeout = atoi(value); + } else { + my.ssl_timeout = 15; + } + } + else if (strmatch(option, "ssl-ciphers")) { + my.ssl_ciphers = stralloc(value); + } + else if (strmatch(option, "spinner")) { + if (!strncasecmp(value, "true", 4)) + my.spinner = TRUE; + else + my.spinner = FALSE; + } else { + hash_add(H, option, value); + } + xfree(value); + xfree(option); + free(tmp); + } /* end of while line=chomp_line */ + + hash_destroy(H); + fclose(fp); + return 0; +} + +/** + * don't be insulted, the author is the DS Module ;-) + */ +void +ds_module_check(void) +{ + if (my.bench) { +#if defined(hpux) || defined(__hpux) + my.delay = 1; +#else + my.delay = 0; +#endif + } + + if (my.secs > 0 && ((my.reps > 0) && (my.reps != MAXREPS))) { + NOTIFY(ERROR, "CONFIG conflict: selected time and repetition based testing" ); + fprintf( stderr, "defaulting to time-based testing: %d seconds\n", my.secs ); + my.reps = MAXREPS; + } + + if (my.cusers <= 0) { /* set concurrency to 1 */ + my.cusers = 1; /* if not defined */ + } + + if (my.get) { + my.cusers = 1; + my.reps = 1; + my.logging = FALSE; + my.bench = TRUE; + } + + if (my.quiet) { + my.verbose = FALSE; // Why would you set quiet and verbose??? + my.debug = FALSE; // why would you set quiet and debug????? + } +} + diff --git a/src/init.h b/src/init.h new file mode 100644 index 0000000..715efcb --- /dev/null +++ b/src/init.h @@ -0,0 +1,31 @@ +/** + * Siege environment initialization. + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INIT_H +#define INIT_H +#include + +int init_config( void ); +int show_config( int EXIT ); +int load_conf( char *filename ); +void ds_module_check(); + +#endif/*INIT_H*/ diff --git a/src/load.c b/src/load.c new file mode 100644 index 0000000..a6536bf --- /dev/null +++ b/src/load.c @@ -0,0 +1,350 @@ +/** + * Load Post Data + * + * Copyright (C) 2002-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * -- + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ContentType { + char *ext; + BOOLEAN ascii; + char *type; +}; + +static const struct ContentType tmap[] = { + {"default", TRUE, "application/x-www-form-urlencoded"}, + {"ai", FALSE, "application/postscript"}, + {"aif", FALSE, "audio/x-aiff"}, + {"aifc", FALSE, "audio/x-aiff"}, + {"aiff", FALSE, "audio/x-aiff"}, + {"asc", TRUE, "text/plain"}, + {"au", FALSE, "audio/basic"}, + {"avi", FALSE, "video/x-msvideo"}, + {"bcpio", FALSE, "application/x-bcpio"}, + {"bin", FALSE, "application/octet-stream"}, + {"c", TRUE, "text/plain"}, + {"cc", TRUE, "text/plain"}, + {"ccad", FALSE, "application/clariscad"}, + {"cdf", FALSE, "application/x-netcdf"}, + {"class", FALSE, "application/octet-stream"}, + {"cpio", FALSE, "application/x-cpio"}, + {"cpt", FALSE, "application/mac-compactpro"}, + {"csh", FALSE, "application/x-csh"}, + {"css", TRUE, "text/css"}, + {"dcr", FALSE, "application/x-director"}, + {"dir", FALSE, "application/x-director"}, + {"dms", FALSE, "application/octet-stream"}, + {"doc", FALSE, "application/msword"}, + {"drw", FALSE, "application/drafting"}, + {"dvi", FALSE, "application/x-dvi"}, + {"dwg", FALSE, "application/acad"}, + {"dxf", FALSE, "application/dxf"}, + {"dxr", FALSE, "application/x-director"}, + {"eps", FALSE, "application/postscript"}, + {"etx", TRUE, "text/x-setext"}, + {"exe", FALSE, "application/octet-stream"}, + {"ez", FALSE, "application/andrew-inset"}, + {"f", TRUE, "text/plain"}, + {"f90", TRUE, "text/plain"}, + {"fli", FALSE, "video/x-fli"}, + {"gif", FALSE, "image/gif"}, + {"gtar", FALSE, "application/x-gtar"}, + {"gz", FALSE, "application/x-gzip"}, + {"h", TRUE, "text/plain"}, + {"hdf", FALSE, "application/x-hdf"}, + {"hh", TRUE, "text/plain"}, + {"hqx", FALSE, "application/mac-binhex40"}, + {"htm", TRUE, "text/html"}, + {"html", TRUE, "text/html"}, + {"ice", FALSE, "x-conference/x-cooltalk"}, + {"ief", FALSE, "image/ief"}, + {"iges", FALSE, "model/iges"}, + {"igs", FALSE, "model/iges"}, + {"ips", FALSE, "application/x-ipscript"}, + {"ipx", FALSE, "application/x-ipix"}, + {"jpe", FALSE, "image/jpeg"}, + {"jpeg", FALSE, "image/jpeg"}, + {"jpg", FALSE, "image/jpeg"}, + {"js", FALSE, "application/x-javascript"}, + {"json", FALSE, "application/json"}, + {"kar", FALSE, "audio/midi"}, + {"latex", FALSE, "application/x-latex"}, + {"lha", FALSE, "application/octet-stream"}, + {"lsp", FALSE, "application/x-lisp"}, + {"lzh", FALSE, "application/octet-stream"}, + {"m", TRUE, "text/plain"}, + {"man", FALSE, "application/x-troff-man"}, + {"me", FALSE, "application/x-troff-me"}, + {"mesh", FALSE, "model/mesh"}, + {"mid", FALSE, "audio/midi"}, + {"midi", FALSE, "audio/midi"}, + {"mif", FALSE, "application/vnd.mif"}, + {"mime", FALSE, "www/mime"}, + {"mov", FALSE, "video/quicktime"}, + {"movie", FALSE, "video/x-sgi-movie"}, + {"mp2", FALSE, "audio/mpeg"}, + {"mp3", FALSE, "audio/mpeg"}, + {"mpe", FALSE, "video/mpeg"}, + {"mpeg", FALSE, "video/mpeg"}, + {"mpg", FALSE, "video/mpeg"}, + {"mpga", FALSE, "audio/mpeg"}, + {"ms", FALSE, "application/x-troff-ms"}, + {"msh", FALSE, "model/mesh"}, + {"nc", FALSE, "application/x-netcdf"}, + {"oda", FALSE, "application/oda"}, + {"pbm", FALSE, "image/x-portable-bitmap"}, + {"pdb", FALSE, "chemical/x-pdb"}, + {"pdf", FALSE, "application/pdf"}, + {"pgm", FALSE, "image/x-portable-graymap"}, + {"pgn", FALSE, "application/x-chess-pgn"}, + {"png", FALSE, "image/png"}, + {"pnm", FALSE, "image/x-portable-anymap"}, + {"pot", FALSE, "application/mspowerpoint"}, + {"ppm", FALSE, "image/x-portable-pixmap"}, + {"pps", FALSE, "application/mspowerpoint"}, + {"ppt", FALSE, "application/mspowerpoint"}, + {"ppz", FALSE, "application/mspowerpoint"}, + {"pre", FALSE, "application/x-freelance"}, + {"prt", FALSE, "application/pro_eng"}, + {"ps", FALSE, "application/postscript"}, + {"qt", FALSE, "video/quicktime"}, + {"ra", FALSE, "audio/x-realaudio"}, + {"ram", FALSE, "audio/x-pn-realaudio"}, + {"ras", FALSE, "image/cmu-raster"}, + {"rgb", FALSE, "image/x-rgb"}, + {"rm", FALSE, "audio/x-pn-realaudio"}, + {"roff", FALSE, "application/x-troff"}, + {"rpm", FALSE, "audio/x-pn-realaudio-plugin"}, + {"rtf", FALSE, "text/rtf"}, + {"rtx", FALSE, "text/richtext"}, + {"scm", FALSE, "application/x-lotusscreencam"}, + {"set", FALSE, "application/set"}, + {"sgm", TRUE, "text/sgml"}, + {"sgml", TRUE, "text/sgml"}, + {"sh", FALSE, "application/x-sh"}, + {"shar", FALSE, "application/x-shar"}, + {"silo", FALSE, "model/mesh"}, + {"sit", FALSE, "application/x-stuffit"}, + {"skd", FALSE, "application/x-koan"}, + {"skm", FALSE, "application/x-koan"}, + {"skp", FALSE, "application/x-koan"}, + {"skt", FALSE, "application/x-koan"}, + {"smi", FALSE, "application/smil"}, + {"smil", FALSE, "application/smil"}, + {"snd", FALSE, "audio/basic"}, + {"sol", FALSE, "application/solids"}, + {"spl", FALSE, "application/x-futuresplash"}, + {"src", FALSE, "application/x-wais-source"}, + {"step", FALSE, "application/STEP"}, + {"stl", FALSE, "application/SLA"}, + {"stp", FALSE, "application/STEP"}, + {"sv4cpio", FALSE, "application/x-sv4cpio"}, + {"sv4crc", FALSE, "application/x-sv4crc"}, + {"swf", FALSE, "application/x-shockwave-flash"}, + {"t", FALSE, "application/x-troff"}, + {"tar", FALSE, "application/x-tar"}, + {"tcl", FALSE, "application/x-tcl"}, + {"tex", FALSE, "application/x-tex"}, + {"texi", FALSE, "application/x-texinfo"}, + {"texinfo", FALSE, "application/x-texinfo"}, + {"tif", FALSE, "image/tiff"}, + {"tiff", FALSE, "image/tiff"}, + {"tr", FALSE, "application/x-troff"}, + {"tsi", FALSE, "audio/TSP-audio"}, + {"tsp", FALSE, "application/dsptype"}, + {"tsv", TRUE, "text/tab-separated-values"}, + {"txt", TRUE, "text/plain"}, + {"unv", FALSE, "application/i-deas"}, + {"ustar", FALSE, "application/x-ustar"}, + {"vcd", FALSE, "application/x-cdlink"}, + {"vda", FALSE, "application/vda"}, + {"viv", FALSE, "video/vnd.vivo"}, + {"vivo", FALSE, "video/vnd.vivo"}, + {"vrml", FALSE, "model/vrml"}, + {"wav", FALSE, "audio/x-wav"}, + {"wrl", FALSE, "model/vrml"}, + {"xbm", FALSE, "image/x-xbitmap"}, + {"xlc", FALSE, "application/vnd.ms-excel"}, + {"xll", FALSE, "application/vnd.ms-excel"}, + {"xlm", FALSE, "application/vnd.ms-excel"}, + {"xls", FALSE, "application/vnd.ms-excel"}, + {"xlw", FALSE, "application/vnd.ms-excel"}, + {"xml", TRUE, "text/xml"}, + {"xpm", FALSE, "image/x-xpixmap"}, + {"xwd", FALSE, "image/x-xwindowdump"}, + {"xyz", FALSE, "chemical/x-pdb"}, + {"zip", FALSE, "application/zip"} +}; + +char * +get_content_type(char *file) +{ + int i; + + for(i=0; i < (int)sizeof(tmap) / (int)sizeof(tmap[0]); i++) { + if(strlen(file) >= strlen(tmap[i].ext)) { + if(strmatch(((char*)file + strlen(file) - strlen(tmap[i].ext)), (char*)tmap[i].ext)) { + return tmap[i].type; + } + } + } + return tmap[0].type; +} + +BOOLEAN +is_ascii(char *file) +{ + int i; + + for(i=0; i < (int)sizeof(tmap) / (int)sizeof(tmap[0]); i++) { + if(strlen(file) >= strlen(tmap[i].ext)) { + if(strmatch(((char*)file + strlen(file) - strlen(tmap[i].ext)), (char*)tmap[i].ext)) { + return tmap[i].ascii; + } + } + } + return tmap[0].ascii; +} + +/** + * maps a file to our address space + * and returns it the calling function. + */ +void +load_file(URL U, char *file) +{ + FILE *fp; + size_t len; + char *buf; + char *filename; + char mode[8]; + + filename = trim(file); + + memset(mode, '\0', sizeof(mode)); + snprintf(mode, sizeof(mode), "%s", (is_ascii(filename))?"r":"rb"); + fp = fopen(filename, mode); + if (! fp) { + NOTIFY(ERROR, "unable to open file: %s", filename ); + return; + } + + fseek(fp, 0, SEEK_END); + len = ftell(fp); + fseek(fp, 0, SEEK_SET); + buf = (char *)xmalloc(len+1); + + if ((fread(buf, 1, len, fp )) == len) { + if (is_ascii(filename)) { + trim(buf); + len = strlen(buf); + } + } else { + NOTIFY(ERROR, "unable to read file: %s", filename ); + } + fclose(fp); + + if (len > 0) { + url_set_conttype(U, get_content_type(filename)); + url_set_postdata(U, buf, len); + } + + xfree(buf); + return; +} + +void +write_file(URL U, char *buf, size_t len) +{ + FILE *fp; + char mode[8]; + + memset(mode, '\0', sizeof(mode)); + snprintf(mode, sizeof(mode), "%s", (url_get_file(U))?"w":"wb"); + fp = fopen(url_get_file(U), mode); + + if (fp) { + fwrite(buf, len, 1, fp); + } else { + NOTIFY(ERROR, "unable to write to file"); + } + + fclose(fp); +} + +#if 0 +void +load_file(URL U, char *file) +{ + FILE *fp; + size_t len = 0; + struct stat st; + char *filename; + char postdata[POSTBUF]; + size_t postlen = 0; + + filename = trim(file); + memset(postdata, 0, POSTBUF); + + if ((lstat(filename, &st) == 0) || (errno != ENOENT)) { + len = (st.st_size >= POSTBUF) ? POSTBUF : st.st_size; + if (len < (unsigned)st.st_size) { + NOTIFY(WARNING, "Truncated file: %s exceeds the post limit of %d bytes.\n", filename, POSTBUF); + } + if ((fp = fopen(filename, "r")) == NULL) { + NOTIFY(ERROR, "could not open file: %s", filename); + return; + } + if ((fread(postdata, 1, len, fp )) == len) { + if (is_ascii(filename)) { + trim(postdata); + postlen = strlen(postdata); + } else { + postlen = len; + } + } else { + NOTIFY(ERROR, "unable to read file: %s", filename ); + } + fclose(fp); + } + + if (strlen(postdata) > 0) { + url_set_conttype(U, get_content_type(filename)); + url_set_postdata(U, postdata, postlen); + } + return; +} +#endif + + + diff --git a/src/load.h b/src/load.h new file mode 100644 index 0000000..9617602 --- /dev/null +++ b/src/load.h @@ -0,0 +1,32 @@ +/** + * Load Post Data + * + * Copyright (C) 2002-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef LOAD_H +#define LOAD_H +#include + +void load_file (URL U, char *filename); +void write_file(URL U, char *buf, size_t len); + + +#endif/*LOAD_H*/ + diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..c04bc6f --- /dev/null +++ b/src/log.c @@ -0,0 +1,184 @@ +/** + * Transacation logging support + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include + +/** + * writes the output from siege to a formatted + * log file. checks if the log exists, if not + * it creates a new formatted file and appends + * text to it. If a file does exist, then it + * simply appends to it. + */ +void +log_transaction(DATA D) +{ + write_to_log( + data_get_count(D), + data_get_elapsed(D), + data_get_megabytes(D), + data_get_total(D), + data_get_code(D), + my.failed + ); + return; +} + +void +write_to_log(int count, float elapsed, int bytes, float ttime, int code, int failed) +{ + int fd; + char entry[512]; +#ifdef HAVE_LOCALTIME_R + struct tm keepsake; +#endif/*HAVE_LOCALTIME_R*/ + struct tm *tmp; + time_t now; + size_t len; + char date[65]; + + now = time(NULL); +#ifdef HAVE_LOCALTIME_R + tmp = (struct tm *)localtime_r(&now, &keepsake); +#else + tmp = localtime(&now); +#endif/*HAVE_LOCALTIME_R*/ + + setlocale(LC_TIME, "C"); + len = strftime(date, sizeof date, "%Y-%m-%d %H:%M:%S", tmp); + + /* if the file does NOT exist then we'll create it. */ + if(my.shlog){ + printf( "FILE: %s\n", my.logfile ); + puts("You can disable this annoying message by editing"); + puts("the .siegerc file in your home directory; change"); + puts("the directive \'show-logfile\' to false." ); + } + + if (!file_exists(my.logfile)) { + if (!create_logfile(my.logfile)) { + NOTIFY(ERROR, "unable to create log file: %s", my.logfile); + return; + } + } + + /* create the log file entry with function params. */ + snprintf( + entry, sizeof entry, + "%s,%7d,%11.2f,%12u,%11.2f,%12.2f,%12.2f,%12.2f,%8d,%8d\n", + date, count, elapsed, bytes, ttime / count, count / elapsed, bytes / elapsed, + ttime / elapsed, code, failed + ); + + /* open the log and write to file */ + if ((fd = open( my.logfile, O_WRONLY | O_APPEND, 0644 )) < 0) { + NOTIFY(ERROR, "Unable to write to file: %s", my.logfile); + return; + } + + write(fd, entry, strlen(entry)); + close(fd); + + return; +} + +/* marks the siege.log with a user defined + message. checks for the existence of a + log and creates one if not found. */ +void +mark_log_file(char *message) +{ + int fd; + char entry[512]; + + /* if the file does NOT exist then create it. */ + if (!file_exists(my.logfile)) { + if (!create_logfile(my.logfile)) { + NOTIFY(ERROR, "unable to create log file: %s", my.logfile); + return; + } + } + + /* create the log file entry */ + snprintf(entry, sizeof entry, "**** %s ****\n", message); + + if ((fd = open( my.logfile, O_WRONLY | O_APPEND, 0644 )) < 0) { + NOTIFY(ERROR, "Unable to write to file: %s", my.logfile); + } + + write(fd, entry, strlen(entry)); + close(fd); + + return; +} + +/** + * returns TRUE if the file exists, + */ +BOOLEAN +file_exists(char *file) +{ + int fd; + + /* open the file read only */ + if((fd = open(file, O_RDONLY)) < 0){ + /* the file does NOT exist */ + close(fd); + return FALSE; + } else { + /* party on Garth... */ + close(fd); + return TRUE; + } + + return FALSE; +} + +/** + * return TRUE upon the successful + * creation of the file, FALSE if not. The + * function adds a header at the top of the + * file, format is comma separated text for + * spreadsheet import. + */ +BOOLEAN +create_logfile(const char *file) +{ + int fd; + char *head = (char*)" Date & Time, Trans, Elap Time, Data Trans, " + "Resp Time, Trans Rate, Throughput, Concurrent, OKAY, Failed\n"; + + if((fd = open(file, O_CREAT | O_WRONLY, 0644)) < 0){ + return FALSE; + } + + /* write the header to the file */ + write(fd, head, strlen(head)); + close(fd); + + return TRUE; +} + diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..f732825 --- /dev/null +++ b/src/log.h @@ -0,0 +1,35 @@ +/** + * Log file support + * + * Copyright (C) 2000-2013 by + * Jeffrey Fulmer - + * This file is distributed as part of Siege + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * -- + */ +#ifndef LOG_H +#define LOG_H +#include +#include + +void log_transaction(DATA D); +void write_to_log(int count, float elapsed, int bytes, float ttime, int code, int failed); +void mark_log_file(char *message); +BOOLEAN file_exists(char *file); +BOOLEAN create_logfile(const char *file); + +#endif/*LOG_H*/ + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..b3b5ed1 --- /dev/null +++ b/src/main.c @@ -0,0 +1,603 @@ +/** + * Siege, http regression tester / benchmark utility + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#define INTERN 1 + +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#ifdef HAVE_PTHREAD_H +# include +#endif/*HAVE_PTHREAD_H*/ + +/*LOCAL HEADERS*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __CYGWIN__ +# include +#else +# include +#endif + +/** + * long options, std options struct + */ +static struct option long_options[] = +{ + { "version", no_argument, NULL, 'V' }, + { "help", no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { "quiet", no_argument, NULL, 'q' }, + { "config", no_argument, NULL, 'C' }, + { "debug", no_argument, NULL, 'D' }, + { "get", no_argument, NULL, 'g' }, + { "concurrent", required_argument, NULL, 'c' }, + { "internet", no_argument, NULL, 'i' }, + { "benchmark", no_argument, NULL, 'b' }, + { "reps", required_argument, NULL, 'r' }, + { "time", required_argument, NULL, 't' }, + { "delay", required_argument, NULL, 'd' }, + { "log", optional_argument, NULL, 'l' }, + { "file", required_argument, NULL, 'f' }, + { "rc", required_argument, NULL, 'R' }, + { "mark", required_argument, NULL, 'm' }, + { "header", required_argument, NULL, 'H' }, + { "user-agent", required_argument, NULL, 'A' }, + { "content-type", required_argument, NULL, 'T' }, + {0, 0, 0, 0} +}; + +/** + * display_version + * displays the version number and exits on boolean false. + * continue running? TRUE=yes, FALSE=no + * return void + */ + +void +display_version(BOOLEAN b) +{ + /** + * version_string is defined in version.c + * adding it to a separate file allows us + * to parse it in configure. + */ + char name[128]; + + memset(name, 0, sizeof name); + strncpy(name, program_name, strlen(program_name)); + + if(my.debug){ + fprintf(stderr,"%s %s: debugging enabled\n\n%s\n", uppercase(name, strlen(name)), version_string, copyright); + } else { + if(b == TRUE){ + fprintf(stderr,"%s %s\n\n%s\n", uppercase(name, strlen(name)), version_string, copyright); + exit(EXIT_SUCCESS); + } else { + fprintf(stderr,"%s %s\n", uppercase(name, strlen(name)), version_string); + } + } +} /* end of display version */ + +/** + * display_help + * displays the help section to STDOUT and exits + */ +void +display_help() +{ + /** + * call display_version, but do not exit + */ + display_version(FALSE); + printf("Usage: %s [options]\n", program_name); + printf(" %s [options] URL\n", program_name); + printf(" %s -g URL\n", program_name); + printf("Options:\n" ); + puts(" -V, --version VERSION, prints the version number."); + puts(" -h, --help HELP, prints this section."); + puts(" -C, --config CONFIGURATION, show the current config."); + puts(" -v, --verbose VERBOSE, prints notification to screen."); + puts(" -q, --quiet QUIET turns verbose off and suppresses output."); + puts(" -g, --get GET, pull down HTTP headers and display the"); + puts(" transaction. Great for application debugging."); + puts(" -c, --concurrent=NUM CONCURRENT users, default is 10"); + puts(" -i, --internet INTERNET user simulation, hits URLs randomly." ); + puts(" -b, --benchmark BENCHMARK: no delays between requests." ); + puts(" -t, --time=NUMm TIMED testing where \"m\" is modifier S, M, or H" ); + puts(" ex: --time=1H, one hour test." ); + puts(" -r, --reps=NUM REPS, number of times to run the test." ); + puts(" -f, --file=FILE FILE, select a specific URLS FILE." ); + printf(" -R, --rc=FILE RC, specify an %src file\n",program_name); + puts(" -l, --log[=FILE] LOG to FILE. If FILE is not specified, the"); + printf(" default is used: PREFIX/var/%s.log\n", program_name); + puts(" -m, --mark=\"text\" MARK, mark the log file with a string." ); + puts(" -d, --delay=NUM Time DELAY, random delay before each requst"); + puts(" between 1 and NUM. (NOT COUNTED IN STATS)"); + puts(" -H, --header=\"text\" Add a header to request (can be many)" ); + puts(" -A, --user-agent=\"text\" Sets User-Agent in request" ); + puts(" -T, --content-type=\"text\" Sets Content-Type in request" ); + puts(""); + puts(copyright); + /** + * our work is done, exit nicely + */ + exit( EXIT_SUCCESS ); +} + +/* Check the command line for the presence of the -R or --RC switch. We + * need to do this seperately from the other command line switches because + * the options are initialized from the .siegerc file before the command line + * switches are parsed. The argument index is reset before leaving the + * function. */ +void +parse_rc_cmdline(int argc, char *argv[]) +{ + int a = 0; + strcpy(my.rc, ""); + + while( a > -1 ){ + a = getopt_long(argc, argv, "VhvqCDgl::ibr:t:f:d:c:m:H:R:A:T:", long_options, (int*)0); + if(a == 'R'){ + strcpy(my.rc, optarg); + a = -1; + } + } + optind = 0; +} + +/** + * parses command line arguments and assigns + * values to run time variables. relies on GNU + * getopts included with this distribution. + */ +void +parse_cmdline(int argc, char *argv[]) +{ + int c = 0; + int nargs; + while ((c = getopt_long(argc, argv, "VhvqCDgl::ibr:t:f:d:c:m:H:R:A:T:", long_options, (int *)0)) != EOF) { + switch (c) { + case 'V': + display_version(TRUE); + break; + case 'h': + display_help(); + exit(EXIT_SUCCESS); + case 'D': + my.debug = TRUE; + break; + case 'C': + my.config = TRUE; + my.get = FALSE; + break; + case 'c': + my.cusers = atoi(optarg); + break; + case 'i': + my.internet = TRUE; + break; + case 'b': + my.bench = TRUE; + break; + case 'd': + /* XXX range checking? use strtol? */ + my.delay = atoi(optarg); + if(my.delay < 0){ + my.delay = 0; + } + break; + case 'g': + my.get = TRUE; + break; + case 'l': + my.logging = TRUE; + if (optarg) { + my.logfile[strlen(optarg)] = '\0'; + strncpy(my.logfile, optarg, strlen(optarg)); + } + break; + case 'm': + my.mark = TRUE; + my.markstr = optarg; + my.logging = TRUE; + break; + case 'q': + my.quiet = TRUE; + break; + case 'v': + my.verbose = TRUE; + break; + case 'r': + if(strmatch(optarg, "once")){ + my.reps = -1; + } else { + my.reps = atoi(optarg); + } + break; + case 't': + parse_time(optarg); + break; + case 'f': + memset(my.file, 0, sizeof(my.file)); + if(optarg == NULL) break; /*paranoia*/ + strncpy(my.file, optarg, strlen(optarg)); + break; + case 'A': + strncpy(my.uagent, optarg, 255); + break; + case 'T': + strncpy(my.conttype, optarg, 255); + break; + case 'R': + /** + * processed above + */ + break; + case 'H': + { + if(!strchr(optarg,':')) NOTIFY(FATAL, "no ':' in http-header"); + if((strlen(optarg) + strlen(my.extra) + 3) > 2048) + NOTIFY(FATAL, "header is too large"); + strcat(my.extra,optarg); + strcat(my.extra,"\015\012"); + } + break; + + } /* end of switch( c ) */ + } /* end of while c = getopt_long */ + nargs = argc - optind; + if (nargs) + my.url = xstrdup(argv[argc-1]); + if (my.get && my.url==NULL) { + puts("ERROR: -g/--get requires a commandline URL"); + exit(1); + } + return; +} /* end of parse_cmdline */ + +int +main(int argc, char *argv[]) +{ + int x; + int j = 0; + int result; + DATA D = new_data(); + ARRAY urls = new_array(); + CREW crew; + LINES *lines; + CLIENT *client; + pthread_t cease; + pthread_t timer; + pthread_attr_t scope_attr; + void *statusp; + sigset_t sigs; + + sigemptyset(&sigs); + sigaddset(&sigs, SIGHUP); + sigaddset(&sigs, SIGINT); + sigaddset(&sigs, SIGALRM); + sigaddset(&sigs, SIGTERM); + sigprocmask(SIG_BLOCK, &sigs, NULL); + + lines = xcalloc(1, sizeof *lines); + lines->index = 0; + lines->line = NULL; + + memset(&my, 0, sizeof(struct CONFIG)); + + parse_rc_cmdline(argc, argv); + if (init_config() < 0) { /* defined in init.h */ + exit( EXIT_FAILURE ); /* polly was a girl... */ + } + parse_cmdline(argc, argv); /* defined above */ + ds_module_check(); /* check config integ */ + + /** + * XXX: we should consider moving the following + * if-checks into the ds_module_check + */ + + if (my.config) { + show_config(TRUE); + } + + if (my.url != NULL) { + my.length = 1; + } else { + my.length = read_cfg_file(lines, my.file); + } + + //if (my.reps < 0) { + // my.reps = my.length; + //} + + if (my.length == 0) { + display_help(); + } + + /* cookie is an EXTERN, defined in setup */ + cookie = xcalloc(sizeof(COOKIE), 1); + cookie->first = NULL; + if ((result = pthread_mutex_init( &(cookie->mutex), NULL)) !=0) { + NOTIFY(FATAL, "pthread_mutex_init" ); + } + + /* memory allocation for threads and clients */ + client = xcalloc(my.cusers, sizeof(CLIENT)); + if ((crew = new_crew(my.cusers, my.cusers, FALSE)) == NULL) { + NOTIFY(FATAL, "unable to allocate memory for %d simulated browser", my.cusers); + } + + /** + * determine the source of the url(s), + * command line or file, and add them + * to the urls struct. + */ + + if (my.url != NULL) { + URL tmp = new_url(my.url); + url_set_ID(tmp, 0); + if (my.get && url_get_method(tmp) != POST && url_get_method(tmp) != PUT) { + url_set_method(tmp, my.method); + } + array_npush(urls, tmp, URLSIZE); // from cmd line + } else { + for (x = 0; x < my.length; x++) { + URL tmp = new_url(lines->line[x]); + url_set_ID(tmp, x); + array_npush(urls, tmp, URLSIZE); + } + } + + /** + * display information about the siege + * to the user and prepare for verbose + * output if necessary. + */ + if (!my.get && !my.quiet) { + fprintf(stderr, "** "); + display_version(FALSE); + fprintf(stderr, "** Preparing %d concurrent users for battle.\n", my.cusers); + fprintf(stderr, "The server is now under siege..."); + if (my.verbose) { fprintf(stderr, "\n"); } + } + + /** + * record start time before spawning threads + * as the threads begin hitting the server as + * soon as they are created. + */ + data_set_start(D); + + /** + * for each concurrent user, spawn a thread and + * loop until condition or pthread_cancel from the + * handler thread. + */ + pthread_attr_init(&scope_attr); + pthread_attr_setscope(&scope_attr, PTHREAD_SCOPE_SYSTEM); +#if defined(_AIX) + /* AIX, for whatever reason, defies the pthreads standard and * + * creates threads detached by default. (see pthread.h on AIX) */ + pthread_attr_setdetachstate(&scope_attr, PTHREAD_CREATE_JOINABLE); +#endif + + /** + * invoke OpenSSL's thread safety + */ +#ifdef HAVE_SSL + SSL_thread_setup(); +#endif + + /** + * create the signal handler and timer; the + * signal handler thread (cease) responds to + * ctrl-C (sigterm) and the timer thread sends + * sigterm to cease on time out. + */ + if ((result = pthread_create(&cease, NULL, (void*)sig_handler, (void*)crew)) < 0) { + NOTIFY(FATAL, "failed to create handler: %d\n", result); + } + if (my.secs > 0) { + if ((result = pthread_create(&timer, NULL, (void*)siege_timer, (void*)cease)) < 0) { + NOTIFY(FATAL, "failed to create handler: %d\n", result); + } + } + + /** + * loop until my.cusers and create a corresponding thread... + */ + for (x = 0; x < my.cusers && crew_get_shutdown(crew) != TRUE; x++) { + client[x].id = x; + client[x].bytes = 0; + client[x].time = 0.0; + client[x].hits = 0; + client[x].code = 0; + client[x].ok200 = 0; + client[x].fail = 0; + if (my.reps > 0 ) { + /** + * Traditional -r/--reps where each user + * loops through every URL in the file. + */ + client[x].urls = urls; + } else { + /** + * -r once/--reps=once where each URL + * in the file is hit only once... + */ + int len = (array_length(urls)/my.cusers); + ARRAY tmp = new_array(); + for ( ; j < ((x+1) * len) && j < (int)array_length(urls); j++) { + URL u = array_get(urls, j); + if (u != NULL && url_get_hostname(u) != NULL && strlen(url_get_hostname(u)) > 1) { + array_npush(tmp, array_get(urls, j), URLSIZE); + } + } + client[x].urls = tmp; + } + client[x].auth.www = 0; + client[x].auth.proxy = 0; + client[x].auth.type.www = BASIC; + client[x].auth.type.proxy = BASIC; + client[x].rand_r_SEED = urandom(); + result = crew_add(crew, (void*)start_routine, &(client[x])); + if (result == FALSE) { + my.verbose = FALSE; + fprintf(stderr, "Unable to spawn additional threads; you may need to\n"); + fprintf(stderr, "upgrade your libraries or tune your system in order\n"); + fprintf(stderr, "to exceed %d users.\n", my.cusers); + NOTIFY(FATAL, "system resources exhausted"); + } + } /* end of for pthread_create */ + + crew_join(crew, TRUE, &statusp); + +#ifdef HAVE_SSL + SSL_thread_cleanup(); +#endif + + /** + * collect all the data from all the threads that + * were spawned by the run. + */ + for (x = 0; x < ((crew_get_total(crew) > my.cusers || + crew_get_total(crew)==0 ) ? my.cusers : crew_get_total(crew)); x++) { + data_increment_count(D, client[x].hits); + data_increment_bytes(D, client[x].bytes); + data_increment_total(D, client[x].time); + data_increment_code (D, client[x].code); + data_increment_ok200(D, client[x].ok200); + data_increment_fail (D, client[x].fail); + data_set_highest (D, client[x].himark); + data_set_lowest (D, client[x].lomark); + client[x].rand_r_SEED = urandom(); + } /* end of stats accumulation */ + + /** + * record stop time + */ + data_set_stop(D); + + /** + * cleanup crew + */ + crew_destroy(crew); + + for (x = 0; x < my.cusers; x++) { + // XXX: TODO + //digest_challenge_destroy(client[x].auth.wwwchlg); + //digest_credential_destroy(client[x].auth.wwwcred); + //digest_challenge_destroy(client[x].auth.proxychlg); + //digest_credential_destroy(client[x].auth.proxycred); + } + array_destroy(my.lurl); + xfree(client); + + if (my.get) { + if (data_get_ok200(D) > 0) { + exit(EXIT_SUCCESS); + } else { + if (!my.quiet) echo("[done]\n"); + exit(EXIT_FAILURE); + } + } + + /** + * take a short nap for cosmetic effect + * this does NOT affect performance stats. + */ + pthread_usleep_np(10000); + if (my.verbose) + fprintf(stderr, "done.\n"); + else + fprintf(stderr, "\b done.\n"); + + /** + * prepare and print statistics. + */ + if (my.failures > 0 && my.failed >= my.failures) { + fprintf(stderr, "%s aborted due to excessive socket failure; you\n", program_name); + fprintf(stderr, "can change the failure threshold in $HOME/.%src\n", program_name); + } + fprintf(stderr, "\nTransactions:\t\t%12u hits\n", data_get_count(D)); + fprintf(stderr, "Availability:\t\t%12.2f %%\n", data_get_count(D)==0 ? 0 : + (double)data_get_count(D) / + (data_get_count(D)+my.failed) + *100 + ); + fprintf(stderr, "Elapsed time:\t\t%12.2f secs\n", data_get_elapsed(D)); + fprintf(stderr, "Data transferred:\t%12.2f MB\n", data_get_megabytes(D)); /*%12llu*/ + fprintf(stderr, "Response time:\t\t%12.2f secs\n", data_get_response_time(D)); + fprintf(stderr, "Transaction rate:\t%12.2f trans/sec\n", data_get_transaction_rate(D)); + fprintf(stderr, "Throughput:\t\t%12.2f MB/sec\n", data_get_throughput(D)); + fprintf(stderr, "Concurrency:\t\t%12.2f\n", data_get_concurrency(D)); + fprintf(stderr, "Successful transactions:%12u\n", data_get_code(D)); + if (my.debug) { + fprintf(stderr, "HTTP OK received:\t%12u\n", data_get_ok200(D)); + } + fprintf(stderr, "Failed transactions:\t%12u\n", my.failed); + fprintf(stderr, "Longest transaction:\t%12.2f\n", data_get_highest(D)); + fprintf(stderr, "Shortest transaction:\t%12.2f\n", data_get_lowest(D)); + fprintf(stderr, " \n"); + if(my.mark) mark_log_file(my.markstr); + if(my.logging) log_transaction(D); + + data_destroy(D); + if (my.url == NULL) { + for (x = 0; x < my.length; x++) + xfree(lines->line[x]); + xfree(lines->line); + xfree(lines); + } else { + xfree(lines->line); + xfree(lines); + } + + pthread_mutex_destroy( &(cookie->mutex)); + + /** + * I should probably take a deeper look + * at cookie content to free it but at + * this point we're two lines from exit + */ + xfree (cookie); + xfree (my.url); + + exit(EXIT_SUCCESS); +} /* end of int main **/ diff --git a/src/md5.c b/src/md5.c new file mode 100644 index 0000000..1908fa8 --- /dev/null +++ b/src/md5.c @@ -0,0 +1,416 @@ +/* md5.c - Functions to compute MD5 message digest of files or memory blocks + according to the definition of MD5 in RFC 1321 from April 1992. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. + NOTE: The canonical source of this file is maintained with the GNU C + Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + 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. */ + +/* Written by Ulrich Drepper , 1995. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#if STDC_HEADERS || defined _LIBC +# include +# include +#else +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#include "md5.h" + +#ifdef _LIBC +# include +# if __BYTE_ORDER == __BIG_ENDIAN +# define WORDS_BIGENDIAN 1 +# endif +#endif + +#ifdef WORDS_BIGENDIAN +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#else +# define SWAP(n) (n) +#endif + + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +void +md5_init_ctx (ctx) + struct md5_ctx *ctx; +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md5_read_ctx (ctx, resbuf) + const struct md5_ctx *ctx; + void *resbuf; +{ + ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); + ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); + ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); + ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md5_finish_ctx (ctx, resbuf) + struct md5_ctx *ctx; + void *resbuf; +{ + /* Take yet unprocessed bytes into account. */ + md5_uint32 bytes = ctx->buflen; + size_t pad; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; + memcpy (&ctx->buffer[bytes], fillbuf, pad); + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); + *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 29)); + + /* Process last bytes. */ + md5_process_block (ctx->buffer, bytes + pad + 8, ctx); + + return md5_read_ctx (ctx, resbuf); +} + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md5_stream (stream, resblock) + FILE *stream; + void *resblock; +{ + /* Important: BLOCKSIZE must be a multiple of 64. */ +#define BLOCKSIZE 4096 + struct md5_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + do + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + } + while (sum < BLOCKSIZE && n != 0); + if (n == 0 && ferror (stream)) + return 1; + + /* If end of file is reached, end the loop. */ + if (n == 0) + break; + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + md5_process_block (buffer, BLOCKSIZE, &ctx); + } + + /* Add the last bytes if necessary. */ + if (sum > 0) + md5_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md5_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +md5_buffer (buffer, len, resblock) + const char *buffer; + size_t len; + void *resblock; +{ + struct md5_ctx ctx; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md5_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md5_finish_ctx (&ctx, resblock); +} + + +void +md5_process_bytes (buffer, len, ctx) + const void *buffer; + size_t len; + struct md5_ctx *ctx; +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&ctx->buffer[left_over], buffer, add); + ctx->buflen += add; + + if (left_over + add > 64) + { + md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], + (left_over + add) & 63); + ctx->buflen = (left_over + add) & 63; + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len > 64) + { + md5_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + memcpy (ctx->buffer, buffer, len); + ctx->buflen = len; + } +} + + +/* These are the four functions used in the four steps of the MD5 algorithm + and defined in the RFC 1321. The first function is a little bit optimized + (as found in Colin Plumbs public domain implementation). */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ + +void +md5_process_block (buffer, len, ctx) + const void *buffer; + size_t len; + struct md5_ctx *ctx; +{ + md5_uint32 correct_words[16]; + const md5_uint32 *words = buffer; + size_t nwords = len / sizeof (md5_uint32); + const md5_uint32 *endp = words + nwords; + md5_uint32 A = ctx->A; + md5_uint32 B = ctx->B; + md5_uint32 C = ctx->C; + md5_uint32 D = ctx->D; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + md5_uint32 *cwp = correct_words; + md5_uint32 A_save = A; + md5_uint32 B_save = B; + md5_uint32 C_save = C; + md5_uint32 D_save = D; + + /* First round: using the given function, the context and a constant + the next context is computed. Because the algorithms processing + unit is a 32-bit word and it is determined to work on words in + little endian byte order we perhaps have to change the byte order + before the computation. To reduce the work for the next steps + we store the swapped words in the array CORRECT_WORDS. */ + +#define OP(a, b, c, d, s, T) \ + do \ + { \ + a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ + ++words; \ + a = rol (a, s); \ + a += b; \ + } \ + while (0) + + /* Before we start, one word to the strange constants. + They are defined in RFC 1321 as + + T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or + perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' + */ + + /* Round 1. */ + OP (A, B, C, D, 7, 0xd76aa478); + OP (D, A, B, C, 12, 0xe8c7b756); + OP (C, D, A, B, 17, 0x242070db); + OP (B, C, D, A, 22, 0xc1bdceee); + OP (A, B, C, D, 7, 0xf57c0faf); + OP (D, A, B, C, 12, 0x4787c62a); + OP (C, D, A, B, 17, 0xa8304613); + OP (B, C, D, A, 22, 0xfd469501); + OP (A, B, C, D, 7, 0x698098d8); + OP (D, A, B, C, 12, 0x8b44f7af); + OP (C, D, A, B, 17, 0xffff5bb1); + OP (B, C, D, A, 22, 0x895cd7be); + OP (A, B, C, D, 7, 0x6b901122); + OP (D, A, B, C, 12, 0xfd987193); + OP (C, D, A, B, 17, 0xa679438e); + OP (B, C, D, A, 22, 0x49b40821); + + /* For the second to fourth round we have the possibly swapped words + in CORRECT_WORDS. Redefine the macro to take an additional first + argument specifying the function to use. */ +#undef OP +#define OP(f, a, b, c, d, k, s, T) \ + do \ + { \ + a += f (b, c, d) + correct_words[k] + T; \ + a = rol (a, s); \ + a += b; \ + } \ + while (0) + + /* Round 2. */ + OP (FG, A, B, C, D, 1, 5, 0xf61e2562); + OP (FG, D, A, B, C, 6, 9, 0xc040b340); + OP (FG, C, D, A, B, 11, 14, 0x265e5a51); + OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); + OP (FG, A, B, C, D, 5, 5, 0xd62f105d); + OP (FG, D, A, B, C, 10, 9, 0x02441453); + OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); + OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); + OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); + OP (FG, D, A, B, C, 14, 9, 0xc33707d6); + OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); + OP (FG, B, C, D, A, 8, 20, 0x455a14ed); + OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); + OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); + OP (FG, C, D, A, B, 7, 14, 0x676f02d9); + OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + + /* Round 3. */ + OP (FH, A, B, C, D, 5, 4, 0xfffa3942); + OP (FH, D, A, B, C, 8, 11, 0x8771f681); + OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); + OP (FH, B, C, D, A, 14, 23, 0xfde5380c); + OP (FH, A, B, C, D, 1, 4, 0xa4beea44); + OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); + OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); + OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); + OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); + OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); + OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); + OP (FH, B, C, D, A, 6, 23, 0x04881d05); + OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); + OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); + OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); + OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); + + /* Round 4. */ + OP (FI, A, B, C, D, 0, 6, 0xf4292244); + OP (FI, D, A, B, C, 7, 10, 0x432aff97); + OP (FI, C, D, A, B, 14, 15, 0xab9423a7); + OP (FI, B, C, D, A, 5, 21, 0xfc93a039); + OP (FI, A, B, C, D, 12, 6, 0x655b59c3); + OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); + OP (FI, C, D, A, B, 10, 15, 0xffeff47d); + OP (FI, B, C, D, A, 1, 21, 0x85845dd1); + OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); + OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); + OP (FI, C, D, A, B, 6, 15, 0xa3014314); + OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); + OP (FI, A, B, C, D, 4, 6, 0xf7537e82); + OP (FI, D, A, B, C, 11, 10, 0xbd3af235); + OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); + OP (FI, B, C, D, A, 9, 21, 0xeb86d391); + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + ctx->A = A; + ctx->B = B; + ctx->C = C; + ctx->D = D; +} diff --git a/src/md5.h b/src/md5.h new file mode 100644 index 0000000..0a6aa5f --- /dev/null +++ b/src/md5.h @@ -0,0 +1,161 @@ +/* md5.h - Declaration of functions and data types used for MD5 sum + computing library functions. + Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. + NOTE: The canonical source of this file is maintained with the GNU C + Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + 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. */ + +#ifndef _MD5_H +#define _MD5_H 1 + +#include + +#if defined HAVE_LIMITS_H || _LIBC +# include +#endif + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + doing that would require that the configure script compile and *run* + the resulting executable. Locally running cross-compiled executables + is usually not possible. */ + +#ifdef _LIBC +# include +typedef u_int32_t md5_uint32; +#else +# if defined __STDC__ && __STDC__ +# define UINT_MAX_32_BITS 4294967295U +# else +# define UINT_MAX_32_BITS 0xFFFFFFFF +# endif + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have ) have 64+-bit integral types. */ + +# ifndef UINT_MAX +# define UINT_MAX UINT_MAX_32_BITS +# endif + +# if UINT_MAX == UINT_MAX_32_BITS + typedef unsigned int md5_uint32; +# else +# if USHRT_MAX == UINT_MAX_32_BITS + typedef unsigned short md5_uint32; +# else +# if ULONG_MAX == UINT_MAX_32_BITS + typedef unsigned long md5_uint32; +# else + /* The following line is intended to evoke an error. + Using #error is not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +# endif +#endif + +#undef __P +#if defined (__STDC__) && __STDC__ +#define __P(x) x +#else +#define __P(x) () +#endif + +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + md5_uint32 A; + md5_uint32 B; + md5_uint32 C; + md5_uint32 D; + + md5_uint32 total[2]; + md5_uint32 buflen; + char buffer[128]; +}; + +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +extern void md5_init_ctx __P ((struct md5_ctx *ctx)); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void md5_process_block __P ((const void *buffer, size_t len, + struct md5_ctx *ctx)); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md5_process_bytes __P ((const void *buffer, size_t len, + struct md5_ctx *ctx)); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF be correctly + aligned for a 32 bits value. */ +extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf)); + + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int md5_stream __P ((FILE *stream, void *resblock)); + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); + +/* The following is from gnupg-1.0.2's cipher/bithelp.h. */ +/* Rotate a 32 bit integer by n bytes */ +#if defined(__GNUC__) && defined(__i386__) +static inline md5_uint32 +rol(md5_uint32 x, int n) +{ + __asm__("roll %%cl,%0" + :"=r" (x) + :"0" (x),"c" (n)); + return x; +} +#else +# define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) +#endif + +#endif diff --git a/src/setup.h b/src/setup.h new file mode 100644 index 0000000..972027a --- /dev/null +++ b/src/setup.h @@ -0,0 +1,241 @@ +/** + * Package header + * + * Copyright (C) 2000-2013 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef SETUP_H +#define SETUP_H + +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LIMITS_H +# include +#endif/*HAVE_LIMITS_H*/ + +#if HAVE_SYS_WAIT_H +# include +#endif + +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif + +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif/*HAVE_UNISTD_H*/ + +#ifdef STDC_HEADERS +# include +#else +# ifndef HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +char *strchr (), *strrchr (); +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# define memmove(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#ifdef HAVE_SYS_TIMES_H +# include +#endif/*HAVE_SYS_TIMES_H*/ + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif/*TIME_WITH_SYS_TIME*/ + +#if HAVE_ERRNO_H +# include +#endif /* HAVE_ERRNO_H */ + +#ifndef HAVE_SNPRINTF +# define portable_snprintf snprintf +# define portable_vsnprintf vsnprintf +#endif + +#ifndef PTHREAD_CREATE_JOINABLE +# define PTHREAD_CREATE_JOINABLE 0 +#endif /*PTHREAD_CREATE_JOINABLE*/ +#ifndef PTHREAD_CREATE_DETACHED +# define PTHREAD_CREATE_DETACHED 1 +#endif /*PTHREAD_CREATE_DETACHED*/ + + +#ifndef HAVE_STRCASECMP +int strcasecmp(); +#endif +#ifndef HAVE_STRNCASECMP +int strncasecmp(); +#endif +#ifndef HAVE_STRNCMP +int strncmp(); +#endif +#ifndef HAVE_STRLEN +int strlen(); +#endif + +#include +#include +#include +#include +#include +#include + +#define MXCHLD 1024 +#define MSG_NOERROR 010000 + +#define F_CONNECTING 1 +#define F_READING 2 +#define F_DONE 4 + +#define MAXREPS 10301062 + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +#ifndef INT_MIN +# define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1)) +#endif +#ifndef INT_MAX +# define INT_MAX (~0 - INT_MIN) +#endif + +void display_help(); +void display_version(BOOLEAN b); + +/** + * configuration struct; + * NOTE: this data is writeable ONLY during + * the configuration step before any threads + * are spawned. + */ +struct CONFIG +{ + BOOLEAN logging; /* boolean, log transactions to log file */ + BOOLEAN shlog; /* show log file configuration directive. */ + char *url; /* URL for the single hit invocation. */ + char logfile[128]; /* alternative user defined simbot.log */ + BOOLEAN verbose; /* boolean, verbose output to screen */ + BOOLEAN quiet; /* boolean, turn off all output to screen */ + BOOLEAN csv; /* boolean, display verbose output in CSV */ + BOOLEAN fullurl; /* boolean, display full url in verbose */ + BOOLEAN display; /* boolean, display the thread id verbose */ + BOOLEAN config; /* boolean, prints the configuration */ + int cusers; /* default concurrent users value. */ + int delay; /* range for random time delay, see -d */ + int timeout; /* socket connection timeout value, def:10 */ + BOOLEAN bench; /* signifies a benchmarking run, no delay */ + BOOLEAN internet; /* use random URL selection if TRUE */ + BOOLEAN timestamp; /* timestamp the output */ + int time; /* length of the siege in hrs, mins, secs */ + int secs; /* time value for the lenght of the siege */ + int reps; /* reps to run the test, default infinite */ + char file[128]; /* urls.txt file, default in joepath.h */ + int length; /* length of the urls array, made global */ + BOOLEAN debug; /* boolean, undocumented debug command */ + BOOLEAN chunked; /* boolean, accept chunked encoding */ + BOOLEAN unique; /* create unique files for upload */ + BOOLEAN get; /* get header information for debugging */ + BOOLEAN mark; /* signifies a log file mark req. */ + char *markstr; /* user defined string value to mark file */ + int protocol; /* 0=HTTP/1.0; 1=HTTP/1.1 */ + BOOLEAN cookies; /* to use cookies or not to use cookies */ + char uagent[256]; /* user defined User-Agent string. */ + char encoding[256]; /* user defined Accept-Encoding string. */ + char conttype[256]; /* user defined default content type. */ + char *username; /* DEPRECATED!! */ + char *password; /* DEPRECATED!! */ + int bids; /* W & P authorization bids before failure */ + AUTH auth; + BOOLEAN keepalive; /* boolean, connection keep-alive value */ + int signaled; /* timed based testing notification bool. */ + char extra[2048]; /* extra http request headers */ + #if 0 + struct { + BOOLEAN required; /* boolean, TRUE == use a proxy server. */ + char *hostname; /* hostname for the proxy server. */ + int port; /* port number for proxysrv */ + char *encode; /* base64 encoded username and password */ + } proxy; + #endif + BOOLEAN login; /* boolean, client must login first. */ + char *loginurl; /* XXX: deprecated the initial login URL */ + ARRAY lurl; + int failures; /* number of failed attempts before abort. */ + int failed; /* total number of socket failures. */ + BOOLEAN escape; /* boolean, TRUE == url-escaping */ + BOOLEAN expire; /* boolean, TRUE == expire cookies ea. run */ + BOOLEAN follow; /* boolean, TRUE == follow 302 */ + BOOLEAN zero_ok; /* boolean, TRUE == zero bytes data is OK. */ + BOOLEAN spinner; /* boolean, TRUE == spin, FALSE not so much*/ + BOOLEAN cache; /* boolean, TRUE == cache revalidate */ + char rc[256]; /* filename of SIEGERC file */ + int ssl_timeout; /* SSL session timeout */ + char *ssl_cert; /* PEM certificate file for client auth */ + char *ssl_key; /* PEM private key file for client auth */ + char *ssl_ciphers; /* SSL chiphers to use : delimited */ + METHOD method; /* HTTP method for --get requests */ + pthread_cond_t cond; + pthread_mutex_t lock; +}; + + +/** + * struct LINES, read by read_cfg_file + * in config.c + */ +typedef struct +{ + int index; + char **line; +} LINES; + +#if INTERN +# define EXTERN /* */ +#else +# define EXTERN extern +#endif + +EXTERN struct CONFIG my; + +#endif /* SETUP_H */ diff --git a/src/sock.c b/src/sock.c new file mode 100644 index 0000000..2f589d5 --- /dev/null +++ b/src/sock.c @@ -0,0 +1,655 @@ +/** + * SIEGE socket library + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif/*HAVE_UNISTD_H*/ + +#ifdef HAVE_ARPA_INET_H +# include +#endif/*HAVE_ARPA_INET_H*/ + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif/*HAVE_SYS_SOCKET_H*/ + +#ifdef HAVE_NETINET_IN_H +# include +#endif/*HAVE_NETINET_IN_H*/ + +#ifdef HAVE_NETDB_H +# include +#endif/*HAVE_NETDB_H*/ + +#ifdef HAVE_SSL +# include +#endif/*HAVE_SSL*/ + +/** + * local prototypes + */ +private int __socket_block(int socket, BOOLEAN block); +private ssize_t __socket_write(int sock, const void *vbuf, size_t len); +private BOOLEAN __socket_check(CONN *C, SDSET mode); +#ifdef HAVE_SSL +private ssize_t __ssl_socket_write(CONN *C, const void *vbuf, size_t len); +#endif/*HAVE_SSL*/ + +/** + * new_socket + * returns int, socket handle + */ +int +new_socket(CONN *C, const char *hostparam, int portparam) +{ + int conn; + int res; + int opt; + int herrno; + struct sockaddr_in cli; + struct hostent *hp; + char hn[512]; + int port; +#if defined(__GLIBC__) + struct hostent hent; + char hbf[8192]; +#elif defined(sun) +# ifndef HAVE_GETIPNODEBYNAME + struct hostent hent; + char hbf[8192]; +# endif/*HAVE_GETIPNODEBYNAME*/ +#elif defined(_AIX) + char *aixbuf; + int rc; +#endif/*_AIX*/ + + C->encrypt = (C->scheme == HTTPS) ? TRUE: FALSE; + C->state = UNDEF; + C->ftp.pasv = TRUE; + C->ftp.size = 0; + + memset(hn, '\0', sizeof hn); + + /* if we are using a proxy, then we make a socket + connection to that server rather then a httpd */ + if (auth_get_proxy_required(my.auth)) { + snprintf(hn, sizeof(hn), "%s", auth_get_proxy_host(my.auth)); + port = auth_get_proxy_port(my.auth); + } else { + snprintf(hn, sizeof(hn), "%s", hostparam); + port = portparam; + } + + /* create a socket, return -1 on failure */ + if ((C->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + switch (errno) { + case EPROTONOSUPPORT: { NOTIFY(ERROR, "unsupported protocol %s:%d", __FILE__, __LINE__); break; } + case EMFILE: { NOTIFY(ERROR, "descriptor table full %s:%d", __FILE__, __LINE__); break; } + case ENFILE: { NOTIFY(ERROR, "file table full %s:%d", __FILE__, __LINE__); break; } + case EACCES: { NOTIFY(ERROR, "permission denied %s:%d", __FILE__, __LINE__); break; } + case ENOBUFS: { NOTIFY(ERROR, "insufficient buffer %s:%d", __FILE__, __LINE__); break; } + default: { NOTIFY(ERROR, "unknown socket error %s:%d", __FILE__, __LINE__); break; } + } socket_close(C); return -1; + } + if (fcntl(C->sock, F_SETFD, O_NDELAY) < 0) { + NOTIFY(ERROR, "unable to set close control %s:%d", __FILE__, __LINE__); + } + +#if defined(__GLIBC__) + { + memset(hbf, '\0', sizeof hbf); + /* for systems using GNU libc */ + if ((gethostbyname_r(hostparam, &hent, hbf, sizeof(hbf), &hp, &herrno) < 0)) { + hp = NULL; + } + } +#elif defined(sun) +# ifdef HAVE_GETIPNODEBYNAME + hp = getipnodebyname(hn, AF_INET, 0, &herrno); +# else /* default use gethostbyname_r*/ + { + memset(hbf, '\0', sizeof hbf); + hp = gethostbyname_r(hn, &hent, hbf, sizeof(hbf), &herrno); + } +# endif/*HAVE_GETIPNODEBYNAME*/ +#elif defined(_AIX) + aixbuf = (char*)xmalloc(8192); + rc = gethostbyname_r(hn, (struct hostent *)aixbuf, + (struct hostent_data *)(aixbuf + sizeof(struct hostent))); + hp = (struct hostent*)aixbuf; +#elif ( defined(hpux) || defined(__hpux) || defined(__osf__) ) + hp = gethostbyname(hn); + herrno = h_errno; +#else + /* simply hoping that gethostbyname is thread-safe */ + hp = gethostbyname(hn); + herrno = h_errno; +#endif/*OS SPECIFICS*/ + + if(hp == NULL){ return -1; } + memset((void*) &cli, 0, sizeof(cli)); + memcpy(&cli.sin_addr, hp->h_addr, hp->h_length); +#if defined(sun) +# ifdef HAVE_FREEHOSTENT + freehostent(hp); +# endif/*HAVE_FREEHOSTENT*/ +#endif + cli.sin_family = AF_INET; + cli.sin_port = htons(port); + + if (C->connection.keepalive) { + opt = 1; + if (setsockopt(C->sock,SOL_SOCKET,SO_KEEPALIVE,(char *)&opt,sizeof(opt))<0) { + switch (errno) { + case EBADF: { NOTIFY(ERROR, "invalid descriptor %s:%d", __FILE__, __LINE__); break; } + case ENOTSOCK: { NOTIFY(ERROR, "not a socket %s:%d", __FILE__, __LINE__); break; } + case ENOPROTOOPT: { NOTIFY(ERROR, "not a protocol option %s:%d", __FILE__, __LINE__); break; } + case EFAULT: { NOTIFY(ERROR, "setsockopt unknown %s:%d", __FILE__, __LINE__); break; } + default: { NOTIFY(ERROR, "unknown sockopt error %s:%d", __FILE__, __LINE__); break; } + } socket_close(C); return -1; + } + } + + if ((__socket_block(C->sock, FALSE)) < 0) { + NOTIFY(ERROR, "socket: unable to set socket to non-blocking %s:%d", __FILE__, __LINE__); + return -1; + } + + /** + * connect to the host + * evaluate the server response and check for + * readability/writeability of the socket.... + */ + conn = connect(C->sock, (struct sockaddr *)&cli, sizeof(struct sockaddr_in)); + pthread_testcancel(); + if (conn < 0 && errno != EINPROGRESS) { + switch (errno) { + case EACCES: {NOTIFY(ERROR, "socket: %d EACCES", pthread_self()); break;} + case EADDRNOTAVAIL: {NOTIFY(ERROR, "socket: %d address is unavailable.", pthread_self()); break;} + case ETIMEDOUT: {NOTIFY(ERROR, "socket: %d connection timed out.", pthread_self()); break;} + case ECONNREFUSED: {NOTIFY(ERROR, "socket: %d connection refused.", pthread_self()); break;} + case ENETUNREACH: {NOTIFY(ERROR, "socket: %d network is unreachable.", pthread_self()); break;} + case EISCONN: {NOTIFY(ERROR, "socket: %d already connected.", pthread_self()); break;} + default: {NOTIFY(ERROR, "socket: %d unknown network error.", pthread_self()); break;} + } socket_close(C); return -1; + } else { + struct timeval timeout; + fd_set rs; + fd_set ws; + FD_ZERO(&rs); + FD_ZERO(&ws); + FD_SET(C->sock, &rs); + FD_SET(C->sock, &ws); + memset((void *)&timeout, '\0', sizeof(struct timeval)); + timeout.tv_sec = (my.timeout > 0)?my.timeout:30; + timeout.tv_usec = 0; + res = select(C->sock+1, &rs, &ws, NULL, &timeout); + if ((res == -1) && (errno == EINTR)) { + pthread_testcancel(); + fprintf(stderr, "socket: connection timed out\n"); + socket_close(C); + return -1; + } else { + /** + * If we reconnect and receive EISCONN, then we have a successful connection + */ + res = connect(C->sock, (struct sockaddr *)&cli, sizeof(struct sockaddr_in)); + if((res < 0)&&(errno != EISCONN)){ + NOTIFY(ERROR, "socket: unable to connect %s:%d", __FILE__, __LINE__); + socket_close(C); + return -1; + } + C->status = S_READING; + } + } /* end of connect conditional */ + + if ((__socket_block(C->sock, TRUE)) < 0) { + NOTIFY(ERROR, "socket: unable to set socket to non-blocking %s:%d", __FILE__, __LINE__); + return -1; + } + + C->connection.status = 1; + return(C->sock); +} + +private BOOLEAN +__socket_check(CONN *C, SDSET mode) +{ + int res; + fd_set fds; + fd_set *rs = NULL; + fd_set *ws = NULL; + double timo; + struct timeval timeout; + + if (C->state == mode) { + return TRUE; + } + + FD_ZERO(&fds); + FD_SET (C->sock, &fds); + if (mode==WRITE) { + *(&ws) = &fds; + } else { + *(&rs) = &fds; + } + + timo = (my.timeout)?my.timeout:15; + timeout.tv_sec = (long)timo; + timeout.tv_usec = 1000000L * (timo - (long)timo); + + if (mode==WRITE) { + __socket_block(C->sock, FALSE); + } + + do { + res = select(C->sock + 1, rs, ws, NULL, &timeout); + pthread_testcancel(); + } while (res < 0 && errno == EINTR); + + if (mode==WRITE) { + __socket_block(C->sock, TRUE); + } + + if (res == 0) { + errno = ETIMEDOUT; + } + + if (res < 1) { + NOTIFY(WARNING, "socket: %d select timed out", pthread_self()); + } + + if (res <= 0) { + C->state = UNDEF; + return FALSE; + } else { + C->state = mode; + return TRUE; + } + //return (res <= 0) ? FALSE : TRUE; +} + +/** + * local function + * set socket to non-blocking + */ +private int +__socket_block(int sock, BOOLEAN block) +{ +#if HAVE_FCNTL_H + int flags; + int retval; +#elif defined(FIONBIO) + ioctl_t status; +#else + return sock; +#endif +return sock; + if (sock==-1) { + return sock; + } + +#if HAVE_FCNTL_H + if ((flags = fcntl(sock, F_GETFL, 0)) < 0) { + switch (errno) { + case EACCES: { NOTIFY(ERROR, "EACCES %s:%d", __FILE__, __LINE__); break; } + case EBADF: { NOTIFY(ERROR, "bad file descriptor %s:%d", __FILE__, __LINE__); break; } + case EAGAIN: { NOTIFY(ERROR, "address is unavailable %s:%d", __FILE__, __LINE__); break; } + default: { NOTIFY(ERROR, "unknown network error %s:%d", __FILE__, __LINE__); break; } + } return -1; + } + + if (block) { + flags &= ~O_NDELAY; + } else { + flags |= O_NDELAY; + #if (defined(hpux) || defined(__hpux) || defined(__osf__)) || defined(__sun) + #else + flags |= O_NONBLOCK; + #endif + } + + if ((retval = fcntl(sock, F_SETFL, flags)) < 0) { + NOTIFY(ERROR, "unable to set fcntl flags %s:%d", __FILE__, __LINE__); + return -1; + } + return retval; + +#elif defined(FIONBIO) + status = block ? 0 : 1; + return ioctl(sock, FIONBIO, &status); +#endif +} + +/** + * returns ssize_t + * writes vbuf to sock + */ +private ssize_t +__socket_write(int sock, const void *vbuf, size_t len) +{ + size_t n; + ssize_t w; + const char *buf; + + buf = vbuf; + n = len; + while (n > 0) { + if ((w = write( sock, buf, n)) <= 0) { + if (errno == EINTR) { + w = 0; + } else { + return -1; + } + } + n -= w; + buf += w; + } + return len; +} + +/** + * local function + * returns ssize_t + * writes vbuf to sock + */ +#ifdef HAVE_SSL +private ssize_t +__ssl_socket_write(CONN *C, const void *vbuf, size_t len) +{ + size_t n; + ssize_t w; + const char *buf; + int err; + + buf = vbuf; + n = len; + + while (n > 0) { + if ((w = SSL_write(C->ssl, buf, n)) <= 0) { + if (w < 0) { + err = SSL_get_error(C->ssl, w); + + switch (err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + return 0; + case SSL_ERROR_SYSCALL: + NOTIFY(ERROR, "SSL_write() failed (syscall)"); + return -1; + case SSL_ERROR_SSL: + return -1; + } + } + NOTIFY(ERROR, "SSL_write() failed."); + return -1; + } + n -= w; + buf += w; + } + return len; +} +#endif/*HAVE_SSL*/ + +ssize_t +socket_read(CONN *C, void *vbuf, size_t len) +{ + int type; + size_t n; + ssize_t r; + char *buf; + int ret_eof = 0; + + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &type); + + buf = vbuf; + n = len; + if (C->encrypt == TRUE) { + #ifdef HAVE_SSL + while (n > 0) { + if (__socket_check(C, READ) == FALSE) { + return -1; + } + if ((r = SSL_read(C->ssl, buf, n)) < 0) { + if (errno == EINTR) + r = 0; + else + return -1; + } + else if (r == 0) break; + n -= r; + buf += r; + } /* end of while */ + #endif/*HAVE_SSL*/ + } else { + while (n > 0) { + if (C->inbuffer < len) { + if (__socket_check(C, READ) == FALSE) { + return -1; + } + } + if (C->inbuffer < n) { + int lidos; + memmove(C->buffer,&C->buffer[C->pos_ini],C->inbuffer); + C->pos_ini = 0; + if (__socket_check(C, READ) == FALSE) { + return -1; + } + lidos = read(C->sock, &C->buffer[C->inbuffer], sizeof(C->buffer)-C->inbuffer); + if (lidos == 0) + ret_eof = 1; + if (lidos < 0) { + if (errno==EINTR || errno==EAGAIN) + lidos = 0; + if (errno==EPIPE){ + return 0; + } else { + NOTIFY(ERROR, "socket: read error %s %s:%d", strerror(errno), __FILE__, __LINE__); + return 0; /* was return -1 */ + } + } + C->inbuffer += lidos; + } + if (C->inbuffer >= n) { + r = n; + } else { + r = C->inbuffer; + } + if (r == 0) break; + memmove(buf,&C->buffer[C->pos_ini],r); + C->pos_ini += r; + C->inbuffer -= r; + n -= r; + buf += r; + if (ret_eof) break; + } /* end of while */ + } /* end of else */ + + pthread_setcanceltype(type,NULL); + pthread_testcancel(); + return (len - n); +} +/** + * this function is used for chunked + * encoding transfers to acquire the + * size of the message check. + */ +ssize_t +socket_readline(CONN *C, char *ptr, size_t maxlen) +{ + int type; + int n, len, res; + char c; + + len = maxlen; + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &type); + + for (n = 1; n < len; n ++) { + if ((res = socket_read(C, &c, 1)) == 1) { + *ptr++ = c; + if (c=='\n') break; + } + else if (res == 0) { + if (n == 1) + return 0; + else + break; + } else { + return -1; /* something bad happened */ + } + } /* end of for loop */ + + *ptr=0; + + pthread_setcanceltype(type,NULL); + pthread_testcancel(); + + return n; +} + +/** + * returns void + * socket_write wrapper function. + */ +int +socket_write(CONN *C, const void *buf, size_t len) +{ + int type; + size_t bytes; + + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &type); +#if 0 + if(__socket_check(C, READ) == WRITE){ + return -1; + } +#endif + if (C->encrypt == TRUE) { + /* handle HTTPS protocol */ + #ifdef HAVE_SSL + /** + * Yeah, sure, this looks like a potential + * endless loop, (see: Loop, endless), but + * a socket timeout will break it... + */ + do { + if ((bytes = __ssl_socket_write(C, buf, len)) != len) { + if (bytes == 0) + ; + else + return -1; + } + } while (bytes == 0); + #else + NOTIFY(ERROR, "%s:%d protocol NOT supported", __FILE__, __LINE__); + return -1; + #endif/*HAVE_SSL*/ + } else { + /* assume HTTP */ + if ((bytes = __socket_write(C->sock, buf, len)) != len) { + NOTIFY(ERROR, "unable to write to socket %s:%d", __FILE__, __LINE__); + return -1; + } + } + + pthread_setcanceltype(type,NULL); + pthread_testcancel(); + + return bytes; +} + +/** + * returns void + * frees ssl resources if using ssl and + * closes the connection and the socket. + */ +void +socket_close(CONN *C) +{ + int type; + int ret = 0; +#ifdef HAVE_SSL + int tries = 0; +#endif/*HAVE_SSL*/ + + if (C==NULL) return; + + /* XXX Is this necessary? */ + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &type); + + if (C->encrypt == TRUE) { +#ifdef HAVE_SSL + if (!C->connection.reuse || C->connection.max == 1){ + if (C->ssl != NULL) { + do { + if ((ret = SSL_shutdown(C->ssl))==1) + break; + tries++; + } while(tries < 5); + } + SSL_free(C->ssl); + C->ssl = NULL; + SSL_CTX_free(C->ctx); + C->ctx = NULL; + close(C->sock); + C->sock = -1; + C->connection.status = 0; + C->connection.max = 0; + C->connection.tested = 0; + } +#endif/*HAVE_SSL*/ + } else { + if (C->connection.reuse == 0 || C->connection.max == 1) { + if (C->sock != -1) { + if ((__socket_block(C->sock, FALSE)) < 0) + NOTIFY(ERROR, "unable to set to non-blocking %s:%d", __FILE__, __LINE__); + if ((C->connection.status > 1)&&(ret = shutdown(C->sock, 2)) < 0) + NOTIFY(ERROR, "unable to shutdown the socket %s:%d", __FILE__, __LINE__); + if ((ret = close(C->sock)) < 0) + NOTIFY(ERROR, "unable to close the socket %s:%d", __FILE__, __LINE__); + } + C->sock = -1; + C->connection.status = 0; + C->connection.max = 0; + C->connection.tested = 0; + } + } + C = NULL; + pthread_setcanceltype(type,NULL); + pthread_testcancel(); + + return; +} + + diff --git a/src/sock.h b/src/sock.h new file mode 100644 index 0000000..1deeffc --- /dev/null +++ b/src/sock.h @@ -0,0 +1,143 @@ +/** + * SIEGE socket header file + * + * Copyright (C) 2000-2014 by + * by Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef SOCK_H +#define SOCK_H + +#ifdef HAVE_NETINET_IN_H +# include +#endif/*HAVE_NETINET_IN_H*/ + +#ifdef HAVE_ARPA_INET_H +# include +#endif/*HAVE_ARPA_INET_H*/ + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif/*HAVE_SYS_SOCKET_H*/ + +#ifdef HAVE_NETDB_H +# include +#endif/*HAVE_NETDB_H*/ + +#ifdef HAVE_SSL +# include +# include +# include +# include +# include +# include +#endif/*HAVE_SSL*/ + +#include +#include +#include + +typedef enum +{ + S_CONNECTING = 1, + S_READING = 2, + S_WRITING = 4, + S_DONE = 8 +} S_STATUS; + +typedef enum +{ + UNDEF = 0, + READ = 1, + WRITE = 2, + RDWR = 3 +} SDSET; + +/** + * Transfer encoding headers + */ +typedef enum +{ + NONE = 0, + CHUNKED = 1, + TRAILER = 2 +} TE; + + +typedef struct +{ + int sock; /* socket file descriptor */ + S_STATUS status; + BOOLEAN encrypt; /* TRUE=encrypt, FALSE=clear */ + SCHEME scheme; + struct { + TE transfer; /* transer encoding specified */ + size_t length; /* length of data chunks */ + } content; /* content encoding data */ + struct { + int max; /* max number of keep-alives */ + int timeout; /* server specified timeout value */ + int reuse; /* boolean, reuse socket if TRUE */ + int status; /* socket status: open=1, close=0 */ + int keepalive; /* keep-alive header directive */ + int tested; /* boolean, has socket been tested */ + } connection; /* persistent connection data */ + struct { + DCHLG *wchlg; + DCRED *wcred; + int www; + DCHLG *pchlg; + DCRED *pcred; + int proxy; + struct { + TYPE www; + TYPE proxy; + } type; + } auth; +#ifdef HAVE_SSL + SSL *ssl; + SSL_CTX *ctx; + SSL_METHOD *method; + X509 *cert; +#else + BOOLEAN nossl; +#endif/*HAVE_SSL*/ + size_t inbuffer; + int pos_ini; + char buffer[4096]; + char chkbuf[1024]; + fd_set *ws; + fd_set *rs; + SDSET state; + struct { + int code; + char host[64]; /* FTP data host */ + int port; /* FTP data port */ + size_t size; /* FTP file size */ + BOOLEAN pasv; + } ftp; +} CONN; + +int new_socket (CONN *conn, const char *hostname, int port); +BOOLEAN socket_check (CONN *C, SDSET test); +int socket_write (CONN *conn, const void *b, size_t n); +ssize_t socket_read (CONN *conn, void *buf, size_t len); +ssize_t socket_readline(CONN *C, char *ptr, size_t maxlen); +void socket_close (CONN *C); + +#endif /* SOCK_H */ + diff --git a/src/ssl.c b/src/ssl.c new file mode 100644 index 0000000..4c16f5c --- /dev/null +++ b/src/ssl.c @@ -0,0 +1,247 @@ +/** + * SSL Thread Safe Setup Functions. + * + * Copyright (C) 2002-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * -- + */ +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * local variables and prototypes + */ +#ifdef HAVE_SSL +static pthread_mutex_t *lock_cs; +static long *lock_count; +#endif/*HAVE_SSL*/ + +unsigned long SSL_pthreads_thread_id(void); +#ifdef HAVE_SSL +private void SSL_error_stack(void); +private void SSL_pthreads_locking_callback(int m, int t, char *f, int l); +#endif/*HAVE_SSL*/ + +BOOLEAN +SSL_initialize(CONN *C) +{ +#ifdef HAVE_SSL + int i; + int serr; + + if (C->ssl) { + return TRUE; + } + + C->ssl = NULL; + C->ctx = NULL; + C->method = NULL; + C->cert = NULL; + + /** + * XXX: SSL_library_init(); + * SSL_load_error_strings(); + * moved to ssl.c:235 - use once + */ + if(!my.ssl_key && my.ssl_cert) { + my.ssl_key = my.ssl_cert; + } + if(!my.ssl_ciphers) { + my.ssl_ciphers = stralloc(SSL_DEFAULT_CIPHER_LIST); + } + + C->method = SSLv23_client_method(); + if(C->method==NULL){ + SSL_error_stack(); + return FALSE; + } + C->ctx = SSL_CTX_new(C->method); + if(C->ctx==NULL){ + SSL_error_stack(); + return FALSE; + } + + SSL_CTX_set_mode(C->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + SSL_CTX_set_session_cache_mode(C->ctx, SSL_SESS_CACHE_BOTH); + SSL_CTX_set_timeout(C->ctx, my.ssl_timeout); + if(my.ssl_ciphers){ + if(!SSL_CTX_set_cipher_list(C->ctx, my.ssl_ciphers)){ + NOTIFY(ERROR, "SSL_CTX_set_cipher_list"); + return FALSE; + } + } + + if(my.ssl_cert){ + if(!SSL_CTX_use_certificate_chain_file(C->ctx, my.ssl_cert)){ + SSL_error_stack(); /* dump the error stack */ + NOTIFY(ERROR, "Error reading certificate file: %s", my.ssl_cert); + } + for(i=0; i<3; i++){ + if(SSL_CTX_use_PrivateKey_file(C->ctx, my.ssl_key, SSL_FILETYPE_PEM)) + break; + if(i<2 && ERR_GET_REASON(ERR_peek_error())==EVP_R_BAD_DECRYPT){ + SSL_error_stack(); /* dump the error stack */ + NOTIFY(WARNING, "Wrong pass phrase: retrying"); + continue; + } + } + + if(!SSL_CTX_check_private_key(C->ctx)){ + NOTIFY(ERROR, "Private key does not match the certificate"); + return FALSE; + } + } + + C->ssl = SSL_new(C->ctx); + if(C->ssl==NULL){ + SSL_error_stack(); + return FALSE; + } + SSL_set_fd(C->ssl, C->sock); + serr = SSL_connect(C->ssl); + return TRUE; +#else + C->nossl = TRUE; + return FALSE; +#endif/*HAVE_SSL*/ +} + +/** + * these functions were more or less taken from + * the openssl thread safe examples included in + * the OpenSSL distribution. + */ +#ifdef HAVE_SSL +void +SSL_thread_setup( void ) +{ + int x; + +#define OPENSSL_THREAD_DEFINES +#include +#if defined(THREADS) || defined(OPENSSL_THREADS) +#else + fprintf( + stderr, + "WARNING: your openssl libraries were compiled without thread support\n" + ); + pthread_sleep_np( 2 ); +#endif + + SSL_library_init(); + SSL_load_error_strings(); + lock_cs = (pthread_mutex_t*)OPENSSL_malloc( + CRYPTO_num_locks()*sizeof(pthread_mutex_t) + ); + lock_count = (long*)OPENSSL_malloc( + CRYPTO_num_locks() * sizeof(long) + ); + + for( x = 0; x < CRYPTO_num_locks(); x++ ){ + lock_count[x] = 0; + pthread_mutex_init(&(lock_cs[x]), NULL); + } + CRYPTO_set_id_callback((unsigned long (*)())SSL_pthreads_thread_id); + CRYPTO_set_locking_callback((void (*)())SSL_pthreads_locking_callback); +} + +void +SSL_thread_cleanup(void) +{ + int x; + + CRYPTO_set_locking_callback(NULL); + for(x = 0; x < CRYPTO_num_locks(); x++){ + pthread_mutex_destroy(&(lock_cs[x])); + } + if(lock_cs!=(pthread_mutex_t *)NULL) { + OPENSSL_free(lock_cs); + lock_cs=(pthread_mutex_t *)NULL; + } + if(lock_count!=(long *)NULL){ + OPENSSL_free(lock_count); + lock_count=(long *)NULL; + } +} + +void +SSL_pthreads_locking_callback(int mode, int type, char *file, int line) +{ + if( my.debug == 4 ){ + fprintf( + stderr,"thread=%4d mode=%s lock=%s %s:%d\n", (int)CRYPTO_thread_id(), + (mode&CRYPTO_LOCK)?"l":"u", (type&CRYPTO_READ)?"r":"w",file,line + ); + } + if(mode & CRYPTO_LOCK){ + pthread_mutex_lock(&(lock_cs[type])); + lock_count[type]++; + } + else{ + pthread_mutex_unlock(&(lock_cs[type])); + } +} + +unsigned long +SSL_pthreads_thread_id(void) +{ + unsigned long ret; + ret = (unsigned long)pthread_self(); + + return(ret); +} + +static void +SSL_error_stack(void) { /* recursive dump of the error stack */ + unsigned long err; + char string[120]; + + err=ERR_get_error(); + if(!err) + return; + SSL_error_stack(); + ERR_error_string(err, string); + NOTIFY(ERROR, "stack: %lX : %s", err, string); +} + +#endif/*HAVE_SSL*/ diff --git a/src/ssl.h b/src/ssl.h new file mode 100644 index 0000000..26ea74e --- /dev/null +++ b/src/ssl.h @@ -0,0 +1,57 @@ +/** + * SSL Thread Safe Setup Functions. + * + * Copyright (C) 2002-2014 by + * Jeffrey Fulmer - , et al + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * -- + */ +#ifndef SSL_H +#define SSL_H + +#ifdef HAVE_CONFIG_H +# include +#endif/*HAVE_CONFIG_H*/ + +#include +#include + +#include +#ifdef HAVE_SSL +#ifdef HAVE_E_OS_H +# include +#endif/*HAVE_E_OSH*/ +#ifdef HAVE_E_OS2_H +# include +#endif/*HAVE_E_OS2_H*/ +#include +#include +#include +#include +#include +#include +#include +#include + +#endif/*HAVE_SSL*/ + +BOOLEAN SSL_initialize(CONN *C); +void SSL_thread_setup(void); +void SSL_thread_cleanup(void); + +#endif/*SSL_H*/ + diff --git a/src/timer.c b/src/timer.c new file mode 100644 index 0000000..ebb4972 --- /dev/null +++ b/src/timer.c @@ -0,0 +1,62 @@ +/** + * Siege timer support. + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include +#include + +void +siege_timer(pthread_t handler) +{ + int err; + time_t now; + struct timespec timeout; + pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t timer_cond = PTHREAD_COND_INITIALIZER; + + if (time(&now) < 0) { + NOTIFY(FATAL, "unable to set the siege timer!"); + } + timeout.tv_sec=now + my.secs; + timeout.tv_nsec=0; + + pthread_mutex_lock(&timer_mutex); + for (;;) { + err = pthread_cond_timedwait( &timer_cond, &timer_mutex, &timeout); + if (err == ETIMEDOUT) { + /* timed out */ + if(my.debug){ printf("TIMED OUT!!\n"); fflush(stdout); } + /*if(our.shutting_down != TRUE){ pthread_kill(handler, SIGTERM); }*/ + my.verbose = FALSE; + pthread_kill(handler, SIGTERM); + break; + } else { + continue; + } + } + pthread_mutex_unlock(&timer_mutex); + return; +} + + diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 0000000..a26a9cf --- /dev/null +++ b/src/timer.h @@ -0,0 +1,30 @@ +/** + * Siege timer support. + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef TIMER_H +#define TIMER_H + +#include + +void siege_timer(pthread_t handler); + +#endif/*TIMER_H*/ diff --git a/src/url.c b/src/url.c new file mode 100644 index 0000000..191ba55 --- /dev/null +++ b/src/url.c @@ -0,0 +1,1115 @@ +/** + * URL Support + * + * Copyright (C) 2013-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct URL_T +{ + int ID; + char * url; + SCHEME scheme; + METHOD method; + char * username; + char * password; + char * hostname; + int port; + char * path; + char * file; + char * params; + BOOLEAN hasparams; + char * query; + char * frag; + char * request; + size_t postlen; + char * postdata; + char * posttemp; + char * conttype; + time_t expires; + time_t modified; + BOOLEAN cached; + char * etag; + char * realm; +}; + +size_t URLSIZE = sizeof(struct URL_T); + +private void __url_parse(URL this, char *url); +private void __parse_post_data(URL this, char *datap); +private char * __url_set_absolute(URL this, char *url); +private BOOLEAN __url_has_scheme (char *url); +private BOOLEAN __url_has_credentials(char *url); +private int __url_default_port(URL this); +private char * __url_set_scheme(URL this, char *url); +private char * __url_set_password(URL this, char *str); +private char * __url_set_username(URL this, char *str); +private char * __url_set_hostname(URL this, char *str); +private char * __url_set_port(URL this, char *str); +private char * __url_set_path(URL this, char *str); +private char * __url_set_file(URL this, char *str); +private char * __url_set_parameters(URL this, char *str); +private char * __url_set_query(URL this, char *str); +private char * __url_set_fragment(URL this, char *str); +private char * __url_escape(const char *s); +private METHOD __url_has_method(const char *url); + + +URL +new_url(char *str) +{ + URL this; + + this = xcalloc(sizeof(struct URL_T), 1); + this->ID = 0; + this->hasparams = FALSE; + __url_parse(this, str); + return this; +} + +URL +url_destroy(URL this) +{ + if (this!=NULL) { + xfree(this->username); + xfree(this->password); + xfree(this->hostname); + xfree(this->path); + xfree(this->file); + xfree(this->query); + xfree(this->frag); + xfree(this->request); + xfree(this->conttype); + xfree(this->postdata); + xfree(this->etag); + xfree(this); + } + return NULL; +} + +/** + * URL setters + */ + +void +url_set_ID(URL this, int ID) +{ + this->ID = ID; + return; +} + +/** + * if we don't have a hostname at + * construction, we can use this + * method to add one... + */ +void +url_set_hostname(URL this, char *hostname) +{ + size_t len; + + if (empty(hostname)) return; + + xfree(this->hostname); + len = strlen(hostname)+1; + this->hostname = xmalloc(len); + memset(this->hostname, 0, sizeof this->hostname); + strncpy(this->hostname, hostname, len); + return; +} + +void +url_set_last_modified(URL this, char *date) +{ + this->modified = strtotime(date); + return; +} + +void +url_set_etag(URL this, char *etag) +{ + size_t len; + + if (empty(etag)) return; + + len = strlen(etag)+1; + this->etag = xmalloc(len); + memset(this->etag, 0, sizeof this->etag); + strncpy(this->etag, etag, len); + return; +} + +void +url_set_conttype(URL this, char *type) { + this->conttype = xstrdup(type); + return; +} + +void +url_set_method(URL this, METHOD method) { + this->method = method; +} + +void +url_set_postdata(URL this, char *postdata, size_t postlen) +{ + this->postlen = postlen; + + if (strlen(postdata) > 0) { + this->postdata = malloc(this->postlen); + memcpy(this->postdata, postdata, this->postlen); + this->postdata[this->postlen] = 0; + } + return; +} + + +/** + * URL getters + */ + +public int +url_get_ID(URL this) +{ + return this->ID; +} + +public char * +url_get_absolute(URL this) +{ + return this->url; +} + +public SCHEME +url_get_scheme(URL this) +{ + return this->scheme; +} + +public char * +url_get_display(URL this) +{ + if (my.fullurl) + return url_get_absolute(this); + + if (this->method == GET) + return url_get_request(this); + + return url_get_absolute(this); +} + +public char * +url_get_scheme_name(URL this) +{ + switch (this->scheme) { + case HTTP: + return "http"; + case HTTPS: + return "https"; + case FTP: + return "ftp"; + case PROXY: + return "proxy"; + case UNSUPPORTED: + default: + return "unsupported"; + } + return "unsupported"; +} + +public char * +url_get_username(URL this) +{ + return this->username; +} + +public char * +url_get_password(URL this) +{ + return this->password; +} + +public char * +url_get_hostname(URL this) +{ + return this->hostname; +} + +public int +url_get_port(URL this) +{ + return this->port; +} + +public char * +url_get_path(URL this) +{ + return this->path; +} + +public char * +url_get_file(URL this) +{ + return this->file; +} + +public char * +url_get_request(URL this) +{ + return this->request; +} + +public char * +url_get_parameters(URL this) +{ + return this->params; +} + +public char * +url_get_query(URL this) +{ + return this->query; +} + +public char * +url_get_fragment(URL this) +{ + return this->frag; +} + +public size_t +url_get_postlen(URL this) { + return this->postlen; +} + +public char * +url_get_postdata(URL this) { + return this->postdata; +} + +public char * +url_get_posttemp(URL this) { + return this->posttemp; +} + +public char * +url_get_conttype(URL this) { + return this->conttype; +} + +public METHOD +url_get_method(URL this) { + return this->method; +} + +public char * +url_get_method_name(URL this) { + switch (this->method){ + case POST: + return "POST"; + case PUT: + return "PUT"; + case DELETE: + return "DELETE"; + case HEAD: + return "HEAD"; + case GET: + default: + return "GET"; + } + return "GET"; +} + +char * +url_get_if_modified_since(URL this) +{ + if (this->cached == FALSE){ + return NULL; + } + + return timetostr(&this->modified); +} + +char * +url_get_etag(URL this) +{ + char *tag; + size_t len; + + if (empty(this->etag)) return NULL; + + len = strlen(this->etag) + 18; + tag = xmalloc(len); + memset(tag, 0, sizeof tag); + + snprintf(tag, len, "If-None-Match: %s\015\012", this->etag); + return tag; +} + +public char * +url_get_realm(URL this) +{ + return (this->realm!=NULL)?this->realm:""; +} + +public void +url_set_realm(URL this, char *realm) +{ + this->realm = xstrdup(realm); +} + +void +url_set_username(URL this, char *username) +{ + size_t len = strlen(username); + + this->username = malloc(len+1); + memset(this->username, '\0', len+1); + memcpy(this->username, username, len); + return; +} + +void +url_set_password(URL this, char *password) +{ + size_t len = strlen(password); + + this->password = malloc(len+1); + memset(this->password, '\0', len+1); + memcpy(this->password, password, len); + return; +} + +void +url_dump(URL this) +{ + printf("URL ID: %d\n", this->ID); + printf("Abolute: %s\n", this->url); + printf("Scheme: %s\n", url_get_scheme_name(this)); + printf("Method: %s\n", url_get_method_name(this)); + printf("Username: %s\n", url_get_username(this)); + printf("Password: %s\n", url_get_password(this)); + printf("Hostname: %s\n", url_get_hostname(this)); + printf("Port: %d\n", url_get_port(this)); + printf("Path: %s\n", url_get_path(this)); + printf("File: %s\n", url_get_file(this)); + printf("Request: %s\n", url_get_request(this)); + if (this->hasparams==TRUE) + printf("Params: %s\n", url_get_parameters(this)); + printf("Query: %s\n", url_get_query(this)); + printf("Fragment: %s\n", url_get_fragment(this)); + printf("Post Len: %d\n", url_get_postlen(this)); + printf("Post Data: %s\n", url_get_postdata(this)); + printf("Cont Type: %s\n", url_get_conttype(this)); + //time_t expires; + //time_t modified; + //BOOLEAN cached; + //char * etag; + //char * realm; + return; +} + +URL +url_normalize(URL req, char *location) +{ + URL ret; + char * url; + size_t len = strlen(url_get_absolute(req)) + strlen(location) + 32; + if (strchr(location, ':') != NULL) { + // it's very likely normalized + ret = new_url(location); + // but we better test it... + if (strchr(url_get_hostname(ret), '.') != NULL) { + return ret; + } + } + if (strchr(location, '.') != NULL) { + // it's *maybe* host/path + ret = new_url(location); + // so we better test it... + if (strchr(url_get_hostname(ret), '.') != NULL) { + return ret; + } + // XXX: do I really need to test for localhost? + } + + // XXX: 8/20/2014 - YES. Yes, I do. + if (strstr(location, "localhost") != NULL) { + ret = new_url(location); + if (strlen(url_get_hostname(ret)) == 9) { + // we found and correctly parsed localhost + return ret; + } + } + + /** + * If we got this far we better construct it... + */ + url = (char*)malloc(len); + memset(url, '\0', len); + + if (location[0] == '/') { + if (strlen(location) > 1 && location[1] == '/') { + /* starts with // so we should use base protocol */ + snprintf(url, len, "%s:%s", url_get_scheme_name(req), location); + } else { + snprintf(url, len, "%s://%s:%d%s", url_get_scheme_name(req), url_get_hostname(req), url_get_port(req), location); + } + } else { + snprintf(url, len, "%s://%s:%d/%s", url_get_scheme_name(req), url_get_hostname(req), url_get_port(req), location); + } + ret = new_url(url); + free(url); + return ret; +} + +private void +__url_parse(URL this, char *url) +{ + char *ptr = NULL; + char *esc = NULL; + char *post; + + /** + * URL escaping is in its infancy so we're + * going to make it a configurable option. + * see: url-escaping in siegerc. + */ + esc = __url_escape(url); + if (my.escape) { + ptr = __url_set_absolute(this, esc); + } else { + ptr = __url_set_absolute(this, url); + } + ptr = __url_set_scheme(this, ptr); + + post = strstr(this->url, " POST"); + if (! post) { + post = strstr(this->url, " PUT"); + } + + if (post != NULL){ + if (!strncasecmp(post," PUT", 4)) { + this->method = PUT; + post += 4; + } else { + this->method = POST; + post += 5; + } + __parse_post_data(this, post); + } else { + this->method = GET; + this->postdata = NULL; + this->posttemp = NULL; + this->postlen = 0; + } + + if (__url_has_credentials(ptr)) { + ptr = __url_set_username(this, ptr); + ptr = __url_set_password(this, ptr); + } + + ptr = __url_set_hostname(this, ptr); + ptr = __url_set_port(this, ptr); + ptr = __url_set_path(this, ptr); + ptr = __url_set_file(this, ptr); + ptr = __url_set_parameters(this, ptr); + ptr = __url_set_query(this, ptr); + ptr = __url_set_fragment(this, ptr); + return; +} + +private void +__parse_post_data(URL this, char *datap) +{ + for (; isspace((unsigned int)*datap); datap++) { + /* Advance past white space */ + } + if (*datap == '<') { + datap++; + load_file(this, datap); + this->file = xmalloc(strlen(datap)+1); + memset(this->file, '\0', strlen(datap)+1); + memcpy(this->file, datap, strlen(datap)); + return; + } else { + this->postdata = xstrdup(datap); + this->postlen = strlen(this->postdata); + if (! empty(my.conttype)) { + this->conttype = xstrdup(my.conttype); + } else { + this->conttype = xstrdup("application/x-www-form-urlencoded"); + } + return; + } + + return; +} + +/** + * assign the full url to this->url + */ +private char * +__url_set_absolute(URL this, char *url) +{ + size_t len; + char *slash; + //char *ptr = url; + + if (empty(url)) return NULL; + + len = strlen(url)+5; + if (!__url_has_scheme(url)) { + this->url = xmalloc(len+7); + memset(this->url, '\0', sizeof this->url); + slash = strstr(url, "/"); + if (slash) { + snprintf(this->url, len+7, "http://%s", url); + } else { + snprintf(this->url, len+7, "http://%s/", url); + } + } else { + this->url = xmalloc(len); + memset(this->url, '\0', sizeof this->url); + snprintf(this->url, len, "%s", url); + } + return this->url; +} + +#define SCHEME_CHAR(ch) (isalnum (ch) || (ch) == '-' || (ch) == '+') +/** + * stolen from wget:url.c + */ +private BOOLEAN +__url_has_scheme (char *url) +{ + const char *p = url; + + /* The first char must be a scheme char. */ + if (!*p || !SCHEME_CHAR (*p)) + return FALSE; + ++p; + /* Followed by 0 or more scheme chars. */ + while (*p && SCHEME_CHAR (*p)) + ++p; + /* Terminated by ':'. */ + return *p == ':'; +} + +private BOOLEAN +__url_has_credentials(char *url) +{ + /** + * if there's an @ before /?#; then we have creds + */ + const char *p = (const char *)strpbrk (url, "@/?#;"); + if (!p || *p != '@') + return FALSE; + return TRUE; +} + +private int +__url_default_port(URL this) +{ + switch(this->scheme){ + case FTP: + return 21; + case HTTP: + return 80; + case HTTPS: + return 443; + case UNSUPPORTED: + default: + return 80; + } +} + +/** + * set the scheme, i.e., http/https + * ://:@:/;?# + */ +private char * +__url_set_scheme(URL this, char *url) +{ + if(!strncasecmp(this->url, "http:", 5)){ + this->scheme = HTTP; + return url+7; + } + if(!strncasecmp(this->url, "https:", 6)){ + this->scheme = HTTPS; + return url+8; + } + if(!strncasecmp(this->url, "ftp:", 4)){ + this->scheme = FTP; + return url+6; + } + this->scheme = UNSUPPORTED; + return url; +} + +/** + * set the username + * ://:@:/;?# + */ +private char * +__url_set_username(URL this, char *str) +{ + int i; + char *a; + char *s; + + a = strchr(str, '@'); + s = strchr(str, '/'); + + if((!a) || (s && (a >= s))){ + return str; + } + + for(i = 0; str[i] && str[i] != ':' && str[i] != '@' && str[i] != '/'; i++); + + if(str[i] != '@' && str[i] != ':'){ + return str; + } + + this->username = malloc(i+1); + memcpy(this->username, str, i + 1); + this->username[i] = '\0'; + str += i + 1; + + return str; +} + +/** + * set the password + * ://:@:/;?# + */ +private char * +__url_set_password(URL this, char *str) +{ + int i; + char *a; + char *s; + a = strchr(str, '@'); + s = strchr(str, '/'); + + if((!a) || (s && (a >= s)) ){ + return str; + } + /** + * XXX: as the original author (Zachary Beane ) notes: + * this code breaks if user has an '@' or a '/' in their password. + */ + for(i = 0 ; str[i] != '@'; i++); + this->password = xmalloc(i+1); + + memcpy(this->password, str, i); + this->password[i] = '\0'; + + str += i + 1; + + return str; +} + +/** + * set the hostname + * ://:@:/;?# + */ +private char * +__url_set_hostname(URL this, char *str) +{ + int i; + + /* skip to end, slash, or port colon */ + for(i = 0; str[i] && str[i] != '/' && str[i] != ':'; i++); + + this->hostname = xmalloc(i + 1); + memcpy(this->hostname, str, i); + + this->hostname[i] = '\0'; + + /* if there's a port */ + if(str[i] == ':'){ + str += i + 1; + } else { + str += i; + } + return str; +} + +/** + * set the port + * ://:@:/;?# + */ +private char * +__url_set_port(URL this, char *str) +{ + char *portstr; + int i; + + this->port = __url_default_port(this); + + for(i = 0; isdigit(str[i]); i++); + + if(i == 0) return str; + + + portstr = malloc(i + 1); + memcpy(portstr, str, i + 1); + portstr[i] = '\0'; + + this->port = atoi(portstr); + xfree(portstr); + + str += i; + return str; +} + +/** + * set the path + * ://:@:/;?# + */ +private char * +__url_set_path(URL this, char *str) +{ + int i; // capture the lenght of the path + int j; // capture the length of the request (sans frag) + + for(i = strlen(str); i > 0 && str[i] != '/'; i--); + for(j = 0; str[j] && (str[j] != '#' && !isspace(str[j])); j++); + + + if(str[i] != '/'){ + this->path = xmalloc(2); + this->request = xmalloc(2); + strncpy(this->path, "/", 2); + strncpy(this->request, "/", 2); + this->path[1] = '\0'; + this->request[1] = '\0'; + } else { + this->path = xmalloc(i+2); + this->request = xmalloc(j+2); + memcpy(this->path, str, i+1); + memcpy(this->request, str, j+1); + this->path[i] = '/'; + this->path[i + 1] = '\0'; + if (this->request[j]=='#') { + this->request[j] = '\0'; // lop the # + } else { + this->request[j+1] = '\0'; // no frag + } + } + trim(this->request); + str += i + 1; + return str; +} + +/** + * set the file + * ://:@:/;?# + */ +private char * +__url_set_file(URL this, char *str) +{ + int i; + + if (str==NULL) return NULL; + if (this->file != NULL && strlen(this->file) > 1) return str; + + for(i = 0; str[i] && (str[i] != ';' && str[i] != '?' && !isspace(str[i])); i++); + this->file = xmalloc(i+1); + memset(this->file, '\0', i+1); + memcpy(this->file, str, i); + trim(this->file); + + /* if there are params or a query string */ + if (str[i] == ';') { + this->hasparams = TRUE; + str += i + 1; + } else if(str[i] == '?') { + str += i + 1; + } else { + str += i; + } + return str; +} + +/** + * set the parameters + * ://:@:/;?# + */ +private char * +__url_set_parameters(URL this, char *str) +{ + int i; + + if (str==NULL) return NULL; + if (this->params != NULL && strlen(this->params) > 1) return str; + + if (this->hasparams == FALSE) { + this->params = ""; + return str; + } + + for (i = 0; str[i] && (str[i] != '?' && !isspace(str[i])); i++); + + this->params = xmalloc(i+1); + memset(this->params, '\0', i+1); + memcpy(this->params, str, i); + + /* if there is a query string */ + if(str[i] == '?'){ + str += i + 1; + } else { + str += i; + } + return str; +} + +/** + * set the query + * ://:@:/;?# + */ +private char * +__url_set_query(URL this, char *str) +{ + int i; + + if (str==NULL) { + this->query = xstrcat(""); + return NULL; + } + + if (this->query != NULL && strlen(this->query) > 1) return str; + + for(i = 0; str[i] && (str[i] != '#' && !isspace(str[i])); i++); + + this->query = xmalloc(i+1); + memset(this->query, '\0', i+1); + memcpy(this->query, str, i); + + /* if there are params or a query string */ + if(str[i] == '#'){ + str += i + 1; + } else { + str += i; + } + return str; +} + +/** + * set the fragment (not used by siege) + * ://:@:/;?# + */ +private char * +__url_set_fragment(URL this, char *str) +{ + int i; + + if (str==NULL) return NULL; + if (this->frag != NULL && strlen(this->frag) > 1) return str; + + for(i = 0; str[i] && !isspace(str[i]); i++); + + this->frag = xmalloc(i+1); + memcpy(this->frag, str, i); + + str += i + 1; + return str; +} + +/** + * The following functions provide url encoding. They + * were lifted from wget: + * Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001 + * Free Software Foundation, Inc. + */ +enum { + /* rfc1738 reserved chars, preserved from encoding. */ + urlchr_reserved = 1, + + /* rfc1738 unsafe chars, plus some more. */ + urlchr_unsafe = 2 +}; + +#define urlchr_test(c, mask) (urlchr_table[(unsigned char)(c)] & (mask)) +#define URL_RESERVED_CHAR(c) urlchr_test(c, urlchr_reserved) +#define URL_UNSAFE_CHAR(c) urlchr_test(c, urlchr_unsafe) + +/* Shorthands for the table: */ +#define R urlchr_reserved +#define U urlchr_unsafe +#define RU R|U + +static const unsigned char urlchr_table[256] = +{ + U, U, U, U, U, U, U, U, /* NUL SOH STX ETX EOT ENQ ACK BEL */ + U, U, U, U, U, U, U, U, /* BS HT LF VT FF CR SO SI */ + U, U, U, U, U, U, U, U, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ + U, U, U, U, U, U, U, U, /* CAN EM SUB ESC FS GS RS US */ + U, 0, U, RU, 0, U, R, 0, /* SP ! " # $ % & ' */ + 0, 0, 0, R, 0, 0, 0, R, /* ( ) * + , - . / */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 1 2 3 4 5 6 7 */ + 0, 0, RU, R, U, R, U, R, /* 8 9 : ; < = > ? */ + RU, 0, 0, 0, 0, 0, 0, 0, /* @ A B C D E F G */ + 0, 0, 0, 0, 0, 0, 0, 0, /* H I J K L M N O */ + 0, 0, 0, 0, 0, 0, 0, 0, /* P Q R S T U V W */ + 0, 0, 0, RU, U, RU, U, 0, /* X Y Z [ \ ] ^ _ */ + U, 0, 0, 0, 0, 0, 0, 0, /* ` a b c d e f g */ + 0, 0, 0, 0, 0, 0, 0, 0, /* h i j k l m n o */ + 0, 0, 0, 0, 0, 0, 0, 0, /* p q r s t u v w */ + 0, 0, 0, U, U, U, U, U, /* x y z { | } ~ DEL */ + + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, +}; +#undef R +#undef U +#undef RU + +enum copy_method { CM_DECODE, CM_ENCODE, CM_PASSTHROUGH }; + +/** + * Decide whether to encode, decode, or pass through the char at P. + * This used to be a macro, but it got a little too convoluted. + */ +static inline enum copy_method +decide_copy_method (const char *p) +{ + if (*p == '%') { + if (ISXDIGIT (*(p + 1)) && ISXDIGIT (*(p + 2))) { + /** + * %xx sequence: decode it, unless it would decode to an + * unsafe or a reserved char; in that case, leave it as is. + */ + char preempt = X2DIGITS_TO_NUM (*(p + 1), *(p + 2)); + if (URL_UNSAFE_CHAR (preempt) || URL_RESERVED_CHAR (preempt)) + return CM_PASSTHROUGH; + else + return CM_DECODE; + } else { + return CM_ENCODE; + } + } + else if (URL_UNSAFE_CHAR (*p) && !URL_RESERVED_CHAR (*p)) + return CM_ENCODE; + else + return CM_PASSTHROUGH; +} + +static METHOD +__url_has_method(const char *url) +{ + unsigned int i = 0; + const char * r = NULL; + static const char* const methods[] = { + " GET", " HEAD", " POST", " PUT", " TRACE", " DELETE", " OPTIONS", " CONNECT" + }; + + for (i = 0; i < sizeof(methods) / sizeof(methods[0]); i++) { + r = strstr(url, methods[i]); + if (r != NULL) return i; + } + + return NOMETHOD; +} + +private char * +__url_escape(const char *s) +{ + const char *p1; + char *newstr, *p2; + int oldlen, newlen; + + int encode_count = 0; + int decode_count = 0; + + /** + * FIXME: we're not going to escape siege method + * URLS, i.e., things with PUT or POST but if the + * path contains spaces they won't be escaped. + */ + if (__url_has_method(s)!=NOMETHOD) { + return (char *)s; + } + + /* First, pass through the string to see if there's anything to do, + and to calculate the new length. */ + for (p1 = s; *p1; p1++) { + switch (decide_copy_method (p1)) { + case CM_ENCODE: + ++encode_count; + break; + case CM_DECODE: + ++decode_count; + break; + case CM_PASSTHROUGH: + break; + } + } + + if (!encode_count && !decode_count) + return (char *)s; /* C const model sucks. */ + + oldlen = p1 - s; + /* Each encoding adds two characters (hex digits), while each + decoding removes two characters. */ + newlen = oldlen + 2 * (encode_count - decode_count); + newstr = xmalloc (newlen + 1); + + p1 = s; + p2 = newstr; + + while (*p1) { + switch (decide_copy_method (p1)) { + case CM_ENCODE: { + unsigned char c = *p1++; + *p2++ = '%'; + *p2++ = XNUM_TO_DIGIT (c >> 4); + *p2++ = XNUM_TO_DIGIT (c & 0xf); + } + break; + case CM_DECODE: + *p2++ = X2DIGITS_TO_NUM (p1[1], p1[2]); + p1 += 3; /* skip %xx */ + break; + case CM_PASSTHROUGH: + *p2++ = *p1++; + } + } + *p2 = '\0'; + return newstr; +} + diff --git a/src/url.h b/src/url.h new file mode 100644 index 0000000..e8f73dc --- /dev/null +++ b/src/url.h @@ -0,0 +1,143 @@ +/** + * URL Support + * + * Copyright (C) 2013-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#ifndef __URL_H +#define __URL_H +#include +#include +#include + +/** + * a URL object + */ +typedef struct URL_T *URL; + +/** + * For memory allocation; URLSIZE + * provides the object size + */ +extern size_t URLSIZE; + +/** + * HTTP method + */ +typedef enum { + NOMETHOD = 0, + HEAD = 1, + GET = 2, + POST = 3, + PUT = 4, + DELETE = 5, + TRACE = 6, + OPTIONS = 7, + CONNECT = 8, +} METHOD; + +/** + * enum SCHEME + */ +typedef enum { + UNSUPPORTED = 0, + HTTP = 1, + HTTPS = 2, + FTP = 3, + PROXY = 4 +} SCHEME; + + +/* Constructor / destructor */ +URL new_url(char *str); +URL url_destroy(URL this); +void url_dump(URL this); + +void url_set_ID(URL this, int id); +void url_set_hostname(URL this, char *hostname); +void url_set_last_modified(URL this, char *date); +void url_set_etag(URL this, char *etag); +void url_set_conttype(URL this, char *type); +void url_set_postdata(URL this, char *postdata, size_t postlen); +void url_set_method(URL this, METHOD method); + +int url_get_ID(URL this); +METHOD url_get_method(URL this); +char * url_get_method_name(URL this) ; + +/* ://:@:/;?# */ +char * url_get_absolute(URL this); + +/* ://:@:/;?# */ +SCHEME url_get_scheme(URL this); +char * url_get_scheme_name(URL this); + +/* ://:@:/;?# */ +char * url_get_username(URL this); + +/* ://:@:/;?# */ +char * url_get_password(URL this); + +/* ://:@:/;?# */ +char * url_get_hostname(URL this); + +/* ://:@:/;?# */ +int url_get_port(URL this); + +/* ://:@:/;?# */ +char * url_get_path(URL this); + +/* ://:@:/;?# */ +char * url_get_file(URL this); +char * url_get_request(URL this); // "" + +/* ://:@:/;?# */ +char * url_get_parameters(URL this); + +/* ://:@:/;?# */ +char * url_get_query(URL this); + +/* ://:@:/;?# */ +char * url_get_fragment(URL this); + + +/* + * Make a decision about what to display. Will show absolute url when fullurl + * is set to ture. Otherwise we check the HTTP method to display the submitted + * URI or the respective line provided from the urls file. + */ +char * url_get_display(URL this); + +/** + * POST method getters + * ://:@:/ POST ?# + */ +size_t url_get_postlen(URL this); +char * url_get_postdata(URL this); +char * url_get_posttemp(URL this); +char * url_get_conttype(URL this); +char * url_get_if_modified_since(URL this); +char * url_get_etag(URL this); +char * url_get_realm(URL this); +void url_set_realm(URL this, char *realm); +void url_set_username(URL this, char *username); +void url_set_password(URL this, char *password); +URL url_normalize(URL req, char *location); + +#endif/*__URL_H*/ diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..292a947 --- /dev/null +++ b/src/util.c @@ -0,0 +1,337 @@ +/** + * Utility Functions + * + * Copyright (C) 2000-2014 by + * Jeffrey Fulmer - , et al. + * This file is distributed as part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *-- + */ +#include +#include +#include +#include +#include +#include +#include + +void pthread_usleep_np(unsigned long usec); + +/** + * parses the -t/--time option for a timed + * interval. The option requires a modifier, + * H, M, or S, hours, minutes or seconds + */ +void +parse_time(char *p) +{ + size_t x = 0; + my.time = my.secs = 0; + + while(ISDIGIT(p[x])) + x++; + if (x==0) return; + my.time = atoi(substring(p, 0, x)); + + for(; x < strlen(p); x ++) + switch(TOLOWER(p[x])){ + case 's': + my.secs = my.time; + my.time = 1; + return; + case 'm': + my.secs = my.time * 60; + my.time = 1; + return; + case 'h': + my.secs = my.time * 3600; + my.time = 1; + return; + default: + break; + } + if((my.time > 0) && (my.secs <= 0)){ + my.secs = my.time * 60; + } + + return; +} + +BOOLEAN +okay(int code) +{ + return (code >= 100 && code <= 299); +} + + +BOOLEAN +strmatch(char *option, char *param) +{ + if(!strncasecmp(option,param,strlen(param))&&strlen(option)==strlen(param)) + return TRUE; + else + return FALSE; +} + +char * +uppercase(char *s, size_t len){ + unsigned char *c, *e; + + c = (unsigned char*)s; + e = c+len; + + while(c < e){ + *c = TOUPPER((unsigned char)(*c)); + c++; + } + return s; +} + + +char * +lowercase(char *s, size_t len){ + unsigned char *c, *e; + + c = (unsigned char*)s; + e = c+len; + + while(c < e){ + *c = TOLOWER((unsigned char)(*c)); + c++; + } + return s; +} + +/** + * sleep and usleep work on all supported + * platforms except solaris, so we'll use + * those functions on non-solaris, but we + * still need to sleep. The macro handles + * that for us. + */ +void +pthread_sleep_np( unsigned int secs ) +{ +#if defined( SOLARIS ) || defined( sun ) + /* Theoretically, this could fail for sizeof(int)==sizeof(long) and + * very large values of secs due to an overflow. + * NB: for 64-bit int, that would mean waiting until the year 584543. + */ + pthread_usleep_np (secs*1000000); +#else + sleep(secs); +#endif/*pthread_sleep_np*/ + + return; +} + + +void +pthread_usleep_np(unsigned long usec) +{ +#if defined(SOLARIS) || defined(sun) + int err, type; + struct timeval now; + struct timespec timeout; + pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t timer_cond = PTHREAD_COND_INITIALIZER; + + pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, &type ); + gettimeofday(&now, NULL); + timeout.tv_sec = now.tv_sec + usec/1000000; + timeout.tv_nsec = (now.tv_usec + usec%1000000)*1000; + /* At most 1s carry. */ + if(timeout.tv_nsec >= 1000000000){ + timeout.tv_nsec -= 1000000000; + timeout.tv_sec++; + } + + pthread_mutex_lock(&timer_mutex); + err = pthread_cond_timedwait(&timer_cond, &timer_mutex, &timeout); + + pthread_setcanceltype(type,NULL); + pthread_testcancel(); +#else + usleep(usec); +#endif + return; +} + +void +echo (const char *fmt, ...) +{ + char buf[256]; + va_list ap; + + if (my.quiet) { + return; + } + + if (my.get) { + va_start(ap, fmt); + vsnprintf(buf, sizeof buf, fmt, ap); + printf("%s", buf); // yes, that's ugly... + va_end(ap); + fflush(stdout); + return; + } + + if (my.debug) { + va_start(ap, fmt); + vsnprintf(buf, sizeof buf, fmt, ap); + if (strlen(buf) == 1) { + printf("%s", buf); + } else { + NOTIFY(DEBUG, buf); + } + va_end(ap); + } + return; +} + +void +debug (const char *fmt, ...) +{ + char buf[256]; + va_list ap; + + if (my.quiet) { + return; + } + + if (my.debug) { + va_start(ap, fmt); + vsnprintf(buf, sizeof buf, fmt, ap); + if (strlen(buf) == 1) { + printf("%s", buf); + } else { + NOTIFY(DEBUG, buf); + } + va_end(ap); + } + return; +} + + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#ifndef HAVE_RAND_R +static int +do_rand(unsigned long *ctx) +{ + return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1)); +} + +int +posix_rand_r(unsigned int *ctx) +{ + u_long val = (u_long) *ctx; + *ctx = do_rand(&val); + return (int) *ctx; +} +#endif + +int +pthread_rand_np(unsigned int *ctx) +{ +#ifndef HAVE_RAND_R + return (int)posix_rand_r(ctx); +#else + return (int)rand_r(ctx); +#endif +} + +int +urandom() +{ +#ifdef HAVE_DEV_RANDOM + int rand = -1; + int fd; + + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0) { + read(fd, &rand, sizeof(rand)); + close(fd); + } + return rand; +#else + unsigned int randrseed; + + randrseed = time(0); + return pthread_rand_np(&randrseed); +#endif +} + +#ifndef strnlen +size_t +strnlen(const char *str, size_t len) +{ + const char *end = memchr(str, '\0', len); + return (end != NULL) ? (size_t) (end - str) : len; +} +#endif + +#ifndef strncasestr +const char * +strncasestr(const char *str1, const char *str2, size_t len) +{ + size_t str1_len = strnlen(str1, len); + size_t str2_len = strlen(str2); + size_t i; + + if (str1_len < 1 || str2_len < 1) { + return NULL; + } + + for(i = 0; i < (str1_len - str2_len + 1); i++){ + if(strncasecmp(str1, str2, str2_len) == 0){ + return str1; + } + str1++; + } + return NULL; +} +#endif diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..24a7863 --- /dev/null +++ b/src/util.h @@ -0,0 +1,47 @@ +/** + * Utility Functions + * + * Copyright (C) 2001-2014 + * by Jeffrey Fulmer , et al. + * This file is part of Siege + * + * 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. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef UTIL_H +#define UTIL_H + +#include + +void parse_time(char *p); +void pthread_sleep_np(unsigned int seconds); +void pthread_usleep_np(unsigned long usec); +int pthread_rand_np(unsigned int *ctx); +int urandom(); +BOOLEAN strmatch(char *str1, char *str2); +BOOLEAN okay(int code); +void echo(const char *fmt, ...); +void debug (const char *fmt, ...); +char *uppercase(char *s, size_t len); +char *lowercase(char *s, size_t len); +#ifndef strnlen +size_t strnlen(const char *str, size_t len); +#endif +#ifndef strncasestr +char *strncasestr(const char *str1, const char *str2, size_t len); +#endif + +#endif /*UTIL_H*/ + diff --git a/src/version.c b/src/version.c new file mode 100644 index 0000000..872f2f8 --- /dev/null +++ b/src/version.c @@ -0,0 +1,15 @@ +/** + * version_string and program_name are used by siege + * and configure; author_name and email_address are + * used by configure to dynamically assign those values + * to documentation files. + */ +const char *version_string = "3.0.8"; +const char *program_name = "siege"; +const char *author_name = "Jeffrey Fulmer, et al."; +const char *email_address = "jeff@joedog.org"; +const char *years = "1999-2014"; +const char *copyright = "Copyright (C) 2014 by Jeffrey Fulmer, et al.\n\ +This is free software; see the source for copying conditions.\n\ +There is NO warranty; not even for MERCHANTABILITY or FITNESS\n\ +FOR A PARTICULAR PURPOSE.\n"; diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..0653610 --- /dev/null +++ b/src/version.h @@ -0,0 +1,10 @@ +#ifndef __VERSION_H +#define __VERSION_H + +extern char *version_string; +extern char *program_name; +extern char *author_name; +extern char *email_address; +extern char *copyright; + +#endif/*__VERSION_H*/ diff --git a/utils/Makefile.am b/utils/Makefile.am new file mode 100644 index 0000000..ecd6323 --- /dev/null +++ b/utils/Makefile.am @@ -0,0 +1,60 @@ +## +## utils/Makefile.am +## +## Copyright (C) 2000-2007 by +## Jeffrey Fulmer - , et al. +## This file is distributed as part of Siege +## +## 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., 675 Mass Ave, Cambridge, MA 02139, USA. +## + +AUTOMAKE_OPTIONS = foreign no-dependencies + +WARN_CFLAGS = @WARN_CFLAGS@ +AM_CFLAGS = $(WARN_CFLAGS) + +SIEGE_UTILITIES = bombardment siege2csv.pl siege.config + +DISTCLEANFILES = $(SIEGE_UTILITIES) + +EXTRA_DIST = \ +bootstrap \ +config.guess \ +config.sub \ +install-sh \ +ltmain.sh \ +mdate-sh \ +missing \ +mkinstalldirs \ +mkstamp \ +siege.config.in \ +bombardment.in \ +siege2csv.in + +install-exec-hook: + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(SIEGE_UTILITIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'| sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall: + @list='$(SIEGE_UTILITIES)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + + diff --git a/utils/bombardment.in b/utils/bombardment.in new file mode 100644 index 0000000..1f10f65 --- /dev/null +++ b/utils/bombardment.in @@ -0,0 +1,105 @@ +#!/bin/sh +#bombardment is a script that invokes siege with an ever-increasing +#number of users. +#Copyright (C) 2001 Peter J. Hutnick + +#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, US + +#For informaion, write the author, Peter Hutnick at phutnick@aperian.com. + + +# Display help if no options or --help specified. +if [ -z $1 ] || [ $1 = --help ] + then + echo "" + echo "usage:" + echo "bombardment [urlfile] [inital # of clients] \ +[inc value] [# of inc] [delay]" + echo "" +# echo "so \"laysiege foo.com 10 5 3\" would test \ +#http:\\\\foo.com\\index.html with 10 then 15 then 20 clients." + echo "" + exit + fi + +# Assign args to useful variables. +site=$1 +startcl=$2 +inc=$3 +numruns=$4 +delay=$5 +serial=`date --iso-8601=minutes` + +# This script can easily be made to overwhelm system resources (processes +# and filehandles. This bit calculates how many processes it will spawn +# on the last run, and warn if it is more than 600. + +total=$startcl +sub=`expr $inc \* $numruns` +total=$total+$sub + +if [ 600 -lt $(($total)) ] + then + echo "The options you specified will generate more than \ +600 concurrent users. This causes problems on many systems. Press \ + to abort, unless you are sure your system can handle more than \ +600 processes and more than 2048 open files, AND that your user account \ +is allowed to do so." + echo "" + echo "Siege will run with the supplied options in 10 sec." +# I would rather use something like "pause" from DOS than the sleep below, +# but I don't know of any such thing. + sleep 10 + fi + + + +# Set a default delay of 15 seconds if none is specified. +if [ -z $5 ] + then + delay=15 + fi +#echo $delay + + +# Find the number of URLs so we can set -t in siege. This deviates +# somewhat from Siege's normal mode of operation. I assume that each +# entry in the URL list should be hit once per client. + +numurls=`cat $site | grep -v "#" | wc -l` +# Debug-o-rama +#echo "the number of URLs is: " +#echo $numurls +#echo "\n" + +# Now we come to the loop that actually runs Siege. This sould be +# self-explainitory. + +currentcl=$startcl # set running count of clients to inital value + +i=1 +while [ $numruns -ge $i ] + do + echo "Starting run number" $i + %_PREFIX%/siege -f $site -c $currentcl -t $numurls -d $delay >> siege.$serial + currentcl=$(($currentcl+$inc)) + i=$(($i+1)) + #sleep 30 + done + +# Finally, we call siege2csv.pl to convert all the human-readable Siege +# output to CSV, for easy spreadsheet usage. + +siege2csv.pl siege.$serial diff --git a/utils/bootstrap b/utils/bootstrap new file mode 100755 index 0000000..13d44bc --- /dev/null +++ b/utils/bootstrap @@ -0,0 +1,13 @@ +#!/bin/sh +# Jeffrey Fulmer +# Sat Jan 6 11:36:27 EST 2001 +# +# part of siege distribution +# automates the autotools + +set -x +aclocal +autoheader +automake --foreign --copy +autoconf + diff --git a/utils/config.guess b/utils/config.guess new file mode 100755 index 0000000..872b96a --- /dev/null +++ b/utils/config.guess @@ -0,0 +1,1537 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-09-25' + +# 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, see . +# +# 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. Please send patches (context +# diff format) to and include a 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. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +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 ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +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 ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # 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 + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + 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 ; set_cc_for_build= ;' + +# 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 tuples: *-*-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 + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-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 -q __ELF__ + 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 + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # 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 ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # 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. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + 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 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + 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 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + 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 ;; + 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 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + 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 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # 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 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* 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 -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + 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 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????: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 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + 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 ;; + *: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 + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + 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 ;; + *:AIX:*:[4567]) + 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 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 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 + #include + + 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 -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + 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 -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + 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 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + 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 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + 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 i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + 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 -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + 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 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + 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 ;; + 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 ;; + 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 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + 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 ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + 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 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + 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 i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + 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 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*: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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + 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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *: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 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + 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 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *: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 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *: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 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +eval $set_cc_for_build +cat >$dummy.c < +# include +#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 + 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\n"); 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 +# 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 -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# 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 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < 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: diff --git a/utils/config.sub b/utils/config.sub new file mode 100755 index 0000000..826e4c6 --- /dev/null +++ b/utils/config.sub @@ -0,0 +1,1787 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-10-10' + +# 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, see . +# +# 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 . Submit a context +# diff and a properly formatted GNU 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. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# 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 ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +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 ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # 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 ;; + + * ) + 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* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + 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 | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -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 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -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/'` + ;; + -sco5v6*) + # 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*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -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 \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # 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-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # 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 + ;; + abacus) + basic_machine=abacus-unknown + ;; + 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 + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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 + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + 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 + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + 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 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + 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*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 + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + 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 + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + 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 + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + 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 + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-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-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + 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 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + 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 + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + 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 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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 + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + 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 + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-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 + ;; + mmix) + basic_machine=mmix-knuth + ;; + 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 + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + 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 + ;; + *-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. + -auroraux) + os=-auroraux + ;; + -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* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -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 + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -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 + ;; + -tpf*) + os=-tpf + ;; + -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 + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -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 + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # 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 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + 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 + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-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 + ;; + -cnk*|-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 + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + 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 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/utils/install-sh b/utils/install-sh new file mode 100755 index 0000000..0ae12c0 --- /dev/null +++ b/utils/install-sh @@ -0,0 +1,401 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-11-07.23 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# 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}" + +posix_glob= +posix_mkdir= + +# Symbolic mode for testing mkdir with directories. +# It is the same as 755, but also tests that "u+" works. +test_mode=u=rwx,g=rx,o=rx,u+wx + +# Desired mode of installed file. +mode=0755 + +# Desired mode of newly created intermediate directories. +# It is empty if not known yet. +intermediate_mode= + +chmodcmd=$chmodprog +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +test -n "$dir_arg" || trap '(exit $?); exit' 1 2 13 15 + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + posix_mkdir=false + if $mkdirprog -m $test_mode -p -- / >/dev/null 2>&1; then + posix_mkdir=true + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./-m "$test_mode" ./-p ./-- 2>/dev/null + fi ;; + esac + + if + $posix_mkdir && { + + # With -d, create the new directory with the user-specified mode. + # Otherwise, create it using the same intermediate mode that + # mkdir -p would use when creating intermediate directories. + # POSIX says that this mode is "$(umask -S),u+wx", so use that + # if umask -S works. + + if test -n "$dir_arg"; then + mkdir_mode=$mode + else + case $intermediate_mode in + '') + if umask_S=`(umask -S) 2>/dev/null`; then + intermediate_mode=$umask_S,u+wx + else + intermediate_mode=$test_mode + fi ;; + esac + mkdir_mode=$intermediate_mode + fi + + $mkdirprog -m "$mkdir_mode" -p -- "$dstdir" + } + then : + else + + # mkdir does not conform to POSIX, or it failed possibly due to + # a race condition. Create the directory the slow way, step by + # step, checking for races as we go. + + case $dstdir in + /*) pathcomp=/ ;; + -*) pathcomp=./ ;; + *) pathcomp= ;; + esac + + case $posix_glob in + '') + if (set -f) 2>/dev/null; then + posix_glob=true + else + posix_glob=false + fi ;; + esac + + oIFS=$IFS + IFS=/ + $posix_glob && set -f + set fnord $dstdir + shift + $posix_glob && set +f + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + pathcomp=$pathcomp$d + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # Don't fail if two instances are running concurrently. + test -d "$pathcomp" || exit 1 + fi + pathcomp=$pathcomp/ + done + obsolete_mkdir_used=true + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # 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 $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dst"; then + $doit $rmcmd -f "$dst" 2>/dev/null \ + || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ + && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ + || { + echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + } || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/utils/ltmain.sh b/utils/ltmain.sh new file mode 100755 index 0000000..0223495 --- /dev/null +++ b/utils/ltmain.sh @@ -0,0 +1,6911 @@ +# 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, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.22 +TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi + +# 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 "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +duplicate_deps=no +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $mkdir "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || { + $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 + exit $EXIT_FAILURE + } + fi + + $echo "X$my_tmpdir" | $Xsed +} + + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + extracted_serial=`expr $extracted_serial + 1` + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then + exit $exit_status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +disable_libs=no + +# 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" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + 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" + $echo + $echo "Copyright (C) 2005 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --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 $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) + prevopt="--tag" + prev=tag + preserve_args="$preserve_args --tag" + ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +case $disable_libs in +no) + ;; +shared) + build_libtool_libs=no + build_old_libs=yes + ;; +static) + build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` + ;; +esac + +# 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 + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + 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 $EXIT_FAILURE + 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= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -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. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + *.obj) xform=obj ;; + 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 $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qlibobj="\"$qlibobj\"" ;; + esac + test "X$libobj" != "X$qlibobj" \ + && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 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 $EXIT_FAILURE" 1 2 15 + else + output_obj= + 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 "$progpath" "$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 $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </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 $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </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 $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && 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 + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_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 $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_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 $EXIT_FAILURE + ;; + 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 + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework|darwin_framework_skip) + test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + prev= + 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 $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework|-arch|-isysroot) + case " $CC " in + *" ${arg} ${1} "* | *" ${arg} ${1} "*) + prev=darwin_framework_skip ;; + *) compiler_flags="$compiler_flags $arg" + prev=darwin_framework ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + 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* | /*-*-irix*) + 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 + absdir="$dir" + notinst_path="$notinst_path $dir" + 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*) + testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -pg pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ + -t[45]*|-txscale*|@*) + + # 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 + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + -shrext) + prev=shrext + 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 + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -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 $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static | -static-libtool-libs) + # 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 + ;; + -version-number) + prev=vinfo + vinfo_number=yes + 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 + ;; + + -XCClinker) + prev=xcclinker + 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 + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + 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 $EXIT_FAILURE + 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 + + oldlibs= + # 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 + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then + exit $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 $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + 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 + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # 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 $EXIT_FAILURE + ;; + 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,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + 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 + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + 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 + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_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 + fi + ;; + *) ;; + esac + fi + 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" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 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) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; 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" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + 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 + 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' or unhandled argument \`$deplib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + 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 variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + 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. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + 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 + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + 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 $EXIT_FAILURE + 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" # used for prog,scan pass + 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... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $absdir" ;; + esac + fi + + # 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 + 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 + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes ; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if 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 + 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* | mingw*) + 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='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $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='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $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" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | + $EGREP ": [^:]* bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + 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" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + 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 $EXIT_FAILURE + 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" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + 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 + # 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 + 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="$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 $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_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 + 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 + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + 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 + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + 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/-version-number' 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 shared_ext=\"$shrext_cmds\" + 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 $EXIT_FAILURE + 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 shared_ext=\"$shrext_cmds\" + 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 $EXIT_FAILURE + 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. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + 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/-version-number' 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 $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # 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]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + 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 $EXIT_FAILURE + 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="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 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" -ne 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 $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + 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, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + 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* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # 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 behavior. + 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 </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 + fi + 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 + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; 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 above 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 + fi + 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="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -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 + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + + # 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" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + 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 shared_ext=\"$shrext_cmds\" + 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 + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + 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 + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + 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 + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + 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 "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_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 $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + fi + fi + + exit $EXIT_SUCCESS + 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 $EXIT_FAILURE + 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 and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + 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" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $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 $EXIT_SUCCESS + 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 $EXIT_SUCCESS + 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" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + 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 + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + 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*) + testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + 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/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + else + $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + 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" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + 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. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + 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 -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -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. + case $host in + *cygwin* | *mingw* ) + if test -f "$output_objdir/${outputname}.def" ; then + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + else + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + fi + ;; + * ) + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + ;; + esac + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + 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" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + exit_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 $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 $EXIT_SUCCESS + 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" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` + 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" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --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 + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + output_name=`basename $output` + output_path=`dirname $output` + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +/* -DDEBUG is fairly common in CFLAGS. */ +#undef DEBUG +#if defined DEBUGWRAPPER +# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +# define DEBUG(format, ...) +#endif + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +const char * base_name (const char *name); +char * find_executable(const char *wrapper); +int check_executable(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + DEBUG("(main) argv[0] : %s\n",argv[0]); + DEBUG("(main) program_name : %s\n",program_name); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = find_executable(argv[0]); + if (newargz[1] == NULL) + lt_fatal("Couldn't find %s", argv[0]); + DEBUG("(main) found exe at : %s\n",newargz[1]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + + for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" + return 127; +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char)name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable(const char * path) +{ + struct stat st; + + DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) && + ( + /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ +#if defined (S_IXOTH) + ((st.st_mode & S_IXOTH) == S_IXOTH) || +#endif +#if defined (S_IXGRP) + ((st.st_mode & S_IXGRP) == S_IXGRP) || +#endif + ((st.st_mode & S_IXUSR) == S_IXUSR)) + ) + return 1; + else + return 0; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise */ +char * +find_executable (const char* wrapper) +{ + int has_slash = 0; + const char* p; + const char* p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char* concat_name; + + DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char* path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char* q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR(*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + return NULL; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 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' + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +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 $EXIT_FAILURE + 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 + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \$*\" + exit $EXIT_FAILURE + 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 $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + 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="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$gentop"; then + exit $exit_status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + 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 $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + 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 | *mingw*,*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 + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# 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 $EXIT_SUCCESS + ;; + + # 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" | 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) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) prev=$arg ;; + -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 $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + ;; + 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 | grep "^# 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 $EXIT_FAILURE + 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 + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` + else + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` + fi + + $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 + exit $EXIT_FAILURE + 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. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_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 $EXIT_FAILURE + ;; + 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 $EXIT_SUCCESS + ;; + + *) + # 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 + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # 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 | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper 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 $EXIT_FAILURE + 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= + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir=`func_mktempdir` + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` + + $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$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + 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 "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $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 $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + 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. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $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 $EXIT_SUCCESS + + $echo "X----------------------------------------------------------------------" | $Xsed + $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 "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS + ;; + + # 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# 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 $EXIT_FAILURE + 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 $EXIT_FAILURE + 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 | grep "^# 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 environment variables + for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + + # 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 $EXIT_SUCCESS + 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 $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + 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 | grep "^# 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" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 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. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # 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 $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +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 + --tag=TAG use configuration variables from tag TAG + --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. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +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 + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -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 uninstalled libtool libraries + -static-libtool-libs + 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 $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +disable_libs=shared +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +disable_libs=static +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/utils/manifier b/utils/manifier new file mode 100755 index 0000000..ef5b03c --- /dev/null +++ b/utils/manifier @@ -0,0 +1,12 @@ +#!/usr/bin/perl +use Pod::Man; +my $input = $ARGV[0] or barf(); +my $output = $ARGV[1] or barf(); + +my $parser = Pod::Man->new (release => $VERSION, section => 8); +$parser->parse_from_file ($input, $output); + +sub barf() { + print "usage: $0 \n"; + exit(1); +} diff --git a/utils/mdate-sh b/utils/mdate-sh new file mode 100755 index 0000000..37171f2 --- /dev/null +++ b/utils/mdate-sh @@ -0,0 +1,92 @@ +#!/bin/sh +# Get modification time of a file or directory and pretty-print it. +# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +# written by Ulrich Drepper , June 1995 +# +# 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. + +# Prevent date giving response in another language. +LANG=C +export LANG +LC_ALL=C +export LC_ALL +LC_TIME=C +export LC_TIME + +# Get the extended ls output of the file or directory. +# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. +if ls -L /dev/null 1>/dev/null 2>&1; then + set - x`ls -L -l -d $1` +else + set - x`ls -l -d $1` +fi +# The month is at least the fourth argument +# (3 shifts here, the next inside the loop). +shift +shift +shift + +# Find the month. Next argument is day, followed by the year or time. +month= +until test $month +do + shift + case $1 in + Jan) month=January; nummonth=1;; + Feb) month=February; nummonth=2;; + Mar) month=March; nummonth=3;; + Apr) month=April; nummonth=4;; + May) month=May; nummonth=5;; + Jun) month=June; nummonth=6;; + Jul) month=July; nummonth=7;; + Aug) month=August; nummonth=8;; + Sep) month=September; nummonth=9;; + Oct) month=October; nummonth=10;; + Nov) month=November; nummonth=11;; + Dec) month=December; nummonth=12;; + esac +done + +day=$2 + +# Here we have to deal with the problem that the ls output gives either +# the time of day or the year. +case $3 in + *:*) set `date`; eval year=\$$# + case $2 in + Jan) nummonthtod=1;; + Feb) nummonthtod=2;; + Mar) nummonthtod=3;; + Apr) nummonthtod=4;; + May) nummonthtod=5;; + Jun) nummonthtod=6;; + Jul) nummonthtod=7;; + Aug) nummonthtod=8;; + Sep) nummonthtod=9;; + Oct) nummonthtod=10;; + Nov) nummonthtod=11;; + Dec) nummonthtod=12;; + esac + # For the first six month of the year the time notation can also + # be used for files modified in the last year. + if (expr $nummonth \> $nummonthtod) > /dev/null; + then + year=`expr $year - 1` + fi;; + *) year=$3;; +esac + +# The result. +echo $day $month $year diff --git a/utils/missing b/utils/missing new file mode 100755 index 0000000..64b5f90 --- /dev/null +++ b/utils/missing @@ -0,0 +1,353 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2004-09-07.08 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 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 + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -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] + +Send bug reports to ." + exit 0 + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit 0 + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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 $msg. 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 $msg. 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 $msg. 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 + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. 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 $msg. 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 $msg. 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) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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 + + # 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 "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && 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 is $msg. + 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 prerequisites 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 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/utils/mkinstalldirs b/utils/mkinstalldirs new file mode 100755 index 0000000..259dbfc --- /dev/null +++ b/utils/mkinstalldirs @@ -0,0 +1,158 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2005-06-29.22 + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +errstatus=0 +dirmode= + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + case $file in + /*) pathcomp=/ ;; + *) pathcomp= ;; + esac + oIFS=$IFS + IFS=/ + set fnord $file + shift + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + 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 + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr= + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp=$pathcomp/ + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/utils/mkstamp b/utils/mkstamp new file mode 100755 index 0000000..ccc566a --- /dev/null +++ b/utils/mkstamp @@ -0,0 +1,9 @@ +#!/bin/sh +# mkstamp by Jeffrey Fulmer +# Sat Jan 19 16:31:45 EST 2002 + +# configure helper util which +# creates a date stamp for .siegerc + +exec date +"%B-%d-%Y" + diff --git a/utils/siege.config.in b/utils/siege.config.in new file mode 100644 index 0000000..ca9e4a7 --- /dev/null +++ b/utils/siege.config.in @@ -0,0 +1,23 @@ +#!%_SHELL% +# SCRIPT: siege.config +# AUTHOR: Jeffrey Fulmer +# DATE: Mon May 28 11:40:28 EDT 2001 +# SYNOP: This script generates an $HOME/.siegerc +# file from the doc/siegerc.in template. +# Its contents are added to this script by +# configure. The siegerc file template is +# maintained once in $(top_srcdir)/doc. + +rcfile="$HOME/.siegerc" + +if test -f $rcfile; then + echo "siege.config" + echo "usage: siege.config [no arguments]" + echo "----------------------------------" + echo "Resource file already install as $rcfile" + echo "Use your favorite editor to change your configuration by" + echo "editing the values in that file." + echo "" + exit +fi +cat > $rcfile << '_EOF_' diff --git a/utils/siege2csv.in b/utils/siege2csv.in new file mode 100644 index 0000000..e07db3c --- /dev/null +++ b/utils/siege2csv.in @@ -0,0 +1,242 @@ +#!%_PERL% +#siege2csv.pl is a perl script that parses the output from bombardmnet.sh +#into comma seperated values for easy use with spreadsheets. +#Copyright (C) 2001 Peter J. Hutnick + +#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, US + +#For information, write the author, Peter Hutnick at phutnick@aperian.com. + +open (INPUT, "< $ARGV[0]") + or die "Can't open data file or no data file specified.\n"; + +{ + +local $/ = undef; +@list = split('\n', ); # each line becomes an string in array list + +} + +close(INPUT); + +$numchunks = scalar(@list); # Find out how many strings, so we can drive + # loops + + +# This ugly thing is where all the work gets done. It maintains data +# associtivity by relying on the coinidence that all the data "just ends +# up" in order. I may try to clean this up at a future date. + +$usersub=0; +$transub=0; +$elapsub=0; +$datasub=0; +$respsub=0; +$tratesub=0; +$tputsub=0; +$consub=0; +$codesub=0; + +for ($i=0; $numchunks > $i; $i++) +{ + +# print $list[$i]; +# print "\n"; + if ($list[$i] =~ /.. Preparing \d* concurrent users.*/ ) + { +# print $list[$i]; print "\n"; + $numusers[$usersub] = $list[$i]; + $usersub++; + } + elsif ($list[$i] =~ /Transactions.*/) + { + $transactions[$transub] = $list[$i]; + $transub++; + } + elsif ($list[$i] =~ /Elapsed.*/) + { + $elapsed[$elapsub] = $list[$i]; + $elapsub++; + } + elsif ($list[$i] =~ /Data transferred.*/) + { + $data[$datasub] = $list[$i]; + $datasub++; + } + elsif ($list[$i] =~ /Response.*/) + { + $response[$respsub] = $list[$i]; + $respsub++; + } + elsif ($list[$i] =~ /Transaction rate.*/) + { + $trate[$tratesub] = $list[$i]; + $tratesub++; + } + elsif ($list[$i] =~ /Throughput.*/) + { + $tput[$tputsub] = $list[$i]; + $tputsub++; + } + elsif ($list[$i] =~ /Concurrency.*/) + { + $concurr[$consub] = $list[$i]; + $consub++; + } + elsif ($list[$i] =~ /Successful transactions.*/) + { + $code200[$codesub] = $list[$i]; + $codesub++; + } + + +} + + + +for ($i=0; $usersub > $i; $i++) +{ +# print "Number of Users\n"; + + $numusers[$i] =~ tr/a-zA-Z//d; + $numusers[$i] =~ tr/://d; + $numusers[$i] =~ tr/\.//d; + $numusers[$i] =~ tr/\*//d; + $numusers[$i] =~ tr/\t//d; + $numusers[$i] =~ tr/ //s; +# print $numusers[$i]; +} + +# These for loops _try_ to prune the strings down to the numeric +# values. The last one (code 200) does not work well because of the +# numeric elemnet of the description. + +# Also, I can't get rid of that last leading space. Doesn't seem to +# bother Excel 2000, but for neatness this should be addressed. + +# I don't know how to do perl functions. Clearly a function would be +# better here. + +for ($i=0; $transub > $i; $i++) +{ +# print "Number of Hits\n"; + + $transactions[$i] =~ tr/a-zA-Z//d; + $transactions[$i] =~ tr/://d; + $transactions[$i] =~ tr/\t//d; + $transactions[$i] =~ tr/ //s; +# print $transactions[$i]; +} + + +for ($i=0; $elapsub > $i; $i++) +{ +# print "Elapsed Time\n"; + + $elapsed[$i] =~ tr/a-zA-Z//d; + $elapsed[$i] =~ tr/://d; + $elapsed[$i] =~ tr/\t//d; + $elapsed[$i] =~ tr/ //s; +# print $elapsed[$i]; +} + + +for ($i=0; $datasub > $i; $i++) +{ +# print "Data Transferred\n"; + + $data[$i] =~ tr/a-zA-Z//d; + $data[$i] =~ tr/://d; + $data[$i] =~ tr/\t//d; + $data[$i] =~ tr/ //s; +# print $data[$i]; +} + + +for ($i=0; $respsub > $i; $i++) +{ +# print "Response Time\n"; + + $response[$i] =~ tr/a-zA-Z//d; + $response[$i] =~ tr/://d; + $response[$i] =~ tr/\t//d; + $response[$i] =~ tr/ //s; +# print $response[$i]; +} + + +for ($i=0; $tratesub > $i; $i++) +{ +# print "Transaction Rate\n"; + + $trate[$i] =~ tr/a-zA-Z//d; + $trate[$i] =~ tr/://d; + $trate[$i] =~ tr/\///d; + $trate[$i] =~ tr/\t//d; + $trate[$i] =~ tr/ //s; +# print $trate[$i]; +} + + +for ($i=0; $tputsub > $i; $i++) +{ +# print "Throughput\n"; + + $tput[$i] =~ tr/a-zA-Z//d; + $tput[$i] =~ tr/://d; + $tput[$i] =~ tr/\///d; + $tput[$i] =~ tr/\t//d; + $tput[$i] =~ tr/ //s; +# print $tput[$i]; +} + + +for ($i=0; $consub > $i; $i++) +{ +# print "Concurrency\n"; + + $concurr[$i] =~ tr/a-zA-Z//d; + $concurr[$i] =~ tr/://d; + $concurr[$i] =~ tr/\t//d; + $concurr[$i] =~ tr/ //s; +# print $concurr[$i]; +} +for ($i=0; $codesub > $i; $i++) +{ +# print "Code 200\n"; + + $code200[$i] =~ tr/a-zA-Z//d; + $code200[$i] =~ tr/200/ /d; + $code200[$i] =~ tr/\t//d; + $code200[$i] =~ tr/://d; + $code200[$i] =~ tr/ //s; +# print $code200[$i]; +} + +# Okay, data is as good as it is going to get. Let's start writing the +# output CSV file. + +open (OUTFILE, "> $ARGV[0].csv") + or die "Cannot write to designated output file: $!\n"; +# The next line sets up the colum titles. +# The leading comma in ",Transactions" causes the number of users colum to +# be titleless. I suppose it could be Users in front instead . . . +print OUTFILE ",Transactions,Elapsed Time,Data Transferred,Response Time,Transaction Rate,Throughput,Concurrency,Code 200 (note that this is horribly broken.) \n"; + +# Here we fill the data in the colums. +for ($i=0; $transub > $i; $i++) +{ + print OUTFILE $numusers[$i], ",", $transactions[$i], ",", +$elapsed[$i], ",", $data[$i], ",", $response[$i], ",", $trate[$i], ",", $tput[$i], ",", $concurr[$i], ",", $code200[$i]; + print OUTFILE "\n"; +} + + +close (OUTFILE);